aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs')
-rw-r--r--nx-X11/programs/Imakefile31
-rw-r--r--nx-X11/programs/Xserver/.gitignore2
-rw-r--r--nx-X11/programs/Xserver/GL/.gitignore341
-rw-r--r--nx-X11/programs/Xserver/GL/Imakefile45
-rw-r--r--nx-X11/programs/Xserver/GL/glx/Imakefile178
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_disptab.c838
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_disptab.h651
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.c4446
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.h158
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_render.c2280
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_renderswap.c3385
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_single.c1785
-rw-r--r--nx-X11/programs/Xserver/GL/glx/g_singleswap.c2206
-rw-r--r--nx-X11/programs/Xserver/GL/glx/global.c74
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxbuf.c295
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxbuf.h56
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxcmds.c2174
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxcmdsswap.c888
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxcontext.h163
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxdrawable.h111
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxerror.h57
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxext.c510
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxext.h130
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxfb.c182
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxfb.h51
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glximports.c186
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glximports.h65
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxmem.c150
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxmem.h47
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxpix.c131
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxpix.h47
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxscreens.c373
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxscreens.h102
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxserver.h326
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxutil.c433
-rw-r--r--nx-X11/programs/Xserver/GL/glx/glxutil.h77
-rw-r--r--nx-X11/programs/Xserver/GL/glx/impsize.h55
-rw-r--r--nx-X11/programs/Xserver/GL/glx/render2.c269
-rw-r--r--nx-X11/programs/Xserver/GL/glx/render2swap.c391
-rw-r--r--nx-X11/programs/Xserver/GL/glx/renderpix.c310
-rw-r--r--nx-X11/programs/Xserver/GL/glx/renderpixswap.c553
-rw-r--r--nx-X11/programs/Xserver/GL/glx/rensize.c1001
-rw-r--r--nx-X11/programs/Xserver/GL/glx/rensizetab.c2447
-rw-r--r--nx-X11/programs/Xserver/GL/glx/single2.c425
-rw-r--r--nx-X11/programs/Xserver/GL/glx/single2swap.c307
-rw-r--r--nx-X11/programs/Xserver/GL/glx/singlepix.c469
-rw-r--r--nx-X11/programs/Xserver/GL/glx/singlepixswap.c523
-rw-r--r--nx-X11/programs/Xserver/GL/glx/singlesize.c1221
-rw-r--r--nx-X11/programs/Xserver/GL/glx/singlesize.h86
-rw-r--r--nx-X11/programs/Xserver/GL/glx/unpack.h240
-rw-r--r--nx-X11/programs/Xserver/GL/glx/xfont.c193
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/GLcore/Imakefile52
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/Imakefile26
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/Imakefile.inc51
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/Imakefile63
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/Imakefile.inc98
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c950
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.c151
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.h105
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/X/xf86glxint.h101
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile36
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile.inc28
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/main/Imakefile40
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/main/Imakefile.inc481
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/math/Imakefile35
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/math/Imakefile.inc76
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/Imakefile40
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/Imakefile.inc100
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile37
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile.inc23
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile40
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile.inc84
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile30
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile.inc12
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile42
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile.inc212
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile34
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile.inc30
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile45
-rw-r--r--nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile.inc219
-rw-r--r--nx-X11/programs/Xserver/Imakefile573
-rw-r--r--nx-X11/programs/Xserver/Xext/Imakefile137
-rw-r--r--nx-X11/programs/Xserver/Xext/SecurityPolicy88
-rw-r--r--nx-X11/programs/Xserver/Xext/bigreq.c103
-rw-r--r--nx-X11/programs/Xserver/Xext/dpms.c435
-rw-r--r--nx-X11/programs/Xserver/Xext/dpmsproc.h15
-rw-r--r--nx-X11/programs/Xserver/Xext/dpmsstubs.c52
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiX.c1287
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiX.h113
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiXSwap.c136
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiXh.h77
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiXprocs.c2368
-rw-r--r--nx-X11/programs/Xserver/Xext/panoramiXsrv.h49
-rw-r--r--nx-X11/programs/Xserver/Xext/saver.c1395
-rw-r--r--nx-X11/programs/Xserver/Xext/security.c2177
-rw-r--r--nx-X11/programs/Xserver/Xext/shape.c1310
-rw-r--r--nx-X11/programs/Xserver/Xext/shm.c1305
-rw-r--r--nx-X11/programs/Xserver/Xext/shmint.h44
-rw-r--r--nx-X11/programs/Xserver/Xext/sleepuntil.c238
-rw-r--r--nx-X11/programs/Xserver/Xext/sleepuntil.h46
-rw-r--r--nx-X11/programs/Xserver/Xext/sync.c2479
-rw-r--r--nx-X11/programs/Xserver/Xext/xcmisc.c239
-rw-r--r--nx-X11/programs/Xserver/Xext/xf86bigfont.c792
-rw-r--r--nx-X11/programs/Xserver/Xext/xres.c314
-rw-r--r--nx-X11/programs/Xserver/Xext/xtest.c594
-rw-r--r--nx-X11/programs/Xserver/Xext/xtest1dd.c1612
-rw-r--r--nx-X11/programs/Xserver/Xext/xtest1dd.h126
-rw-r--r--nx-X11/programs/Xserver/Xext/xtest1di.c915
-rw-r--r--nx-X11/programs/Xserver/Xext/xvdisp.c2190
-rw-r--r--nx-X11/programs/Xserver/Xext/xvdisp.h1
-rw-r--r--nx-X11/programs/Xserver/Xext/xvdix.h290
-rw-r--r--nx-X11/programs/Xserver/Xext/xvmain.c1198
-rw-r--r--nx-X11/programs/Xserver/Xext/xvmc.c790
-rw-r--r--nx-X11/programs/Xserver/Xext/xvmcext.h115
-rw-r--r--nx-X11/programs/Xserver/Xi/Imakefile93
-rw-r--r--nx-X11/programs/Xserver/Xi/allowev.c139
-rw-r--r--nx-X11/programs/Xserver/Xi/allowev.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/chgdctl.c211
-rw-r--r--nx-X11/programs/Xserver/Xi/chgdctl.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/chgfctl.c645
-rw-r--r--nx-X11/programs/Xserver/Xi/chgfctl.h97
-rw-r--r--nx-X11/programs/Xserver/Xi/chgkbd.c208
-rw-r--r--nx-X11/programs/Xserver/Xi/chgkbd.h51
-rw-r--r--nx-X11/programs/Xserver/Xi/chgkmap.c130
-rw-r--r--nx-X11/programs/Xserver/Xi/chgkmap.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/chgprop.c163
-rw-r--r--nx-X11/programs/Xserver/Xi/chgprop.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/chgptr.c254
-rw-r--r--nx-X11/programs/Xserver/Xi/chgptr.h72
-rw-r--r--nx-X11/programs/Xserver/Xi/closedev.c185
-rw-r--r--nx-X11/programs/Xserver/Xi/closedev.h57
-rw-r--r--nx-X11/programs/Xserver/Xi/devbell.c167
-rw-r--r--nx-X11/programs/Xserver/Xi/devbell.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/exevents.c1363
-rw-r--r--nx-X11/programs/Xserver/Xi/exglobals.h79
-rw-r--r--nx-X11/programs/Xserver/Xi/extinit.c1002
-rw-r--r--nx-X11/programs/Xserver/Xi/getbmap.c146
-rw-r--r--nx-X11/programs/Xserver/Xi/getbmap.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/getdctl.c221
-rw-r--r--nx-X11/programs/Xserver/Xi/getdctl.h58
-rw-r--r--nx-X11/programs/Xserver/Xi/getfctl.c408
-rw-r--r--nx-X11/programs/Xserver/Xi/getfctl.h92
-rw-r--r--nx-X11/programs/Xserver/Xi/getfocus.c149
-rw-r--r--nx-X11/programs/Xserver/Xi/getfocus.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/getkmap.c170
-rw-r--r--nx-X11/programs/Xserver/Xi/getkmap.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/getmmap.c150
-rw-r--r--nx-X11/programs/Xserver/Xi/getmmap.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/getprop.c207
-rw-r--r--nx-X11/programs/Xserver/Xi/getprop.h59
-rw-r--r--nx-X11/programs/Xserver/Xi/getselev.c188
-rw-r--r--nx-X11/programs/Xserver/Xi/getselev.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/getvers.c150
-rw-r--r--nx-X11/programs/Xserver/Xi/getvers.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdev.c221
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdev.h60
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdevb.c159
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdevb.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdevk.c162
-rw-r--r--nx-X11/programs/Xserver/Xi/grabdevk.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/gtmotion.c203
-rw-r--r--nx-X11/programs/Xserver/Xi/gtmotion.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/listdev.c396
-rw-r--r--nx-X11/programs/Xserver/Xi/listdev.h102
-rw-r--r--nx-X11/programs/Xserver/Xi/opendev.c198
-rw-r--r--nx-X11/programs/Xserver/Xi/opendev.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/queryst.c206
-rw-r--r--nx-X11/programs/Xserver/Xi/queryst.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/selectev.c148
-rw-r--r--nx-X11/programs/Xserver/Xi/selectev.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/sendexev.c186
-rw-r--r--nx-X11/programs/Xserver/Xi/sendexev.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/setbmap.c162
-rw-r--r--nx-X11/programs/Xserver/Xi/setbmap.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/setdval.c166
-rw-r--r--nx-X11/programs/Xserver/Xi/setdval.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/setfocus.c120
-rw-r--r--nx-X11/programs/Xserver/Xi/setfocus.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/setmmap.c156
-rw-r--r--nx-X11/programs/Xserver/Xi/setmmap.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/setmode.c150
-rw-r--r--nx-X11/programs/Xserver/Xi/setmode.h50
-rw-r--r--nx-X11/programs/Xserver/Xi/stubs.c314
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdev.c117
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdev.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdevb.c172
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdevb.h43
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdevk.c178
-rw-r--r--nx-X11/programs/Xserver/Xi/ungrdevk.h43
-rw-r--r--nx-X11/programs/Xserver/composite/.gitignore0
-rw-r--r--nx-X11/programs/Xserver/composite/Imakefile29
-rw-r--r--nx-X11/programs/Xserver/composite/compalloc.c710
-rw-r--r--nx-X11/programs/Xserver/composite/compext.c1063
-rw-r--r--nx-X11/programs/Xserver/composite/compinit.c492
-rw-r--r--nx-X11/programs/Xserver/composite/compint.h360
-rw-r--r--nx-X11/programs/Xserver/composite/compositeext.h44
-rw-r--r--nx-X11/programs/Xserver/composite/compoverlay.c178
-rw-r--r--nx-X11/programs/Xserver/composite/compwindow.c909
-rw-r--r--nx-X11/programs/Xserver/damageext/Imakefile28
-rw-r--r--nx-X11/programs/Xserver/damageext/damageext.c475
-rw-r--r--nx-X11/programs/Xserver/damageext/damageext.h35
-rw-r--r--nx-X11/programs/Xserver/damageext/damageextint.h87
-rw-r--r--nx-X11/programs/Xserver/dbe/Imakefile18
-rw-r--r--nx-X11/programs/Xserver/dbe/dbe.c1986
-rw-r--r--nx-X11/programs/Xserver/dbe/dbestruct.h235
-rw-r--r--nx-X11/programs/Xserver/dbe/midbe.c847
-rw-r--r--nx-X11/programs/Xserver/dbe/midbe.h48
-rw-r--r--nx-X11/programs/Xserver/dbe/midbestr.h99
-rw-r--r--nx-X11/programs/Xserver/dix/Imakefile143
-rw-r--r--nx-X11/programs/Xserver/dix/atom.c210
-rw-r--r--nx-X11/programs/Xserver/dix/buildatoms43
-rw-r--r--nx-X11/programs/Xserver/dix/colormap.c2755
-rw-r--r--nx-X11/programs/Xserver/dix/cursor.c457
-rw-r--r--nx-X11/programs/Xserver/dix/devices.c1646
-rw-r--r--nx-X11/programs/Xserver/dix/dispatch.c4201
-rw-r--r--nx-X11/programs/Xserver/dix/dispatch.h146
-rw-r--r--nx-X11/programs/Xserver/dix/dixfonts.c2553
-rw-r--r--nx-X11/programs/Xserver/dix/dixutils.c923
-rw-r--r--nx-X11/programs/Xserver/dix/events.c4490
-rw-r--r--nx-X11/programs/Xserver/dix/extension.c456
-rw-r--r--nx-X11/programs/Xserver/dix/ffs.c36
-rw-r--r--nx-X11/programs/Xserver/dix/gc.c1286
-rw-r--r--nx-X11/programs/Xserver/dix/globals.c161
-rw-r--r--nx-X11/programs/Xserver/dix/glyphcurs.c195
-rw-r--r--nx-X11/programs/Xserver/dix/grabs.c435
-rw-r--r--nx-X11/programs/Xserver/dix/initatoms.c84
-rw-r--r--nx-X11/programs/Xserver/dix/main.c578
-rw-r--r--nx-X11/programs/Xserver/dix/pixmap.c150
-rw-r--r--nx-X11/programs/Xserver/dix/privates.c398
-rw-r--r--nx-X11/programs/Xserver/dix/property.c694
-rw-r--r--nx-X11/programs/Xserver/dix/region.c1742
-rw-r--r--nx-X11/programs/Xserver/dix/resource.c936
-rw-r--r--nx-X11/programs/Xserver/dix/swaprep.c1220
-rw-r--r--nx-X11/programs/Xserver/dix/swapreq.c1019
-rw-r--r--nx-X11/programs/Xserver/dix/tables.c510
-rw-r--r--nx-X11/programs/Xserver/dix/window.c3841
-rw-r--r--nx-X11/programs/Xserver/dix/xpstubs.c48
-rw-r--r--nx-X11/programs/Xserver/fb/Imakefile164
-rw-r--r--nx-X11/programs/Xserver/fb/fb.h2047
-rw-r--r--nx-X11/programs/Xserver/fb/fb24_32.c621
-rw-r--r--nx-X11/programs/Xserver/fb/fballpriv.c92
-rw-r--r--nx-X11/programs/Xserver/fb/fbarc.c119
-rw-r--r--nx-X11/programs/Xserver/fb/fbbits.c178
-rw-r--r--nx-X11/programs/Xserver/fb/fbbits.h960
-rw-r--r--nx-X11/programs/Xserver/fb/fbblt.c932
-rw-r--r--nx-X11/programs/Xserver/fb/fbbltone.c879
-rw-r--r--nx-X11/programs/Xserver/fb/fbbstore.c65
-rw-r--r--nx-X11/programs/Xserver/fb/fbcmap.c671
-rw-r--r--nx-X11/programs/Xserver/fb/fbcompose.c3628
-rw-r--r--nx-X11/programs/Xserver/fb/fbcopy.c636
-rw-r--r--nx-X11/programs/Xserver/fb/fbedge.c314
-rw-r--r--nx-X11/programs/Xserver/fb/fbedgeimp.h143
-rw-r--r--nx-X11/programs/Xserver/fb/fbfill.c215
-rw-r--r--nx-X11/programs/Xserver/fb/fbfillrect.c114
-rw-r--r--nx-X11/programs/Xserver/fb/fbfillsp.c102
-rw-r--r--nx-X11/programs/Xserver/fb/fbgc.c314
-rw-r--r--nx-X11/programs/Xserver/fb/fbgetsp.c87
-rw-r--r--nx-X11/programs/Xserver/fb/fbglyph.c476
-rw-r--r--nx-X11/programs/Xserver/fb/fbimage.c364
-rw-r--r--nx-X11/programs/Xserver/fb/fbline.c175
-rw-r--r--nx-X11/programs/Xserver/fb/fboverlay.c459
-rw-r--r--nx-X11/programs/Xserver/fb/fboverlay.h127
-rw-r--r--nx-X11/programs/Xserver/fb/fbpict.c1225
-rw-r--r--nx-X11/programs/Xserver/fb/fbpict.h610
-rw-r--r--nx-X11/programs/Xserver/fb/fbpixmap.c390
-rw-r--r--nx-X11/programs/Xserver/fb/fbpoint.c163
-rw-r--r--nx-X11/programs/Xserver/fb/fbpush.c246
-rw-r--r--nx-X11/programs/Xserver/fb/fbrop.h138
-rw-r--r--nx-X11/programs/Xserver/fb/fbscreen.c300
-rw-r--r--nx-X11/programs/Xserver/fb/fbseg.c728
-rw-r--r--nx-X11/programs/Xserver/fb/fbsetsp.c103
-rw-r--r--nx-X11/programs/Xserver/fb/fbsolid.c213
-rw-r--r--nx-X11/programs/Xserver/fb/fbstipple.c315
-rw-r--r--nx-X11/programs/Xserver/fb/fbtile.c203
-rw-r--r--nx-X11/programs/Xserver/fb/fbtrap.c240
-rw-r--r--nx-X11/programs/Xserver/fb/fbutil.c364
-rw-r--r--nx-X11/programs/Xserver/fb/fbwindow.c349
-rwxr-xr-xnx-X11/programs/Xserver/fix-miregion29
-rwxr-xr-xnx-X11/programs/Xserver/fix-miregion-private14
-rwxr-xr-xnx-X11/programs/Xserver/fix-region40
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/.gitignore3
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Agent.h136
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Args.c2613
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Args.h97
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Atoms.c796
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Atoms.h73
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Binder.c185
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Binder.h35
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/BitmapUtils.c118
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Client.c546
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Client.h128
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c1677
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.h69
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Colormap.c600
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Colormap.h92
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Composite.c207
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Composite.h59
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Cursor.c600
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Cursor.h117
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Dialog.c546
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Dialog.h216
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Display.c2963
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Display.h178
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Drawable.c3308
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Drawable.h229
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Error.c644
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Error.h47
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.c4767
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.h238
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Extensions.c470
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Extensions.h43
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Font.c1864
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Font.h85
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/GC.c1717
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/GCOps.c2104
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/GCOps.h113
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/GCs.h119
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Handlers.c1325
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Handlers.h129
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Holder.c235
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Holder.h35
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Icons.h39
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Image.c1828
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Image.h116
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Imakefile270
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Init.c581
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Init.h54
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keyboard.c1930
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keyboard.h135
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.c662
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.h90
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Literals.h213
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Millis.c78
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Millis.h38
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdamage.c225
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c1362
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c1543
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXevents.c613
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXextension.c195
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXglxext.c204
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXglyph.c381
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c180
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphRef.h60
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphSet.h64
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c743
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c123
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXpicture.c654
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXpicturestr_PictSolidFill.h63
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXproperty.c653
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXrender.c1730
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXresource.c595
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXshm.c547
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXwindow.c1127
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c245
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Options.c210
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Options.h479
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pixels.c392
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pixels.h188
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pixmap.c1660
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h145
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pointer.c199
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Pointer.h62
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Reconnect.c849
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Reconnect.h78
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Render.c3047
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Render.h119
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Rootless.c1291
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Rootless.h101
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Screen.c4741
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Screen.h149
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Splash.c424
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Splash.h54
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Split.c1256
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Split.h92
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/TestExt.c91
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Trap.c122
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Trap.h124
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Utils.h55
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Visual.c167
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Visual.h81
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Window.c3930
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Windows.h328
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xcomposite_nxagent.h106
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xfixes_nxagent.h90
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xinerama_nxagent.h74
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrandr_nxagent.h83
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrender_nxagent.h528
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrenderint_nxagent.h106
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/X11/include/xpm_nxagent.h259
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c50
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h45
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c120
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h44
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c349
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h44
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c50
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h45
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c4778
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h912
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile48
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c480
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h46
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c802
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h48
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Png.c730
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Png.h76
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c51
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h44
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c51
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h44
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Z.c309
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/compext/Z.h60
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/man/nxagent.11050
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm49
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm56
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/screensaver711
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/x2go.xpm163
-rw-r--r--nx-X11/programs/Xserver/include/.gitignore1
-rw-r--r--nx-X11/programs/Xserver/include/Imakefile54
-rw-r--r--nx-X11/programs/Xserver/include/XIstubs.h75
-rw-r--r--nx-X11/programs/Xserver/include/bstore.h22
-rw-r--r--nx-X11/programs/Xserver/include/bstorestr.h57
-rw-r--r--nx-X11/programs/Xserver/include/client.h60
-rw-r--r--nx-X11/programs/Xserver/include/closestr.h156
-rw-r--r--nx-X11/programs/Xserver/include/closure.h57
-rw-r--r--nx-X11/programs/Xserver/include/colormap.h186
-rw-r--r--nx-X11/programs/Xserver/include/colormapst.h120
-rw-r--r--nx-X11/programs/Xserver/include/cursor.h146
-rw-r--r--nx-X11/programs/Xserver/include/cursorstr.h93
-rw-r--r--nx-X11/programs/Xserver/include/dix.h786
-rw-r--r--nx-X11/programs/Xserver/include/dixevents.h105
-rw-r--r--nx-X11/programs/Xserver/include/dixfont.h174
-rw-r--r--nx-X11/programs/Xserver/include/dixfontstr.h96
-rw-r--r--nx-X11/programs/Xserver/include/dixgrabs.h58
-rw-r--r--nx-X11/programs/Xserver/include/dixstruct.h220
-rw-r--r--nx-X11/programs/Xserver/include/exevents.h182
-rw-r--r--nx-X11/programs/Xserver/include/extension.h65
-rw-r--r--nx-X11/programs/Xserver/include/extinit.h165
-rw-r--r--nx-X11/programs/Xserver/include/extnsionst.h150
-rw-r--r--nx-X11/programs/Xserver/include/gc.h190
-rw-r--r--nx-X11/programs/Xserver/include/gcstruct.h326
-rw-r--r--nx-X11/programs/Xserver/include/globals.h147
-rw-r--r--nx-X11/programs/Xserver/include/input.h389
-rw-r--r--nx-X11/programs/Xserver/include/inputstr.h312
-rw-r--r--nx-X11/programs/Xserver/include/list.h494
-rw-r--r--nx-X11/programs/Xserver/include/misc.h400
-rw-r--r--nx-X11/programs/Xserver/include/miscstruct.h78
-rw-r--r--nx-X11/programs/Xserver/include/opaque.h83
-rw-r--r--nx-X11/programs/Xserver/include/os.h555
-rw-r--r--nx-X11/programs/Xserver/include/pixmap.h108
-rw-r--r--nx-X11/programs/Xserver/include/pixmapstr.h87
-rw-r--r--nx-X11/programs/Xserver/include/property.h72
-rw-r--r--nx-X11/programs/Xserver/include/propertyst.h66
-rw-r--r--nx-X11/programs/Xserver/include/protocol-versions.h182
-rw-r--r--nx-X11/programs/Xserver/include/region.h53
-rw-r--r--nx-X11/programs/Xserver/include/regionstr.h411
-rw-r--r--nx-X11/programs/Xserver/include/resource.h272
-rw-r--r--nx-X11/programs/Xserver/include/rgb.h53
-rw-r--r--nx-X11/programs/Xserver/include/screenint.h110
-rw-r--r--nx-X11/programs/Xserver/include/scrnintstr.h756
-rw-r--r--nx-X11/programs/Xserver/include/selection.h68
-rw-r--r--nx-X11/programs/Xserver/include/servermd.h415
-rw-r--r--nx-X11/programs/Xserver/include/site.h133
-rw-r--r--nx-X11/programs/Xserver/include/swaprep.h310
-rw-r--r--nx-X11/programs/Xserver/include/swapreq.h119
-rw-r--r--nx-X11/programs/Xserver/include/validate.h40
-rw-r--r--nx-X11/programs/Xserver/include/window.h267
-rw-r--r--nx-X11/programs/Xserver/include/windowstr.h255
-rw-r--r--nx-X11/programs/Xserver/include/xkbfile.h479
-rw-r--r--nx-X11/programs/Xserver/include/xkbrules.h184
-rw-r--r--nx-X11/programs/Xserver/include/xkbsrv.h1181
-rw-r--r--nx-X11/programs/Xserver/include/xkbstr.h608
-rw-r--r--nx-X11/programs/Xserver/mi/Imakefile202
-rw-r--r--nx-X11/programs/Xserver/mi/cbrt.c46
-rw-r--r--nx-X11/programs/Xserver/mi/mi.h639
-rw-r--r--nx-X11/programs/Xserver/mi/miarc.c3721
-rw-r--r--nx-X11/programs/Xserver/mi/mibitblt.c845
-rw-r--r--nx-X11/programs/Xserver/mi/mibstore.c3897
-rw-r--r--nx-X11/programs/Xserver/mi/mibstore.h29
-rw-r--r--nx-X11/programs/Xserver/mi/mibstorest.h91
-rw-r--r--nx-X11/programs/Xserver/mi/miclipn.c82
-rw-r--r--nx-X11/programs/Xserver/mi/micmap.c696
-rw-r--r--nx-X11/programs/Xserver/mi/micmap.h64
-rw-r--r--nx-X11/programs/Xserver/mi/micoord.h70
-rw-r--r--nx-X11/programs/Xserver/mi/micursor.c75
-rw-r--r--nx-X11/programs/Xserver/mi/midash.c313
-rw-r--r--nx-X11/programs/Xserver/mi/midispcur.c813
-rw-r--r--nx-X11/programs/Xserver/mi/mieq.c204
-rw-r--r--nx-X11/programs/Xserver/mi/miexpose.c906
-rw-r--r--nx-X11/programs/Xserver/mi/mifillarc.c815
-rw-r--r--nx-X11/programs/Xserver/mi/mifillarc.h214
-rw-r--r--nx-X11/programs/Xserver/mi/mifillrct.c142
-rw-r--r--nx-X11/programs/Xserver/mi/mifpoly.h109
-rw-r--r--nx-X11/programs/Xserver/mi/mifpolycon.c282
-rw-r--r--nx-X11/programs/Xserver/mi/migc.c300
-rw-r--r--nx-X11/programs/Xserver/mi/migc.h72
-rw-r--r--nx-X11/programs/Xserver/mi/miglblt.c264
-rw-r--r--nx-X11/programs/Xserver/mi/miinitext.c488
-rw-r--r--nx-X11/programs/Xserver/mi/miline.h172
-rw-r--r--nx-X11/programs/Xserver/mi/mioverlay.c2077
-rw-r--r--nx-X11/programs/Xserver/mi/mioverlay.h32
-rw-r--r--nx-X11/programs/Xserver/mi/mipointer.c545
-rw-r--r--nx-X11/programs/Xserver/mi/mipointer.h160
-rw-r--r--nx-X11/programs/Xserver/mi/mipointrst.h62
-rw-r--r--nx-X11/programs/Xserver/mi/mipoly.c127
-rw-r--r--nx-X11/programs/Xserver/mi/mipoly.h215
-rw-r--r--nx-X11/programs/Xserver/mi/mipolycon.c246
-rw-r--r--nx-X11/programs/Xserver/mi/mipolygen.c230
-rw-r--r--nx-X11/programs/Xserver/mi/mipolypnt.c123
-rw-r--r--nx-X11/programs/Xserver/mi/mipolyrect.c191
-rw-r--r--nx-X11/programs/Xserver/mi/mipolyseg.c83
-rw-r--r--nx-X11/programs/Xserver/mi/mipolytext.c200
-rw-r--r--nx-X11/programs/Xserver/mi/mipolyutil.c399
-rw-r--r--nx-X11/programs/Xserver/mi/mipushpxl.c274
-rw-r--r--nx-X11/programs/Xserver/mi/miscanfill.h147
-rw-r--r--nx-X11/programs/Xserver/mi/miscrinit.c368
-rw-r--r--nx-X11/programs/Xserver/mi/mispans.c561
-rw-r--r--nx-X11/programs/Xserver/mi/mispans.h115
-rw-r--r--nx-X11/programs/Xserver/mi/misprite.c828
-rw-r--r--nx-X11/programs/Xserver/mi/misprite.h94
-rw-r--r--nx-X11/programs/Xserver/mi/mispritest.h132
-rw-r--r--nx-X11/programs/Xserver/mi/mistruct.h63
-rw-r--r--nx-X11/programs/Xserver/mi/mivalidate.h52
-rw-r--r--nx-X11/programs/Xserver/mi/mivaltree.c823
-rw-r--r--nx-X11/programs/Xserver/mi/miwideline.c2240
-rw-r--r--nx-X11/programs/Xserver/mi/miwideline.h222
-rw-r--r--nx-X11/programs/Xserver/mi/miwindow.c1187
-rw-r--r--nx-X11/programs/Xserver/mi/mizerarc.c853
-rw-r--r--nx-X11/programs/Xserver/mi/mizerarc.h132
-rw-r--r--nx-X11/programs/Xserver/mi/mizerclip.c635
-rw-r--r--nx-X11/programs/Xserver/mi/mizerline.c378
-rw-r--r--nx-X11/programs/Xserver/miext/cw/Imakefile22
-rw-r--r--nx-X11/programs/Xserver/miext/cw/cw.c701
-rw-r--r--nx-X11/programs/Xserver/miext/cw/cw.h173
-rw-r--r--nx-X11/programs/Xserver/miext/cw/cw_ops.c472
-rw-r--r--nx-X11/programs/Xserver/miext/cw/cw_render.c473
-rw-r--r--nx-X11/programs/Xserver/miext/damage/Imakefile29
-rw-r--r--nx-X11/programs/Xserver/miext/damage/damage.c1980
-rw-r--r--nx-X11/programs/Xserver/miext/damage/damage.h84
-rw-r--r--nx-X11/programs/Xserver/miext/damage/damagestr.h113
-rw-r--r--nx-X11/programs/Xserver/os/Imakefile262
-rw-r--r--nx-X11/programs/Xserver/os/WaitFor.c829
-rw-r--r--nx-X11/programs/Xserver/os/access.c2285
-rw-r--r--nx-X11/programs/Xserver/os/auth.c602
-rw-r--r--nx-X11/programs/Xserver/os/client.c397
-rw-r--r--nx-X11/programs/Xserver/os/connection.c1377
-rw-r--r--nx-X11/programs/Xserver/os/io.c1293
-rw-r--r--nx-X11/programs/Xserver/os/log.c779
-rw-r--r--nx-X11/programs/Xserver/os/mitauth.c197
-rw-r--r--nx-X11/programs/Xserver/os/oscolor.c1661
-rw-r--r--nx-X11/programs/Xserver/os/osdep.h313
-rw-r--r--nx-X11/programs/Xserver/os/osinit.c234
-rw-r--r--nx-X11/programs/Xserver/os/reallocarray.c43
-rw-r--r--nx-X11/programs/Xserver/os/rpcauth.c201
-rw-r--r--nx-X11/programs/Xserver/os/secauth.c203
-rw-r--r--nx-X11/programs/Xserver/os/strlcat.c57
-rw-r--r--nx-X11/programs/Xserver/os/strlcpy.c53
-rw-r--r--nx-X11/programs/Xserver/os/timingsafe_memcmp.c47
-rw-r--r--nx-X11/programs/Xserver/os/utils.c2260
-rw-r--r--nx-X11/programs/Xserver/os/xdmauth.c501
-rw-r--r--nx-X11/programs/Xserver/os/xdmcp.c1629
-rw-r--r--nx-X11/programs/Xserver/os/xprintf.c163
-rw-r--r--nx-X11/programs/Xserver/os/xstrans.c17
-rw-r--r--nx-X11/programs/Xserver/randr/Imakefile89
-rw-r--r--nx-X11/programs/Xserver/randr/panoramiXproto.h198
-rw-r--r--nx-X11/programs/Xserver/randr/randr.c793
-rw-r--r--nx-X11/programs/Xserver/randr/randrstr.h1212
-rw-r--r--nx-X11/programs/Xserver/randr/rrcrtc.c1883
-rw-r--r--nx-X11/programs/Xserver/randr/rrdispatch.c276
-rw-r--r--nx-X11/programs/Xserver/randr/rrinfo.c324
-rw-r--r--nx-X11/programs/Xserver/randr/rrmode.c435
-rw-r--r--nx-X11/programs/Xserver/randr/rrmonitor.c787
-rw-r--r--nx-X11/programs/Xserver/randr/rroutput.c650
-rw-r--r--nx-X11/programs/Xserver/randr/rrpointer.c182
-rw-r--r--nx-X11/programs/Xserver/randr/rrproperty.c738
-rw-r--r--nx-X11/programs/Xserver/randr/rrprovider.c486
-rw-r--r--nx-X11/programs/Xserver/randr/rrproviderproperty.c738
-rw-r--r--nx-X11/programs/Xserver/randr/rrscreen.c1207
-rw-r--r--nx-X11/programs/Xserver/randr/rrsdispatch.c671
-rw-r--r--nx-X11/programs/Xserver/randr/rrtransform.c297
-rw-r--r--nx-X11/programs/Xserver/randr/rrtransform.h79
-rw-r--r--nx-X11/programs/Xserver/randr/rrxinerama.c479
-rw-r--r--nx-X11/programs/Xserver/record/Imakefile26
-rw-r--r--nx-X11/programs/Xserver/record/record.c3047
-rw-r--r--nx-X11/programs/Xserver/record/set.c691
-rw-r--r--nx-X11/programs/Xserver/record/set.h147
-rw-r--r--nx-X11/programs/Xserver/render/Imakefile66
-rw-r--r--nx-X11/programs/Xserver/render/animcur.c400
-rw-r--r--nx-X11/programs/Xserver/render/filter.c364
-rw-r--r--nx-X11/programs/Xserver/render/glyph.c696
-rw-r--r--nx-X11/programs/Xserver/render/glyphstr.h154
-rw-r--r--nx-X11/programs/Xserver/render/matrix.c86
-rw-r--r--nx-X11/programs/Xserver/render/miindex.c355
-rw-r--r--nx-X11/programs/Xserver/render/mipict.c644
-rw-r--r--nx-X11/programs/Xserver/render/mipict.h214
-rw-r--r--nx-X11/programs/Xserver/render/mirect.c185
-rw-r--r--nx-X11/programs/Xserver/render/mitrap.c190
-rw-r--r--nx-X11/programs/Xserver/render/mitri.c190
-rw-r--r--nx-X11/programs/Xserver/render/picture.c1883
-rw-r--r--nx-X11/programs/Xserver/render/picture.h235
-rw-r--r--nx-X11/programs/Xserver/render/picturestr.h686
-rw-r--r--nx-X11/programs/Xserver/render/render.c3323
-rw-r--r--nx-X11/programs/Xserver/render/renderedge.c202
-rw-r--r--nx-X11/programs/Xserver/render/renderedge.h120
-rw-r--r--nx-X11/programs/Xserver/xfixes/Imakefile28
-rw-r--r--nx-X11/programs/Xserver/xfixes/cursor.c740
-rw-r--r--nx-X11/programs/Xserver/xfixes/region.c840
-rw-r--r--nx-X11/programs/Xserver/xfixes/saveset.c78
-rw-r--r--nx-X11/programs/Xserver/xfixes/select.c281
-rw-r--r--nx-X11/programs/Xserver/xfixes/xfixes.c231
-rw-r--r--nx-X11/programs/Xserver/xfixes/xfixes.h54
-rw-r--r--nx-X11/programs/Xserver/xfixes/xfixesint.h242
-rw-r--r--nx-X11/programs/Xserver/xkb/Imakefile81
-rw-r--r--nx-X11/programs/Xserver/xkb/XKBAlloc.c487
-rw-r--r--nx-X11/programs/Xserver/xkb/XKBGAlloc.c1006
-rw-r--r--nx-X11/programs/Xserver/xkb/XKBMAlloc.c1006
-rw-r--r--nx-X11/programs/Xserver/xkb/XKBMisc.c964
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxBeep.c338
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxConfig.c208
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxCtrls.c128
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxDevBtn.c99
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxFakeBtn.c58
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxFakeMtn.c118
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxInit.c45
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxKeyClick.c49
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxKillSrv.c66
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxLEDs.c71
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxList.c299
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxLoad.c908
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxPrivate.c43
-rw-r--r--nx-X11/programs/Xserver/xkb/ddxVT.c69
-rw-r--r--nx-X11/programs/Xserver/xkb/maprules.c1334
-rw-r--r--nx-X11/programs/Xserver/xkb/xkb.c6214
-rw-r--r--nx-X11/programs/Xserver/xkb/xkb.h70
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbAccessX.c744
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbActions.c1428
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbDflts.h517
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbEvents.c1048
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbInit.c1045
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbLEDs.c1064
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c185
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c81
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbSwap.c543
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbUtils.c979
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbconfig.c1335
-rw-r--r--nx-X11/programs/Xserver/xkb/xkberrs.c70
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbfmisc.c675
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbgeom.h655
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbout.c1051
-rw-r--r--nx-X11/programs/Xserver/xkb/xkbtext.c1326
-rw-r--r--nx-X11/programs/Xserver/xkb/xkmread.c1287
651 files changed, 325009 insertions, 0 deletions
diff --git a/nx-X11/programs/Imakefile b/nx-X11/programs/Imakefile
new file mode 100644
index 000000000..743851143
--- /dev/null
+++ b/nx-X11/programs/Imakefile
@@ -0,0 +1,31 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#define IHaveSubdirs
+#define PassCDebugFlags CDEBUGFLAGS="$(CDEBUGFLAGS)"
+
+#if BuildServer
+ XSSRCDIR = Xserver
+#endif
+
+SUBDIRS = $(XSSRCDIR)
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/nx-X11/programs/Xserver/.gitignore b/nx-X11/programs/Xserver/.gitignore
new file mode 100644
index 000000000..ea37aa3ef
--- /dev/null
+++ b/nx-X11/programs/Xserver/.gitignore
@@ -0,0 +1,2 @@
+nxagent
+nxagent.bak
diff --git a/nx-X11/programs/Xserver/GL/.gitignore b/nx-X11/programs/Xserver/GL/.gitignore
new file mode 100644
index 000000000..5231f1978
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/.gitignore
@@ -0,0 +1,341 @@
+glx/DONE
+glx/glcontextmodes.c
+glx/glcontextmodes.h
+glx/indirect_size.c
+glx/indirect_size.h
+mesa/X/DONE
+mesa/X/compsize.c
+mesa/X/driverfuncs.c
+mesa/X/driverfuncs.h
+mesa/X/xm_api.c
+mesa/X/xm_buffer.c
+mesa/X/xm_dd.c
+mesa/X/xm_line.c
+mesa/X/xm_span.c
+mesa/X/xm_tri.c
+mesa/array_cache/DONE
+mesa/array_cache/ac_context.c
+mesa/array_cache/ac_context.h
+mesa/array_cache/ac_import.c
+mesa/array_cache/acache.h
+mesa/main/DONE
+mesa/main/accum.c
+mesa/main/accum.h
+mesa/main/api_arrayelt.c
+mesa/main/api_arrayelt.h
+mesa/main/api_eval.h
+mesa/main/api_loopback.c
+mesa/main/api_loopback.h
+mesa/main/api_noop.c
+mesa/main/api_noop.h
+mesa/main/api_validate.c
+mesa/main/api_validate.h
+mesa/main/attrib.c
+mesa/main/attrib.h
+mesa/main/blend.c
+mesa/main/blend.h
+mesa/main/bufferobj.c
+mesa/main/bufferobj.h
+mesa/main/buffers.c
+mesa/main/buffers.h
+mesa/main/clip.c
+mesa/main/clip.h
+mesa/main/colormac.h
+mesa/main/colortab.c
+mesa/main/colortab.h
+mesa/main/config.h
+mesa/main/context.c
+mesa/main/context.h
+mesa/main/convolve.c
+mesa/main/convolve.h
+mesa/main/dd.h
+mesa/main/debug.c
+mesa/main/debug.h
+mesa/main/depth.c
+mesa/main/depth.h
+mesa/main/dispatch.c
+mesa/main/dlist.c
+mesa/main/dlist.h
+mesa/main/drawpix.c
+mesa/main/drawpix.h
+mesa/main/enable.c
+mesa/main/enable.h
+mesa/main/enums.c
+mesa/main/enums.h
+mesa/main/eval.c
+mesa/main/eval.h
+mesa/main/execmem.c
+mesa/main/extensions.c
+mesa/main/extensions.h
+mesa/main/fbobject.c
+mesa/main/fbobject.h
+mesa/main/feedback.c
+mesa/main/feedback.h
+mesa/main/fog.c
+mesa/main/fog.h
+mesa/main/framebuffer.c
+mesa/main/framebuffer.h
+mesa/main/get.c
+mesa/main/get.h
+mesa/main/getstring.c
+mesa/main/glapi.c
+mesa/main/glheader.h
+mesa/main/glthread.c
+mesa/main/hash.c
+mesa/main/hash.h
+mesa/main/hint.c
+mesa/main/hint.h
+mesa/main/histogram.c
+mesa/main/histogram.h
+mesa/main/image.c
+mesa/main/image.h
+mesa/main/imports.c
+mesa/main/imports.h
+mesa/main/light.c
+mesa/main/light.h
+mesa/main/lines.c
+mesa/main/lines.h
+mesa/main/macros.h
+mesa/main/matrix.c
+mesa/main/matrix.h
+mesa/main/mm.c
+mesa/main/mm.h
+mesa/main/mtypes.h
+mesa/main/occlude.c
+mesa/main/occlude.h
+mesa/main/pixel.c
+mesa/main/pixel.h
+mesa/main/points.c
+mesa/main/points.h
+mesa/main/polygon.c
+mesa/main/polygon.h
+mesa/main/rastpos.c
+mesa/main/rastpos.h
+mesa/main/renderbuffer.c
+mesa/main/renderbuffer.h
+mesa/main/simple_list.h
+mesa/main/state.c
+mesa/main/state.h
+mesa/main/stencil.c
+mesa/main/stencil.h
+mesa/main/texcompress.c
+mesa/main/texcompress.h
+mesa/main/texcompress_fxt1.c
+mesa/main/texcompress_s3tc.c
+mesa/main/texenvprogram.c
+mesa/main/texenvprogram.h
+mesa/main/texformat.c
+mesa/main/texformat.h
+mesa/main/texformat_tmp.h
+mesa/main/teximage.c
+mesa/main/teximage.h
+mesa/main/texobj.c
+mesa/main/texobj.h
+mesa/main/texrender.c
+mesa/main/texrender.h
+mesa/main/texstate.c
+mesa/main/texstate.h
+mesa/main/texstore.c
+mesa/main/texstore.h
+mesa/main/varray.c
+mesa/main/varray.h
+mesa/main/version.h
+mesa/main/vtxfmt.c
+mesa/main/vtxfmt.h
+mesa/main/vtxfmt_tmp.h
+mesa/math/DONE
+mesa/math/m_clip_tmp.h
+mesa/math/m_copy_tmp.h
+mesa/math/m_debug.h
+mesa/math/m_debug_clip.c
+mesa/math/m_debug_norm.c
+mesa/math/m_debug_util.h
+mesa/math/m_debug_xform.c
+mesa/math/m_dotprod_tmp.h
+mesa/math/m_eval.c
+mesa/math/m_eval.h
+mesa/math/m_matrix.c
+mesa/math/m_matrix.h
+mesa/math/m_norm_tmp.h
+mesa/math/m_trans_tmp.h
+mesa/math/m_translate.c
+mesa/math/m_translate.h
+mesa/math/m_vector.c
+mesa/math/m_vector.h
+mesa/math/m_xform.c
+mesa/math/m_xform.h
+mesa/math/m_xform_tmp.h
+mesa/math/mathmod.h
+mesa/shader/DONE
+mesa/shader/arbfragparse.c
+mesa/shader/arbfragparse.h
+mesa/shader/arbprogparse.c
+mesa/shader/arbprogparse.h
+mesa/shader/arbprogram.c
+mesa/shader/arbprogram.h
+mesa/shader/arbprogram_syn.h
+mesa/shader/arbvertparse.c
+mesa/shader/arbvertparse.h
+mesa/shader/atifragshader.c
+mesa/shader/atifragshader.h
+mesa/shader/grammar/DONE
+mesa/shader/grammar/grammar.c
+mesa/shader/grammar/grammar.h
+mesa/shader/grammar/grammar_mesa.c
+mesa/shader/grammar/grammar_mesa.h
+mesa/shader/grammar/grammar_syn.h
+mesa/shader/nvfragparse.c
+mesa/shader/nvfragparse.h
+mesa/shader/nvfragprog.h
+mesa/shader/nvprogram.c
+mesa/shader/nvprogram.h
+mesa/shader/nvvertexec.c
+mesa/shader/nvvertexec.h
+mesa/shader/nvvertparse.c
+mesa/shader/nvvertparse.h
+mesa/shader/nvvertprog.h
+mesa/shader/program.c
+mesa/shader/program.h
+mesa/shader/shaderobjects.c
+mesa/shader/shaderobjects.h
+mesa/shader/shaderobjects_3dlabs.c
+mesa/shader/shaderobjects_3dlabs.h
+mesa/shader/slang/DONE
+mesa/shader/slang/library/slang_common_builtin_gc.h
+mesa/shader/slang/library/slang_common_builtin_gc_bin.h
+mesa/shader/slang/library/slang_core_gc.h
+mesa/shader/slang/library/slang_core_gc_bin.h
+mesa/shader/slang/library/slang_fragment_builtin_gc.h
+mesa/shader/slang/library/slang_fragment_builtin_gc_bin.h
+mesa/shader/slang/library/slang_shader_syn.h
+mesa/shader/slang/library/slang_version_syn.h
+mesa/shader/slang/library/slang_vertex_builtin_gc.h
+mesa/shader/slang/library/slang_vertex_builtin_gc_bin.h
+mesa/shader/slang/slang_assemble.c
+mesa/shader/slang/slang_assemble.h
+mesa/shader/slang/slang_assemble_assignment.c
+mesa/shader/slang/slang_assemble_assignment.h
+mesa/shader/slang/slang_assemble_conditional.c
+mesa/shader/slang/slang_assemble_conditional.h
+mesa/shader/slang/slang_assemble_constructor.c
+mesa/shader/slang/slang_assemble_constructor.h
+mesa/shader/slang/slang_assemble_typeinfo.c
+mesa/shader/slang/slang_assemble_typeinfo.h
+mesa/shader/slang/slang_compile.c
+mesa/shader/slang/slang_compile.h
+mesa/shader/slang/slang_execute.c
+mesa/shader/slang/slang_execute.h
+mesa/shader/slang/slang_preprocess.c
+mesa/shader/slang/slang_preprocess.h
+mesa/shader/slang/slang_storage.c
+mesa/shader/slang/slang_storage.h
+mesa/shader/slang/slang_utility.c
+mesa/shader/slang/slang_utility.h
+mesa/shader/slang/traverse_wrap.h
+mesa/swrast/DONE
+mesa/swrast/s_aaline.c
+mesa/swrast/s_aaline.h
+mesa/swrast/s_aalinetemp.h
+mesa/swrast/s_aatriangle.c
+mesa/swrast/s_aatriangle.h
+mesa/swrast/s_aatritemp.h
+mesa/swrast/s_accum.c
+mesa/swrast/s_accum.h
+mesa/swrast/s_alpha.c
+mesa/swrast/s_alpha.h
+mesa/swrast/s_atifragshader.c
+mesa/swrast/s_atifragshader.h
+mesa/swrast/s_bitmap.c
+mesa/swrast/s_blend.c
+mesa/swrast/s_blend.h
+mesa/swrast/s_buffers.c
+mesa/swrast/s_context.c
+mesa/swrast/s_context.h
+mesa/swrast/s_copypix.c
+mesa/swrast/s_depth.c
+mesa/swrast/s_depth.h
+mesa/swrast/s_drawpix.c
+mesa/swrast/s_drawpix.h
+mesa/swrast/s_feedback.c
+mesa/swrast/s_feedback.h
+mesa/swrast/s_fog.c
+mesa/swrast/s_fog.h
+mesa/swrast/s_imaging.c
+mesa/swrast/s_lines.c
+mesa/swrast/s_lines.h
+mesa/swrast/s_linetemp.h
+mesa/swrast/s_logic.c
+mesa/swrast/s_logic.h
+mesa/swrast/s_masking.c
+mesa/swrast/s_masking.h
+mesa/swrast/s_nvfragprog.c
+mesa/swrast/s_nvfragprog.h
+mesa/swrast/s_pixeltex.c
+mesa/swrast/s_pixeltex.h
+mesa/swrast/s_points.c
+mesa/swrast/s_points.h
+mesa/swrast/s_pointtemp.h
+mesa/swrast/s_readpix.c
+mesa/swrast/s_span.c
+mesa/swrast/s_span.h
+mesa/swrast/s_spantemp.h
+mesa/swrast/s_stencil.c
+mesa/swrast/s_stencil.h
+mesa/swrast/s_texstore.c
+mesa/swrast/s_texture.c
+mesa/swrast/s_texture.h
+mesa/swrast/s_triangle.c
+mesa/swrast/s_triangle.h
+mesa/swrast/s_trispan.h
+mesa/swrast/s_tritemp.h
+mesa/swrast/s_zoom.c
+mesa/swrast/s_zoom.h
+mesa/swrast/swrast.h
+mesa/swrast_setup/DONE
+mesa/swrast_setup/ss_context.c
+mesa/swrast_setup/ss_context.h
+mesa/swrast_setup/ss_triangle.c
+mesa/swrast_setup/ss_triangle.h
+mesa/swrast_setup/ss_tritmp.h
+mesa/swrast_setup/swrast_setup.h
+mesa/tnl/DONE
+mesa/tnl/t_array_api.c
+mesa/tnl/t_array_api.h
+mesa/tnl/t_array_import.c
+mesa/tnl/t_array_import.h
+mesa/tnl/t_context.c
+mesa/tnl/t_context.h
+mesa/tnl/t_pipeline.c
+mesa/tnl/t_pipeline.h
+mesa/tnl/t_save_api.c
+mesa/tnl/t_save_api.h
+mesa/tnl/t_save_loopback.c
+mesa/tnl/t_save_playback.c
+mesa/tnl/t_vb_arbprogram.c
+mesa/tnl/t_vb_arbprogram.h
+mesa/tnl/t_vb_arbprogram_sse.c
+mesa/tnl/t_vb_cliptmp.h
+mesa/tnl/t_vb_cull.c
+mesa/tnl/t_vb_fog.c
+mesa/tnl/t_vb_light.c
+mesa/tnl/t_vb_lighttmp.h
+mesa/tnl/t_vb_normals.c
+mesa/tnl/t_vb_points.c
+mesa/tnl/t_vb_program.c
+mesa/tnl/t_vb_render.c
+mesa/tnl/t_vb_rendertmp.h
+mesa/tnl/t_vb_texgen.c
+mesa/tnl/t_vb_texmat.c
+mesa/tnl/t_vb_vertex.c
+mesa/tnl/t_vertex.c
+mesa/tnl/t_vertex.h
+mesa/tnl/t_vertex_generic.c
+mesa/tnl/t_vertex_sse.c
+mesa/tnl/t_vp_build.c
+mesa/tnl/t_vp_build.h
+mesa/tnl/t_vtx_api.c
+mesa/tnl/t_vtx_api.h
+mesa/tnl/t_vtx_eval.c
+mesa/tnl/t_vtx_exec.c
+mesa/tnl/t_vtx_generic.c
+mesa/tnl/tnl.h
diff --git a/nx-X11/programs/Xserver/GL/Imakefile b/nx-X11/programs/Xserver/GL/Imakefile
new file mode 100644
index 000000000..19b5902a5
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/Imakefile
@@ -0,0 +1,45 @@
+#define IHaveModules
+#include <Server.tmpl>
+
+#define IHaveSubdirs
+
+ CORE_SUBDIR = mesa
+
+SUBDIRS = glx $(CORE_SUBDIR)
+
+
+#if BuildModuleInSubdir
+SRCS = glx/module/?*.c $(MSRCS)
+OBJS = glx/module/?*.o $(MOBJS)
+#else
+SRCS = glx/?*.c $(MSRCS)
+OBJS = glx/?*.o $(MOBJS)
+#endif
+
+DONES = glx/DONE
+
+INCLUDES = -Iinclude -I$(SERVERSRC)/include -I$(SERVERSRC)/mi \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(XF86OSSRC)
+DEPEND_DEFINES = $(EXT_DEFINES) DependDefines
+DEFINES = $(GLX_DEFINES)
+
+#if HasParallelMake
+MakeMutex($(SUBDIRS) $(OBJS) $(DONES))
+#endif
+
+#if HasGnuMake || HasBsdMake
+$(DONES): $(SUBDIRS)
+#endif
+
+ModuleObjectRule()
+
+DepLibraryModuleTarget(glx,$(SUBDIRS) $(DONES) $(MOBJS),$(OBJS))
+
+InstallLibraryModule(glx,$(MODULEDIR),extensions)
+ForceSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+MakeLintLibSubdirs($(SUBDIRS))
+LintSubdirs($(SUBDIRS))
+
+InstallDriverSDKLibraryModule(glx,$(DRIVERSDKMODULEDIR),extensions)
diff --git a/nx-X11/programs/Xserver/GL/glx/Imakefile b/nx-X11/programs/Xserver/GL/glx/Imakefile
new file mode 100644
index 000000000..2ee2d17e6
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/Imakefile
@@ -0,0 +1,178 @@
+NULL =
+
+
+/* Large PIC tables needed for SPARC builds */
+#if defined(sparc) || defined(SparcArchitecture)
+# define LargePICTable YES
+ PICFLAGS = LargePositionIndependentCFlags
+#endif
+
+#include <Server.tmpl>
+
+LinkSourceFile(glcontextmodes.c, $(MESASRCDIR)/src/mesa/drivers/dri/common)
+LinkSourceFile(glcontextmodes.h, $(MESASRCDIR)/src/mesa/drivers/dri/common)
+LinkSourceFile(indirect_size.c, $(MESASRCDIR)/src/glx/x11)
+LinkSourceFile(indirect_size.h, $(MESASRCDIR)/src/glx/x11)
+
+#if (!(defined(NXAgentServer) && NXAgentServer))
+NXAGENT_SKIP_SRCS = \
+ glxext.c \
+ $(NULL)
+NXAGENT_SKIP_OBJS = \
+ glxext.o \
+ $(NULL)
+#else
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ SRCS = global.c \
+ glxbuf.c \
+ glxcmds.c \
+ glxcmdsswap.c \
+ glxfb.c \
+ glximports.c \
+ glxmem.c \
+ glxpix.c \
+ glxscreens.c \
+ glxutil.c \
+ render2.c \
+ render2swap.c \
+ renderpix.c \
+ renderpixswap.c \
+ rensize.c \
+ rensizetab.c \
+ single2.c \
+ single2swap.c \
+ singlepix.c \
+ singlepixswap.c \
+ singlesize.c \
+ xfont.c \
+ g_disptab.c \
+ g_disptab_EXT.c \
+ g_render.c \
+ g_renderswap.c \
+ g_single.c \
+ g_singleswap.c \
+ glcontextmodes.c \
+ indirect_size.c \
+ $(MSRCS) \
+ $(NXAGENT_SKIP_SRCS) \
+ $(NULL)
+
+ OBJS = global.o \
+ glxbuf.o \
+ glxcmds.o \
+ glxcmdsswap.o \
+ glxfb.o \
+ glximports.o \
+ glxmem.o \
+ glxpix.o \
+ glxscreens.o \
+ glxutil.o \
+ render2.o \
+ render2swap.o \
+ renderpix.o \
+ renderpixswap.o \
+ rensize.o \
+ rensizetab.o \
+ single2.o \
+ single2swap.o \
+ singlepix.o \
+ singlepixswap.o \
+ singlesize.o \
+ xfont.o \
+ g_disptab.o \
+ g_disptab_EXT.o \
+ g_render.o \
+ g_renderswap.o \
+ g_single.o \
+ g_singleswap.o \
+ glcontextmodes.o \
+ indirect_size.o \
+ $(MOBJS) \
+ $(NXAGENT_SKIP_OBJS) \
+ $(NULL)
+
+ INCLUDES = -I$(SERVERSRC)/GL/glx \
+ -I$(SERVERSRC)/GL/include \
+ -I$(SERVERSRC)/include \
+ -I$(INCLUDESRC) \
+ -I$(MESASRCDIR)/include \
+ -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/mi \
+ -I$(EXTINCSRC) \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) \
+ `pkg-config --cflags-only-I pixman-1` \
+ $(NULL)
+
+#if defined(DarwinArchitecture) && ((OSMajorVersion == 6 && OSMinorVersion < 3) || OSMajorVersion < 6)
+ NO_EXT_DEFS = -DMISSING_GL_EXTS
+#endif
+#if defined(Win32Architecture)
+# undef __stdcall
+ APIENTRY_DEFS = -DAPIENTRY=__stdcall
+#endif
+
+XCOMM If you add "-DDEBUG" in DEFINES, then make sure you also
+XCOMM add DEBUG to the define in ../mesa/src/X/xf86glx.c
+ DEFINES = \
+ $(GLX_DEFINES) \
+ $(NO_EXT_DEFS) \
+ $(APIENTRY_DEFS) \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(glx,$(OBJS))
+#if defined(GlxUseWindows) && GlxUseWindows
+clean::
+ RemoveFiles($(foreach obj,$(OBJS), stdcall/$(obj)))
+includes::
+ MakeDir(stdcall)
+SpecialObjectRule(stdcall/%.o,%.c,-DUSE_OPENGL32 -o $@)
+NormalLibraryTarget(glx_stdcall,$(foreach obj,$(OBJS), stdcall/$(obj)))
+#endif
+SubdirLibraryRule($(OBJS))
+
+LintLibraryTarget(glx,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+#ifdef LinkDirectory
+LinkSourceFile(global.c,LinkDirectory)
+LinkSourceFile(glxbuf.c,LinkDirectory)
+LinkSourceFile(glxcmds.c,LinkDirectory)
+LinkSourceFile(glxcmdsswap.c,LinkDirectory)
+LinkSourceFile(glxext.c,LinkDirectory)
+LinkSourceFile(glxfb.c,LinkDirectory)
+LinkSourceFile(glximports.c,LinkDirectory)
+LinkSourceFile(glxmem.c,LinkDirectory)
+LinkSourceFile(glxpix.c,LinkDirectory)
+LinkSourceFile(glxscreens.c,LinkDirectory)
+LinkSourceFile(glxutil.c,LinkDirectory)
+LinkSourceFile(render2.c,LinkDirectory)
+LinkSourceFile(render2swap.c,LinkDirectory)
+LinkSourceFile(renderpix.c,LinkDirectory)
+LinkSourceFile(renderpixswap.c,LinkDirectory)
+LinkSourceFile(rensize.c,LinkDirectory)
+LinkSourceFile(rensizetab.c,LinkDirectory)
+LinkSourceFile(single2.c,LinkDirectory)
+LinkSourceFile(single2swap.c,LinkDirectory)
+LinkSourceFile(singlepix.c,LinkDirectory)
+LinkSourceFile(singlepixswap.c,LinkDirectory)
+LinkSourceFile(singlesize.c,LinkDirectory)
+LinkSourceFile(xfont.c,LinkDirectory)
+LinkSourceFile(g_disptab.c,LinkDirectory)
+LinkSourceFile(g_disptab_EXT.c,LinkDirectory)
+LinkSourceFile(g_render.c,LinkDirectory)
+LinkSourceFile(g_renderswap.c,LinkDirectory)
+LinkSourceFile(g_single.c,LinkDirectory)
+LinkSourceFile(g_singleswap.c,LinkDirectory)
+#endif
diff --git a/nx-X11/programs/Xserver/GL/glx/g_disptab.c b/nx-X11/programs/Xserver/GL/glx/g_disptab.c
new file mode 100644
index 000000000..533bc6c9d
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_disptab.c
@@ -0,0 +1,838 @@
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+__GLXdispatchSingleProcPtr __glXSingleTable[__GLX_SINGLE_TABLE_SIZE] = {
+ __glXNoSuchSingleOpcode,
+ __glXRender,
+ __glXRenderLarge,
+ __glXCreateContext,
+ __glXDestroyContext,
+ __glXMakeCurrent,
+ __glXIsDirect,
+ __glXQueryVersion,
+ __glXWaitGL,
+ __glXWaitX,
+ __glXCopyContext,
+ __glXSwapBuffers,
+ __glXUseXFont,
+ __glXCreateGLXPixmap,
+ __glXGetVisualConfigs,
+ __glXDestroyGLXPixmap,
+ __glXVendorPrivate,
+ __glXVendorPrivateWithReply,
+ __glXQueryExtensionsString,
+ __glXQueryServerString,
+ __glXClientInfo,
+ __glXGetFBConfigs,
+ __glXCreatePixmap,
+ __glXDestroyGLXPixmap, /* glXDestroyPixmap */
+ __glXCreateNewContext,
+ __glXNoSuchSingleOpcode, /* glXQueryContext */
+ __glXMakeContextCurrent,
+ __glXNoSuchSingleOpcode, /* glXCreatePbuffer */
+ __glXNoSuchSingleOpcode, /* glXDestroyPbuffer */
+ __glXNoSuchSingleOpcode, /* glXGetDrawableAttributes */
+ __glXNoSuchSingleOpcode, /* glXChangeDrawableAttributes */
+ __glXNoSuchSingleOpcode, /* glXCreateWindow */
+ __glXNoSuchSingleOpcode, /* glXDestroyWindow */
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXDisp_NewList,
+ __glXDisp_EndList,
+ __glXDisp_DeleteLists,
+ __glXDisp_GenLists,
+ __glXDisp_FeedbackBuffer,
+ __glXDisp_SelectBuffer,
+ __glXDisp_RenderMode,
+ __glXDisp_Finish,
+ __glXDisp_PixelStoref,
+ __glXDisp_PixelStorei,
+ __glXDisp_ReadPixels,
+ __glXDisp_GetBooleanv,
+ __glXDisp_GetClipPlane,
+ __glXDisp_GetDoublev,
+ __glXDisp_GetError,
+ __glXDisp_GetFloatv,
+ __glXDisp_GetIntegerv,
+ __glXDisp_GetLightfv,
+ __glXDisp_GetLightiv,
+ __glXDisp_GetMapdv,
+ __glXDisp_GetMapfv,
+ __glXDisp_GetMapiv,
+ __glXDisp_GetMaterialfv,
+ __glXDisp_GetMaterialiv,
+ __glXDisp_GetPixelMapfv,
+ __glXDisp_GetPixelMapuiv,
+ __glXDisp_GetPixelMapusv,
+ __glXDisp_GetPolygonStipple,
+ __glXDisp_GetString,
+ __glXDisp_GetTexEnvfv,
+ __glXDisp_GetTexEnviv,
+ __glXDisp_GetTexGendv,
+ __glXDisp_GetTexGenfv,
+ __glXDisp_GetTexGeniv,
+ __glXDisp_GetTexImage,
+ __glXDisp_GetTexParameterfv,
+ __glXDisp_GetTexParameteriv,
+ __glXDisp_GetTexLevelParameterfv,
+ __glXDisp_GetTexLevelParameteriv,
+ __glXDisp_IsEnabled,
+ __glXDisp_IsList,
+ __glXDisp_Flush,
+ __glXDisp_AreTexturesResident,
+ __glXDisp_DeleteTextures,
+ __glXDisp_GenTextures,
+ __glXDisp_IsTexture,
+ __glXDisp_GetColorTable,
+ __glXDisp_GetColorTableParameterfv,
+ __glXDisp_GetColorTableParameteriv,
+ __glXDisp_GetConvolutionFilter,
+ __glXDisp_GetConvolutionParameterfv,
+ __glXDisp_GetConvolutionParameteriv,
+ __glXDisp_GetSeparableFilter,
+ __glXDisp_GetHistogram,
+ __glXDisp_GetHistogramParameterfv,
+ __glXDisp_GetHistogramParameteriv,
+ __glXDisp_GetMinmax,
+ __glXDisp_GetMinmaxParameterfv,
+ __glXDisp_GetMinmaxParameteriv,
+};
+
+__GLXdispatchRenderProcPtr __glXRenderTable[] = {
+ __glXNoSuchRenderOpcode,
+ __glXDisp_CallList,
+ __glXDisp_CallLists,
+ __glXDisp_ListBase,
+ __glXDisp_Begin,
+ __glXDisp_Bitmap,
+ __glXDisp_Color3bv,
+ __glXDisp_Color3dv,
+ __glXDisp_Color3fv,
+ __glXDisp_Color3iv,
+ __glXDisp_Color3sv,
+ __glXDisp_Color3ubv,
+ __glXDisp_Color3uiv,
+ __glXDisp_Color3usv,
+ __glXDisp_Color4bv,
+ __glXDisp_Color4dv,
+ __glXDisp_Color4fv,
+ __glXDisp_Color4iv,
+ __glXDisp_Color4sv,
+ __glXDisp_Color4ubv,
+ __glXDisp_Color4uiv,
+ __glXDisp_Color4usv,
+ __glXDisp_EdgeFlagv,
+ __glXDisp_End,
+ __glXDisp_Indexdv,
+ __glXDisp_Indexfv,
+ __glXDisp_Indexiv,
+ __glXDisp_Indexsv,
+ __glXDisp_Normal3bv,
+ __glXDisp_Normal3dv,
+ __glXDisp_Normal3fv,
+ __glXDisp_Normal3iv,
+ __glXDisp_Normal3sv,
+ __glXDisp_RasterPos2dv,
+ __glXDisp_RasterPos2fv,
+ __glXDisp_RasterPos2iv,
+ __glXDisp_RasterPos2sv,
+ __glXDisp_RasterPos3dv,
+ __glXDisp_RasterPos3fv,
+ __glXDisp_RasterPos3iv,
+ __glXDisp_RasterPos3sv,
+ __glXDisp_RasterPos4dv,
+ __glXDisp_RasterPos4fv,
+ __glXDisp_RasterPos4iv,
+ __glXDisp_RasterPos4sv,
+ __glXDisp_Rectdv,
+ __glXDisp_Rectfv,
+ __glXDisp_Rectiv,
+ __glXDisp_Rectsv,
+ __glXDisp_TexCoord1dv,
+ __glXDisp_TexCoord1fv,
+ __glXDisp_TexCoord1iv,
+ __glXDisp_TexCoord1sv,
+ __glXDisp_TexCoord2dv,
+ __glXDisp_TexCoord2fv,
+ __glXDisp_TexCoord2iv,
+ __glXDisp_TexCoord2sv,
+ __glXDisp_TexCoord3dv,
+ __glXDisp_TexCoord3fv,
+ __glXDisp_TexCoord3iv,
+ __glXDisp_TexCoord3sv,
+ __glXDisp_TexCoord4dv,
+ __glXDisp_TexCoord4fv,
+ __glXDisp_TexCoord4iv,
+ __glXDisp_TexCoord4sv,
+ __glXDisp_Vertex2dv,
+ __glXDisp_Vertex2fv,
+ __glXDisp_Vertex2iv,
+ __glXDisp_Vertex2sv,
+ __glXDisp_Vertex3dv,
+ __glXDisp_Vertex3fv,
+ __glXDisp_Vertex3iv,
+ __glXDisp_Vertex3sv,
+ __glXDisp_Vertex4dv,
+ __glXDisp_Vertex4fv,
+ __glXDisp_Vertex4iv,
+ __glXDisp_Vertex4sv,
+ __glXDisp_ClipPlane,
+ __glXDisp_ColorMaterial,
+ __glXDisp_CullFace,
+ __glXDisp_Fogf,
+ __glXDisp_Fogfv,
+ __glXDisp_Fogi,
+ __glXDisp_Fogiv,
+ __glXDisp_FrontFace,
+ __glXDisp_Hint,
+ __glXDisp_Lightf,
+ __glXDisp_Lightfv,
+ __glXDisp_Lighti,
+ __glXDisp_Lightiv,
+ __glXDisp_LightModelf,
+ __glXDisp_LightModelfv,
+ __glXDisp_LightModeli,
+ __glXDisp_LightModeliv,
+ __glXDisp_LineStipple,
+ __glXDisp_LineWidth,
+ __glXDisp_Materialf,
+ __glXDisp_Materialfv,
+ __glXDisp_Materiali,
+ __glXDisp_Materialiv,
+ __glXDisp_PointSize,
+ __glXDisp_PolygonMode,
+ __glXDisp_PolygonStipple,
+ __glXDisp_Scissor,
+ __glXDisp_ShadeModel,
+ __glXDisp_TexParameterf,
+ __glXDisp_TexParameterfv,
+ __glXDisp_TexParameteri,
+ __glXDisp_TexParameteriv,
+ __glXDisp_TexImage1D,
+ __glXDisp_TexImage2D,
+ __glXDisp_TexEnvf,
+ __glXDisp_TexEnvfv,
+ __glXDisp_TexEnvi,
+ __glXDisp_TexEnviv,
+ __glXDisp_TexGend,
+ __glXDisp_TexGendv,
+ __glXDisp_TexGenf,
+ __glXDisp_TexGenfv,
+ __glXDisp_TexGeni,
+ __glXDisp_TexGeniv,
+ __glXDisp_InitNames,
+ __glXDisp_LoadName,
+ __glXDisp_PassThrough,
+ __glXDisp_PopName,
+ __glXDisp_PushName,
+ __glXDisp_DrawBuffer,
+ __glXDisp_Clear,
+ __glXDisp_ClearAccum,
+ __glXDisp_ClearIndex,
+ __glXDisp_ClearColor,
+ __glXDisp_ClearStencil,
+ __glXDisp_ClearDepth,
+ __glXDisp_StencilMask,
+ __glXDisp_ColorMask,
+ __glXDisp_DepthMask,
+ __glXDisp_IndexMask,
+ __glXDisp_Accum,
+ __glXDisp_Disable,
+ __glXDisp_Enable,
+ __glXNoSuchRenderOpcode,
+ __glXDisp_PopAttrib,
+ __glXDisp_PushAttrib,
+ __glXDisp_Map1d,
+ __glXDisp_Map1f,
+ __glXDisp_Map2d,
+ __glXDisp_Map2f,
+ __glXDisp_MapGrid1d,
+ __glXDisp_MapGrid1f,
+ __glXDisp_MapGrid2d,
+ __glXDisp_MapGrid2f,
+ __glXDisp_EvalCoord1dv,
+ __glXDisp_EvalCoord1fv,
+ __glXDisp_EvalCoord2dv,
+ __glXDisp_EvalCoord2fv,
+ __glXDisp_EvalMesh1,
+ __glXDisp_EvalPoint1,
+ __glXDisp_EvalMesh2,
+ __glXDisp_EvalPoint2,
+ __glXDisp_AlphaFunc,
+ __glXDisp_BlendFunc,
+ __glXDisp_LogicOp,
+ __glXDisp_StencilFunc,
+ __glXDisp_StencilOp,
+ __glXDisp_DepthFunc,
+ __glXDisp_PixelZoom,
+ __glXDisp_PixelTransferf,
+ __glXDisp_PixelTransferi,
+ __glXDisp_PixelMapfv,
+ __glXDisp_PixelMapuiv,
+ __glXDisp_PixelMapusv,
+ __glXDisp_ReadBuffer,
+ __glXDisp_CopyPixels,
+ __glXDisp_DrawPixels,
+ __glXDisp_DepthRange,
+ __glXDisp_Frustum,
+ __glXDisp_LoadIdentity,
+ __glXDisp_LoadMatrixf,
+ __glXDisp_LoadMatrixd,
+ __glXDisp_MatrixMode,
+ __glXDisp_MultMatrixf,
+ __glXDisp_MultMatrixd,
+ __glXDisp_Ortho,
+ __glXDisp_PopMatrix,
+ __glXDisp_PushMatrix,
+ __glXDisp_Rotated,
+ __glXDisp_Rotatef,
+ __glXDisp_Scaled,
+ __glXDisp_Scalef,
+ __glXDisp_Translated,
+ __glXDisp_Translatef,
+ __glXDisp_Viewport,
+ __glXDisp_PolygonOffset,
+ __glXDisp_DrawArrays,
+ __glXDisp_Indexubv,
+ __glXDisp_ColorSubTable,
+ __glXDisp_CopyColorSubTable,
+ __glXDisp_ActiveTextureARB,
+ __glXDisp_MultiTexCoord1dvARB,
+ __glXDisp_MultiTexCoord1fvARB,
+ __glXDisp_MultiTexCoord1ivARB,
+ __glXDisp_MultiTexCoord1svARB,
+ __glXDisp_MultiTexCoord2dvARB,
+ __glXDisp_MultiTexCoord2fvARB,
+ __glXDisp_MultiTexCoord2ivARB,
+ __glXDisp_MultiTexCoord2svARB,
+ __glXDisp_MultiTexCoord3dvARB,
+ __glXDisp_MultiTexCoord3fvARB,
+ __glXDisp_MultiTexCoord3ivARB,
+ __glXDisp_MultiTexCoord3svARB,
+ __glXDisp_MultiTexCoord4dvARB,
+ __glXDisp_MultiTexCoord4fvARB,
+ __glXDisp_MultiTexCoord4ivARB,
+ __glXDisp_MultiTexCoord4svARB, /* 213 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 220 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXDisp_SampleCoverageARB,
+#ifndef MISSING_GL_EXTS
+ __glXDisp_WindowPos3fARB /* 230 */
+#else
+ __glXNoSuchRenderOpcode
+#endif
+};
+
+__GLXdispatchSingleProcPtr __glXSwapSingleTable[__GLX_SINGLE_TABLE_SIZE] = {
+ __glXNoSuchSingleOpcode,
+ __glXSwapRender,
+ __glXSwapRenderLarge,
+ __glXSwapCreateContext,
+ __glXSwapDestroyContext,
+ __glXSwapMakeCurrent,
+ __glXSwapIsDirect,
+ __glXSwapQueryVersion,
+ __glXSwapWaitGL,
+ __glXSwapWaitX,
+ __glXSwapCopyContext,
+ __glXSwapSwapBuffers,
+ __glXSwapUseXFont,
+ __glXSwapCreateGLXPixmap,
+ __glXSwapGetVisualConfigs,
+ __glXSwapDestroyGLXPixmap,
+ __glXSwapVendorPrivate,
+ __glXSwapVendorPrivateWithReply,
+ __glXSwapQueryExtensionsString,
+ __glXSwapQueryServerString,
+ __glXSwapClientInfo,
+ __glXSwapGetFBConfigs,
+ __glXSwapCreatePixmap,
+ __glXSwapDestroyGLXPixmap, /* glXDestroyPixmap */
+ __glXSwapCreateNewContext,
+ __glXNoSuchSingleOpcode, /* glXQueryContext */
+ __glXSwapMakeContextCurrent,
+ __glXNoSuchSingleOpcode, /* glXCreatePbuffer */
+ __glXNoSuchSingleOpcode, /* glXDestroyPbuffer */
+ __glXNoSuchSingleOpcode, /* glXGetDrawableAttributes */
+ __glXNoSuchSingleOpcode, /* glXChangeDrawableAttributes */
+ __glXNoSuchSingleOpcode, /* glXCreateWindow */
+ __glXNoSuchSingleOpcode, /* glXDestroyWindow */
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXNoSuchSingleOpcode,
+ __glXDispSwap_NewList,
+ __glXDispSwap_EndList,
+ __glXDispSwap_DeleteLists,
+ __glXDispSwap_GenLists,
+ __glXDispSwap_FeedbackBuffer,
+ __glXDispSwap_SelectBuffer,
+ __glXDispSwap_RenderMode,
+ __glXDispSwap_Finish,
+ __glXDispSwap_PixelStoref,
+ __glXDispSwap_PixelStorei,
+ __glXDispSwap_ReadPixels,
+ __glXDispSwap_GetBooleanv,
+ __glXDispSwap_GetClipPlane,
+ __glXDispSwap_GetDoublev,
+ __glXDispSwap_GetError,
+ __glXDispSwap_GetFloatv,
+ __glXDispSwap_GetIntegerv,
+ __glXDispSwap_GetLightfv,
+ __glXDispSwap_GetLightiv,
+ __glXDispSwap_GetMapdv,
+ __glXDispSwap_GetMapfv,
+ __glXDispSwap_GetMapiv,
+ __glXDispSwap_GetMaterialfv,
+ __glXDispSwap_GetMaterialiv,
+ __glXDispSwap_GetPixelMapfv,
+ __glXDispSwap_GetPixelMapuiv,
+ __glXDispSwap_GetPixelMapusv,
+ __glXDispSwap_GetPolygonStipple,
+ __glXDispSwap_GetString,
+ __glXDispSwap_GetTexEnvfv,
+ __glXDispSwap_GetTexEnviv,
+ __glXDispSwap_GetTexGendv,
+ __glXDispSwap_GetTexGenfv,
+ __glXDispSwap_GetTexGeniv,
+ __glXDispSwap_GetTexImage,
+ __glXDispSwap_GetTexParameterfv,
+ __glXDispSwap_GetTexParameteriv,
+ __glXDispSwap_GetTexLevelParameterfv,
+ __glXDispSwap_GetTexLevelParameteriv,
+ __glXDispSwap_IsEnabled,
+ __glXDispSwap_IsList,
+ __glXDispSwap_Flush,
+ __glXDispSwap_AreTexturesResident,
+ __glXDispSwap_DeleteTextures,
+ __glXDispSwap_GenTextures,
+ __glXDispSwap_IsTexture,
+ __glXDispSwap_GetColorTable,
+ __glXDispSwap_GetColorTableParameterfv,
+ __glXDispSwap_GetColorTableParameteriv,
+ __glXDispSwap_GetConvolutionFilter,
+ __glXDispSwap_GetConvolutionParameterfv,
+ __glXDispSwap_GetConvolutionParameteriv,
+ __glXDispSwap_GetSeparableFilter,
+ __glXDispSwap_GetHistogram,
+ __glXDispSwap_GetHistogramParameterfv,
+ __glXDispSwap_GetHistogramParameteriv,
+ __glXDispSwap_GetMinmax,
+ __glXDispSwap_GetMinmaxParameterfv,
+ __glXDispSwap_GetMinmaxParameteriv,
+};
+
+__GLXdispatchRenderProcPtr __glXSwapRenderTable[__GLX_RENDER_TABLE_SIZE] = {
+ __glXNoSuchRenderOpcode,
+ __glXDispSwap_CallList,
+ __glXDispSwap_CallLists,
+ __glXDispSwap_ListBase,
+ __glXDispSwap_Begin,
+ __glXDispSwap_Bitmap,
+ __glXDispSwap_Color3bv,
+ __glXDispSwap_Color3dv,
+ __glXDispSwap_Color3fv,
+ __glXDispSwap_Color3iv,
+ __glXDispSwap_Color3sv,
+ __glXDispSwap_Color3ubv,
+ __glXDispSwap_Color3uiv,
+ __glXDispSwap_Color3usv,
+ __glXDispSwap_Color4bv,
+ __glXDispSwap_Color4dv,
+ __glXDispSwap_Color4fv,
+ __glXDispSwap_Color4iv,
+ __glXDispSwap_Color4sv,
+ __glXDispSwap_Color4ubv,
+ __glXDispSwap_Color4uiv,
+ __glXDispSwap_Color4usv,
+ __glXDispSwap_EdgeFlagv,
+ __glXDispSwap_End,
+ __glXDispSwap_Indexdv,
+ __glXDispSwap_Indexfv,
+ __glXDispSwap_Indexiv,
+ __glXDispSwap_Indexsv,
+ __glXDispSwap_Normal3bv,
+ __glXDispSwap_Normal3dv,
+ __glXDispSwap_Normal3fv,
+ __glXDispSwap_Normal3iv,
+ __glXDispSwap_Normal3sv,
+ __glXDispSwap_RasterPos2dv,
+ __glXDispSwap_RasterPos2fv,
+ __glXDispSwap_RasterPos2iv,
+ __glXDispSwap_RasterPos2sv,
+ __glXDispSwap_RasterPos3dv,
+ __glXDispSwap_RasterPos3fv,
+ __glXDispSwap_RasterPos3iv,
+ __glXDispSwap_RasterPos3sv,
+ __glXDispSwap_RasterPos4dv,
+ __glXDispSwap_RasterPos4fv,
+ __glXDispSwap_RasterPos4iv,
+ __glXDispSwap_RasterPos4sv,
+ __glXDispSwap_Rectdv,
+ __glXDispSwap_Rectfv,
+ __glXDispSwap_Rectiv,
+ __glXDispSwap_Rectsv,
+ __glXDispSwap_TexCoord1dv,
+ __glXDispSwap_TexCoord1fv,
+ __glXDispSwap_TexCoord1iv,
+ __glXDispSwap_TexCoord1sv,
+ __glXDispSwap_TexCoord2dv,
+ __glXDispSwap_TexCoord2fv,
+ __glXDispSwap_TexCoord2iv,
+ __glXDispSwap_TexCoord2sv,
+ __glXDispSwap_TexCoord3dv,
+ __glXDispSwap_TexCoord3fv,
+ __glXDispSwap_TexCoord3iv,
+ __glXDispSwap_TexCoord3sv,
+ __glXDispSwap_TexCoord4dv,
+ __glXDispSwap_TexCoord4fv,
+ __glXDispSwap_TexCoord4iv,
+ __glXDispSwap_TexCoord4sv,
+ __glXDispSwap_Vertex2dv,
+ __glXDispSwap_Vertex2fv,
+ __glXDispSwap_Vertex2iv,
+ __glXDispSwap_Vertex2sv,
+ __glXDispSwap_Vertex3dv,
+ __glXDispSwap_Vertex3fv,
+ __glXDispSwap_Vertex3iv,
+ __glXDispSwap_Vertex3sv,
+ __glXDispSwap_Vertex4dv,
+ __glXDispSwap_Vertex4fv,
+ __glXDispSwap_Vertex4iv,
+ __glXDispSwap_Vertex4sv,
+ __glXDispSwap_ClipPlane,
+ __glXDispSwap_ColorMaterial,
+ __glXDispSwap_CullFace,
+ __glXDispSwap_Fogf,
+ __glXDispSwap_Fogfv,
+ __glXDispSwap_Fogi,
+ __glXDispSwap_Fogiv,
+ __glXDispSwap_FrontFace,
+ __glXDispSwap_Hint,
+ __glXDispSwap_Lightf,
+ __glXDispSwap_Lightfv,
+ __glXDispSwap_Lighti,
+ __glXDispSwap_Lightiv,
+ __glXDispSwap_LightModelf,
+ __glXDispSwap_LightModelfv,
+ __glXDispSwap_LightModeli,
+ __glXDispSwap_LightModeliv,
+ __glXDispSwap_LineStipple,
+ __glXDispSwap_LineWidth,
+ __glXDispSwap_Materialf,
+ __glXDispSwap_Materialfv,
+ __glXDispSwap_Materiali,
+ __glXDispSwap_Materialiv,
+ __glXDispSwap_PointSize,
+ __glXDispSwap_PolygonMode,
+ __glXDispSwap_PolygonStipple,
+ __glXDispSwap_Scissor,
+ __glXDispSwap_ShadeModel,
+ __glXDispSwap_TexParameterf,
+ __glXDispSwap_TexParameterfv,
+ __glXDispSwap_TexParameteri,
+ __glXDispSwap_TexParameteriv,
+ __glXDispSwap_TexImage1D,
+ __glXDispSwap_TexImage2D,
+ __glXDispSwap_TexEnvf,
+ __glXDispSwap_TexEnvfv,
+ __glXDispSwap_TexEnvi,
+ __glXDispSwap_TexEnviv,
+ __glXDispSwap_TexGend,
+ __glXDispSwap_TexGendv,
+ __glXDispSwap_TexGenf,
+ __glXDispSwap_TexGenfv,
+ __glXDispSwap_TexGeni,
+ __glXDispSwap_TexGeniv,
+ __glXDispSwap_InitNames,
+ __glXDispSwap_LoadName,
+ __glXDispSwap_PassThrough,
+ __glXDispSwap_PopName,
+ __glXDispSwap_PushName,
+ __glXDispSwap_DrawBuffer,
+ __glXDispSwap_Clear,
+ __glXDispSwap_ClearAccum,
+ __glXDispSwap_ClearIndex,
+ __glXDispSwap_ClearColor,
+ __glXDispSwap_ClearStencil,
+ __glXDispSwap_ClearDepth,
+ __glXDispSwap_StencilMask,
+ __glXDispSwap_ColorMask,
+ __glXDispSwap_DepthMask,
+ __glXDispSwap_IndexMask,
+ __glXDispSwap_Accum,
+ __glXDispSwap_Disable,
+ __glXDispSwap_Enable,
+ __glXNoSuchRenderOpcode,
+ __glXDispSwap_PopAttrib,
+ __glXDispSwap_PushAttrib,
+ __glXDispSwap_Map1d,
+ __glXDispSwap_Map1f,
+ __glXDispSwap_Map2d,
+ __glXDispSwap_Map2f,
+ __glXDispSwap_MapGrid1d,
+ __glXDispSwap_MapGrid1f,
+ __glXDispSwap_MapGrid2d,
+ __glXDispSwap_MapGrid2f,
+ __glXDispSwap_EvalCoord1dv,
+ __glXDispSwap_EvalCoord1fv,
+ __glXDispSwap_EvalCoord2dv,
+ __glXDispSwap_EvalCoord2fv,
+ __glXDispSwap_EvalMesh1,
+ __glXDispSwap_EvalPoint1,
+ __glXDispSwap_EvalMesh2,
+ __glXDispSwap_EvalPoint2,
+ __glXDispSwap_AlphaFunc,
+ __glXDispSwap_BlendFunc,
+ __glXDispSwap_LogicOp,
+ __glXDispSwap_StencilFunc,
+ __glXDispSwap_StencilOp,
+ __glXDispSwap_DepthFunc,
+ __glXDispSwap_PixelZoom,
+ __glXDispSwap_PixelTransferf,
+ __glXDispSwap_PixelTransferi,
+ __glXDispSwap_PixelMapfv,
+ __glXDispSwap_PixelMapuiv,
+ __glXDispSwap_PixelMapusv,
+ __glXDispSwap_ReadBuffer,
+ __glXDispSwap_CopyPixels,
+ __glXDispSwap_DrawPixels,
+ __glXDispSwap_DepthRange,
+ __glXDispSwap_Frustum,
+ __glXDispSwap_LoadIdentity,
+ __glXDispSwap_LoadMatrixf,
+ __glXDispSwap_LoadMatrixd,
+ __glXDispSwap_MatrixMode,
+ __glXDispSwap_MultMatrixf,
+ __glXDispSwap_MultMatrixd,
+ __glXDispSwap_Ortho,
+ __glXDispSwap_PopMatrix,
+ __glXDispSwap_PushMatrix,
+ __glXDispSwap_Rotated,
+ __glXDispSwap_Rotatef,
+ __glXDispSwap_Scaled,
+ __glXDispSwap_Scalef,
+ __glXDispSwap_Translated,
+ __glXDispSwap_Translatef,
+ __glXDispSwap_Viewport,
+ __glXDispSwap_PolygonOffset,
+ __glXDispSwap_DrawArrays,
+ __glXDispSwap_Indexubv,
+ __glXDispSwap_ColorSubTable,
+ __glXDispSwap_CopyColorSubTable,
+ __glXDispSwap_ActiveTextureARB,
+ __glXDispSwap_MultiTexCoord1dvARB,
+ __glXDispSwap_MultiTexCoord1fvARB,
+ __glXDispSwap_MultiTexCoord1ivARB,
+ __glXDispSwap_MultiTexCoord1svARB,
+ __glXDispSwap_MultiTexCoord2dvARB,
+ __glXDispSwap_MultiTexCoord2fvARB,
+ __glXDispSwap_MultiTexCoord2ivARB,
+ __glXDispSwap_MultiTexCoord2svARB,
+ __glXDispSwap_MultiTexCoord3dvARB,
+ __glXDispSwap_MultiTexCoord3fvARB,
+ __glXDispSwap_MultiTexCoord3ivARB,
+ __glXDispSwap_MultiTexCoord3svARB,
+ __glXDispSwap_MultiTexCoord4dvARB,
+ __glXDispSwap_MultiTexCoord4fvARB,
+ __glXDispSwap_MultiTexCoord4ivARB,
+ __glXDispSwap_MultiTexCoord4svARB, /* 213 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 220 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXDispSwap_SampleCoverageARB,
+#ifndef MISSING_GL_EXTS
+ __glXDispSwap_WindowPos3fARB /* 230 */
+#else
+ __glXNoSuchRenderOpcode
+#endif
+};
diff --git a/nx-X11/programs/Xserver/GL/glx/g_disptab.h b/nx-X11/programs/Xserver/GL/glx/g_disptab.h
new file mode 100644
index 000000000..85906cb43
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_disptab.h
@@ -0,0 +1,651 @@
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_g_disptab_h_
+#define _GLX_g_disptab_h_
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+extern int __glXRender(__GLXclientState*, GLbyte*);
+extern int __glXRenderLarge(__GLXclientState*, GLbyte*);
+extern int __glXCreateContext(__GLXclientState*, GLbyte*);
+extern int __glXDestroyContext(__GLXclientState*, GLbyte*);
+extern int __glXMakeCurrent(__GLXclientState*, GLbyte*);
+extern int __glXIsDirect(__GLXclientState*, GLbyte*);
+extern int __glXQueryVersion(__GLXclientState*, GLbyte*);
+extern int __glXWaitGL(__GLXclientState*, GLbyte*);
+extern int __glXWaitX(__GLXclientState*, GLbyte*);
+extern int __glXCopyContext(__GLXclientState*, GLbyte*);
+extern int __glXSwapBuffers(__GLXclientState*, GLbyte*);
+extern int __glXUseXFont(__GLXclientState*, GLbyte*);
+extern int __glXCreateGLXPixmap(__GLXclientState*, GLbyte*);
+extern int __glXGetVisualConfigs(__GLXclientState*, GLbyte*);
+extern int __glXDestroyGLXPixmap(__GLXclientState*, GLbyte*);
+extern int __glXVendorPrivate(__GLXclientState*, GLbyte*);
+extern int __glXVendorPrivateWithReply(__GLXclientState*, GLbyte*);
+extern int __glXQueryExtensionsString(__GLXclientState*, GLbyte*);
+extern int __glXQueryServerString(__GLXclientState*, GLbyte*);
+extern int __glXClientInfo(__GLXclientState*, GLbyte*);
+extern int __glXMakeContextCurrent(__GLXclientState*, GLbyte*);
+extern int __glXGetFBConfigs(__GLXclientState*, GLbyte*);
+extern int __glXCreateNewContext(__GLXclientState*, GLbyte*);
+extern int __glXCreatePixmap(__GLXclientState*, GLbyte*);
+
+extern int __glXDisp_NewList(__GLXclientState*, GLbyte*);
+extern int __glXDisp_EndList(__GLXclientState*, GLbyte*);
+extern int __glXDisp_DeleteLists(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GenLists(__GLXclientState*, GLbyte*);
+extern int __glXDisp_FeedbackBuffer(__GLXclientState*, GLbyte*);
+extern int __glXDisp_SelectBuffer(__GLXclientState*, GLbyte*);
+extern int __glXDisp_RenderMode(__GLXclientState*, GLbyte*);
+extern int __glXDisp_Finish(__GLXclientState*, GLbyte*);
+extern int __glXDisp_PixelStoref(__GLXclientState*, GLbyte*);
+extern int __glXDisp_PixelStorei(__GLXclientState*, GLbyte*);
+extern int __glXDisp_ReadPixels(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetBooleanv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetClipPlane(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetDoublev(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetError(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetFloatv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetIntegerv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetLightfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetLightiv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMapdv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMapfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMapiv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMaterialfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMaterialiv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetPixelMapfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetPixelMapuiv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetPixelMapusv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetPolygonStipple(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetString(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexEnvfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexEnviv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexGendv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexGenfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexGeniv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexImage(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexLevelParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetTexLevelParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_IsEnabled(__GLXclientState*, GLbyte*);
+extern int __glXDisp_IsList(__GLXclientState*, GLbyte*);
+extern int __glXDisp_Flush(__GLXclientState*, GLbyte*);
+extern int __glXDisp_AreTexturesResident(__GLXclientState*, GLbyte*);
+extern int __glXDisp_DeleteTextures(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GenTextures(__GLXclientState*, GLbyte*);
+extern int __glXDisp_IsTexture(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetColorTable(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetColorTableParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetColorTableParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetConvolutionFilter(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetConvolutionParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetConvolutionParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetSeparableFilter(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetHistogram(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetHistogramParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetHistogramParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMinmax(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMinmaxParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GetMinmaxParameteriv(__GLXclientState*, GLbyte*);
+
+extern void __glXDisp_CallList(GLbyte*);
+extern void __glXDisp_CallLists(GLbyte*);
+extern void __glXDisp_ListBase(GLbyte*);
+extern void __glXDisp_Begin(GLbyte*);
+extern void __glXDisp_Bitmap(GLbyte*);
+extern void __glXDisp_Color3bv(GLbyte*);
+extern void __glXDisp_Color3dv(GLbyte*);
+extern void __glXDisp_Color3fv(GLbyte*);
+extern void __glXDisp_Color3iv(GLbyte*);
+extern void __glXDisp_Color3sv(GLbyte*);
+extern void __glXDisp_Color3ubv(GLbyte*);
+extern void __glXDisp_Color3uiv(GLbyte*);
+extern void __glXDisp_Color3usv(GLbyte*);
+extern void __glXDisp_Color4bv(GLbyte*);
+extern void __glXDisp_Color4dv(GLbyte*);
+extern void __glXDisp_Color4fv(GLbyte*);
+extern void __glXDisp_Color4iv(GLbyte*);
+extern void __glXDisp_Color4sv(GLbyte*);
+extern void __glXDisp_Color4ubv(GLbyte*);
+extern void __glXDisp_Color4uiv(GLbyte*);
+extern void __glXDisp_Color4usv(GLbyte*);
+extern void __glXDisp_EdgeFlagv(GLbyte*);
+extern void __glXDisp_End(GLbyte*);
+extern void __glXDisp_Indexdv(GLbyte*);
+extern void __glXDisp_Indexfv(GLbyte*);
+extern void __glXDisp_Indexiv(GLbyte*);
+extern void __glXDisp_Indexsv(GLbyte*);
+extern void __glXDisp_Normal3bv(GLbyte*);
+extern void __glXDisp_Normal3dv(GLbyte*);
+extern void __glXDisp_Normal3fv(GLbyte*);
+extern void __glXDisp_Normal3iv(GLbyte*);
+extern void __glXDisp_Normal3sv(GLbyte*);
+extern void __glXDisp_RasterPos2dv(GLbyte*);
+extern void __glXDisp_RasterPos2fv(GLbyte*);
+extern void __glXDisp_RasterPos2iv(GLbyte*);
+extern void __glXDisp_RasterPos2sv(GLbyte*);
+extern void __glXDisp_RasterPos3dv(GLbyte*);
+extern void __glXDisp_RasterPos3fv(GLbyte*);
+extern void __glXDisp_RasterPos3iv(GLbyte*);
+extern void __glXDisp_RasterPos3sv(GLbyte*);
+extern void __glXDisp_RasterPos4dv(GLbyte*);
+extern void __glXDisp_RasterPos4fv(GLbyte*);
+extern void __glXDisp_RasterPos4iv(GLbyte*);
+extern void __glXDisp_RasterPos4sv(GLbyte*);
+extern void __glXDisp_Rectdv(GLbyte*);
+extern void __glXDisp_Rectfv(GLbyte*);
+extern void __glXDisp_Rectiv(GLbyte*);
+extern void __glXDisp_Rectsv(GLbyte*);
+extern void __glXDisp_TexCoord1dv(GLbyte*);
+extern void __glXDisp_TexCoord1fv(GLbyte*);
+extern void __glXDisp_TexCoord1iv(GLbyte*);
+extern void __glXDisp_TexCoord1sv(GLbyte*);
+extern void __glXDisp_TexCoord2dv(GLbyte*);
+extern void __glXDisp_TexCoord2fv(GLbyte*);
+extern void __glXDisp_TexCoord2iv(GLbyte*);
+extern void __glXDisp_TexCoord2sv(GLbyte*);
+extern void __glXDisp_TexCoord3dv(GLbyte*);
+extern void __glXDisp_TexCoord3fv(GLbyte*);
+extern void __glXDisp_TexCoord3iv(GLbyte*);
+extern void __glXDisp_TexCoord3sv(GLbyte*);
+extern void __glXDisp_TexCoord4dv(GLbyte*);
+extern void __glXDisp_TexCoord4fv(GLbyte*);
+extern void __glXDisp_TexCoord4iv(GLbyte*);
+extern void __glXDisp_TexCoord4sv(GLbyte*);
+extern void __glXDisp_Vertex2dv(GLbyte*);
+extern void __glXDisp_Vertex2fv(GLbyte*);
+extern void __glXDisp_Vertex2iv(GLbyte*);
+extern void __glXDisp_Vertex2sv(GLbyte*);
+extern void __glXDisp_Vertex3dv(GLbyte*);
+extern void __glXDisp_Vertex3fv(GLbyte*);
+extern void __glXDisp_Vertex3iv(GLbyte*);
+extern void __glXDisp_Vertex3sv(GLbyte*);
+extern void __glXDisp_Vertex4dv(GLbyte*);
+extern void __glXDisp_Vertex4fv(GLbyte*);
+extern void __glXDisp_Vertex4iv(GLbyte*);
+extern void __glXDisp_Vertex4sv(GLbyte*);
+extern void __glXDisp_ClipPlane(GLbyte*);
+extern void __glXDisp_ColorMaterial(GLbyte*);
+extern void __glXDisp_CullFace(GLbyte*);
+extern void __glXDisp_Fogf(GLbyte*);
+extern void __glXDisp_Fogfv(GLbyte*);
+extern void __glXDisp_Fogi(GLbyte*);
+extern void __glXDisp_Fogiv(GLbyte*);
+extern void __glXDisp_FrontFace(GLbyte*);
+extern void __glXDisp_Hint(GLbyte*);
+extern void __glXDisp_Lightf(GLbyte*);
+extern void __glXDisp_Lightfv(GLbyte*);
+extern void __glXDisp_Lighti(GLbyte*);
+extern void __glXDisp_Lightiv(GLbyte*);
+extern void __glXDisp_LightModelf(GLbyte*);
+extern void __glXDisp_LightModelfv(GLbyte*);
+extern void __glXDisp_LightModeli(GLbyte*);
+extern void __glXDisp_LightModeliv(GLbyte*);
+extern void __glXDisp_LineStipple(GLbyte*);
+extern void __glXDisp_LineWidth(GLbyte*);
+extern void __glXDisp_Materialf(GLbyte*);
+extern void __glXDisp_Materialfv(GLbyte*);
+extern void __glXDisp_Materiali(GLbyte*);
+extern void __glXDisp_Materialiv(GLbyte*);
+extern void __glXDisp_PointSize(GLbyte*);
+extern void __glXDisp_PolygonMode(GLbyte*);
+extern void __glXDisp_PolygonStipple(GLbyte*);
+extern void __glXDisp_Scissor(GLbyte*);
+extern void __glXDisp_ShadeModel(GLbyte*);
+extern void __glXDisp_TexParameterf(GLbyte*);
+extern void __glXDisp_TexParameterfv(GLbyte*);
+extern void __glXDisp_TexParameteri(GLbyte*);
+extern void __glXDisp_TexParameteriv(GLbyte*);
+extern void __glXDisp_TexImage1D(GLbyte*);
+extern void __glXDisp_TexImage2D(GLbyte*);
+extern void __glXDisp_TexEnvf(GLbyte*);
+extern void __glXDisp_TexEnvfv(GLbyte*);
+extern void __glXDisp_TexEnvi(GLbyte*);
+extern void __glXDisp_TexEnviv(GLbyte*);
+extern void __glXDisp_TexGend(GLbyte*);
+extern void __glXDisp_TexGendv(GLbyte*);
+extern void __glXDisp_TexGenf(GLbyte*);
+extern void __glXDisp_TexGenfv(GLbyte*);
+extern void __glXDisp_TexGeni(GLbyte*);
+extern void __glXDisp_TexGeniv(GLbyte*);
+extern void __glXDisp_InitNames(GLbyte*);
+extern void __glXDisp_LoadName(GLbyte*);
+extern void __glXDisp_PassThrough(GLbyte*);
+extern void __glXDisp_PopName(GLbyte*);
+extern void __glXDisp_PushName(GLbyte*);
+extern void __glXDisp_DrawBuffer(GLbyte*);
+extern void __glXDisp_Clear(GLbyte*);
+extern void __glXDisp_ClearAccum(GLbyte*);
+extern void __glXDisp_ClearIndex(GLbyte*);
+extern void __glXDisp_ClearColor(GLbyte*);
+extern void __glXDisp_ClearStencil(GLbyte*);
+extern void __glXDisp_ClearDepth(GLbyte*);
+extern void __glXDisp_StencilMask(GLbyte*);
+extern void __glXDisp_ColorMask(GLbyte*);
+extern void __glXDisp_DepthMask(GLbyte*);
+extern void __glXDisp_IndexMask(GLbyte*);
+extern void __glXDisp_Accum(GLbyte*);
+extern void __glXDisp_Disable(GLbyte*);
+extern void __glXDisp_Enable(GLbyte*);
+extern void __glXDisp_PopAttrib(GLbyte*);
+extern void __glXDisp_PushAttrib(GLbyte*);
+extern void __glXDisp_Map1d(GLbyte*);
+extern void __glXDisp_Map1f(GLbyte*);
+extern void __glXDisp_Map2d(GLbyte*);
+extern void __glXDisp_Map2f(GLbyte*);
+extern void __glXDisp_MapGrid1d(GLbyte*);
+extern void __glXDisp_MapGrid1f(GLbyte*);
+extern void __glXDisp_MapGrid2d(GLbyte*);
+extern void __glXDisp_MapGrid2f(GLbyte*);
+extern void __glXDisp_EvalCoord1dv(GLbyte*);
+extern void __glXDisp_EvalCoord1fv(GLbyte*);
+extern void __glXDisp_EvalCoord2dv(GLbyte*);
+extern void __glXDisp_EvalCoord2fv(GLbyte*);
+extern void __glXDisp_EvalMesh1(GLbyte*);
+extern void __glXDisp_EvalPoint1(GLbyte*);
+extern void __glXDisp_EvalMesh2(GLbyte*);
+extern void __glXDisp_EvalPoint2(GLbyte*);
+extern void __glXDisp_AlphaFunc(GLbyte*);
+extern void __glXDisp_BlendFunc(GLbyte*);
+extern void __glXDisp_LogicOp(GLbyte*);
+extern void __glXDisp_StencilFunc(GLbyte*);
+extern void __glXDisp_StencilOp(GLbyte*);
+extern void __glXDisp_DepthFunc(GLbyte*);
+extern void __glXDisp_PixelZoom(GLbyte*);
+extern void __glXDisp_PixelTransferf(GLbyte*);
+extern void __glXDisp_PixelTransferi(GLbyte*);
+extern void __glXDisp_PixelMapfv(GLbyte*);
+extern void __glXDisp_PixelMapuiv(GLbyte*);
+extern void __glXDisp_PixelMapusv(GLbyte*);
+extern void __glXDisp_ReadBuffer(GLbyte*);
+extern void __glXDisp_CopyPixels(GLbyte*);
+extern void __glXDisp_DrawPixels(GLbyte*);
+extern void __glXDisp_DepthRange(GLbyte*);
+extern void __glXDisp_Frustum(GLbyte*);
+extern void __glXDisp_LoadIdentity(GLbyte*);
+extern void __glXDisp_LoadMatrixf(GLbyte*);
+extern void __glXDisp_LoadMatrixd(GLbyte*);
+extern void __glXDisp_MatrixMode(GLbyte*);
+extern void __glXDisp_MultMatrixf(GLbyte*);
+extern void __glXDisp_MultMatrixd(GLbyte*);
+extern void __glXDisp_Ortho(GLbyte*);
+extern void __glXDisp_PopMatrix(GLbyte*);
+extern void __glXDisp_PushMatrix(GLbyte*);
+extern void __glXDisp_Rotated(GLbyte*);
+extern void __glXDisp_Rotatef(GLbyte*);
+extern void __glXDisp_Scaled(GLbyte*);
+extern void __glXDisp_Scalef(GLbyte*);
+extern void __glXDisp_Translated(GLbyte*);
+extern void __glXDisp_Translatef(GLbyte*);
+extern void __glXDisp_Viewport(GLbyte*);
+extern void __glXDisp_PolygonOffset(GLbyte*);
+extern void __glXDisp_DrawArrays(GLbyte*);
+extern void __glXDisp_Indexubv(GLbyte*);
+extern void __glXDisp_ColorSubTable(GLbyte*);
+extern void __glXDisp_CopyColorSubTable(GLbyte*);
+extern void __glXDisp_ActiveTextureARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord1dvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord1fvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord1ivARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord1svARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord2dvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord2fvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord2ivARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord2svARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord3dvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord3fvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord3ivARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord3svARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord4dvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord4fvARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord4ivARB(GLbyte*);
+extern void __glXDisp_MultiTexCoord4svARB(GLbyte*);
+extern void __glXDisp_SampleCoverageARB(GLbyte *);
+extern void __glXDisp_WindowPos3fARB(GLbyte *);
+
+extern int __glXSwapRender(__GLXclientState*, GLbyte*);
+extern int __glXSwapRenderLarge(__GLXclientState*, GLbyte*);
+extern int __glXSwapCreateContext(__GLXclientState*, GLbyte*);
+extern int __glXSwapDestroyContext(__GLXclientState*, GLbyte*);
+extern int __glXSwapMakeCurrent(__GLXclientState*, GLbyte*);
+extern int __glXSwapIsDirect(__GLXclientState*, GLbyte*);
+extern int __glXSwapQueryVersion(__GLXclientState*, GLbyte*);
+extern int __glXSwapWaitGL(__GLXclientState*, GLbyte*);
+extern int __glXSwapWaitX(__GLXclientState*, GLbyte*);
+extern int __glXSwapCopyContext(__GLXclientState*, GLbyte*);
+extern int __glXSwapSwapBuffers(__GLXclientState*, GLbyte*);
+extern int __glXSwapUseXFont(__GLXclientState*, GLbyte*);
+extern int __glXSwapCreateGLXPixmap(__GLXclientState*, GLbyte*);
+extern int __glXSwapGetVisualConfigs(__GLXclientState*, GLbyte*);
+extern int __glXSwapDestroyGLXPixmap(__GLXclientState*, GLbyte*);
+extern int __glXSwapVendorPrivate(__GLXclientState*, GLbyte*);
+extern int __glXSwapVendorPrivateWithReply(__GLXclientState*, GLbyte*);
+extern int __glXSwapQueryExtensionsString(__GLXclientState*, GLbyte*);
+extern int __glXSwapQueryServerString(__GLXclientState*, GLbyte*);
+extern int __glXSwapClientInfo(__GLXclientState*, GLbyte*);
+extern int __glXSwapMakeContextCurrent(__GLXclientState*, GLbyte*);
+extern int __glXSwapGetFBConfigs(__GLXclientState*, GLbyte*);
+extern int __glXSwapCreateNewContext(__GLXclientState*, GLbyte*);
+extern int __glXSwapCreatePixmap(__GLXclientState*, GLbyte*);
+
+extern int __glXDispSwap_NewList(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_EndList(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_DeleteLists(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GenLists(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_FeedbackBuffer(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_SelectBuffer(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_RenderMode(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_Finish(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_PixelStoref(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_PixelStorei(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_ReadPixels(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetBooleanv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetClipPlane(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetDoublev(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetError(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetFloatv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetIntegerv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetLightfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetLightiv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMapdv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMapfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMapiv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMaterialfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMaterialiv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetPixelMapfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetPixelMapuiv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetPixelMapusv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetPolygonStipple(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetString(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexEnvfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexEnviv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexGendv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexGenfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexGeniv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexImage(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexLevelParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetTexLevelParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_IsEnabled(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_IsList(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_Flush(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_AreTexturesResident(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_DeleteTextures(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GenTextures(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_IsTexture(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetColorTable(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetColorTableParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetColorTableParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetConvolutionFilter(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetConvolutionParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetConvolutionParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetSeparableFilter(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetHistogram(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetHistogramParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetHistogramParameteriv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMinmax(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMinmaxParameterfv(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GetMinmaxParameteriv(__GLXclientState*, GLbyte*);
+
+extern void __glXDispSwap_CallList(GLbyte*);
+extern void __glXDispSwap_CallLists(GLbyte*);
+extern void __glXDispSwap_ListBase(GLbyte*);
+extern void __glXDispSwap_Begin(GLbyte*);
+extern void __glXDispSwap_Bitmap(GLbyte*);
+extern void __glXDispSwap_Color3bv(GLbyte*);
+extern void __glXDispSwap_Color3dv(GLbyte*);
+extern void __glXDispSwap_Color3fv(GLbyte*);
+extern void __glXDispSwap_Color3iv(GLbyte*);
+extern void __glXDispSwap_Color3sv(GLbyte*);
+extern void __glXDispSwap_Color3ubv(GLbyte*);
+extern void __glXDispSwap_Color3uiv(GLbyte*);
+extern void __glXDispSwap_Color3usv(GLbyte*);
+extern void __glXDispSwap_Color4bv(GLbyte*);
+extern void __glXDispSwap_Color4dv(GLbyte*);
+extern void __glXDispSwap_Color4fv(GLbyte*);
+extern void __glXDispSwap_Color4iv(GLbyte*);
+extern void __glXDispSwap_Color4sv(GLbyte*);
+extern void __glXDispSwap_Color4ubv(GLbyte*);
+extern void __glXDispSwap_Color4uiv(GLbyte*);
+extern void __glXDispSwap_Color4usv(GLbyte*);
+extern void __glXDispSwap_EdgeFlagv(GLbyte*);
+extern void __glXDispSwap_End(GLbyte*);
+extern void __glXDispSwap_Indexdv(GLbyte*);
+extern void __glXDispSwap_Indexfv(GLbyte*);
+extern void __glXDispSwap_Indexiv(GLbyte*);
+extern void __glXDispSwap_Indexsv(GLbyte*);
+extern void __glXDispSwap_Normal3bv(GLbyte*);
+extern void __glXDispSwap_Normal3dv(GLbyte*);
+extern void __glXDispSwap_Normal3fv(GLbyte*);
+extern void __glXDispSwap_Normal3iv(GLbyte*);
+extern void __glXDispSwap_Normal3sv(GLbyte*);
+extern void __glXDispSwap_RasterPos2dv(GLbyte*);
+extern void __glXDispSwap_RasterPos2fv(GLbyte*);
+extern void __glXDispSwap_RasterPos2iv(GLbyte*);
+extern void __glXDispSwap_RasterPos2sv(GLbyte*);
+extern void __glXDispSwap_RasterPos3dv(GLbyte*);
+extern void __glXDispSwap_RasterPos3fv(GLbyte*);
+extern void __glXDispSwap_RasterPos3iv(GLbyte*);
+extern void __glXDispSwap_RasterPos3sv(GLbyte*);
+extern void __glXDispSwap_RasterPos4dv(GLbyte*);
+extern void __glXDispSwap_RasterPos4fv(GLbyte*);
+extern void __glXDispSwap_RasterPos4iv(GLbyte*);
+extern void __glXDispSwap_RasterPos4sv(GLbyte*);
+extern void __glXDispSwap_Rectdv(GLbyte*);
+extern void __glXDispSwap_Rectfv(GLbyte*);
+extern void __glXDispSwap_Rectiv(GLbyte*);
+extern void __glXDispSwap_Rectsv(GLbyte*);
+extern void __glXDispSwap_TexCoord1dv(GLbyte*);
+extern void __glXDispSwap_TexCoord1fv(GLbyte*);
+extern void __glXDispSwap_TexCoord1iv(GLbyte*);
+extern void __glXDispSwap_TexCoord1sv(GLbyte*);
+extern void __glXDispSwap_TexCoord2dv(GLbyte*);
+extern void __glXDispSwap_TexCoord2fv(GLbyte*);
+extern void __glXDispSwap_TexCoord2iv(GLbyte*);
+extern void __glXDispSwap_TexCoord2sv(GLbyte*);
+extern void __glXDispSwap_TexCoord3dv(GLbyte*);
+extern void __glXDispSwap_TexCoord3fv(GLbyte*);
+extern void __glXDispSwap_TexCoord3iv(GLbyte*);
+extern void __glXDispSwap_TexCoord3sv(GLbyte*);
+extern void __glXDispSwap_TexCoord4dv(GLbyte*);
+extern void __glXDispSwap_TexCoord4fv(GLbyte*);
+extern void __glXDispSwap_TexCoord4iv(GLbyte*);
+extern void __glXDispSwap_TexCoord4sv(GLbyte*);
+extern void __glXDispSwap_Vertex2dv(GLbyte*);
+extern void __glXDispSwap_Vertex2fv(GLbyte*);
+extern void __glXDispSwap_Vertex2iv(GLbyte*);
+extern void __glXDispSwap_Vertex2sv(GLbyte*);
+extern void __glXDispSwap_Vertex3dv(GLbyte*);
+extern void __glXDispSwap_Vertex3fv(GLbyte*);
+extern void __glXDispSwap_Vertex3iv(GLbyte*);
+extern void __glXDispSwap_Vertex3sv(GLbyte*);
+extern void __glXDispSwap_Vertex4dv(GLbyte*);
+extern void __glXDispSwap_Vertex4fv(GLbyte*);
+extern void __glXDispSwap_Vertex4iv(GLbyte*);
+extern void __glXDispSwap_Vertex4sv(GLbyte*);
+extern void __glXDispSwap_ClipPlane(GLbyte*);
+extern void __glXDispSwap_ColorMaterial(GLbyte*);
+extern void __glXDispSwap_CullFace(GLbyte*);
+extern void __glXDispSwap_Fogf(GLbyte*);
+extern void __glXDispSwap_Fogfv(GLbyte*);
+extern void __glXDispSwap_Fogi(GLbyte*);
+extern void __glXDispSwap_Fogiv(GLbyte*);
+extern void __glXDispSwap_FrontFace(GLbyte*);
+extern void __glXDispSwap_Hint(GLbyte*);
+extern void __glXDispSwap_Lightf(GLbyte*);
+extern void __glXDispSwap_Lightfv(GLbyte*);
+extern void __glXDispSwap_Lighti(GLbyte*);
+extern void __glXDispSwap_Lightiv(GLbyte*);
+extern void __glXDispSwap_LightModelf(GLbyte*);
+extern void __glXDispSwap_LightModelfv(GLbyte*);
+extern void __glXDispSwap_LightModeli(GLbyte*);
+extern void __glXDispSwap_LightModeliv(GLbyte*);
+extern void __glXDispSwap_LineStipple(GLbyte*);
+extern void __glXDispSwap_LineWidth(GLbyte*);
+extern void __glXDispSwap_Materialf(GLbyte*);
+extern void __glXDispSwap_Materialfv(GLbyte*);
+extern void __glXDispSwap_Materiali(GLbyte*);
+extern void __glXDispSwap_Materialiv(GLbyte*);
+extern void __glXDispSwap_PointSize(GLbyte*);
+extern void __glXDispSwap_PolygonMode(GLbyte*);
+extern void __glXDispSwap_PolygonStipple(GLbyte*);
+extern void __glXDispSwap_Scissor(GLbyte*);
+extern void __glXDispSwap_ShadeModel(GLbyte*);
+extern void __glXDispSwap_TexParameterf(GLbyte*);
+extern void __glXDispSwap_TexParameterfv(GLbyte*);
+extern void __glXDispSwap_TexParameteri(GLbyte*);
+extern void __glXDispSwap_TexParameteriv(GLbyte*);
+extern void __glXDispSwap_TexImage1D(GLbyte*);
+extern void __glXDispSwap_TexImage2D(GLbyte*);
+extern void __glXDispSwap_TexEnvf(GLbyte*);
+extern void __glXDispSwap_TexEnvfv(GLbyte*);
+extern void __glXDispSwap_TexEnvi(GLbyte*);
+extern void __glXDispSwap_TexEnviv(GLbyte*);
+extern void __glXDispSwap_TexGend(GLbyte*);
+extern void __glXDispSwap_TexGendv(GLbyte*);
+extern void __glXDispSwap_TexGenf(GLbyte*);
+extern void __glXDispSwap_TexGenfv(GLbyte*);
+extern void __glXDispSwap_TexGeni(GLbyte*);
+extern void __glXDispSwap_TexGeniv(GLbyte*);
+extern void __glXDispSwap_InitNames(GLbyte*);
+extern void __glXDispSwap_LoadName(GLbyte*);
+extern void __glXDispSwap_PassThrough(GLbyte*);
+extern void __glXDispSwap_PopName(GLbyte*);
+extern void __glXDispSwap_PushName(GLbyte*);
+extern void __glXDispSwap_DrawBuffer(GLbyte*);
+extern void __glXDispSwap_Clear(GLbyte*);
+extern void __glXDispSwap_ClearAccum(GLbyte*);
+extern void __glXDispSwap_ClearIndex(GLbyte*);
+extern void __glXDispSwap_ClearColor(GLbyte*);
+extern void __glXDispSwap_ClearStencil(GLbyte*);
+extern void __glXDispSwap_ClearDepth(GLbyte*);
+extern void __glXDispSwap_StencilMask(GLbyte*);
+extern void __glXDispSwap_ColorMask(GLbyte*);
+extern void __glXDispSwap_DepthMask(GLbyte*);
+extern void __glXDispSwap_IndexMask(GLbyte*);
+extern void __glXDispSwap_Accum(GLbyte*);
+extern void __glXDispSwap_Disable(GLbyte*);
+extern void __glXDispSwap_Enable(GLbyte*);
+extern void __glXDispSwap_PopAttrib(GLbyte*);
+extern void __glXDispSwap_PushAttrib(GLbyte*);
+extern void __glXDispSwap_Map1d(GLbyte*);
+extern void __glXDispSwap_Map1f(GLbyte*);
+extern void __glXDispSwap_Map2d(GLbyte*);
+extern void __glXDispSwap_Map2f(GLbyte*);
+extern void __glXDispSwap_MapGrid1d(GLbyte*);
+extern void __glXDispSwap_MapGrid1f(GLbyte*);
+extern void __glXDispSwap_MapGrid2d(GLbyte*);
+extern void __glXDispSwap_MapGrid2f(GLbyte*);
+extern void __glXDispSwap_EvalCoord1dv(GLbyte*);
+extern void __glXDispSwap_EvalCoord1fv(GLbyte*);
+extern void __glXDispSwap_EvalCoord2dv(GLbyte*);
+extern void __glXDispSwap_EvalCoord2fv(GLbyte*);
+extern void __glXDispSwap_EvalMesh1(GLbyte*);
+extern void __glXDispSwap_EvalPoint1(GLbyte*);
+extern void __glXDispSwap_EvalMesh2(GLbyte*);
+extern void __glXDispSwap_EvalPoint2(GLbyte*);
+extern void __glXDispSwap_AlphaFunc(GLbyte*);
+extern void __glXDispSwap_BlendFunc(GLbyte*);
+extern void __glXDispSwap_LogicOp(GLbyte*);
+extern void __glXDispSwap_StencilFunc(GLbyte*);
+extern void __glXDispSwap_StencilOp(GLbyte*);
+extern void __glXDispSwap_DepthFunc(GLbyte*);
+extern void __glXDispSwap_PixelZoom(GLbyte*);
+extern void __glXDispSwap_PixelTransferf(GLbyte*);
+extern void __glXDispSwap_PixelTransferi(GLbyte*);
+extern void __glXDispSwap_PixelMapfv(GLbyte*);
+extern void __glXDispSwap_PixelMapuiv(GLbyte*);
+extern void __glXDispSwap_PixelMapusv(GLbyte*);
+extern void __glXDispSwap_ReadBuffer(GLbyte*);
+extern void __glXDispSwap_CopyPixels(GLbyte*);
+extern void __glXDispSwap_DrawPixels(GLbyte*);
+extern void __glXDispSwap_DepthRange(GLbyte*);
+extern void __glXDispSwap_Frustum(GLbyte*);
+extern void __glXDispSwap_LoadIdentity(GLbyte*);
+extern void __glXDispSwap_LoadMatrixf(GLbyte*);
+extern void __glXDispSwap_LoadMatrixd(GLbyte*);
+extern void __glXDispSwap_MatrixMode(GLbyte*);
+extern void __glXDispSwap_MultMatrixf(GLbyte*);
+extern void __glXDispSwap_MultMatrixd(GLbyte*);
+extern void __glXDispSwap_Ortho(GLbyte*);
+extern void __glXDispSwap_PopMatrix(GLbyte*);
+extern void __glXDispSwap_PushMatrix(GLbyte*);
+extern void __glXDispSwap_Rotated(GLbyte*);
+extern void __glXDispSwap_Rotatef(GLbyte*);
+extern void __glXDispSwap_Scaled(GLbyte*);
+extern void __glXDispSwap_Scalef(GLbyte*);
+extern void __glXDispSwap_Translated(GLbyte*);
+extern void __glXDispSwap_Translatef(GLbyte*);
+extern void __glXDispSwap_Viewport(GLbyte*);
+extern void __glXDispSwap_PolygonOffset(GLbyte*);
+extern void __glXDispSwap_DrawArrays(GLbyte*);
+extern void __glXDispSwap_Indexubv(GLbyte*);
+extern void __glXDispSwap_ColorSubTable(GLbyte*);
+extern void __glXDispSwap_CopyColorSubTable(GLbyte*);
+extern void __glXDispSwap_ActiveTextureARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord1dvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord1fvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord1ivARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord1svARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord2dvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord2fvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord2ivARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord2svARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord3dvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord3fvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord3ivARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord3svARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord4dvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord4fvARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord4ivARB(GLbyte*);
+extern void __glXDispSwap_MultiTexCoord4svARB(GLbyte*);
+extern void __glXDispSwap_SampleCoverageARB(GLbyte *);
+extern void __glXDispSwap_WindowPos3fARB(GLbyte *);
+
+#define __GLX_MIN_GLXCMD_OPCODE 1
+#define __GLX_MAX_GLXCMD_OPCODE 20
+#define __GLX_MIN_RENDER_OPCODE 1
+/*#define __GLX_MAX_RENDER_OPCODE 213*/
+#define __GLX_MAX_RENDER_OPCODE 230
+#define __GLX_MIN_SINGLE_OPCODE 1
+#define __GLX_MAX_SINGLE_OPCODE 159
+#define __GLX_SINGLE_TABLE_SIZE 160
+/*#define __GLX_RENDER_TABLE_SIZE 214*/
+#define __GLX_RENDER_TABLE_SIZE 231
+extern __GLXdispatchRenderProcPtr __glXRenderTable[__GLX_RENDER_TABLE_SIZE];
+extern __GLXdispatchSingleProcPtr __glXSingleTable[__GLX_SINGLE_TABLE_SIZE];
+extern __GLXdispatchRenderProcPtr __glXSwapRenderTable[__GLX_RENDER_TABLE_SIZE];
+extern __GLXdispatchSingleProcPtr __glXSwapSingleTable[__GLX_SINGLE_TABLE_SIZE];
+#endif /* _GLX_g_disptab_h_ */
diff --git a/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.c b/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.c
new file mode 100644
index 000000000..754e9854d
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.c
@@ -0,0 +1,4446 @@
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab_EXT.h"
+__GLXdispatchRenderProcPtr __glXRenderTable_EXT[__GLX_MAX_RENDER_OPCODE_EXT - __GLX_MIN_RENDER_OPCODE_EXT + 1] = {
+ __glXDisp_ColorTable, /* 2053 */
+ __glXDisp_ColorTableParameterfv, /* 2054 */
+ __glXDisp_ColorTableParameteriv,
+ __glXDisp_CopyColorTable,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 2060 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#ifndef MISSING_GL_EXTS
+ __glXDisp_PointParameterfARB, /* 2065 */
+ __glXDisp_PointParameterfvARB, /* 2066 */
+#else
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#endif
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 2070 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXDisp_BlendColor, /* 4096 */
+ __glXDisp_BlendEquation, /* 4097 */
+ __glXNoSuchRenderOpcode, /* 4098 */
+ __glXDisp_TexSubImage1D, /* 4099 */
+ __glXDisp_TexSubImage2D, /* 4100 */
+ __glXDisp_ConvolutionFilter1D,
+ __glXDisp_ConvolutionFilter2D,
+ __glXDisp_ConvolutionParameterf,
+ __glXDisp_ConvolutionParameterfv,
+ __glXDisp_ConvolutionParameteri,
+ __glXDisp_ConvolutionParameteriv,
+ __glXDisp_CopyConvolutionFilter1D,
+ __glXDisp_CopyConvolutionFilter2D,
+ __glXDisp_SeparableFilter2D,
+ __glXDisp_Histogram, /* 4110 */
+ __glXDisp_Minmax,
+ __glXDisp_ResetHistogram,
+ __glXDisp_ResetMinmax,
+ __glXDisp_TexImage3D,
+ __glXDisp_TexSubImage3D,
+ __glXDisp_DrawArraysEXT,
+ __glXDisp_BindTexture,
+ __glXDisp_PrioritizeTextures,
+ __glXDisp_CopyTexImage1D,
+ __glXDisp_CopyTexImage2D, /* 4120 */
+ __glXDisp_CopyTexSubImage1D, /* 4121 */
+ __glXDisp_CopyTexSubImage2D, /* 4122 */
+ __glXDisp_CopyTexSubImage3D, /* 4123 */
+#ifndef MISSING_GL_EXTS
+ __glXDisp_FogCoordfv, /* 4124 */
+ __glXDisp_FogCoorddv, /* 4125 */
+ __glXDisp_SecondaryColor3bv, /* 4126 */
+ __glXDisp_SecondaryColor3sv, /* 4127 */
+ __glXDisp_SecondaryColor3iv, /* 4128 */
+ __glXDisp_SecondaryColor3fv, /* 4129 */
+ __glXDisp_SecondaryColor3dv, /* 4130 */
+ __glXDisp_SecondaryColor3ubv, /* 4131 */
+ __glXDisp_SecondaryColor3usv, /* 4132 */
+ __glXDisp_SecondaryColor3uiv, /* 4133 */
+ __glXDisp_BlendFuncSeparate, /* 4134 */
+#else
+ __glXNoSuchRenderOpcode, /* 4124 */
+ __glXNoSuchRenderOpcode, /* 4125 */
+ __glXNoSuchRenderOpcode, /* 4126 */
+ __glXNoSuchRenderOpcode, /* 4127 */
+ __glXNoSuchRenderOpcode, /* 4128 */
+ __glXNoSuchRenderOpcode, /* 4129 */
+ __glXNoSuchRenderOpcode, /* 4130 */
+ __glXNoSuchRenderOpcode, /* 4131 */
+ __glXNoSuchRenderOpcode, /* 4132 */
+ __glXNoSuchRenderOpcode, /* 4133 */
+ __glXNoSuchRenderOpcode, /* 4134 */
+#endif
+ __glXNoSuchRenderOpcode, /* 4135 */
+ __glXNoSuchRenderOpcode, /* 4136 */
+ __glXNoSuchRenderOpcode, /* 4137 */
+ __glXNoSuchRenderOpcode, /* 4138 */
+ __glXNoSuchRenderOpcode, /* 4139 */
+ __glXNoSuchRenderOpcode, /* 4140 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4150 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4160 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4170 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4180 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4190 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4200 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4210 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4219 */
+#ifndef MISSING_GL_EXTS
+ __glXDisp_ActiveStencilFaceEXT, /* 4220 */
+ __glXDisp_PointParameteriNV, /* 4221 */
+ __glXDisp_PointParameterivNV, /* 4222 */
+#else
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#endif
+};
+__GLXdispatchVendorPrivProcPtr __glXVendorPrivTable_EXT[__GLX_MAX_VENDPRIV_OPCODE_EXT - __GLX_MIN_VENDPRIV_OPCODE_EXT + 1] = {
+ __glXDisp_AreTexturesResidentEXT, /* 11 */
+ __glXDisp_DeleteTexturesEXT, /* 12 */
+ __glXDisp_GenTexturesEXT, /* 13 */
+ __glXDisp_IsTextureEXT, /* 14 */
+};
+
+
+__GLXdispatchRenderProcPtr __glXSwapRenderTable_EXT[__GLX_MAX_RENDER_OPCODE_EXT - __GLX_MIN_RENDER_OPCODE_EXT + 1] = {
+ __glXDispSwap_ColorTable, /* 2053 */
+ __glXDispSwap_ColorTableParameterfv, /* 2054 */
+ __glXDispSwap_ColorTableParameteriv,
+ __glXDispSwap_CopyColorTable,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 2060 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#ifndef MISSING_GL_EXTS
+ __glXDispSwap_PointParameterfARB, /* 2065 */
+ __glXDispSwap_PointParameterfvARB, /* 2066 */
+#else
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#endif
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 2070 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXDispSwap_BlendColor,
+ __glXDispSwap_BlendEquation,
+ __glXNoSuchRenderOpcode,
+ __glXDispSwap_TexSubImage1D,
+ __glXDispSwap_TexSubImage2D,
+ __glXDispSwap_ConvolutionFilter1D,
+ __glXDispSwap_ConvolutionFilter2D,
+ __glXDispSwap_ConvolutionParameterf,
+ __glXDispSwap_ConvolutionParameterfv,
+ __glXDispSwap_ConvolutionParameteri,
+ __glXDispSwap_ConvolutionParameteriv,
+ __glXDispSwap_CopyConvolutionFilter1D,
+ __glXDispSwap_CopyConvolutionFilter2D,
+ __glXDispSwap_SeparableFilter2D,
+ __glXDispSwap_Histogram,
+ __glXDispSwap_Minmax,
+ __glXDispSwap_ResetHistogram,
+ __glXDispSwap_ResetMinmax,
+ __glXDispSwap_TexImage3D,
+ __glXDispSwap_TexSubImage3D,
+ __glXDispSwap_DrawArraysEXT,
+ __glXDispSwap_BindTexture,
+ __glXDispSwap_PrioritizeTextures,
+ __glXDispSwap_CopyTexImage1D,
+ __glXDispSwap_CopyTexImage2D, /* 4120 */
+ __glXDispSwap_CopyTexSubImage1D, /* 4121 */
+ __glXDispSwap_CopyTexSubImage2D, /* 4122 */
+ __glXDispSwap_CopyTexSubImage3D, /* 4123 */
+#ifndef MISSING_GL_EXTS
+ __glXDispSwap_FogCoordfv, /* 4124 */
+ __glXDispSwap_FogCoorddv, /* 4125 */
+ __glXDispSwap_SecondaryColor3bv, /* 4126 */
+ __glXDispSwap_SecondaryColor3sv, /* 4127 */
+ __glXDispSwap_SecondaryColor3iv, /* 4128 */
+ __glXDispSwap_SecondaryColor3fv, /* 4129 */
+ __glXDispSwap_SecondaryColor3dv, /* 4130 */
+ __glXDispSwap_SecondaryColor3ubv, /* 4131 */
+ __glXDispSwap_SecondaryColor3usv, /* 4132 */
+ __glXDispSwap_SecondaryColor3uiv, /* 4133 */
+ __glXDisp_BlendFuncSeparate, /* 4134 */
+#else
+ __glXNoSuchRenderOpcode, /* 4124 */
+ __glXNoSuchRenderOpcode, /* 4125 */
+ __glXNoSuchRenderOpcode, /* 4126 */
+ __glXNoSuchRenderOpcode, /* 4127 */
+ __glXNoSuchRenderOpcode, /* 4128 */
+ __glXNoSuchRenderOpcode, /* 4129 */
+ __glXNoSuchRenderOpcode, /* 4130 */
+ __glXNoSuchRenderOpcode, /* 4131 */
+ __glXNoSuchRenderOpcode, /* 4132 */
+ __glXNoSuchRenderOpcode, /* 4133 */
+ __glXNoSuchRenderOpcode, /* 4134 */
+#endif
+ __glXNoSuchRenderOpcode, /* 4135 */
+ __glXNoSuchRenderOpcode, /* 4136 */
+ __glXNoSuchRenderOpcode, /* 4137 */
+ __glXNoSuchRenderOpcode, /* 4138 */
+ __glXNoSuchRenderOpcode, /* 4139 */
+ __glXNoSuchRenderOpcode, /* 4140 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4150 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4160 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4170 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4180 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4190 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4200 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4210 */
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode, /* 4219 */
+#ifndef MISSING_GL_EXTS
+ __glXDispSwap_ActiveStencilFaceEXT, /* 4220 */
+ __glXDispSwap_PointParameteriNV, /* 4221 */
+ __glXDispSwap_PointParameterivNV, /* 4222 */
+#else
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+ __glXNoSuchRenderOpcode,
+#endif
+};
+__GLXdispatchVendorPrivProcPtr __glXSwapVendorPrivTable_EXT[__GLX_MAX_VENDPRIV_OPCODE_EXT - __GLX_MIN_VENDPRIV_OPCODE_EXT + 1] = {
+ __glXDispSwap_AreTexturesResidentEXT, /* 11 */
+ __glXDispSwap_DeleteTexturesEXT, /* 12 */
+ __glXDispSwap_GenTexturesEXT, /* 13 */
+ __glXDispSwap_IsTextureEXT, /* 14 */
+};
+
diff --git a/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.h b/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.h
new file mode 100644
index 000000000..3c1872f09
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_disptab_EXT.h
@@ -0,0 +1,158 @@
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_g_disptab_EXT_h_
+#define _GLX_g_disptab_EXT_h_
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+extern int __glXDisp_AreTexturesResidentEXT(__GLXclientState*, GLbyte*);
+extern int __glXDisp_DeleteTexturesEXT(__GLXclientState*, GLbyte*);
+extern int __glXDisp_GenTexturesEXT(__GLXclientState*, GLbyte*);
+extern int __glXDisp_IsTextureEXT(__GLXclientState*, GLbyte*);
+
+extern void __glXDisp_ColorTable(GLbyte*);
+extern void __glXDisp_ColorTableParameterfv(GLbyte*);
+extern void __glXDisp_ColorTableParameteriv(GLbyte*);
+extern void __glXDisp_CopyColorTable(GLbyte*);
+extern void __glXDisp_BlendColor(GLbyte*);
+extern void __glXDisp_BlendEquation(GLbyte*);
+extern void __glXDisp_TexSubImage1D(GLbyte*);
+extern void __glXDisp_TexSubImage2D(GLbyte*);
+extern void __glXDisp_ConvolutionFilter1D(GLbyte*);
+extern void __glXDisp_ConvolutionFilter2D(GLbyte*);
+extern void __glXDisp_ConvolutionParameterf(GLbyte*);
+extern void __glXDisp_ConvolutionParameterfv(GLbyte*);
+extern void __glXDisp_ConvolutionParameteri(GLbyte*);
+extern void __glXDisp_ConvolutionParameteriv(GLbyte*);
+extern void __glXDisp_CopyConvolutionFilter1D(GLbyte*);
+extern void __glXDisp_CopyConvolutionFilter2D(GLbyte*);
+extern void __glXDisp_SeparableFilter2D(GLbyte*);
+extern void __glXDisp_Histogram(GLbyte*);
+extern void __glXDisp_Minmax(GLbyte*);
+extern void __glXDisp_ResetHistogram(GLbyte*);
+extern void __glXDisp_ResetMinmax(GLbyte*);
+extern void __glXDisp_TexImage3D(GLbyte*);
+extern void __glXDisp_TexSubImage3D(GLbyte*);
+extern void __glXDisp_DrawArraysEXT(GLbyte*);
+extern void __glXDisp_BindTexture(GLbyte*);
+extern void __glXDisp_PrioritizeTextures(GLbyte*);
+extern void __glXDisp_CopyTexImage1D(GLbyte*);
+extern void __glXDisp_CopyTexImage2D(GLbyte*);
+extern void __glXDisp_CopyTexSubImage1D(GLbyte*);
+extern void __glXDisp_CopyTexSubImage2D(GLbyte*);
+extern void __glXDisp_CopyTexSubImage3D(GLbyte*);
+extern void __glXDisp_PointParameterfARB(GLbyte*);
+extern void __glXDisp_PointParameterfvARB(GLbyte*);
+
+extern void __glXDisp_FogCoordfv(GLbyte *);
+extern void __glXDisp_FogCoorddv(GLbyte *);
+extern void __glXDispSwap_FogCoordfv(GLbyte *);
+extern void __glXDispSwap_FogCoorddv(GLbyte *);
+
+extern void __glXDisp_SecondaryColor3bv(GLbyte *);
+extern void __glXDisp_SecondaryColor3sv(GLbyte *);
+extern void __glXDisp_SecondaryColor3iv(GLbyte *);
+extern void __glXDisp_SecondaryColor3ubv(GLbyte *);
+extern void __glXDisp_SecondaryColor3usv(GLbyte *);
+extern void __glXDisp_SecondaryColor3uiv(GLbyte *);
+extern void __glXDisp_SecondaryColor3fv(GLbyte *);
+extern void __glXDisp_SecondaryColor3dv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3bv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3sv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3iv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3ubv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3usv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3uiv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3fv(GLbyte *);
+extern void __glXDispSwap_SecondaryColor3dv(GLbyte *);
+
+extern void __glXDisp_BlendFuncSeparate(GLbyte *);
+extern void __glXDispSwap_BlendFuncSeparate(GLbyte *);
+
+extern void __glXDisp_PointParameteriNV(GLbyte *);
+extern void __glXDisp_PointParameterivNV(GLbyte *);
+extern void __glXDispSwap_PointParameteriNV(GLbyte *);
+extern void __glXDispSwap_PointParameterivNV(GLbyte *);
+
+extern void __glXDisp_ActiveStencilFaceEXT(GLbyte*);
+
+extern int __glXDispSwap_AreTexturesResidentEXT(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_DeleteTexturesEXT(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_GenTexturesEXT(__GLXclientState*, GLbyte*);
+extern int __glXDispSwap_IsTextureEXT(__GLXclientState*, GLbyte*);
+
+extern void __glXDispSwap_ColorTable(GLbyte*);
+extern void __glXDispSwap_ColorTableParameterfv(GLbyte*);
+extern void __glXDispSwap_ColorTableParameteriv(GLbyte*);
+extern void __glXDispSwap_CopyColorTable(GLbyte*);
+extern void __glXDispSwap_BlendColor(GLbyte*);
+extern void __glXDispSwap_BlendEquation(GLbyte*);
+extern void __glXDispSwap_TexSubImage1D(GLbyte*);
+extern void __glXDispSwap_TexSubImage2D(GLbyte*);
+extern void __glXDispSwap_ConvolutionFilter1D(GLbyte*);
+extern void __glXDispSwap_ConvolutionFilter2D(GLbyte*);
+extern void __glXDispSwap_ConvolutionParameterf(GLbyte*);
+extern void __glXDispSwap_ConvolutionParameterfv(GLbyte*);
+extern void __glXDispSwap_ConvolutionParameteri(GLbyte*);
+extern void __glXDispSwap_ConvolutionParameteriv(GLbyte*);
+extern void __glXDispSwap_CopyConvolutionFilter1D(GLbyte*);
+extern void __glXDispSwap_CopyConvolutionFilter2D(GLbyte*);
+extern void __glXDispSwap_SeparableFilter2D(GLbyte*);
+extern void __glXDispSwap_Histogram(GLbyte*);
+extern void __glXDispSwap_Minmax(GLbyte*);
+extern void __glXDispSwap_ResetHistogram(GLbyte*);
+extern void __glXDispSwap_ResetMinmax(GLbyte*);
+extern void __glXDispSwap_TexImage3D(GLbyte*);
+extern void __glXDispSwap_TexSubImage3D(GLbyte*);
+extern void __glXDispSwap_DrawArraysEXT(GLbyte*);
+extern void __glXDispSwap_BindTexture(GLbyte*);
+extern void __glXDispSwap_PrioritizeTextures(GLbyte*);
+extern void __glXDispSwap_CopyTexImage1D(GLbyte*);
+extern void __glXDispSwap_CopyTexImage2D(GLbyte*);
+extern void __glXDispSwap_CopyTexSubImage1D(GLbyte*);
+extern void __glXDispSwap_CopyTexSubImage2D(GLbyte*);
+extern void __glXDispSwap_CopyTexSubImage3D(GLbyte*);
+extern void __glXDispSwap_PointParameterfARB(GLbyte*);
+extern void __glXDispSwap_PointParameterfvARB(GLbyte*);
+extern void __glXDispSwap_ActiveStencilFaceEXT(GLbyte*);
+
+#define __GLX_MIN_RENDER_OPCODE_EXT 2053
+#define __GLX_MAX_RENDER_OPCODE_EXT 4222
+#define __GLX_MIN_VENDPRIV_OPCODE_EXT 11
+#define __GLX_MAX_VENDPRIV_OPCODE_EXT 14
+#define __GLX_VENDPRIV_TABLE_SIZE_EXT (__GLX_MAX_VENDPRIV_OPCODE_EXT - __GLX_MIN_VENDPRIV_OPCODE_EXT + 1)
+#define __GLX_RENDER_TABLE_SIZE_EXT (__GLX_MAX_RENDER_OPCODE_EXT - __GLX_MIN_RENDER_OPCODE_EXT + 1)
+extern __GLXdispatchRenderProcPtr __glXRenderTable_EXT[__GLX_RENDER_TABLE_SIZE_EXT];
+extern __GLXdispatchVendorPrivProcPtr __glXVendorPrivTable_EXT[__GLX_VENDPRIV_TABLE_SIZE_EXT];
+extern __GLXdispatchRenderProcPtr __glXSwapRenderTable_EXT[__GLX_RENDER_TABLE_SIZE_EXT];
+extern __GLXdispatchVendorPrivProcPtr __glXSwapVendorPrivTable_EXT[__GLX_VENDPRIV_TABLE_SIZE_EXT];
+#endif /* _GLX_g_disptab_EXT_h_ */
diff --git a/nx-X11/programs/Xserver/GL/glx/g_render.c b/nx-X11/programs/Xserver/GL/glx/g_render.c
new file mode 100644
index 000000000..ae3416bed
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_render.c
@@ -0,0 +1,2280 @@
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "unpack.h"
+#include "impsize.h"
+#include "singlesize.h"
+
+void __glXDisp_CallList(GLbyte *pc)
+{
+ glCallList(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_ListBase(GLbyte *pc)
+{
+ glListBase(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Begin(GLbyte *pc)
+{
+ glBegin(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+#define __GLX_SWAP_GLbyte(ptr)
+#define __GLX_SWAP_GLshort(ptr) __GLX_SWAP_SHORT(ptr)
+#define __GLX_SWAP_GLint(ptr) __GLX_SWAP_INT(ptr)
+#define __GLX_SWAP_GLubyte(ptr)
+#define __GLX_SWAP_GLushort(ptr) __GLX_SWAP_SHORT(ptr)
+#define __GLX_SWAP_GLuint(ptr) __GLX_SWAP_INT(ptr)
+#define __GLX_SWAP_GLdouble(ptr) __GLX_SWAP_DOUBLE(ptr)
+#define __GLX_SWAP_GLfloat(ptr) __GLX_SWAP_FLOAT(ptr)
+
+#define __GLX_SWAP_GLbyte_ARRAY(ptr,count) (void) swapEnd; (void) swapPC; (void) sw;
+#define __GLX_SWAP_GLshort_ARRAY(ptr,count) __GLX_SWAP_SHORT_ARRAY(ptr,count)
+#define __GLX_SWAP_GLint_ARRAY(ptr,count) __GLX_SWAP_INT_ARRAY(ptr,count)
+#define __GLX_SWAP_GLenum_ARRAY(ptr,count) __GLX_SWAP_INT_ARRAY(ptr,count)
+#define __GLX_SWAP_GLubyte_ARRAY(ptr,count) (void) swapEnd; (void) swapPC; (void) sw;
+#define __GLX_SWAP_GLushort_ARRAY(ptr,count) __GLX_SWAP_SHORT_ARRAY(ptr,count)
+#define __GLX_SWAP_GLuint_ARRAY(ptr,count) __GLX_SWAP_INT_ARRAY(ptr,count)
+#define __GLX_SWAP_GLdouble_ARRAY(ptr,count) __GLX_SWAP_DOUBLE_ARRAY(ptr,count)
+#define __GLX_SWAP_GLfloat_ARRAY(ptr,count) __GLX_SWAP_FLOAT_ARRAY(ptr,count)
+
+#ifdef __GLX_ALIGN64
+/* If type is not GLdouble, the compiler should optimize this away.
+ */
+# define GLX_DO_ALIGN_MAGIC(count, type) \
+ do { \
+ if ( (sizeof(type) == 8) && ((unsigned long)(pc) & 7)) \
+ { \
+ __GLX_MEM_COPY(pc-4, pc, (count * sizeof( type ) )); \
+ pc -= 4; \
+ } \
+ } while( 0 )
+#else
+# define GLX_DO_ALIGN_MAGIC(count, type)
+#endif
+
+#define dispatch_template_1( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ GLX_DO_ALIGN_MAGIC( 1, type ); \
+ gl ## name ( (type *) pc ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ GLX_DO_ALIGN_MAGIC( 1, type ); \
+ __GLX_SWAP_ ## type ( pc ); \
+ gl ## name ( (type *) pc ); \
+ }
+
+#define dispatch_template_3( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ GLX_DO_ALIGN_MAGIC( 3, type ); \
+ gl ## name ( (type *) pc ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES; \
+ GLX_DO_ALIGN_MAGIC( 3, type ); \
+ __GLX_SWAP_ ## type ## _ARRAY(pc, 3); \
+ gl ## name ( (type *) pc ); \
+ }
+
+#define dispatch_template_4( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ GLX_DO_ALIGN_MAGIC( 4, type ); \
+ gl ## name ( (type *) pc ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES; \
+ GLX_DO_ALIGN_MAGIC( 4, type ); \
+ __GLX_SWAP_ ## type ## _ARRAY(pc, 4); \
+ gl ## name ( (type *) pc ); \
+ }
+
+#define dispatch_template_4s( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ GLX_DO_ALIGN_MAGIC( 4, type ); \
+ gl ## name ( ((type *) pc)[0], ((type *) pc)[1], \
+ ((type *) pc)[2], ((type *) pc)[3] ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES; \
+ GLX_DO_ALIGN_MAGIC( 4, type ); \
+ __GLX_SWAP_ ## type ## _ARRAY(pc, 4); \
+ gl ## name ( ((type *) pc)[0], ((type *) pc)[1], \
+ ((type *) pc)[2], ((type *) pc)[3] ); \
+ }
+
+/**
+ * \bug All of the enum1 templates need to be updated to handle the case where
+ * \c type is \c GLdouble. When the type is a double, the data comes before
+ * the enum. This is also the reason the invocation of the
+ * \c GLX_DO_ALIGN_MAGIC macro was removed.
+ */
+#define dispatch_template_enum1_1s( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ gl ## name ( *(GLenum *) (pc + 0), \
+ *(type *) (pc + 4) ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ __GLX_SWAP_INT (pc + 0); \
+ __GLX_SWAP_ ## type (pc + 4); \
+ gl ## name ( *(GLenum *) (pc + 0), \
+ *(type *) (pc + 4) ); \
+ }
+
+#define dispatch_template_enum1_Vv( name, type ) \
+ void __glXDisp_ ## name ( GLbyte * pc ) \
+ { \
+ gl ## name ( *(GLenum *) (pc + 0), \
+ (type *) (pc + 4) ); \
+ } \
+ void __glXDispSwap_ ## name ( GLbyte * pc ) \
+ { \
+ GLenum pname; GLint compsize; \
+ __GLX_DECLARE_SWAP_VARIABLES; \
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES; \
+ __GLX_SWAP_INT(pc + 0); \
+ pname = *(GLenum *)(pc + 0); \
+ compsize = __gl ## name ## _size(pname); \
+ if (compsize < 0) compsize = 0; \
+ __GLX_SWAP_ ## type ## _ARRAY(pc + 4, compsize); \
+ gl ## name ( *(GLenum *) (pc + 0), \
+ (type *) (pc + 4) ); \
+ }
+
+#ifndef MISSING_GL_EXTS
+dispatch_template_1( FogCoordfv, GLfloat )
+dispatch_template_1( FogCoorddv, GLdouble )
+dispatch_template_3( SecondaryColor3bv, GLbyte )
+dispatch_template_3( SecondaryColor3sv, GLshort )
+dispatch_template_3( SecondaryColor3iv, GLint )
+dispatch_template_3( SecondaryColor3ubv, GLubyte )
+dispatch_template_3( SecondaryColor3usv, GLushort )
+dispatch_template_3( SecondaryColor3uiv, GLuint )
+dispatch_template_3( SecondaryColor3fv, GLfloat )
+dispatch_template_3( SecondaryColor3dv, GLdouble )
+
+dispatch_template_4s( BlendFuncSeparate, GLenum )
+#endif /* !MISSING_GL_EXTS */
+
+void __glXDisp_Color3bv(GLbyte *pc)
+{
+ glColor3bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glColor3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3fv(GLbyte *pc)
+{
+ glColor3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3iv(GLbyte *pc)
+{
+ glColor3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3sv(GLbyte *pc)
+{
+ glColor3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3ubv(GLbyte *pc)
+{
+ glColor3ubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3uiv(GLbyte *pc)
+{
+ glColor3uiv(
+ (GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color3usv(GLbyte *pc)
+{
+ glColor3usv(
+ (GLushort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4bv(GLbyte *pc)
+{
+ glColor4bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glColor4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4fv(GLbyte *pc)
+{
+ glColor4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4iv(GLbyte *pc)
+{
+ glColor4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4sv(GLbyte *pc)
+{
+ glColor4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4ubv(GLbyte *pc)
+{
+ glColor4ubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4uiv(GLbyte *pc)
+{
+ glColor4uiv(
+ (GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Color4usv(GLbyte *pc)
+{
+ glColor4usv(
+ (GLushort *)(pc + 0)
+ );
+}
+
+void __glXDisp_EdgeFlagv(GLbyte *pc)
+{
+ glEdgeFlagv(
+ (GLboolean *)(pc + 0)
+ );
+}
+
+void __glXDisp_End(GLbyte *pc)
+{
+ glEnd(
+ );
+}
+
+void __glXDisp_Indexdv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ glIndexdv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Indexfv(GLbyte *pc)
+{
+ glIndexfv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Indexiv(GLbyte *pc)
+{
+ glIndexiv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Indexsv(GLbyte *pc)
+{
+ glIndexsv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Normal3bv(GLbyte *pc)
+{
+ glNormal3bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_Normal3dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glNormal3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Normal3fv(GLbyte *pc)
+{
+ glNormal3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Normal3iv(GLbyte *pc)
+{
+ glNormal3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Normal3sv(GLbyte *pc)
+{
+ glNormal3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos2dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glRasterPos2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos2fv(GLbyte *pc)
+{
+ glRasterPos2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos2iv(GLbyte *pc)
+{
+ glRasterPos2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos2sv(GLbyte *pc)
+{
+ glRasterPos2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos3dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glRasterPos3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos3fv(GLbyte *pc)
+{
+ glRasterPos3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos3iv(GLbyte *pc)
+{
+ glRasterPos3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos3sv(GLbyte *pc)
+{
+ glRasterPos3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos4dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glRasterPos4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos4fv(GLbyte *pc)
+{
+ glRasterPos4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos4iv(GLbyte *pc)
+{
+ glRasterPos4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_RasterPos4sv(GLbyte *pc)
+{
+ glRasterPos4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Rectdv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glRectdv(
+ (GLdouble *)(pc + 0),
+ (GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDisp_Rectfv(GLbyte *pc)
+{
+ glRectfv(
+ (GLfloat *)(pc + 0),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Rectiv(GLbyte *pc)
+{
+ glRectiv(
+ (GLint *)(pc + 0),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_Rectsv(GLbyte *pc)
+{
+ glRectsv(
+ (GLshort *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDisp_TexCoord1dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ glTexCoord1dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord1fv(GLbyte *pc)
+{
+ glTexCoord1fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord1iv(GLbyte *pc)
+{
+ glTexCoord1iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord1sv(GLbyte *pc)
+{
+ glTexCoord1sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord2dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glTexCoord2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord2fv(GLbyte *pc)
+{
+ glTexCoord2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord2iv(GLbyte *pc)
+{
+ glTexCoord2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord2sv(GLbyte *pc)
+{
+ glTexCoord2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord3dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glTexCoord3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord3fv(GLbyte *pc)
+{
+ glTexCoord3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord3iv(GLbyte *pc)
+{
+ glTexCoord3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord3sv(GLbyte *pc)
+{
+ glTexCoord3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord4dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glTexCoord4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord4fv(GLbyte *pc)
+{
+ glTexCoord4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord4iv(GLbyte *pc)
+{
+ glTexCoord4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexCoord4sv(GLbyte *pc)
+{
+ glTexCoord4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex2dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glVertex2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex2fv(GLbyte *pc)
+{
+ glVertex2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex2iv(GLbyte *pc)
+{
+ glVertex2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex2sv(GLbyte *pc)
+{
+ glVertex2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex3dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glVertex3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex3fv(GLbyte *pc)
+{
+ glVertex3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex3iv(GLbyte *pc)
+{
+ glVertex3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex3sv(GLbyte *pc)
+{
+ glVertex3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex4dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glVertex4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex4fv(GLbyte *pc)
+{
+ glVertex4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex4iv(GLbyte *pc)
+{
+ glVertex4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Vertex4sv(GLbyte *pc)
+{
+ glVertex4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDisp_ClipPlane(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 36);
+ pc -= 4;
+ }
+#endif
+ glClipPlane(
+ *(GLenum *)(pc + 32),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_ColorMaterial(GLbyte *pc)
+{
+ glColorMaterial(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDisp_CullFace(GLbyte *pc)
+{
+ glCullFace(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_Fogf(GLbyte *pc)
+{
+ glFogf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_Fogfv(GLbyte *pc)
+{
+ glFogfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_Fogi(GLbyte *pc)
+{
+ glFogi(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_Fogiv(GLbyte *pc)
+{
+ glFogiv(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_FrontFace(GLbyte *pc)
+{
+ glFrontFace(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_Hint(GLbyte *pc)
+{
+ glHint(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDisp_Lightf(GLbyte *pc)
+{
+ glLightf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Lightfv(GLbyte *pc)
+{
+ glLightfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Lighti(GLbyte *pc)
+{
+ glLighti(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_Lightiv(GLbyte *pc)
+{
+ glLightiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_LightModelf(GLbyte *pc)
+{
+ glLightModelf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_LightModelfv(GLbyte *pc)
+{
+ glLightModelfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_LightModeli(GLbyte *pc)
+{
+ glLightModeli(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_LightModeliv(GLbyte *pc)
+{
+ glLightModeliv(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_LineStipple(GLbyte *pc)
+{
+ glLineStipple(
+ *(GLint *)(pc + 0),
+ *(GLushort *)(pc + 4)
+ );
+}
+
+void __glXDisp_LineWidth(GLbyte *pc)
+{
+ glLineWidth(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_Materialf(GLbyte *pc)
+{
+ glMaterialf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Materialfv(GLbyte *pc)
+{
+ glMaterialfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Materiali(GLbyte *pc)
+{
+ glMateriali(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_Materialiv(GLbyte *pc)
+{
+ glMaterialiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_PointSize(GLbyte *pc)
+{
+ glPointSize(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_PolygonMode(GLbyte *pc)
+{
+ glPolygonMode(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDisp_Scissor(GLbyte *pc)
+{
+ glScissor(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12)
+ );
+}
+
+void __glXDisp_ShadeModel(GLbyte *pc)
+{
+ glShadeModel(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexParameterf(GLbyte *pc)
+{
+ glTexParameterf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexParameterfv(GLbyte *pc)
+{
+ glTexParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexParameteri(GLbyte *pc)
+{
+ glTexParameteri(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexParameteriv(GLbyte *pc)
+{
+ glTexParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexEnvf(GLbyte *pc)
+{
+ glTexEnvf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexEnvfv(GLbyte *pc)
+{
+ glTexEnvfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexEnvi(GLbyte *pc)
+{
+ glTexEnvi(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexEnviv(GLbyte *pc)
+{
+ glTexEnviv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexGend(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glTexGend(
+ *(GLenum *)(pc + 8),
+ *(GLenum *)(pc + 12),
+ *(GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_TexGendv(GLbyte *pc)
+{
+#ifdef __GLX_ALIGN64
+ GLenum pname;
+ GLint cmdlen;
+ GLint compsize;
+
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexGendv_size(pname);
+ if (compsize < 0) compsize = 0;
+ cmdlen = __GLX_PAD(8+compsize*8);
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, cmdlen);
+ pc -= 4;
+ }
+#endif
+
+ glTexGendv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexGenf(GLbyte *pc)
+{
+ glTexGenf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexGenfv(GLbyte *pc)
+{
+ glTexGenfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexGeni(GLbyte *pc)
+{
+ glTexGeni(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_TexGeniv(GLbyte *pc)
+{
+ glTexGeniv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_InitNames(GLbyte *pc)
+{
+ glInitNames(
+ );
+}
+
+void __glXDisp_LoadName(GLbyte *pc)
+{
+ glLoadName(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_PassThrough(GLbyte *pc)
+{
+ glPassThrough(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_PopName(GLbyte *pc)
+{
+ glPopName(
+ );
+}
+
+void __glXDisp_PushName(GLbyte *pc)
+{
+ glPushName(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_DrawBuffer(GLbyte *pc)
+{
+ glDrawBuffer(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_Clear(GLbyte *pc)
+{
+ glClear(
+ *(GLbitfield *)(pc + 0)
+ );
+}
+
+void __glXDisp_ClearAccum(GLbyte *pc)
+{
+ glClearAccum(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLfloat *)(pc + 12)
+ );
+}
+
+void __glXDisp_ClearIndex(GLbyte *pc)
+{
+ glClearIndex(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_ClearColor(GLbyte *pc)
+{
+ glClearColor(
+ *(GLclampf *)(pc + 0),
+ *(GLclampf *)(pc + 4),
+ *(GLclampf *)(pc + 8),
+ *(GLclampf *)(pc + 12)
+ );
+}
+
+void __glXDisp_ClearStencil(GLbyte *pc)
+{
+ glClearStencil(
+ *(GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_ClearDepth(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ glClearDepth(
+ *(GLclampd *)(pc + 0)
+ );
+}
+
+void __glXDisp_StencilMask(GLbyte *pc)
+{
+ glStencilMask(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_ColorMask(GLbyte *pc)
+{
+ glColorMask(
+ *(GLboolean *)(pc + 0),
+ *(GLboolean *)(pc + 1),
+ *(GLboolean *)(pc + 2),
+ *(GLboolean *)(pc + 3)
+ );
+}
+
+void __glXDisp_DepthMask(GLbyte *pc)
+{
+ glDepthMask(
+ *(GLboolean *)(pc + 0)
+ );
+}
+
+void __glXDisp_IndexMask(GLbyte *pc)
+{
+ glIndexMask(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDisp_Accum(GLbyte *pc)
+{
+ glAccum(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_Disable(GLbyte *pc)
+{
+ glDisable(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_Enable(GLbyte *pc)
+{
+ glEnable(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_PopAttrib(GLbyte *pc)
+{
+ glPopAttrib(
+ );
+}
+
+void __glXDisp_PushAttrib(GLbyte *pc)
+{
+ glPushAttrib(
+ *(GLbitfield *)(pc + 0)
+ );
+}
+
+void __glXDisp_MapGrid1d(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 20);
+ pc -= 4;
+ }
+#endif
+ glMapGrid1d(
+ *(GLint *)(pc + 16),
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8)
+ );
+}
+
+void __glXDisp_MapGrid1f(GLbyte *pc)
+{
+ glMapGrid1f(
+ *(GLint *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_MapGrid2d(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 40);
+ pc -= 4;
+ }
+#endif
+ glMapGrid2d(
+ *(GLint *)(pc + 32),
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLint *)(pc + 36),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24)
+ );
+}
+
+void __glXDisp_MapGrid2f(GLbyte *pc)
+{
+ glMapGrid2f(
+ *(GLint *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLfloat *)(pc + 16),
+ *(GLfloat *)(pc + 20)
+ );
+}
+
+void __glXDisp_EvalCoord1dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ glEvalCoord1dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_EvalCoord1fv(GLbyte *pc)
+{
+ glEvalCoord1fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_EvalCoord2dv(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glEvalCoord2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_EvalCoord2fv(GLbyte *pc)
+{
+ glEvalCoord2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_EvalMesh1(GLbyte *pc)
+{
+ glEvalMesh1(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_EvalPoint1(GLbyte *pc)
+{
+ glEvalPoint1(
+ *(GLint *)(pc + 0)
+ );
+}
+
+void __glXDisp_EvalMesh2(GLbyte *pc)
+{
+ glEvalMesh2(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16)
+ );
+}
+
+void __glXDisp_EvalPoint2(GLbyte *pc)
+{
+ glEvalPoint2(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_AlphaFunc(GLbyte *pc)
+{
+ glAlphaFunc(
+ *(GLenum *)(pc + 0),
+ *(GLclampf *)(pc + 4)
+ );
+}
+
+void __glXDisp_BlendFunc(GLbyte *pc)
+{
+ glBlendFunc(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDisp_LogicOp(GLbyte *pc)
+{
+ glLogicOp(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_StencilFunc(GLbyte *pc)
+{
+ glStencilFunc(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLuint *)(pc + 8)
+ );
+}
+
+void __glXDisp_StencilOp(GLbyte *pc)
+{
+ glStencilOp(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8)
+ );
+}
+
+void __glXDisp_DepthFunc(GLbyte *pc)
+{
+ glDepthFunc(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_PixelZoom(GLbyte *pc)
+{
+ glPixelZoom(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_PixelTransferf(GLbyte *pc)
+{
+ glPixelTransferf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_PixelTransferi(GLbyte *pc)
+{
+ glPixelTransferi(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_PixelMapfv(GLbyte *pc)
+{
+ glPixelMapfv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_PixelMapuiv(GLbyte *pc)
+{
+ glPixelMapuiv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLuint *)(pc + 8)
+ );
+}
+
+void __glXDisp_PixelMapusv(GLbyte *pc)
+{
+ glPixelMapusv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLushort *)(pc + 8)
+ );
+}
+
+void __glXDisp_ReadBuffer(GLbyte *pc)
+{
+ glReadBuffer(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_CopyPixels(GLbyte *pc)
+{
+ glCopyPixels(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12),
+ *(GLenum *)(pc + 16)
+ );
+}
+
+void __glXDisp_DepthRange(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ glDepthRange(
+ *(GLclampd *)(pc + 0),
+ *(GLclampd *)(pc + 8)
+ );
+}
+
+void __glXDisp_Frustum(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 48);
+ pc -= 4;
+ }
+#endif
+ glFrustum(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24),
+ *(GLdouble *)(pc + 32),
+ *(GLdouble *)(pc + 40)
+ );
+}
+
+void __glXDisp_LoadIdentity(GLbyte *pc)
+{
+ glLoadIdentity(
+ );
+}
+
+void __glXDisp_LoadMatrixf(GLbyte *pc)
+{
+ glLoadMatrixf(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_LoadMatrixd(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 128);
+ pc -= 4;
+ }
+#endif
+ glLoadMatrixd(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_MatrixMode(GLbyte *pc)
+{
+ glMatrixMode(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultMatrixf(GLbyte *pc)
+{
+ glMultMatrixf(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultMatrixd(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 128);
+ pc -= 4;
+ }
+#endif
+ glMultMatrixd(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_Ortho(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 48);
+ pc -= 4;
+ }
+#endif
+ glOrtho(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24),
+ *(GLdouble *)(pc + 32),
+ *(GLdouble *)(pc + 40)
+ );
+}
+
+void __glXDisp_PopMatrix(GLbyte *pc)
+{
+ glPopMatrix(
+ );
+}
+
+void __glXDisp_PushMatrix(GLbyte *pc)
+{
+ glPushMatrix(
+ );
+}
+
+void __glXDisp_Rotated(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ glRotated(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24)
+ );
+}
+
+void __glXDisp_Rotatef(GLbyte *pc)
+{
+ glRotatef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLfloat *)(pc + 12)
+ );
+}
+
+void __glXDisp_Scaled(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glScaled(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDisp_Scalef(GLbyte *pc)
+{
+ glScalef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Translated(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ glTranslated(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDisp_Translatef(GLbyte *pc)
+{
+ glTranslatef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_Viewport(GLbyte *pc)
+{
+ glViewport(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12)
+ );
+}
+
+void __glXDisp_PolygonOffset(GLbyte *pc)
+{
+ glPolygonOffset(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_CopyTexImage1D(GLbyte *pc)
+{
+ glCopyTexImage1D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20),
+ *(GLint *)(pc + 24)
+ );
+}
+
+void __glXDisp_CopyTexImage2D(GLbyte *pc)
+{
+ glCopyTexImage2D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20),
+ *(GLsizei *)(pc + 24),
+ *(GLint *)(pc + 28)
+ );
+}
+
+void __glXDisp_CopyTexSubImage1D(GLbyte *pc)
+{
+ glCopyTexSubImage1D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20)
+ );
+}
+
+void __glXDisp_CopyTexSubImage2D(GLbyte *pc)
+{
+ glCopyTexSubImage2D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLint *)(pc + 20),
+ *(GLsizei *)(pc + 24),
+ *(GLsizei *)(pc + 28)
+ );
+}
+
+void __glXDisp_BindTexture(GLbyte *pc)
+{
+ glBindTexture(
+ *(GLenum *)(pc + 0),
+ *(GLuint *)(pc + 4)
+ );
+}
+
+void __glXDisp_PrioritizeTextures(GLbyte *pc)
+{
+ GLsizei n;
+
+ n = *(GLsizei *)(pc + 0);
+
+ glPrioritizeTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLclampf *)(pc + 4+n*4)
+ );
+}
+
+void __glXDisp_Indexubv(GLbyte *pc)
+{
+ glIndexubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDisp_BlendColor(GLbyte *pc)
+{
+ glBlendColor(
+ *(GLclampf *)(pc + 0),
+ *(GLclampf *)(pc + 4),
+ *(GLclampf *)(pc + 8),
+ *(GLclampf *)(pc + 12)
+ );
+}
+
+void __glXDisp_BlendEquation(GLbyte *pc)
+{
+ glBlendEquation(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_ColorTableParameterfv(GLbyte *pc)
+{
+ glColorTableParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_ColorTableParameteriv(GLbyte *pc)
+{
+ glColorTableParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_CopyColorTable(GLbyte *pc)
+{
+ glCopyColorTable(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDisp_CopyColorSubTable(GLbyte *pc)
+{
+ glCopyColorSubTable(
+ *(GLenum *)(pc + 0),
+ *(GLsizei *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDisp_ConvolutionParameterf(GLbyte *pc)
+{
+ glConvolutionParameterf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_ConvolutionParameterfv(GLbyte *pc)
+{
+ glConvolutionParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDisp_ConvolutionParameteri(GLbyte *pc)
+{
+ glConvolutionParameteri(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_ConvolutionParameteriv(GLbyte *pc)
+{
+ glConvolutionParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDisp_CopyConvolutionFilter1D(GLbyte *pc)
+{
+ glCopyConvolutionFilter1D(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDisp_CopyConvolutionFilter2D(GLbyte *pc)
+{
+ glCopyConvolutionFilter2D(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16),
+ *(GLsizei *)(pc + 20)
+ );
+}
+
+void __glXDisp_Histogram(GLbyte *pc)
+{
+ glHistogram(
+ *(GLenum *)(pc + 0),
+ *(GLsizei *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLboolean *)(pc + 12)
+ );
+}
+
+void __glXDisp_Minmax(GLbyte *pc)
+{
+ glMinmax(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLboolean *)(pc + 8)
+ );
+}
+
+void __glXDisp_ResetHistogram(GLbyte *pc)
+{
+ glResetHistogram(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_ResetMinmax(GLbyte *pc)
+{
+ glResetMinmax(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_CopyTexSubImage3D(GLbyte *pc)
+{
+ glCopyTexSubImage3D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLint *)(pc + 20),
+ *(GLint *)(pc + 24),
+ *(GLsizei *)(pc + 28),
+ *(GLsizei *)(pc + 32)
+ );
+}
+
+void __glXDisp_ActiveTextureARB(GLbyte *pc)
+{
+ glActiveTextureARB(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultiTexCoord1dvARB(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 12);
+ pc -= 4;
+ }
+#endif
+ glMultiTexCoord1dvARB(
+ *(GLenum *)(pc + 8),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultiTexCoord1fvARB(GLbyte *pc)
+{
+ glMultiTexCoord1fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord1ivARB(GLbyte *pc)
+{
+ glMultiTexCoord1ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord1svARB(GLbyte *pc)
+{
+ glMultiTexCoord1svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord2dvARB(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 20);
+ pc -= 4;
+ }
+#endif
+ glMultiTexCoord2dvARB(
+ *(GLenum *)(pc + 16),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultiTexCoord2fvARB(GLbyte *pc)
+{
+ glMultiTexCoord2fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord2ivARB(GLbyte *pc)
+{
+ glMultiTexCoord2ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord2svARB(GLbyte *pc)
+{
+ glMultiTexCoord2svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord3dvARB(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 28);
+ pc -= 4;
+ }
+#endif
+ glMultiTexCoord3dvARB(
+ *(GLenum *)(pc + 24),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultiTexCoord3fvARB(GLbyte *pc)
+{
+ glMultiTexCoord3fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord3ivARB(GLbyte *pc)
+{
+ glMultiTexCoord3ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord3svARB(GLbyte *pc)
+{
+ glMultiTexCoord3svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord4dvARB(GLbyte *pc)
+{
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 36);
+ pc -= 4;
+ }
+#endif
+ glMultiTexCoord4dvARB(
+ *(GLenum *)(pc + 32),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDisp_MultiTexCoord4fvARB(GLbyte *pc)
+{
+ glMultiTexCoord4fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord4ivARB(GLbyte *pc)
+{
+ glMultiTexCoord4ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDisp_MultiTexCoord4svARB(GLbyte *pc)
+{
+ glMultiTexCoord4svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+
+/*
+ * Extensions
+ */
+
+#ifndef MISSING_GL_EXTS
+
+void __glXDisp_PointParameterfARB(GLbyte *pc)
+{
+ glPointParameterfARB(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+
+void __glXDisp_PointParameterfvARB(GLbyte *pc)
+{
+ glPointParameterfvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+dispatch_template_enum1_1s(PointParameteriNV, GLint)
+dispatch_template_enum1_Vv(PointParameterivNV, GLint)
+
+void __glXDisp_ActiveStencilFaceEXT(GLbyte *pc)
+{
+ glActiveStencilFaceEXT(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDisp_WindowPos3fARB(GLbyte *pc)
+{
+ glWindowPos3fARB(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+#endif /* !MISSING_GL_EXTS */
+
+void __glXDisp_SampleCoverageARB(GLbyte *pc)
+{
+ glSampleCoverageARB(
+ *(GLfloat *)(pc + 0),
+ *(GLboolean *)(pc + 4)
+ );
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/g_renderswap.c b/nx-X11/programs/Xserver/GL/glx/g_renderswap.c
new file mode 100644
index 000000000..38b1497f1
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_renderswap.c
@@ -0,0 +1,3385 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "unpack.h"
+#include "impsize.h"
+#include "singlesize.h"
+
+void __glXDispSwap_CallList(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glCallList(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ListBase(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glListBase(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Begin(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glBegin(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3bv(GLbyte *pc)
+{
+ glColor3bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glColor3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
+
+ glColor3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glColor3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glColor3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3ubv(GLbyte *pc)
+{
+ glColor3ubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3uiv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glColor3uiv(
+ (GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color3usv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glColor3usv(
+ (GLushort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4bv(GLbyte *pc)
+{
+ glColor4bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glColor4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
+
+ glColor4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 4);
+
+ glColor4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
+
+ glColor4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4ubv(GLbyte *pc)
+{
+ glColor4ubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4uiv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 4);
+
+ glColor4uiv(
+ (GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Color4usv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
+
+ glColor4usv(
+ (GLushort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EdgeFlagv(GLbyte *pc)
+{
+ glEdgeFlagv(
+ (GLboolean *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_End(GLbyte *pc)
+{
+ glEnd(
+ );
+}
+
+void __glXDispSwap_Indexdv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
+
+ glIndexdv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Indexfv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
+
+ glIndexfv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Indexiv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 1);
+
+ glIndexiv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Indexsv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 1);
+
+ glIndexsv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Normal3bv(GLbyte *pc)
+{
+ glNormal3bv(
+ (GLbyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Normal3dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glNormal3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Normal3fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
+
+ glNormal3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Normal3iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glNormal3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Normal3sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glNormal3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos2dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+
+ glRasterPos2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos2fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
+
+ glRasterPos2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos2iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 2);
+
+ glRasterPos2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos2sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
+
+ glRasterPos2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos3dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glRasterPos3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos3fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
+
+ glRasterPos3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos3iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glRasterPos3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos3sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glRasterPos3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos4dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glRasterPos4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos4fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
+
+ glRasterPos4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos4iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 4);
+
+ glRasterPos4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_RasterPos4sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
+
+ glRasterPos4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Rectdv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 16, 2);
+
+ glRectdv(
+ (GLdouble *)(pc + 0),
+ (GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_Rectfv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, 2);
+
+ glRectfv(
+ (GLfloat *)(pc + 0),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Rectiv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 2);
+ __GLX_SWAP_INT_ARRAY(pc + 8, 2);
+
+ glRectiv(
+ (GLint *)(pc + 0),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Rectsv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
+ __GLX_SWAP_SHORT_ARRAY(pc + 4, 2);
+
+ glRectsv(
+ (GLshort *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_TexCoord1dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
+
+ glTexCoord1dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord1fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
+
+ glTexCoord1fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord1iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 1);
+
+ glTexCoord1iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord1sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 1);
+
+ glTexCoord1sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord2dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+
+ glTexCoord2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord2fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
+
+ glTexCoord2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord2iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 2);
+
+ glTexCoord2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord2sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
+
+ glTexCoord2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord3dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glTexCoord3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord3fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
+
+ glTexCoord3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord3iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glTexCoord3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord3sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glTexCoord3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord4dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glTexCoord4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord4fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
+
+ glTexCoord4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord4iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 4);
+
+ glTexCoord4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexCoord4sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
+
+ glTexCoord4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex2dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+
+ glVertex2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex2fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
+
+ glVertex2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex2iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 2);
+
+ glVertex2iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex2sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 2);
+
+ glVertex2sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex3dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glVertex3dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex3fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 3);
+
+ glVertex3fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex3iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 3);
+
+ glVertex3iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex3sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 3);
+
+ glVertex3sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex4dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glVertex4dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex4fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 4);
+
+ glVertex4fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex4iv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT_ARRAY(pc + 0, 4);
+
+ glVertex4iv(
+ (GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Vertex4sv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_SHORT_ARRAY(pc + 0, 4);
+
+ glVertex4sv(
+ (GLshort *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ClipPlane(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 36);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 32);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glClipPlane(
+ *(GLenum *)(pc + 32),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ColorMaterial(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glColorMaterial(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_CullFace(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glCullFace(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Fogf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glFogf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Fogfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glFogfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize);
+
+ glFogfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Fogi(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glFogi(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Fogiv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glFogiv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT_ARRAY(pc + 4, compsize);
+
+ glFogiv(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_FrontFace(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glFrontFace(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Hint(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glHint(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Lightf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glLightf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Lightfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glLightfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glLightfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Lighti(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glLighti(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Lightiv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glLightiv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glLightiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_LightModelf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glLightModelf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LightModelfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glLightModelfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize);
+
+ glLightModelfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LightModeli(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glLightModeli(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LightModeliv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glLightModeliv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT_ARRAY(pc + 4, compsize);
+
+ glLightModeliv(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LineStipple(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT(pc + 4);
+
+ glLineStipple(
+ *(GLint *)(pc + 0),
+ *(GLushort *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LineWidth(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+
+ glLineWidth(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Materialf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glMaterialf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Materialfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glMaterialfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glMaterialfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Materiali(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glMateriali(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Materialiv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glMaterialiv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glMaterialiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_PointSize(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+
+ glPointSize(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_PolygonMode(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glPolygonMode(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Scissor(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+
+ glScissor(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_ShadeModel(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glShadeModel(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexParameterf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glTexParameterf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexParameterfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glTexParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexParameteri(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glTexParameteri(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexParameteriv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glTexParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexEnvf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glTexEnvf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexEnvfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexEnvfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glTexEnvfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexEnvi(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glTexEnvi(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexEnviv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexEnviv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glTexEnviv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexGend(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_DOUBLE(pc + 0);
+
+ glTexGend(
+ *(GLenum *)(pc + 8),
+ *(GLenum *)(pc + 12),
+ *(GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_TexGendv(GLbyte *pc)
+{
+ GLenum pname;
+#ifdef __GLX_ALIGN64
+ GLint cmdlen;
+#endif
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexGendv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+#ifdef __GLX_ALIGN64
+ cmdlen = __GLX_PAD(8+compsize*8);
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, cmdlen);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 8, compsize);
+
+ glTexGendv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexGenf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glTexGenf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexGenfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexGenfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glTexGenfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexGeni(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glTexGeni(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_TexGeniv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glTexGeniv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glTexGeniv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_InitNames(GLbyte *pc)
+{
+ glInitNames(
+ );
+}
+
+void __glXDispSwap_LoadName(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glLoadName(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_PassThrough(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+
+ glPassThrough(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_PopName(GLbyte *pc)
+{
+ glPopName(
+ );
+}
+
+void __glXDispSwap_PushName(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glPushName(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_DrawBuffer(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glDrawBuffer(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Clear(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glClear(
+ *(GLbitfield *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ClearAccum(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_FLOAT(pc + 12);
+
+ glClearAccum(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLfloat *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_ClearIndex(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+
+ glClearIndex(
+ *(GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ClearColor(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_FLOAT(pc + 12);
+
+ glClearColor(
+ *(GLclampf *)(pc + 0),
+ *(GLclampf *)(pc + 4),
+ *(GLclampf *)(pc + 8),
+ *(GLclampf *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_ClearStencil(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glClearStencil(
+ *(GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ClearDepth(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+
+ glClearDepth(
+ *(GLclampd *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_StencilMask(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glStencilMask(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ColorMask(GLbyte *pc)
+{
+ glColorMask(
+ *(GLboolean *)(pc + 0),
+ *(GLboolean *)(pc + 1),
+ *(GLboolean *)(pc + 2),
+ *(GLboolean *)(pc + 3)
+ );
+}
+
+void __glXDispSwap_DepthMask(GLbyte *pc)
+{
+ glDepthMask(
+ *(GLboolean *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_IndexMask(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glIndexMask(
+ *(GLuint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Accum(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glAccum(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_Disable(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glDisable(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Enable(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glEnable(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_PopAttrib(GLbyte *pc)
+{
+ glPopAttrib(
+ );
+}
+
+void __glXDispSwap_PushAttrib(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glPushAttrib(
+ *(GLbitfield *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MapGrid1d(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 20);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+
+ glMapGrid1d(
+ *(GLint *)(pc + 16),
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_MapGrid1f(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glMapGrid1f(
+ *(GLint *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_MapGrid2d(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 40);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 32);
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_INT(pc + 36);
+ __GLX_SWAP_DOUBLE(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 24);
+
+ glMapGrid2d(
+ *(GLint *)(pc + 32),
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLint *)(pc + 36),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24)
+ );
+}
+
+void __glXDispSwap_MapGrid2f(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_FLOAT(pc + 16);
+ __GLX_SWAP_FLOAT(pc + 20);
+
+ glMapGrid2f(
+ *(GLint *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLfloat *)(pc + 16),
+ *(GLfloat *)(pc + 20)
+ );
+}
+
+void __glXDispSwap_EvalCoord1dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 8);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
+
+ glEvalCoord1dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EvalCoord1fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 1);
+
+ glEvalCoord1fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EvalCoord2dv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+
+ glEvalCoord2dv(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EvalCoord2fv(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 2);
+
+ glEvalCoord2fv(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EvalMesh1(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glEvalMesh1(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_EvalPoint1(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glEvalPoint1(
+ *(GLint *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_EvalMesh2(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+
+ glEvalMesh2(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_EvalPoint2(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glEvalPoint2(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_AlphaFunc(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glAlphaFunc(
+ *(GLenum *)(pc + 0),
+ *(GLclampf *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_BlendFunc(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glBlendFunc(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_LogicOp(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glLogicOp(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_StencilFunc(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glStencilFunc(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLuint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_StencilOp(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glStencilOp(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_DepthFunc(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glDepthFunc(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_PixelZoom(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glPixelZoom(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_PixelTransferf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glPixelTransferf(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_PixelTransferi(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glPixelTransferi(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_PixelMapfv(GLbyte *pc)
+{
+ GLint mapsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ mapsize = *(GLint *)(pc + 4);
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, mapsize);
+
+ glPixelMapfv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_PixelMapuiv(GLbyte *pc)
+{
+ GLint mapsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ mapsize = *(GLint *)(pc + 4);
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, mapsize);
+
+ glPixelMapuiv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLuint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_PixelMapusv(GLbyte *pc)
+{
+ GLint mapsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ mapsize = *(GLint *)(pc + 4);
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT_ARRAY(pc + 8, mapsize);
+
+ glPixelMapusv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ (GLushort *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ReadBuffer(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glReadBuffer(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_CopyPixels(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+
+ glCopyPixels(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12),
+ *(GLenum *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_DepthRange(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 16);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+
+ glDepthRange(
+ *(GLclampd *)(pc + 0),
+ *(GLclampd *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Frustum(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 48);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 24);
+ __GLX_SWAP_DOUBLE(pc + 32);
+ __GLX_SWAP_DOUBLE(pc + 40);
+
+ glFrustum(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24),
+ *(GLdouble *)(pc + 32),
+ *(GLdouble *)(pc + 40)
+ );
+}
+
+void __glXDispSwap_LoadIdentity(GLbyte *pc)
+{
+ glLoadIdentity(
+ );
+}
+
+void __glXDispSwap_LoadMatrixf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16);
+
+ glLoadMatrixf(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_LoadMatrixd(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 128);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16);
+
+ glLoadMatrixd(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MatrixMode(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glMatrixMode(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultMatrixf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_FLOAT_ARRAY(pc + 0, 16);
+
+ glMultMatrixf(
+ (GLfloat *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultMatrixd(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 128);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 16);
+
+ glMultMatrixd(
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_Ortho(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 48);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 24);
+ __GLX_SWAP_DOUBLE(pc + 32);
+ __GLX_SWAP_DOUBLE(pc + 40);
+
+ glOrtho(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24),
+ *(GLdouble *)(pc + 32),
+ *(GLdouble *)(pc + 40)
+ );
+}
+
+void __glXDispSwap_PopMatrix(GLbyte *pc)
+{
+ glPopMatrix(
+ );
+}
+
+void __glXDispSwap_PushMatrix(GLbyte *pc)
+{
+ glPushMatrix(
+ );
+}
+
+void __glXDispSwap_Rotated(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 32);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 24);
+
+ glRotated(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16),
+ *(GLdouble *)(pc + 24)
+ );
+}
+
+void __glXDispSwap_Rotatef(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_FLOAT(pc + 12);
+
+ glRotatef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8),
+ *(GLfloat *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_Scaled(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+
+ glScaled(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_Scalef(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glScalef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Translated(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 24);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+
+ glTranslated(
+ *(GLdouble *)(pc + 0),
+ *(GLdouble *)(pc + 8),
+ *(GLdouble *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_Translatef(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glTranslatef(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_Viewport(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+
+ glViewport(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_PolygonOffset(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glPolygonOffset(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_CopyTexImage1D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+ __GLX_SWAP_INT(pc + 24);
+
+ glCopyTexImage1D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20),
+ *(GLint *)(pc + 24)
+ );
+}
+
+void __glXDispSwap_CopyTexImage2D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+ __GLX_SWAP_INT(pc + 24);
+ __GLX_SWAP_INT(pc + 28);
+
+ glCopyTexImage2D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20),
+ *(GLsizei *)(pc + 24),
+ *(GLint *)(pc + 28)
+ );
+}
+
+void __glXDispSwap_CopyTexSubImage1D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+
+ glCopyTexSubImage1D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLsizei *)(pc + 20)
+ );
+}
+
+void __glXDispSwap_CopyTexSubImage2D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+ __GLX_SWAP_INT(pc + 24);
+ __GLX_SWAP_INT(pc + 28);
+
+ glCopyTexSubImage2D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLint *)(pc + 20),
+ *(GLsizei *)(pc + 24),
+ *(GLsizei *)(pc + 28)
+ );
+}
+
+void __glXDispSwap_BindTexture(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glBindTexture(
+ *(GLenum *)(pc + 0),
+ *(GLuint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_PrioritizeTextures(GLbyte *pc)
+{
+ GLsizei n;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, n);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4+n*4, n);
+
+ glPrioritizeTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLclampf *)(pc + 4+n*4)
+ );
+}
+
+void __glXDispSwap_Indexubv(GLbyte *pc)
+{
+ glIndexubv(
+ (GLubyte *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_BlendColor(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_FLOAT(pc + 12);
+
+ glBlendColor(
+ *(GLclampf *)(pc + 0),
+ *(GLclampf *)(pc + 4),
+ *(GLclampf *)(pc + 8),
+ *(GLclampf *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_BlendEquation(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glBlendEquation(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ColorTableParameterfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glColorTableParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glColorTableParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ColorTableParameteriv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glColorTableParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glColorTableParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_CopyColorTable(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+
+ glCopyColorTable(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_CopyColorSubTable(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+
+ glCopyColorSubTable(
+ *(GLenum *)(pc + 0),
+ *(GLsizei *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_ConvolutionParameterf(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ glConvolutionParameterf(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ConvolutionParameterfv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glConvolutionParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 8, compsize);
+
+ glConvolutionParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ConvolutionParameteri(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glConvolutionParameteri(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ConvolutionParameteriv(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glConvolutionParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 8, compsize);
+
+ glConvolutionParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_CopyConvolutionFilter1D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+
+ glCopyConvolutionFilter1D(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16)
+ );
+}
+
+void __glXDispSwap_CopyConvolutionFilter2D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+
+ glCopyConvolutionFilter2D(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLsizei *)(pc + 16),
+ *(GLsizei *)(pc + 20)
+ );
+}
+
+void __glXDispSwap_Histogram(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+
+ glHistogram(
+ *(GLenum *)(pc + 0),
+ *(GLsizei *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLboolean *)(pc + 12)
+ );
+}
+
+void __glXDispSwap_Minmax(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glMinmax(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLboolean *)(pc + 8)
+ );
+}
+
+void __glXDispSwap_ResetHistogram(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glResetHistogram(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_ResetMinmax(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glResetMinmax(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_CopyTexSubImage3D(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+ __GLX_SWAP_INT(pc + 24);
+ __GLX_SWAP_INT(pc + 28);
+ __GLX_SWAP_INT(pc + 32);
+
+ glCopyTexSubImage3D(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLint *)(pc + 8),
+ *(GLint *)(pc + 12),
+ *(GLint *)(pc + 16),
+ *(GLint *)(pc + 20),
+ *(GLint *)(pc + 24),
+ *(GLsizei *)(pc + 28),
+ *(GLsizei *)(pc + 32)
+ );
+}
+
+void __glXDispSwap_ActiveTextureARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glActiveTextureARB(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord1dvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 12);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 8);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 1);
+
+ glMultiTexCoord1dvARB(
+ *(GLenum *)(pc + 8),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord1fvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, 1);
+
+ glMultiTexCoord1fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord1ivARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, 1);
+
+ glMultiTexCoord1ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord1svARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT_ARRAY(pc + 4, 1);
+
+ glMultiTexCoord1svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord2dvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 20);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 2);
+
+ glMultiTexCoord2dvARB(
+ *(GLenum *)(pc + 16),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord2fvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, 2);
+
+ glMultiTexCoord2fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord2ivARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, 2);
+
+ glMultiTexCoord2ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord2svARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT_ARRAY(pc + 4, 2);
+
+ glMultiTexCoord2svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord3dvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 28);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 24);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 3);
+
+ glMultiTexCoord3dvARB(
+ *(GLenum *)(pc + 24),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord3fvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, 3);
+
+ glMultiTexCoord3fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord3ivARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, 3);
+
+ glMultiTexCoord3ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord3svARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT_ARRAY(pc + 4, 3);
+
+ glMultiTexCoord3svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord4dvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+#ifdef __GLX_ALIGN64
+ if ((unsigned long)(pc) & 7) {
+ __GLX_MEM_COPY(pc-4, pc, 36);
+ pc -= 4;
+ }
+#endif
+ __GLX_SWAP_INT(pc + 32);
+ __GLX_SWAP_DOUBLE_ARRAY(pc + 0, 4);
+
+ glMultiTexCoord4dvARB(
+ *(GLenum *)(pc + 32),
+ (GLdouble *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord4fvARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, 4);
+
+ glMultiTexCoord4fvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord4ivARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, 4);
+
+ glMultiTexCoord4ivARB(
+ *(GLenum *)(pc + 0),
+ (GLint *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_MultiTexCoord4svARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_SHORT_ARRAY(pc + 4, 4);
+
+ glMultiTexCoord4svARB(
+ *(GLenum *)(pc + 0),
+ (GLshort *)(pc + 4)
+ );
+}
+
+
+/*
+ * Extensions
+ */
+
+#ifndef MISSING_GL_EXTS
+
+void __glXDispSwap_PointParameterfARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ glPointParameterfARB(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_PointParameterfvARB(GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glPointParameterfvEXT_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_FLOAT_ARRAY(pc + 4, compsize);
+
+ glPointParameterfvARB(
+ *(GLenum *)(pc + 0),
+ (GLfloat *)(pc + 4)
+ );
+}
+
+void __glXDispSwap_ActiveStencilFaceEXT(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+
+ glActiveStencilFaceEXT(
+ *(GLenum *)(pc + 0)
+ );
+}
+
+void __glXDispSwap_WindowPos3fARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ glWindowPos3fARB(
+ *(GLfloat *)(pc + 0),
+ *(GLfloat *)(pc + 4),
+ *(GLfloat *)(pc + 8)
+ );
+}
+#endif /* !MISSING_GL_EXTS */
+
+void __glXDispSwap_SampleCoverageARB(GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_FLOAT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glSampleCoverageARB(
+ *(GLfloat *)(pc + 0),
+ *(GLboolean *)(pc + 4)
+ );
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/g_single.c b/nx-X11/programs/Xserver/GL/glx/g_single.c
new file mode 100644
index 000000000..486ae7a25
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_single.c
@@ -0,0 +1,1785 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "unpack.h"
+#include "impsize.h"
+#include "singlesize.h"
+
+int __glXDisp_NewList(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ glNewList(
+ *(GLuint *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_EndList(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ glEndList(
+ );
+ return Success;
+}
+
+int __glXDisp_DeleteLists(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ glDeleteLists(
+ *(GLuint *)(pc + 0),
+ *(GLsizei *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_GenLists(__GLXclientState *cl, GLbyte *pc)
+{
+ GLuint retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ retval =
+ glGenLists(
+ *(GLsizei *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDisp_PixelStoref(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ glPixelStoref(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_PixelStorei(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ glPixelStorei(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_GetBooleanv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetBooleanv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetBooleanv(
+ *(GLenum *)(pc + 0),
+ (GLboolean *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_BYTE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetDoublev(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetDoublev_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetDoublev(
+ *(GLenum *)(pc + 0),
+ (GLdouble *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetError(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ retval =
+ glGetError(
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDisp_GetFloatv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetFloatv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetFloatv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetIntegerv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetIntegerv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetIntegerv(
+ *(GLenum *)(pc + 0),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetLightfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetLightfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetLightfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetLightiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetLightiv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetLightiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMapdv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapdv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetMapdv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMapfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapfv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMapfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMapiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapiv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMapiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMaterialfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMaterialfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMaterialfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMaterialiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMaterialiv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMaterialiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetPixelMapfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapfv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetPixelMapfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetPixelMapuiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapuiv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetPixelMapuiv(
+ *(GLenum *)(pc + 0),
+ (GLuint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetPixelMapusv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLushort answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapusv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*2,2);
+ __glXClearErrorOccured();
+ glGetPixelMapusv(
+ *(GLenum *)(pc + 0),
+ (GLushort *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_SHORT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*2);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_SHORT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexEnvfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexEnvfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexEnvfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexEnviv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexEnviv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexEnviv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexGendv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGendv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetTexGendv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexGenfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGenfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexGenfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexGeniv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGeniv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexGeniv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexLevelParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 8);
+ compsize = __glGetTexLevelParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexLevelParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexLevelParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 8);
+ compsize = __glGetTexLevelParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexLevelParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_IsEnabled(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ retval =
+ glIsEnabled(
+ *(GLenum *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDisp_IsList(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ retval =
+ glIsList(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDisp_AreTexturesResident(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n,1);
+ retval =
+ glAreTexturesResident(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLboolean *) answer
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(n);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(n);
+ return Success;
+}
+
+int __glXDisp_DeleteTextures(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ glDeleteTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4)
+ );
+ return Success;
+}
+
+int __glXDisp_GenTextures(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n*4,4);
+ glGenTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *) answer
+ );
+ __GLX_BEGIN_REPLY(n*4);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(n);
+ return Success;
+}
+
+int __glXDisp_IsTexture(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ retval =
+ glIsTexture(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDisp_GetColorTableParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetColorTableParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetColorTableParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetColorTableParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetColorTableParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetColorTableParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetConvolutionParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetConvolutionParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetConvolutionParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetConvolutionParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetConvolutionParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetConvolutionParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetHistogramParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetHistogramParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetHistogramParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetHistogramParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetHistogramParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetHistogramParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMinmaxParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMinmaxParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMinmaxParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetMinmaxParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMinmaxParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMinmaxParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_SIZE(1);
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_AreTexturesResidentEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n,1);
+ retval =
+ glAreTexturesResidentEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLboolean *) answer
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(n);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(n);
+ return Success;
+}
+
+int __glXDisp_DeleteTexturesEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+
+ glDeleteTexturesEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4)
+ );
+ return Success;
+}
+
+int __glXDisp_GenTexturesEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n*4,4);
+ glGenTexturesEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *) answer
+ );
+ __GLX_BEGIN_REPLY(n*4);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(n);
+ return Success;
+}
+
+int __glXDisp_IsTextureEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+
+ retval =
+ glIsTextureEXT(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/g_singleswap.c b/nx-X11/programs/Xserver/GL/glx/g_singleswap.c
new file mode 100644
index 000000000..7ec32dd96
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/g_singleswap.c
@@ -0,0 +1,2206 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: This software was created using the
+** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has
+** not been independently verified as being compliant with the OpenGL(R)
+** version 1.2.1 Specification.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "unpack.h"
+#include "impsize.h"
+#include "singlesize.h"
+
+int __glXDispSwap_NewList(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glNewList(
+ *(GLuint *)(pc + 0),
+ *(GLenum *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_EndList(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ glEndList(
+ );
+ return Success;
+}
+
+int __glXDispSwap_DeleteLists(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glDeleteLists(
+ *(GLuint *)(pc + 0),
+ *(GLsizei *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_GenLists(__GLXclientState *cl, GLbyte *pc)
+{
+ GLuint retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ retval =
+ glGenLists(
+ *(GLsizei *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDispSwap_PixelStoref(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_FLOAT(pc + 4);
+
+ glPixelStoref(
+ *(GLenum *)(pc + 0),
+ *(GLfloat *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_PixelStorei(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ glPixelStorei(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4)
+ );
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_GetBooleanv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetBooleanv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetBooleanv(
+ *(GLenum *)(pc + 0),
+ (GLboolean *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_BYTE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetDoublev(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetDoublev_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetDoublev(
+ *(GLenum *)(pc + 0),
+ (GLdouble *) answer
+ );
+ __GLX_SWAP_DOUBLE_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetError(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ retval =
+ glGetError(
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDispSwap_GetFloatv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetFloatv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetFloatv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetIntegerv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ pname = *(GLenum *)(pc + 0);
+ compsize = __glGetIntegerv_size(pname);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetIntegerv(
+ *(GLenum *)(pc + 0),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetLightfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetLightfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetLightfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetLightiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetLightiv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetLightiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMapdv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapdv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetMapdv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *) answer
+ );
+ __GLX_SWAP_DOUBLE_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMapfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapfv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMapfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMapiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum target;
+ GLenum query;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+ target = *(GLenum *)(pc + 0);
+ query = *(GLenum *)(pc + 4);
+ compsize = __glGetMapiv_size(target,query);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMapiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMaterialfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMaterialfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMaterialfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMaterialiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMaterialiv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMaterialiv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetPixelMapfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapfv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetPixelMapfv(
+ *(GLenum *)(pc + 0),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetPixelMapuiv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapuiv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetPixelMapuiv(
+ *(GLenum *)(pc + 0),
+ (GLuint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetPixelMapusv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum map;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLushort answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ map = *(GLenum *)(pc + 0);
+ compsize = __glGetPixelMapusv_size(map);
+ if (compsize < 0) compsize = 0;
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*2,2);
+ __glXClearErrorOccured();
+ glGetPixelMapusv(
+ *(GLenum *)(pc + 0),
+ (GLushort *) answer
+ );
+ __GLX_SWAP_SHORT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_SHORT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*2);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_SHORT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexEnvfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexEnvfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexEnvfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexEnviv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexEnviv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexEnviv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexGendv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGendv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*8,8);
+ __glXClearErrorOccured();
+ glGetTexGendv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLdouble *) answer
+ );
+ __GLX_SWAP_DOUBLE_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_DOUBLE();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*8);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexGenfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGenfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexGenfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexGeniv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexGeniv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexGeniv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetTexParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexLevelParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 8);
+ pname = *(GLenum *)(pc + 8);
+ compsize = __glGetTexLevelParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexLevelParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexLevelParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 8);
+ pname = *(GLenum *)(pc + 8);
+ compsize = __glGetTexLevelParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 4);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetTexLevelParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_IsEnabled(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ retval =
+ glIsEnabled(
+ *(GLenum *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDispSwap_IsList(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ retval =
+ glIsList(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDispSwap_AreTexturesResident(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, n);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n,1);
+ retval =
+ glAreTexturesResident(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLboolean *) answer
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(n);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(n);
+ return Success;
+}
+
+int __glXDispSwap_DeleteTextures(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, n);
+
+ glDeleteTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4)
+ );
+ return Success;
+}
+
+int __glXDispSwap_GenTextures(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n*4,4);
+ glGenTextures(
+ *(GLsizei *)(pc + 0),
+ (GLuint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, n);
+ __GLX_BEGIN_REPLY(n*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(n);
+ return Success;
+}
+
+int __glXDispSwap_IsTexture(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ retval =
+ glIsTexture(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+int __glXDispSwap_GetColorTableParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetColorTableParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetColorTableParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetColorTableParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetColorTableParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetColorTableParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetConvolutionParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetConvolutionParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetConvolutionParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetConvolutionParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetConvolutionParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetConvolutionParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetHistogramParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetHistogramParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetHistogramParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetHistogramParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetHistogramParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetHistogramParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMinmaxParameterfv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLfloat answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMinmaxParameterfv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMinmaxParameterfv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLfloat *) answer
+ );
+ __GLX_SWAP_FLOAT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_FLOAT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_FLOAT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetMinmaxParameteriv(__GLXclientState *cl, GLbyte *pc)
+{
+ GLenum pname;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 4);
+ pname = *(GLenum *)(pc + 4);
+ compsize = __glGetMinmaxParameteriv_size(pname);
+ if (compsize < 0) compsize = 0;
+ __GLX_SWAP_INT(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize*4,4);
+ __glXClearErrorOccured();
+ glGetMinmaxParameteriv(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ (GLint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, compsize);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(0);
+ __GLX_SEND_HEADER();
+ } else if (compsize == 1) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(1);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_PUT_INT();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_PUT_SIZE(compsize);
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_AreTexturesResidentEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLboolean answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXVendorPrivateReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, n);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n,1);
+ retval =
+ glAreTexturesResidentEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4),
+ (GLboolean *) answer
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(n);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(n);
+ return Success;
+}
+
+int __glXDispSwap_DeleteTexturesEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXVendorPrivateReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+ __GLX_SWAP_INT_ARRAY(pc + 4, n);
+
+ glDeleteTexturesEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *)(pc + 4)
+ );
+ return Success;
+}
+
+int __glXDispSwap_GenTexturesEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei n;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLuint answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXVendorPrivateReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+ n = *(GLsizei *)(pc + 0);
+
+ __GLX_GET_ANSWER_BUFFER(answer,cl,n*4,4);
+ glGenTexturesEXT(
+ *(GLsizei *)(pc + 0),
+ (GLuint *) answer
+ );
+ __GLX_SWAP_INT_ARRAY(answer, n);
+ __GLX_BEGIN_REPLY(n*4);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_INT_ARRAY(n);
+ return Success;
+}
+
+int __glXDispSwap_IsTextureEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean retval;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXVendorPrivateReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ retval =
+ glIsTextureEXT(
+ *(GLuint *)(pc + 0)
+ );
+ __GLX_PUT_RETVAL(retval);
+ __GLX_SWAP_REPLY_RETVAL();
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/global.c b/nx-X11/programs/Xserver/GL/glx/global.c
new file mode 100644
index 000000000..2ce275ba3
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/global.c
@@ -0,0 +1,74 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+
+/*
+** The last context used by the server. It is the context that is current
+** from the server's perspective.
+*/
+__GLXcontext *__glXLastContext;
+
+/*
+** X resources.
+*/
+RESTYPE __glXContextRes;
+RESTYPE __glXClientRes;
+RESTYPE __glXPixmapRes;
+RESTYPE __glXSwapBarrierRes;
+
+/*
+** Error codes with the extension error base already added in.
+*/
+int __glXBadContext, __glXBadContextState, __glXBadDrawable, __glXBadPixmap;
+int __glXBadContextTag, __glXBadCurrentWindow;
+int __glXBadRenderRequest, __glXBadLargeRequest;
+int __glXUnsupportedPrivateRequest;
+
+/*
+** Reply for most singles.
+*/
+xGLXSingleReply __glXReply;
+
+/*
+** A set of state for each client. The 0th one is unused because client
+** indices start at 1, not 0.
+*/
+__GLXclientState *__glXClients[MAXCLIENTS+1];
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxbuf.c b/nx-X11/programs/Xserver/GL/glx/glxbuf.c
new file mode 100644
index 000000000..047bc569e
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxbuf.c
@@ -0,0 +1,295 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxbuf.h"
+#include "glxfb.h"
+#include "glxmem.h"
+#include "glxpix.h"
+
+void
+__glXFBInitDrawable(__GLXdrawablePrivate *glxPriv, __GLcontextModes *modes)
+{
+ __GLdrawablePrivate *glPriv;
+ GLint rgbBits;
+ GLint accumBits;
+
+ glPriv = &glxPriv->glPriv;
+ rgbBits = modes->rgbBits;
+ accumBits = modes->accumRedBits + modes->accumGreenBits +
+ modes->accumBlueBits + modes->accumAlphaBits;
+
+#if defined(__GL_ALIGNED_BUFFERS)
+ /* initialize pixel alignments (for more details see context.h) */
+ glPriv->xAlignment = 1;
+ glPriv->yAlignment = 1;
+#endif
+
+ glxPriv->swapBuffers = __glXFBMemSwapBuffers;
+
+ glPriv->yInverted = GL_TRUE; /* Y is upside-down */
+
+ if (modes->doubleBufferMode) {
+ if (modes->colorIndexMode) {
+ __glXInitFB(&glPriv->frontBuffer, glPriv, modes->indexBits);
+ __glXInitMem(&glPriv->backBuffer, glPriv, modes->indexBits);
+ } else {
+ __glXInitFB(&glPriv->frontBuffer, glPriv, rgbBits);
+ __glXInitMem(&glPriv->backBuffer, glPriv, rgbBits);
+ }
+ } else {
+ if (modes->colorIndexMode) {
+ __glXInitFB(&glPriv->frontBuffer, glPriv, modes->indexBits);
+ } else {
+ __glXInitFB(&glPriv->frontBuffer, glPriv, rgbBits);
+ }
+ }
+
+#if defined(__GL_MAX_AUXBUFFERS) && (__GL_MAX_AUXBUFFERS > 0)
+ if (modes->maxAuxBuffers > 0) {
+ GLint i;
+
+ for (i=0; i < modes->maxAuxBuffers; i++) {
+ if (modes->colorIndexMode) {
+ __glXInitMem(&glPriv->auxBuffer[i], glPriv, modes->indexBits);
+ } else {
+ __glXInitMem(&glPriv->auxBuffer[i], glPriv, rgbBits);
+ }
+ }
+ }
+#endif
+
+ if (modes->haveAccumBuffer) {
+ __glXInitMem(&glPriv->accumBuffer, glPriv, accumBits);
+ }
+ if (modes->haveDepthBuffer) {
+ __glXInitMem(&glPriv->depthBuffer, glPriv, modes->depthBits);
+ }
+ if (modes->haveStencilBuffer) {
+ __glXInitMem(&glPriv->stencilBuffer, glPriv, modes->stencilBits);
+ }
+}
+
+void
+__glXPixInitDrawable(__GLXdrawablePrivate *glxPriv, __GLcontextModes *modes)
+{
+ __GLdrawablePrivate *glPriv;
+ GLint rgbBits;
+ GLint accumBits;
+
+ assert(glxPriv->pGlxPixmap);
+
+ glPriv = &glxPriv->glPriv;
+ rgbBits = modes->rgbBits;
+ accumBits = modes->accumRedBits + modes->accumGreenBits +
+ modes->accumBlueBits + modes->accumAlphaBits;
+
+#if defined(__GL_ALIGNED_BUFFERS)
+ /* initialize pixel alignments (for more details see context.h) */
+ glPriv->xAlignment = 1;
+ glPriv->yAlignment = 1;
+#endif
+
+ glxPriv->swapBuffers = (GLboolean (*)(__GLXdrawablePrivate *))__glXNop;
+
+ glPriv->yInverted = GL_FALSE;
+
+ if (modes->doubleBufferMode) {
+ if (modes->colorIndexMode) {
+ __glXInitPix(&glPriv->frontBuffer, glPriv, rgbBits,
+ glxPriv->drawId, glxPriv->pGlxPixmap);
+ __glXInitMem(&glPriv->backBuffer, glPriv, modes->indexBits);
+ } else {
+ __glXInitPix(&glPriv->frontBuffer, glPriv, rgbBits,
+ glxPriv->drawId, glxPriv->pGlxPixmap);
+ __glXInitMem(&glPriv->backBuffer, glPriv, rgbBits);
+ }
+ } else {
+ if (modes->colorIndexMode) {
+ __glXInitPix(&glPriv->frontBuffer, glPriv, rgbBits,
+ glxPriv->drawId, glxPriv->pGlxPixmap);
+ } else {
+ __glXInitPix(&glPriv->frontBuffer, glPriv, rgbBits,
+ glxPriv->drawId, glxPriv->pGlxPixmap);
+ }
+ }
+
+#if defined(__GL_MAX_AUXBUFFERS) && (__GL_MAX_AUXBUFFERS > 0)
+ if (modes->maxAuxBuffers > 0) {
+ GLint i;
+
+ for (i=0; i < modes->maxAuxBuffers; i++) {
+ if (modes->colorIndexMode) {
+ __glXInitMem(&glPriv->auxBuffer[i], glPriv, modes->indexBits);
+ } else {
+ __glXInitMem(&glPriv->auxBuffer[i], glPriv, rgbBits);
+ }
+ }
+ }
+#endif
+
+ if (modes->haveAccumBuffer) {
+ __glXInitMem(&glPriv->accumBuffer, glPriv, accumBits);
+ }
+ if (modes->haveDepthBuffer) {
+ __glXInitMem(&glPriv->depthBuffer, glPriv, modes->depthBits);
+ }
+ if (modes->haveStencilBuffer) {
+ __glXInitMem(&glPriv->stencilBuffer, glPriv, modes->stencilBits);
+ }
+}
+
+
+#define __GLX_SET_ACCEL_BUFFER_MASK(bm) \
+ if (status == GL_FALSE) return GL_FALSE; \
+ if (status == GL_TRUE) accelBufferMask |= bm; \
+ /* for __GL_BUFFER_FALLBACK don't do anything */
+
+GLboolean
+__glXResizeBuffers(__GLdrawablePrivate *glPriv,
+ GLint x, GLint y, GLuint width, GLuint height)
+{
+ __GLcontextModes *modes;
+ __GLdrawableRegion *glRegion;
+ GLboolean status;
+ GLuint accelBufferMask;
+
+ modes = glPriv->modes;
+ accelBufferMask = 0;
+
+ status = (*glPriv->frontBuffer.resize)(&glPriv->frontBuffer,
+ x, y, width, height, glPriv,
+ __GL_FRONT_BUFFER_MASK);
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_FRONT_BUFFER_MASK);
+
+ if (modes->doubleBufferMode) {
+ status = (*glPriv->backBuffer.resize)(&glPriv->backBuffer,
+ x, y, width, height, glPriv,
+ __GL_BACK_BUFFER_MASK);
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_BACK_BUFFER_MASK);
+ }
+
+#if defined(__GL_MAX_AUXBUFFERS) && (__GL_MAX_AUXBUFFERS > 0)
+ if (modes->maxAuxBuffers > 0) {
+ GLint i;
+
+ for (i=0; i < modes->maxAuxBuffers; i++) {
+ status = (*glPriv->auxBuffers[i].resize)(&glPriv->auxBuffer[i],
+ x, y, width, height,
+ glPriv,
+ __GL_AUX_BUFFER_MASK(i));
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_AUX_BUFFER_MASK(i));
+ }
+ }
+#endif
+
+ if (modes->haveAccumBuffer) {
+ status = (*glPriv->accumBuffer.resize)(&glPriv->accumBuffer,
+ x, y, width, height, glPriv,
+ __GL_ACCUM_BUFFER_MASK);
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_ACCUM_BUFFER_MASK);
+ }
+
+ if (modes->haveDepthBuffer) {
+ status = (*glPriv->depthBuffer.resize)(&glPriv->depthBuffer,
+ x, y, width, height, glPriv,
+ __GL_DEPTH_BUFFER_MASK);
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_DEPTH_BUFFER_MASK);
+ }
+
+ if (modes->haveStencilBuffer) {
+ status = (*glPriv->stencilBuffer.resize)(&glPriv->stencilBuffer,
+ x, y, width, height, glPriv,
+ __GL_STENCIL_BUFFER_MASK);
+ __GLX_SET_ACCEL_BUFFER_MASK(__GL_STENCIL_BUFFER_MASK);
+ }
+
+ glPriv->accelBufferMask = accelBufferMask;
+
+ /* finally, update the ownership region */
+ glRegion = &glPriv->ownershipRegion;
+ glRegion->numRects = 1;
+ glRegion->rects[0].x0 = 0;
+ glRegion->rects[0].y0 = 0;
+ glRegion->rects[0].x1 = width;
+ glRegion->rects[0].y1 = height;
+
+ return GL_TRUE;
+}
+
+void
+__glXFreeBuffers(__GLXdrawablePrivate *glxPriv)
+{
+ __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+#if defined(__GL_MAX_AUXBUFFERS) && (__GL_MAX_AUXBUFFERS > 0)
+ __GLcontextModes *modes = glPriv->modes;
+#endif
+
+ if (glPriv->frontBuffer.free) {
+ (*glPriv->frontBuffer.free)(&glPriv->frontBuffer, glPriv);
+ }
+ if (glPriv->backBuffer.free) {
+ (*glPriv->backBuffer.free)(&glPriv->backBuffer, glPriv);
+ }
+
+#if defined(__GL_MAX_AUXBUFFERS) && (__GL_MAX_AUXBUFFERS > 0)
+ if (modes->maxAuxBuffers > 0) {
+ GLint i;
+
+ for (i=0; i < modes->maxAuxBuffers; i++) {
+ if (glPriv->auxBuffer[i].free) {
+ (*glPriv->auxBuffer[i].free)(&glPriv->auxBuffer[i], glPriv);
+ }
+ }
+ }
+#endif
+
+ if (glPriv->accumBuffer.free) {
+ (*glPriv->accumBuffer.free)(&glPriv->accumBuffer, glPriv);
+ }
+
+ if (glPriv->depthBuffer.free) {
+ (*glPriv->depthBuffer.free)(&glPriv->depthBuffer, glPriv);
+ }
+
+ if (glPriv->stencilBuffer.free) {
+ (*glPriv->stencilBuffer.free)(&glPriv->stencilBuffer, glPriv);
+ }
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxbuf.h b/nx-X11/programs/Xserver/GL/glx/glxbuf.h
new file mode 100644
index 000000000..9354dc4f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxbuf.h
@@ -0,0 +1,56 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxbuf_h_
+#define _glxbuf_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void __glXFBInitDrawable(__GLXdrawablePrivate *glxPriv,
+ __GLcontextModes *modes);
+extern void __glXPixInitDrawable(__GLXdrawablePrivate *glxPriv,
+ __GLcontextModes *modes);
+
+extern GLboolean __glXResizeBuffers(__GLdrawablePrivate *glPriv,
+ GLint x, GLint y,
+ GLuint width, GLuint height);
+
+extern void __glXFreeBuffers(__GLXdrawablePrivate *glxPriv);
+extern void __glXUpdatePalette(__GLXdrawablePrivate *);
+
+#endif /* _glxbuf_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxcmds.c b/nx-X11/programs/Xserver/GL/glx/glxcmds.c
new file mode 100644
index 000000000..efe5b25e9
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxcmds.c
@@ -0,0 +1,2174 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#define FONT_PCF
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include <assert.h>
+
+#include "glxserver.h"
+#include <GL/glxtokens.h>
+#include <unpack.h>
+#include "g_disptab.h"
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "g_disptab_EXT.h"
+#include "glximports.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "glcontextmodes.h"
+
+/************************************************************************/
+
+static __GLimports imports = {
+ __glXImpMalloc,
+ __glXImpCalloc,
+ __glXImpRealloc,
+ __glXImpFree,
+ __glXImpWarning,
+ __glXImpFatal,
+ __glXImpGetenv,
+ __glXImpAtoi,
+ __glXImpSprintf,
+ __glXImpFopen,
+ __glXImpFclose,
+ __glXImpFprintf,
+ __glXImpGetDrawablePrivate,
+ __glXImpGetReadablePrivate,
+ NULL
+};
+
+static int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc);
+
+static int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxQueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxDestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc);
+static int __glxQueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glxHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+
+
+/************************************************************************/
+
+/**
+ * Create a GL context with the given properties. This routine is used
+ * to implement \c glXCreateContext, \c glXCreateNewContext, and
+ * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
+ * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
+ * same as the VisualID.
+ */
+
+int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
+ GLXContextID shareList, VisualID visual,
+ GLuint screen, GLboolean isDirect)
+{
+ ClientPtr client = cl->client;
+ VisualPtr pVisual;
+ ScreenPtr pScreen;
+ __GLXcontext *glxc, *shareglxc;
+ __GLcontextModes *modes;
+ __GLXscreenInfo *pGlxScreen;
+ __GLinterface *shareGC;
+ GLint i;
+
+ LEGAL_NEW_RESOURCE(gcId, client);
+
+ /*
+ ** Check if screen exists.
+ */
+ if (screen >= screenInfo.numScreens) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+ pScreen = screenInfo.screens[screen];
+ pGlxScreen = &__glXActiveScreens[screen];
+
+ /*
+ ** Check if the visual ID is valid for this screen.
+ */
+ pVisual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pScreen->numVisuals) {
+ client->errorValue = visual;
+ return BadValue;
+ }
+
+ /*
+ ** Get configuration of the visual. This assumes that the
+ ** glXActiveScreens structure contains visual configurations only for the
+ ** subset of Visuals that are supported by this implementation of the
+ ** OpenGL.
+ */
+
+ modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual );
+ if (modes == NULL) {
+ /*
+ ** Visual not support on this screen by this OpenGL implementation.
+ */
+ client->errorValue = visual;
+ return BadValue;
+ }
+
+ /*
+ ** Find the display list space that we want to share.
+ **
+ ** NOTE: In a multithreaded X server, we would need to keep a reference
+ ** count for each display list so that if one client detroyed a list that
+ ** another client was using, the list would not really be freed until it
+ ** was no longer in use. Since this sample implementation has no support
+ ** for multithreaded servers, we don't do this.
+ */
+ if (shareList == None) {
+ shareGC = 0;
+ } else {
+ shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes);
+ if (!shareglxc) {
+ client->errorValue = shareList;
+ return __glXBadContext;
+ }
+ if (shareglxc->isDirect) {
+ /*
+ ** NOTE: no support for sharing display lists between direct
+ ** contexts, even if they are in the same address space.
+ */
+#if 0
+ /* Disabling this code seems to allow shared display lists
+ * and texture objects to work. We'll leave it disabled for now.
+ */
+ client->errorValue = shareList;
+ return BadMatch;
+#endif
+ } else {
+ /*
+ ** Create an indirect context regardless of what the client asked
+ ** for; this way we can share display list space with shareList.
+ */
+ isDirect = GL_FALSE;
+ }
+ shareGC = shareglxc->gc;
+ }
+
+ /*
+ ** Allocate memory for the new context
+ */
+ glxc = (__GLXcontext *) malloc(sizeof(__GLXcontext));
+ if (!glxc) {
+ return BadAlloc;
+ }
+ memset(glxc, 0, sizeof(__GLXcontext));
+
+ /*
+ ** Initially, setup the part of the context that could be used by
+ ** a GL core that needs windowing information (e.g., Mesa).
+ */
+ glxc->pScreen = pScreen;
+ glxc->pGlxScreen = pGlxScreen;
+ glxc->pVisual = pVisual;
+ glxc->modes = modes;
+
+ if (!isDirect) {
+
+ /*
+ ** Allocate a GL context
+ */
+ imports.other = (void *)glxc;
+ glxc->gc = (*pGlxScreen->createContext)(&imports, glxc->modes, shareGC);
+ if (!glxc->gc) {
+ free(glxc);
+ client->errorValue = gcId;
+ return BadAlloc;
+ }
+ } else {
+ /*
+ ** Don't need local GL context for a direct context.
+ */
+ glxc->gc = 0;
+ }
+ /*
+ ** Register this context as a resource.
+ */
+ if (!AddResource(gcId, __glXContextRes, (void *)glxc)) {
+ if (!isDirect) {
+ (*glxc->gc->exports.destroyContext)((__GLcontext *)glxc->gc);
+ }
+ free(glxc);
+ client->errorValue = gcId;
+ return BadAlloc;
+ }
+
+ /*
+ ** Finally, now that everything is working, setup the rest of the
+ ** context.
+ */
+ glxc->id = gcId;
+ glxc->share_id = shareList;
+ glxc->idExists = GL_TRUE;
+ glxc->isCurrent = GL_FALSE;
+ glxc->isDirect = isDirect;
+ glxc->renderMode = GL_RENDER;
+
+ return Success;
+}
+
+
+int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ return DoCreateContext( cl, req->context, req->shareList, req->visual,
+ req->screen, req->isDirect );
+}
+
+
+int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+ return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
+ req->screen, req->isDirect );
+}
+
+
+int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextWithConfigSGIXReq *req =
+ (xGLXCreateContextWithConfigSGIXReq *) pc;
+ return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
+ req->screen, req->isDirect );
+}
+
+/*
+** Destroy a GL context as an X resource.
+*/
+int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
+ GLXContextID gcId = req->context;
+ __GLXcontext *glxc;
+
+ glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes);
+ if (glxc) {
+ /*
+ ** Just free the resource; don't actually destroy the context,
+ ** because it might be in use. The
+ ** destroy method will be called by the resource destruction routine
+ ** if necessary.
+ */
+ FreeResourceByType(gcId, __glXContextRes, FALSE);
+ return Success;
+ } else {
+ client->errorValue = gcId;
+ return __glXBadContext;
+ }
+}
+
+/*****************************************************************************/
+
+/*
+** For each client, the server keeps a table of all the contexts that are
+** current for that client (each thread of a client may have its own current
+** context). These routines add, change, and lookup contexts in the table.
+*/
+
+/*
+** Add a current context, and return the tag that will be used to refer to it.
+*/
+static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc)
+{
+ int i;
+ int num = cl->numCurrentContexts;
+ __GLXcontext **table = cl->currentContexts;
+
+ if (!glxc) return -1;
+
+ /*
+ ** Try to find an empty slot and use it.
+ */
+ for (i=0; i < num; i++) {
+ if (!table[i]) {
+ table[i] = glxc;
+ return i+1;
+ }
+ }
+ /*
+ ** Didn't find a free slot, so we'll have to grow the table.
+ */
+ if (!num) {
+ table = (__GLXcontext **) malloc(sizeof(__GLXcontext *));
+ } else {
+ table = (__GLXcontext **) realloc(table,
+ (num+1)*sizeof(__GLXcontext *));
+ }
+ table[num] = glxc;
+ cl->currentContexts = table;
+ cl->numCurrentContexts++;
+ return num+1;
+}
+
+/*
+** Given a tag, change the current context for the corresponding entry.
+*/
+static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
+ GLXContextTag tag)
+{
+ __GLXcontext **table = cl->currentContexts;
+ table[tag-1] = glxc;
+}
+
+/*
+** For this implementation we have chosen to simply use the index of the
+** context's entry in the table as the context tag. A tag must be greater
+** than 0.
+*/
+__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
+{
+ int num = cl->numCurrentContexts;
+
+ if (tag < 1 || tag > num) {
+ return 0;
+ } else {
+ return cl->currentContexts[tag-1];
+ }
+}
+
+/*****************************************************************************/
+
+static void StopUsingContext(__GLXcontext *glxc)
+{
+ if (glxc) {
+ if (glxc == __glXLastContext) {
+ /* Tell server GL library */
+ __glXLastContext = 0;
+ }
+ glxc->isCurrent = GL_FALSE;
+ if (!glxc->idExists) {
+ __glXFreeContext(glxc);
+ }
+ }
+}
+
+static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
+{
+ glxc->isCurrent = GL_TRUE;
+}
+
+/*****************************************************************************/
+/*
+** Make an OpenGL context and drawable current.
+*/
+
+int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->drawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readdrawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readable,
+ req->context, req->oldContextTag );
+}
+
+
+/**
+ * Given a drawable ID, get the associated drawable and / or pixmap.
+ *
+ * If the specified drawable ID is not a pixmap, \c ppPixmap will be set
+ * to \c NULL on return. In either case, \c ppDraw will be set to a drawable.
+ * In the case where the drawable ID is a pixmap, \c ppDraw will be set to
+ * the drawable associated with that pixmap.
+ *
+ * \param glxc Associated GLX context.
+ * \param drawId ID of the drawable.
+ * \param ppDraw Location to store the pointer to the drawable.
+ * \param ppPixmap Location to store the pointer to the pixmap.
+ * \param client Pointer to the client state.
+ * \return Zero is returned on success. Otherwise a GLX / X11 protocol error
+ * is returned.
+ *
+ * \notes This function will need some modification when support pbuffers
+ * is added.
+ */
+static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId,
+ DrawablePtr *ppDraw, __GLXpixmap **ppPixmap,
+ ClientPtr client )
+{
+ DrawablePtr pDraw;
+ __GLXpixmap *drawPixmap = NULL;
+
+ pDraw = (DrawablePtr) LookupDrawable(drawId, client);
+ if (pDraw) {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X Window.
+ */
+ WindowPtr pWin = (WindowPtr)pDraw;
+ VisualID vid = wVisual(pWin);
+
+ /*
+ ** Check if window and context are similar.
+ */
+ if ((vid != glxc->pVisual->vid) ||
+ (pWin->drawable.pScreen != glxc->pScreen)) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+ } else {
+ /*
+ ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
+ ** is, but it must first be created with glxCreateGLXPixmap).
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ } else {
+ drawPixmap = (__GLXpixmap *) LookupIDByType(drawId, __glXPixmapRes);
+ if (drawPixmap) {
+ /*
+ ** Check if pixmap and context are similar.
+ */
+ if (drawPixmap->pScreen != glxc->pScreen ||
+ drawPixmap->modes->visualID != glxc->modes->visualID) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+ pDraw = drawPixmap->pDraw;
+
+ } else {
+ /*
+ ** Drawable is neither a Window nor a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ *ppPixmap = drawPixmap;
+ *ppDraw = pDraw;
+
+ return 0;
+}
+
+
+int DoMakeCurrent( __GLXclientState *cl,
+ GLXDrawable drawId, GLXDrawable readId,
+ GLXContextID contextId, GLXContextTag tag )
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ DrawablePtr pRead;
+ xGLXMakeCurrentReply reply;
+ __GLXpixmap *drawPixmap = NULL;
+ __GLXpixmap *readPixmap = NULL;
+ __GLXcontext *glxc, *prevglxc;
+ __GLinterface *gc, *prevgc;
+ __GLXdrawablePrivate *drawPriv = NULL;
+ __GLXdrawablePrivate *readPriv = NULL;
+ GLint error;
+ GLuint mask;
+
+ /*
+ ** If one is None and the other isn't, it's a bad match.
+ */
+
+ mask = (drawId == None) ? (1 << 0) : 0;
+ mask |= (readId == None) ? (1 << 1) : 0;
+ mask |= (contextId == None) ? (1 << 2) : 0;
+
+ if ( (mask != 0x00) && (mask != 0x07) ) {
+ return BadMatch;
+ }
+
+ /*
+ ** Lookup old context. If we have one, it must be in a usable state.
+ */
+ if (tag != 0) {
+ prevglxc = __glXLookupContextByTag(cl, tag);
+ if (!prevglxc) {
+ /*
+ ** Tag for previous context is invalid.
+ */
+ return __glXBadContextTag;
+ }
+ if (prevglxc->renderMode != GL_RENDER) {
+ /* Oops. Not in render mode render. */
+ client->errorValue = prevglxc->id;
+ return __glXBadContextState;
+ }
+ prevgc = prevglxc->gc;
+ } else {
+ prevglxc = 0;
+ prevgc = 0;
+ }
+
+ /*
+ ** Lookup new context. It must not be current for someone else.
+ */
+ if (contextId != None) {
+ int status;
+
+ glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
+ if (!glxc) {
+ client->errorValue = contextId;
+ return __glXBadContext;
+ }
+ if ((glxc != prevglxc) && glxc->isCurrent) {
+ /* Context is current to somebody else */
+ return BadAccess;
+ }
+ gc = glxc->gc;
+
+
+ assert( drawId != None );
+ assert( readId != None );
+
+ status = GetDrawableOrPixmap( glxc, drawId, & pDraw, & drawPixmap,
+ client );
+ if ( status != 0 ) {
+ return status;
+ }
+
+ if ( readId != drawId ) {
+ status = GetDrawableOrPixmap( glxc, readId, & pRead, & readPixmap,
+ client );
+ if ( status != 0 ) {
+ return status;
+ }
+ } else {
+ pRead = pDraw;
+ }
+
+ /* FIXME: Finish refactoring this. - idr */
+ /* get the drawable private */
+ if (pDraw) {
+ drawPriv = __glXGetDrawablePrivate(pDraw, drawId, glxc->modes);
+ if (drawPriv == NULL) {
+ return __glXBadDrawable;
+ }
+ }
+
+ if (pRead != pDraw) {
+ readPriv = __glXGetDrawablePrivate(pRead, readId, glxc->modes);
+ if (readPriv == NULL) {
+ return __glXBadDrawable;
+ }
+ } else {
+ readPriv = drawPriv;
+ }
+
+ } else {
+ /* Switching to no context. Ignore new drawable. */
+ glxc = 0;
+ gc = 0;
+ pDraw = 0;
+ pRead = 0;
+ }
+
+
+ if (prevglxc) {
+ /*
+ ** Flush the previous context if needed.
+ */
+ if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) {
+ if (__glXForceCurrent(cl, tag, (int *)&error)) {
+ glFlush();
+ __GLX_NOTE_FLUSHED_CMDS(prevglxc);
+ } else {
+ return error;
+ }
+ }
+
+ /*
+ ** Make the previous context not current.
+ */
+ if (!(*prevgc->exports.loseCurrent)((__GLcontext *)prevgc)) {
+ return __glXBadContext;
+ }
+ __glXDeassociateContext(prevglxc);
+ }
+
+
+ if ((glxc != 0) && !glxc->isDirect) {
+
+ glxc->drawPriv = drawPriv;
+ glxc->readPriv = readPriv;
+ __glXCacheDrawableSize(drawPriv);
+
+ /* make the context current */
+ if (!(*gc->exports.makeCurrent)((__GLcontext *)gc)) {
+ glxc->drawPriv = NULL;
+ glxc->readPriv = NULL;
+ return __glXBadContext;
+ }
+
+ /* resize the buffers */
+ if (!__glXResizeDrawableBuffers(drawPriv)) {
+ /* could not do initial resize. make current failed */
+ (*gc->exports.loseCurrent)((__GLcontext *)gc);
+ glxc->drawPriv = NULL;
+ glxc->readPriv = NULL;
+ return __glXBadContext;
+ }
+
+ glxc->isCurrent = GL_TRUE;
+ __glXAssociateContext(glxc);
+ assert(drawPriv->drawGlxc == glxc);
+ assert(readPriv->readGlxc == glxc);
+ }
+
+ if (prevglxc) {
+ if (prevglxc->drawPixmap) {
+ if (prevglxc->readPixmap &&
+ prevglxc->drawPixmap != prevglxc->readPixmap) {
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ prevglxc->readPixmap->refcnt--;
+ if (!prevglxc->readPixmap->idExists &&
+ !prevglxc->readPixmap->refcnt) {
+ PixmapPtr pPixmap = (PixmapPtr) prevglxc->readPixmap->pDraw;
+ /*
+ ** The DestroyPixmap routine should decrement the
+ ** refcount of the X pixmap and free only if it's zero.
+ */
+ (*prevglxc->readPixmap->pScreen->DestroyPixmap)(pPixmap);
+ free(prevglxc->readPixmap);
+ }
+ }
+
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ prevglxc->drawPixmap->refcnt--;
+ if (!prevglxc->drawPixmap->idExists &&
+ !prevglxc->drawPixmap->refcnt) {
+ PixmapPtr pPixmap = (PixmapPtr) prevglxc->drawPixmap->pDraw;
+ /*
+ ** The DestroyPixmap routine should decrement the
+ ** refcount of the X pixmap and free only if it's zero.
+ */
+ (*prevglxc->drawPixmap->pScreen->DestroyPixmap)(pPixmap);
+ free(prevglxc->drawPixmap);
+ }
+
+ prevglxc->drawPixmap = NULL;
+ }
+ ChangeCurrentContext(cl, glxc, tag);
+ StopUsingContext(prevglxc);
+ } else {
+ tag = AddCurrentContext(cl, glxc);
+ }
+
+ if (glxc) {
+ if (drawPixmap) {
+ drawPixmap->refcnt++;
+ glxc->drawPixmap = drawPixmap;
+ }
+
+ if (readPixmap && (readPixmap != drawPixmap)) {
+ readPixmap->refcnt++;
+ glxc->readPixmap = readPixmap;
+ }
+
+ StartUsingContext(cl, glxc);
+ reply.contextTag = tag;
+ } else {
+ reply.contextTag = 0;
+ }
+
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapMakeCurrentReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXMakeCurrentReply, &reply);
+ }
+ return Success;
+}
+
+int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
+ xGLXIsDirectReply reply;
+ __GLXcontext *glxc;
+
+ /*
+ ** Find the GL context.
+ */
+ glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
+ if (!glxc) {
+ client->errorValue = req->context;
+ return __glXBadContext;
+ }
+
+ reply.isDirect = glxc->isDirect;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapIsDirectReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXIsDirectReply, &reply);
+ }
+
+ return Success;
+}
+
+int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
+ xGLXQueryVersionReply reply;
+ GLuint major, minor;
+
+ major = req->majorVersion;
+ minor = req->minorVersion;
+ (void)major;
+ (void)minor;
+
+ memset(&reply, 0, sizeof(xGLXQueryVersionReply));
+
+ /*
+ ** Server should take into consideration the version numbers sent by the
+ ** client if it wants to work with older clients; however, in this
+ ** implementation the server just returns its version number.
+ */
+ reply.majorVersion = GLX_SERVER_MAJOR_VERSION;
+ reply.minorVersion = GLX_SERVER_MINOR_VERSION;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, &reply);
+ }
+ return Success;
+}
+
+int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
+ int error;
+
+ if (!__glXForceCurrent(cl, req->contextTag, &error)) {
+ return error;
+ }
+ glFinish();
+ return Success;
+}
+
+int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
+ int error;
+
+ if (!__glXForceCurrent(cl, req->contextTag, &error)) {
+ return error;
+ }
+ /*
+ ** In a multithreaded server that had separate X and GL threads, we would
+ ** have to wait for the X thread to finish before returning. As it stands,
+ ** this sample implementation only supports singlethreaded servers, and
+ ** nothing needs to be done here.
+ */
+ return Success;
+}
+
+int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
+ GLXContextID source = req->source;
+ GLXContextID dest = req->dest;
+ GLXContextTag tag = req->contextTag;
+ unsigned long mask = req->mask;
+ __GLXcontext *src, *dst;
+ int error;
+
+ /*
+ ** Check that each context exists.
+ */
+ src = (__GLXcontext *) LookupIDByType(source, __glXContextRes);
+ if (!src) {
+ client->errorValue = source;
+ return __glXBadContext;
+ }
+ dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes);
+ if (!dst) {
+ client->errorValue = dest;
+ return __glXBadContext;
+ }
+
+ /*
+ ** They must be in the same address space, and same screen.
+ ** NOTE: no support for direct rendering contexts here.
+ */
+ if (src->isDirect || dst->isDirect ||
+ (src->pGlxScreen != dst->pGlxScreen)) {
+ client->errorValue = source;
+ return BadMatch;
+ }
+
+ /*
+ ** The destination context must not be current for any client.
+ */
+ if (dst->isCurrent) {
+ client->errorValue = dest;
+ return BadAccess;
+ }
+
+ if (tag) {
+ __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
+
+ if (!tagcx) {
+ return __glXBadContextTag;
+ }
+ if (tagcx != src) {
+ /*
+ ** This would be caused by a faulty implementation of the client
+ ** library.
+ */
+ return BadMatch;
+ }
+ /*
+ ** In this case, glXCopyContext is in both GL and X streams, in terms
+ ** of sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the copy is executed.
+ */
+ glFinish();
+ __GLX_NOTE_FLUSHED_CMDS(tagcx);
+ } else {
+ return error;
+ }
+ }
+ /*
+ ** Issue copy. The only reason for failure is a bad mask.
+ */
+ if (!(*dst->gc->exports.copyContext)((__GLcontext *)dst->gc,
+ (__GLcontext *)src->gc,
+ mask)) {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ return Success;
+}
+
+
+int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
+ GLboolean do_swap)
+{
+ ClientPtr client = cl->client;
+ xGLXGetVisualConfigsReply reply;
+ __GLXscreenInfo *pGlxScreen;
+ __GLcontextModes *modes;
+ CARD32 buf[__GLX_TOTAL_CONFIG];
+ int p;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ if (screen >= screenInfo.numScreens) {
+ /* The client library must send a valid screen number. */
+ client->errorValue = screen;
+ return BadValue;
+ }
+ pGlxScreen = &__glXActiveScreens[screen];
+
+ reply.numVisuals = pGlxScreen->numUsableVisuals;
+ reply.numProps = __GLX_TOTAL_CONFIG;
+ reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 *
+ __GLX_TOTAL_CONFIG) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if ( do_swap ) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ }
+
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, &reply);
+
+ for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) {
+ if (modes->visualID == 0) {
+ /* not a usable visual */
+ continue;
+ }
+ p = 0;
+ buf[p++] = modes->visualID;
+ buf[p++] = _gl_convert_to_x_visual_type( modes->visualType );
+ buf[p++] = modes->rgbMode;
+
+ buf[p++] = modes->redBits;
+ buf[p++] = modes->greenBits;
+ buf[p++] = modes->blueBits;
+ buf[p++] = modes->alphaBits;
+ buf[p++] = modes->accumRedBits;
+ buf[p++] = modes->accumGreenBits;
+ buf[p++] = modes->accumBlueBits;
+ buf[p++] = modes->accumAlphaBits;
+
+ buf[p++] = modes->doubleBufferMode;
+ buf[p++] = modes->stereoMode;
+
+ buf[p++] = modes->rgbBits;
+ buf[p++] = modes->depthBits;
+ buf[p++] = modes->stencilBits;
+ buf[p++] = modes->numAuxBuffers;
+ buf[p++] = modes->level;
+ /*
+ ** Add token/value pairs for extensions.
+ */
+ buf[p++] = GLX_VISUAL_CAVEAT_EXT;
+ buf[p++] = modes->visualRating;
+ buf[p++] = GLX_TRANSPARENT_TYPE;
+ buf[p++] = modes->transparentPixel;
+ buf[p++] = GLX_TRANSPARENT_RED_VALUE;
+ buf[p++] = modes->transparentRed;
+ buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
+ buf[p++] = modes->transparentGreen;
+ buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
+ buf[p++] = modes->transparentBlue;
+ buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
+ buf[p++] = modes->transparentAlpha;
+ buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
+ buf[p++] = modes->transparentIndex;
+
+ if ( do_swap ) {
+ __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG);
+ }
+ WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
+ buf);
+ }
+ return Success;
+}
+
+int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
+ return DoGetVisualConfigs( cl, req->screen, GL_FALSE );
+}
+
+
+
+#define __GLX_TOTAL_FBCONFIG_ATTRIBS (28)
+#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
+/**
+ * Send the set of GLXFBConfigs to the client. There is not currently
+ * and interface into the driver on the server-side to get GLXFBConfigs,
+ * so we "invent" some based on the \c __GLXvisualConfig structures that
+ * the driver does supply.
+ *
+ * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
+ * is the same, so this routine pulls double duty.
+ */
+
+int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
+{
+ ClientPtr client = cl->client;
+ xGLXGetFBConfigsReply reply;
+ __GLXscreenInfo *pGlxScreen;
+ CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
+ int p;
+ __GLcontextModes *modes;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+
+ if (screen >= screenInfo.numScreens) {
+ /* The client library must send a valid screen number. */
+ client->errorValue = screen;
+ return BadValue;
+ }
+ pGlxScreen = &__glXActiveScreens[screen];
+
+ reply.numFBConfigs = pGlxScreen->numUsableVisuals;
+ reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
+ reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if ( do_swap ) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numFBConfigs);
+ __GLX_SWAP_INT(&reply.numAttribs);
+ }
+
+ WriteToClient(client, sz_xGLXGetFBConfigsReply, &reply);
+
+ for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) {
+ if (modes->visualID == 0) {
+ /* not a usable visual */
+ continue;
+ }
+ p = 0;
+
+#define WRITE_PAIR(tag,value) \
+ do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
+
+ WRITE_PAIR( GLX_VISUAL_ID, modes->visualID );
+ WRITE_PAIR( GLX_FBCONFIG_ID, modes->visualID );
+ WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE );
+
+ WRITE_PAIR( GLX_RGBA, modes->rgbMode );
+ WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode );
+ WRITE_PAIR( GLX_STEREO, modes->stereoMode );
+
+ WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits );
+ WRITE_PAIR( GLX_LEVEL, modes->level );
+ WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers );
+ WRITE_PAIR( GLX_RED_SIZE, modes->redBits );
+ WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits );
+ WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits );
+ WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits );
+ WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits );
+ WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits );
+ WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits );
+ WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
+ WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits );
+ WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits );
+
+ WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType );
+
+ /*
+ ** Add token/value pairs for extensions.
+ */
+ WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
+ WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
+ WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
+ WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen );
+ WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue );
+ WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha );
+ WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
+ WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
+
+ if ( do_swap ) {
+ __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
+ }
+ WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
+ buf);
+ }
+ return Success;
+}
+
+
+int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
+ return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+}
+
+
+int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
+ return DoGetFBConfigs( cl, req->screen, GL_FALSE );
+}
+
+
+/*
+** Create a GLX Pixmap from an X Pixmap.
+*/
+int DoCreateGLXPixmap(__GLXclientState *cl, VisualID visual,
+ GLuint screenNum, XID pixmapId, XID glxpixmapId)
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ __GLXpixmap *pGlxPixmap;
+ __GLXscreenInfo *pGlxScreen;
+ __GLcontextModes *modes;
+ int i;
+
+ LEGAL_NEW_RESOURCE(glxpixmapId, client);
+
+ pDraw = (DrawablePtr) LookupDrawable(pixmapId, client);
+ if (!pDraw || pDraw->type != DRAWABLE_PIXMAP) {
+ client->errorValue = pixmapId;
+ return BadPixmap;
+ }
+
+ /*
+ ** Check if screen of visual matches screen of pixmap.
+ */
+ pScreen = pDraw->pScreen;
+ if (screenNum != pScreen->myNum) {
+ return BadMatch;
+ }
+
+ /*
+ ** Find the VisualRec for this visual.
+ */
+ pVisual = pScreen->visuals;
+ for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pScreen->numVisuals) {
+ client->errorValue = visual;
+ return BadValue;
+ }
+ /*
+ ** Check if depth of visual matches depth of pixmap.
+ */
+ if (pVisual->nplanes != pDraw->depth) {
+ return BadMatch;
+ }
+
+ /*
+ ** Get configuration of the visual.
+ */
+ pGlxScreen = &__glXActiveScreens[screenNum];
+ modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual );
+ if (modes == NULL) {
+ /*
+ ** Visual not support on this screen by this OpenGL implementation.
+ */
+ client->errorValue = visual;
+ return BadValue;
+ }
+
+ pGlxPixmap = (__GLXpixmap *) malloc(sizeof(__GLXpixmap));
+ if (!pGlxPixmap) {
+ return BadAlloc;
+ }
+ if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
+ return BadAlloc;
+ }
+ pGlxPixmap->pDraw = pDraw;
+ pGlxPixmap->pGlxScreen = pGlxScreen;
+ pGlxPixmap->pScreen = pScreen;
+ pGlxPixmap->idExists = True;
+ pGlxPixmap->refcnt = 0;
+
+ pGlxPixmap->modes = modes;
+
+ /*
+ ** Bump the ref count on the X pixmap so it won't disappear.
+ */
+ ((PixmapPtr) pDraw)->refcnt++;
+
+ return Success;
+}
+
+int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
+ return DoCreateGLXPixmap( cl, req->visual, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+ return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+int __glXCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapWithConfigSGIXReq *req =
+ (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
+ return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+
+/**
+ * Destroy a GLX pixmap. This function is used for both
+ * \c glXDestroyGLXPixmap and \c glXDestroyPixmap.
+ */
+
+int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
+ XID glxpixmap = req->glxpixmap;
+
+ /*
+ ** Check if it's a valid GLX pixmap.
+ */
+ if (!LookupIDByType(glxpixmap, __glXPixmapRes)) {
+ client->errorValue = glxpixmap;
+ return __glXBadPixmap;
+ }
+ FreeResource(glxpixmap, FALSE);
+ return Success;
+}
+
+/*****************************************************************************/
+
+/*
+** NOTE: There is no portable implementation for swap buffers as of
+** this time that is of value. Consequently, this code must be
+** implemented by somebody other than SGI.
+*/
+int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
+ GLXContextTag tag = req->contextTag;
+ XID drawId = req->drawable;
+ __GLXpixmap *pGlxPixmap;
+ __GLXcontext *glxc = NULL;
+ int error;
+
+ /*
+ ** Check that the GLX drawable is valid.
+ */
+ pDraw = (DrawablePtr) LookupDrawable(drawId, client);
+ if (pDraw) {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X window.
+ */
+ } else {
+ /*
+ ** Drawable is an X pixmap, which is not allowed.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ } else {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ /*
+ ** Drawable is a GLX pixmap.
+ */
+ } else {
+ /*
+ ** Drawable is neither a X window nor a GLX pixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXBadContextTag;
+ }
+ /*
+ ** The calling thread is swapping its current drawable. In this case,
+ ** glxSwapBuffers is in both GL and X streams, in terms of
+ ** sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the swap is executed.
+ */
+ glFinish();
+ __GLX_NOTE_FLUSHED_CMDS(glxc);
+ } else {
+ return error;
+ }
+ }
+
+ if (pDraw) {
+ __GLXdrawablePrivate *glxPriv;
+
+ if (glxc) {
+ glxPriv = __glXGetDrawablePrivate(pDraw, drawId, glxc->modes);
+ if (glxPriv == NULL) {
+ return __glXBadDrawable;
+ }
+ }
+ else {
+ glxPriv = __glXFindDrawablePrivate(drawId);
+ if (glxPriv == NULL) {
+ /* This is a window we've never seen before, do nothing */
+ return Success;
+ }
+ }
+
+ if ((*glxPriv->swapBuffers)(glxPriv) == GL_FALSE) {
+ return __glXBadDrawable;
+ }
+ }
+
+ return Success;
+}
+
+
+int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *ctx;
+ xGLXQueryContextInfoEXTReq *req;
+ xGLXQueryContextInfoEXTReply reply;
+ int nProps;
+ int *sendBuf, *pSendBuf;
+ int nReplyBytes;
+
+ req = (xGLXQueryContextInfoEXTReq *)pc;
+ ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
+ if (!ctx) {
+ client->errorValue = req->context;
+ return __glXBadContext;
+ }
+
+ nProps = 3;
+ reply.length = nProps << 1;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.n = nProps;
+
+ nReplyBytes = reply.length << 2;
+ sendBuf = (int *)malloc((size_t)nReplyBytes);
+ if (sendBuf == NULL) {
+ return __glXBadContext; /* XXX: Is this correct? */
+ }
+ pSendBuf = sendBuf;
+ *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
+ *pSendBuf++ = (int)(ctx->share_id);
+ *pSendBuf++ = GLX_VISUAL_ID_EXT;
+ *pSendBuf++ = (int)(ctx->pVisual->vid);
+ *pSendBuf++ = GLX_SCREEN_EXT;
+ *pSendBuf++ = (int)(ctx->pScreen->myNum);
+
+ if (client->swapped) {
+ __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, &reply);
+ WriteToClient(client, nReplyBytes, sendBuf);
+ }
+ free((char *)sendBuf);
+
+ return Success;
+}
+
+
+/************************************************************************/
+
+/*
+** Render and Renderlarge are not in the GLX API. They are used by the GLX
+** client library to send batches of GL rendering commands.
+*/
+
+/*
+** Execute all the drawing commands in a request.
+*/
+int __glXRender(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderReq *req;
+ ClientPtr client= cl->client;
+ int left, cmdlen, error;
+ int commandsDone;
+ CARD16 opcode;
+ __GLXrenderHeader *hdr;
+ __GLXcontext *glxc;
+
+ /*
+ ** NOTE: much of this code also appears in the byteswapping version of this
+ ** routine, __glXSwapRender(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ req = (xGLXRenderReq *) pc;
+ glxc = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!glxc) {
+ return error;
+ }
+
+ commandsDone = 0;
+ pc += sz_xGLXRenderReq;
+ left = (req->length << 2) - sz_xGLXRenderReq;
+ while (left > 0) {
+ __GLXrenderSizeData *entry;
+ int extra = 0;
+ void (* proc)(GLbyte *);
+
+ /*
+ ** Verify that the header length and the overall length agree.
+ ** Also, each command must be word aligned.
+ */
+ hdr = (__GLXrenderHeader *) pc;
+ cmdlen = hdr->length;
+ opcode = hdr->opcode;
+
+ if (left < cmdlen)
+ return BadLength;
+
+ /*
+ ** Check for core opcodes and grab entry data.
+ */
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ entry = &__glXRenderSizeTable[opcode];
+ proc = __glXRenderTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ entry =
+ &__glXRenderSizeTable_EXT[opcode -
+ __GLX_MIN_RENDER_OPCODE_EXT];
+ proc = __glXRenderTable_EXT[opcode -
+ __GLX_MIN_RENDER_OPCODE_EXT];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = commandsDone;
+ return __glXBadRenderRequest;
+ }
+
+ if (!entry->bytes) {
+ /* unused opcode */
+ client->errorValue = commandsDone;
+ return __glXBadRenderRequest;
+ }
+
+ if (cmdlen < entry->bytes) {
+ return BadLength;
+ }
+
+ if (entry->varsize) {
+ /* variable size command */
+ extra = (*entry->varsize)(pc + __GLX_RENDER_HDR_SIZE, False, left - __GLX_RENDER_HDR_SIZE);
+ if (extra < 0) {
+ return BadLength;
+ }
+ }
+ if (cmdlen != safe_pad(safe_add(entry->bytes, extra))) {
+ return BadLength;
+ }
+
+ /*
+ ** Skip over the header and execute the command. We allow the
+ ** caller to trash the command memory. This is useful especially
+ ** for things that require double alignment - they can just shift
+ ** the data towards lower memory (trashing the header) by 4 bytes
+ ** and achieve the required alignment.
+ */
+ (*proc)(pc + __GLX_RENDER_HDR_SIZE);
+ pc += cmdlen;
+ left -= cmdlen;
+ commandsDone++;
+ }
+ __GLX_NOTE_UNFLUSHED_CMDS(glxc);
+ return Success;
+}
+
+/*
+** Execute a large rendering request (one that spans multiple X requests).
+*/
+int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderLargeReq *req;
+ ClientPtr client= cl->client;
+ GLuint dataBytes;
+ void (*proc)(GLbyte *);
+ __GLXrenderLargeHeader *hdr;
+ __GLXcontext *glxc;
+ int error;
+ CARD16 opcode;
+
+ /*
+ ** NOTE: much of this code also appears in the byteswapping version of this
+ ** routine, __glXSwapRenderLarge(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
+
+ req = (xGLXRenderLargeReq *) pc;
+ glxc = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!glxc) {
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return error;
+ }
+ if (safe_pad(req->dataBytes) < 0)
+ return BadLength;
+
+ dataBytes = req->dataBytes;
+
+ /*
+ ** Check the request length.
+ */
+ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
+ client->errorValue = req->length;
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return BadLength;
+ }
+ pc += sz_xGLXRenderLargeReq;
+
+ if (cl->largeCmdRequestsSoFar == 0) {
+ __GLXrenderSizeData *entry;
+ int extra = 0, cmdlen;
+ int left = (req->length << 2) - sz_xGLXRenderLargeReq;
+ /*
+ ** This is the first request of a multi request command.
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (req->requestNumber != 1) {
+ client->errorValue = req->requestNumber;
+ return __glXBadLargeRequest;
+ }
+
+ if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
+ return BadLength;
+
+ hdr = (__GLXrenderLargeHeader *) pc;
+ opcode = hdr->opcode;
+ if ((cmdlen = safe_pad(hdr->length)) < 0)
+ return BadLength;
+
+ /*
+ ** Check for core opcodes and grab entry data.
+ */
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ entry = &__glXRenderSizeTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ opcode -= __GLX_MIN_RENDER_OPCODE_EXT;
+ entry = &__glXRenderSizeTable_EXT[opcode];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+
+ if (!entry->bytes) {
+ /* unused opcode */
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+ if (entry->varsize) {
+ /*
+ ** If it's a variable-size command (a command whose length must
+ ** be computed from its parameters), all the parameters needed
+ ** will be in the 1st request, so it's okay to do this.
+ */
+ extra = (*entry->varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, False,
+ left - __GLX_RENDER_LARGE_HDR_SIZE);
+ if (extra < 0) {
+ return BadLength;
+ }
+ }
+
+ /* the +4 is safe because we know entry.bytes is small */
+ if (cmdlen != safe_pad(safe_add(entry->bytes + 4, extra))) {
+ return BadLength;
+ }
+
+ /*
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (cl->largeCmdBufSize < cmdlen) {
+ if (!cl->largeCmdBuf) {
+ cl->largeCmdBuf = (GLbyte *) malloc((size_t)cmdlen);
+ } else {
+ cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf,
+ (size_t)cmdlen);
+ }
+ if (!cl->largeCmdBuf) {
+ return BadAlloc;
+ }
+ cl->largeCmdBufSize = cmdlen;
+ }
+ memcpy(cl->largeCmdBuf, pc, dataBytes);
+
+ cl->largeCmdBytesSoFar = dataBytes;
+ cl->largeCmdBytesTotal = cmdlen;
+ cl->largeCmdRequestsSoFar = 1;
+ cl->largeCmdRequestsTotal = req->requestTotal;
+ return Success;
+
+ } else {
+ /*
+ ** We are receiving subsequent (i.e. not the first) requests of a
+ ** multi request command.
+ */
+ int bytesSoFar; /* including this packet */
+
+ /*
+ ** Check the request number and the total request count.
+ */
+ if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
+ client->errorValue = req->requestNumber;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ if (req->requestTotal != cl->largeCmdRequestsTotal) {
+ client->errorValue = req->requestTotal;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Check that we didn't get too much data.
+ */
+ if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+
+ if (bytesSoFar > cl->largeCmdBytesTotal) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
+ cl->largeCmdBytesSoFar += dataBytes;
+ cl->largeCmdRequestsSoFar++;
+
+ if (req->requestNumber == cl->largeCmdRequestsTotal) {
+ /*
+ ** This is the last request; it must have enough bytes to complete
+ ** the command.
+ */
+ /* NOTE: the pad macro below is needed because the client library
+ ** pads the total byte count, but not the per-request byte counts.
+ ** The Protocol Encoding says the total byte count should not be
+ ** padded, so a proposal will be made to the ARB to relax the
+ ** padding constraint on the total byte count, thus preserving
+ ** backward compatibility. Meanwhile, the padding done below
+ ** fixes a bug that did not allow large commands of odd sizes to
+ ** be accepted by the server.
+ */
+ if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
+ opcode = hdr->opcode;
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ proc = __glXRenderTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ opcode -= __GLX_MIN_RENDER_OPCODE_EXT;
+ proc = __glXRenderTable_EXT[opcode];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Skip over the header and execute the command.
+ */
+ (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
+ __GLX_NOTE_UNFLUSHED_CMDS(glxc);
+
+ /*
+ ** Reset for the next RenderLarge series.
+ */
+ __glXResetLargeCommandStatus(cl);
+ } else {
+ /*
+ ** This is neither the first nor the last request.
+ */
+ }
+ return Success;
+ }
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *) pc;
+ XID drawable = req->drawable;
+ int barrier = req->barrier;
+ DrawablePtr pDraw = (DrawablePtr) LookupDrawable(drawable, client);
+ int screen = pDraw->pScreen->myNum;
+
+
+ if (pDraw && (pDraw->type == DRAWABLE_WINDOW)) {
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc) {
+ int ret = __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, barrier);
+ if (ret == Success) {
+ if (barrier)
+ /* add source for cleanup when drawable is gone */
+ AddResource(drawable, __glXSwapBarrierRes, (void *)screen);
+ else
+ /* delete source */
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ }
+ return ret;
+ }
+ }
+ client->errorValue = drawable;
+ return __glXBadDrawable;
+}
+
+
+static int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryMaxSwapBarriersSGIXReq *req =
+ (xGLXQueryMaxSwapBarriersSGIXReq *) pc;
+ xGLXQueryMaxSwapBarriersSGIXReply reply;
+ int screen = req->screen;
+
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc)
+ reply.max = __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc(screen);
+ else
+ reply.max = 0;
+
+
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+
+ WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
+ &reply);
+ return Success;
+}
+
+#define GLX_BAD_HYPERPIPE_SGIX 92
+
+static int __glxQueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeNetworkSGIXReq * req = (xGLXQueryHyperpipeNetworkSGIXReq *) pc;
+ xGLXQueryHyperpipeNetworkSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+
+ int length=0;
+ int npipes=0;
+
+ int n= 0;
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc != NULL) {
+ rdata =
+ (__glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc(screen, &npipes, &n));
+ }
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+ WriteToClient(client, sz_xGLXQueryHyperpipeNetworkSGIXReply,
+ &reply);
+
+ WriteToClient(client, length << 2, rdata);
+
+ return Success;
+}
+
+static int __glxDestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyHyperpipeConfigSGIXReq * req =
+ (xGLXDestroyHyperpipeConfigSGIXReq *) pc;
+ xGLXDestroyHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ int success = GLX_BAD_HYPERPIPE_SGIX;
+ int hpId ;
+
+ hpId = req->hpId;
+
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc != NULL) {
+ success = __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc(screen, hpId);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.success = success;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+ WriteToClient(client,
+ sz_xGLXDestroyHyperpipeConfigSGIXReply,
+ &reply);
+ return Success;
+}
+
+static int __glxQueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeConfigSGIXReq * req =
+ (xGLXQueryHyperpipeConfigSGIXReq *) pc;
+ xGLXQueryHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+ int length;
+ int npipes=0;
+ int n= 0;
+ int hpId;
+
+ hpId = req->hpId;
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc != NULL) {
+ rdata = __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
+ }
+
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+
+ WriteToClient(client, sz_xGLXQueryHyperpipeConfigSGIXReply,
+ &reply);
+
+ WriteToClient(client, length << 2, rdata);
+
+ return Success;
+}
+
+static int __glxHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXHyperpipeConfigSGIXReq * req =
+ (xGLXHyperpipeConfigSGIXReq *) pc;
+ xGLXHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata;
+
+ int npipes=0, networkId;
+ int hpId=-1;
+
+ networkId = (int)req->networkId;
+ npipes = (int)req->npipes;
+ rdata = (void *)(req +1);
+
+ if (__glXHyperpipeFuncs &&
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc != NULL) {
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc(screen,networkId,
+ &hpId, &npipes,
+ (void *) rdata);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.npipes = npipes;
+ reply.hpId = hpId;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.npipes);
+ __GLX_SWAP_INT(&reply.hpId);
+ }
+
+ WriteToClient(client, sz_xGLXHyperpipeConfigSGIXReply,
+ &reply);
+
+ return Success;
+}
+
+
+/************************************************************************/
+
+/*
+** No support is provided for the vendor-private requests other than
+** allocating the entry points in the dispatch table.
+*/
+
+int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req;
+ GLint vendorcode;
+
+ req = (xGLXVendorPrivateReq *) pc;
+ vendorcode = req->vendorCode;
+
+#ifndef __DARWIN__
+ switch( vendorcode ) {
+ case X_GLvop_SampleMaskSGIS:
+ glSampleMaskSGIS(*(GLfloat *)(pc + 4),
+ *(GLboolean *)(pc + 8));
+ return Success;
+ case X_GLvop_SamplePatternSGIS:
+ glSamplePatternSGIS( *(GLenum *)(pc + 4));
+ return Success;
+ case X_GLXvop_BindSwapBarrierSGIX:
+ return __glXBindSwapBarrierSGIX(cl, pc);
+ }
+#endif
+
+ if ((vendorcode >= __GLX_MIN_VENDPRIV_OPCODE_EXT) &&
+ (vendorcode <= __GLX_MAX_VENDPRIV_OPCODE_EXT)) {
+ (*__glXVendorPrivTable_EXT[vendorcode-__GLX_MIN_VENDPRIV_OPCODE_EXT])
+ (cl, (GLbyte*)req);
+ return Success;
+ }
+ /*
+ ** This sample implemention does not support any private requests.
+ */
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+}
+
+int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateWithReplyReq *req;
+ GLint vendorcode;
+
+ req = (xGLXVendorPrivateWithReplyReq *) pc;
+ vendorcode = req->vendorCode;
+
+ switch (vendorcode) {
+ case X_GLXvop_QueryContextInfoEXT:
+ return __glXQueryContextInfoEXT(cl, pc);
+ case X_GLXvop_MakeCurrentReadSGI:
+ return __glXMakeCurrentReadSGI(cl, pc);
+ case X_GLXvop_QueryMaxSwapBarriersSGIX:
+ return __glXQueryMaxSwapBarriersSGIX(cl, pc);
+ case X_GLXvop_QueryHyperpipeNetworkSGIX:
+ return __glxQueryHyperpipeNetworkSGIX(cl, pc);
+ case X_GLXvop_QueryHyperpipeConfigSGIX:
+ return __glxQueryHyperpipeConfigSGIX(cl, pc);
+ case X_GLXvop_DestroyHyperpipeConfigSGIX:
+ return __glxDestroyHyperpipeConfigSGIX(cl, pc);
+ case X_GLXvop_HyperpipeConfigSGIX:
+ return __glxHyperpipeConfigSGIX(cl, pc);
+ case X_GLXvop_GetFBConfigsSGIX:
+ return __glXGetFBConfigsSGIX(cl, pc);
+ case X_GLXvop_CreateContextWithConfigSGIX:
+ return __glXCreateContextWithConfigSGIX(cl, pc);
+ case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
+ return __glXCreateGLXPixmapWithConfigSGIX(cl, pc);
+ default:
+ break;
+ }
+
+ if ((vendorcode >= __GLX_MIN_VENDPRIV_OPCODE_EXT) &&
+ (vendorcode <= __GLX_MAX_VENDPRIV_OPCODE_EXT)) {
+ return
+ (*__glXVendorPrivTable_EXT[vendorcode-__GLX_MIN_VENDPRIV_OPCODE_EXT])
+ (cl, (GLbyte*)req);
+ }
+
+ cl->client->errorValue = vendorcode;
+ return __glXUnsupportedPrivateRequest;
+}
+
+int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
+ xGLXQueryExtensionsStringReply reply;
+ GLuint screen;
+ size_t n, length;
+ const char *ptr;
+ char *buf;
+
+ screen = req->screen;
+ /*
+ ** Check if screen exists.
+ */
+ if (screen >= screenInfo.numScreens) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+
+ ptr = __glXActiveScreens[screen].GLXextensions;
+
+ n = strlen(ptr) + 1;
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+
+ /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/
+ buf = (char *) malloc(length << 2);
+ if (buf == NULL)
+ return BadAlloc;
+ memcpy(buf, ptr, n);
+
+ if (client->swapped) {
+ glxSwapQueryExtensionsStringReply(client, &reply, buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryExtensionsStringReply,&reply);
+ WriteToClient(client, (int)(length << 2), buf);
+ }
+
+ free(buf);
+ return Success;
+}
+
+int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
+ xGLXQueryServerStringReply reply;
+ int name;
+ GLuint screen;
+ size_t n, length;
+ const char *ptr;
+ char *buf;
+
+ name = req->name;
+ screen = req->screen;
+ /*
+ ** Check if screen exists.
+ */
+ if (screen >= screenInfo.numScreens) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+ switch(name) {
+ case GLX_VENDOR:
+ ptr = __glXActiveScreens[screen].GLXvendor;
+ break;
+ case GLX_VERSION:
+ ptr = __glXActiveScreens[screen].GLXversion;
+ break;
+ case GLX_EXTENSIONS:
+ ptr = __glXActiveScreens[screen].GLXextensions;
+ break;
+ default:
+ return BadValue;
+ }
+
+ n = strlen(ptr) + 1;
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+
+ if ((buf = (char *) malloc(length << 2)) == NULL) {
+ return BadAlloc;
+ }
+ memcpy(buf, ptr, n);
+
+ if (client->swapped) {
+ glxSwapQueryServerStringReply(client, &reply, buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryServerStringReply, &reply);
+ WriteToClient(client, (int)(length << 2), buf);
+ }
+
+ free(buf);
+ return Success;
+}
+
+int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
+ const char *buf;
+
+ cl->GLClientmajorVersion = req->major;
+ cl->GLClientminorVersion = req->minor;
+ if (cl->GLClientextensions)
+ free(cl->GLClientextensions);
+ buf = (const char *)(req+1);
+ cl->GLClientextensions = xstrdup(buf);
+
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxcmdsswap.c b/nx-X11/programs/Xserver/GL/glx/glxcmdsswap.c
new file mode 100644
index 000000000..98acfe5af
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxcmdsswap.c
@@ -0,0 +1,888 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#define FONT_PCF
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include <GL/glxtokens.h>
+#include <unpack.h>
+#include <g_disptab.h>
+#include <g_disptab_EXT.h>
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "glxext.h"
+
+static int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXSwapCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc);
+static int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc);
+
+/************************************************************************/
+
+/*
+** Byteswapping versions of GLX commands. In most cases they just swap
+** the incoming arguments and then call the unswapped routine. For commands
+** that have replies, a separate swapping routine for the reply is provided;
+** it is called at the end of the unswapped routine.
+*/
+
+int __glXSwapCreateContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->visual);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->shareList);
+
+ return DoCreateContext( cl, req->context, req->shareList, req->visual,
+ req->screen, req->isDirect );
+}
+
+int __glXSwapCreateNewContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->renderType);
+ __GLX_SWAP_INT(&req->shareList);
+
+ return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
+ req->screen, req->isDirect );
+}
+
+int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextWithConfigSGIXReq *req =
+ (xGLXCreateContextWithConfigSGIXReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->renderType);
+ __GLX_SWAP_INT(&req->shareList);
+
+ return DoCreateContext( cl, req->context, req->shareList, req->fbconfig,
+ req->screen, req->isDirect );
+}
+
+int __glXSwapDestroyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+
+ return __glXDestroyContext(cl, pc);
+}
+
+int __glXSwapMakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->drawable);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->oldContextTag);
+
+ return DoMakeCurrent( cl, req->drawable, req->drawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->drawable);
+ __GLX_SWAP_INT(&req->readdrawable);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->oldContextTag);
+
+ return DoMakeCurrent( cl, req->drawable, req->readdrawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->drawable);
+ __GLX_SWAP_INT(&req->readable);
+ __GLX_SWAP_INT(&req->context);
+ __GLX_SWAP_INT(&req->oldContextTag);
+
+ return DoMakeCurrent( cl, req->drawable, req->readable,
+ req->context, req->oldContextTag );
+}
+
+int __glXSwapIsDirect(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+
+ return __glXIsDirect(cl, pc);
+}
+
+int __glXSwapQueryVersion(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->majorVersion);
+ __GLX_SWAP_INT(&req->minorVersion);
+
+ return __glXQueryVersion(cl, pc);
+}
+
+int __glXSwapWaitGL(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitGLReq *req = (xGLXWaitGLReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ return __glXWaitGL(cl, pc);
+}
+
+int __glXSwapWaitX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitXReq *req = (xGLXWaitXReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ return __glXWaitX(cl, pc);
+}
+
+int __glXSwapCopyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->source);
+ __GLX_SWAP_INT(&req->dest);
+ __GLX_SWAP_INT(&req->mask);
+
+ return __glXCopyContext(cl, pc);
+}
+
+int __glXSwapGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->screen);
+ return DoGetVisualConfigs( cl, req->screen, GL_TRUE );
+}
+
+int __glXSwapGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->screen);
+ return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+}
+
+int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&req->screen);
+ return DoGetFBConfigs( cl, req->screen, GL_TRUE );
+}
+
+int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->visual);
+ __GLX_SWAP_INT(&req->pixmap);
+ __GLX_SWAP_INT(&req->glxpixmap);
+
+ return DoCreateGLXPixmap( cl, req->visual, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+int __glXSwapCreatePixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->pixmap);
+ __GLX_SWAP_INT(&req->glxpixmap);
+
+ return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+int __glXSwapCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapWithConfigSGIXReq *req =
+ (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->fbconfig);
+ __GLX_SWAP_INT(&req->pixmap);
+ __GLX_SWAP_INT(&req->glxpixmap);
+
+ return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
+ req->pixmap, req->glxpixmap );
+}
+
+int __glXSwapDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->glxpixmap);
+
+ return __glXDestroyGLXPixmap(cl, pc);
+}
+
+int __glXSwapSwapBuffers(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+ __GLX_SWAP_INT(&req->drawable);
+
+ return __glXSwapBuffers(cl, pc);
+}
+
+int __glXSwapUseXFont(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXUseXFontReq *req = (xGLXUseXFontReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+ __GLX_SWAP_INT(&req->font);
+ __GLX_SWAP_INT(&req->first);
+ __GLX_SWAP_INT(&req->count);
+ __GLX_SWAP_INT(&req->listBase);
+
+ return __glXUseXFont(cl, pc);
+}
+
+
+int __glXSwapQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryExtensionsStringReq *req = NULL;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->screen);
+
+ return __glXQueryExtensionsString(cl, pc);
+}
+
+int __glXSwapQueryServerString(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->screen);
+ __GLX_SWAP_INT(&req->name);
+
+ return __glXQueryServerString(cl, pc);
+}
+
+int __glXSwapClientInfo(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->major);
+ __GLX_SWAP_INT(&req->minor);
+ __GLX_SWAP_INT(&req->numbytes);
+
+ return __glXClientInfo(cl, pc);
+}
+
+int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->context);
+
+ return __glXQueryContextInfoEXT(cl, pc);
+}
+
+/************************************************************************/
+
+/*
+** Swap replies.
+*/
+
+void __glXSwapMakeCurrentReply(ClientPtr client, xGLXMakeCurrentReply *reply)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->contextTag);
+ WriteToClient(client, sz_xGLXMakeCurrentReply, reply);
+}
+
+void __glXSwapIsDirectReply(ClientPtr client, xGLXIsDirectReply *reply)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ WriteToClient(client, sz_xGLXIsDirectReply, reply);
+}
+
+void __glXSwapQueryVersionReply(ClientPtr client, xGLXQueryVersionReply *reply)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->majorVersion);
+ __GLX_SWAP_INT(&reply->minorVersion);
+ WriteToClient(client, sz_xGLXQueryVersionReply, reply);
+}
+
+void glxSwapQueryExtensionsStringReply(ClientPtr client,
+ xGLXQueryExtensionsStringReply *reply, char *buf)
+{
+ int length = reply->length;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->n);
+ WriteToClient(client, sz_xGLXQueryExtensionsStringReply, reply);
+ __GLX_SWAP_INT_ARRAY((int *)buf, length);
+ WriteToClient(client, length << 2, buf);
+}
+
+void glxSwapQueryServerStringReply(ClientPtr client,
+ xGLXQueryServerStringReply *reply, char *buf)
+{
+ int length = reply->length;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->n);
+ WriteToClient(client, sz_xGLXQueryServerStringReply, reply);
+ /** no swap is needed for an array of chars **/
+ /* __GLX_SWAP_INT_ARRAY((int *)buf, length); */
+ WriteToClient(client, length << 2, buf);
+}
+
+void __glXSwapQueryContextInfoEXTReply(ClientPtr client, xGLXQueryContextInfoEXTReply *reply, int *buf)
+{
+ int length = reply->length;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->n);
+ WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, reply);
+ __GLX_SWAP_INT_ARRAY((int *)buf, length);
+ WriteToClient(client, length << 2, buf);
+}
+
+
+/************************************************************************/
+
+/*
+** Render and Renderlarge are not in the GLX API. They are used by the GLX
+** client library to send batches of GL rendering commands.
+*/
+
+int __glXSwapRender(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderReq *req;
+ ClientPtr client= cl->client;
+ int left, cmdlen, error;
+ int commandsDone;
+ CARD16 opcode;
+ __GLXrenderHeader *hdr;
+ __GLXcontext *cx;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ /*
+ ** NOTE: much of this code also appears in the nonswapping version of this
+ ** routine, __glXRender(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ req = (xGLXRenderReq *) pc;
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ cx = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!cx) {
+ return error;
+ }
+
+ commandsDone = 0;
+ pc += sz_xGLXRenderReq;
+ left = (req->length << 2) - sz_xGLXRenderReq;
+ while (left > 0) {
+ __GLXrenderSizeData *entry;
+ int extra = 0;
+ void (* proc)(GLbyte *);
+
+ /*
+ ** Verify that the header length and the overall length agree.
+ ** Also, each command must be word aligned.
+ */
+ hdr = (__GLXrenderHeader *) pc;
+ __GLX_SWAP_SHORT(&hdr->length);
+ __GLX_SWAP_SHORT(&hdr->opcode);
+ cmdlen = hdr->length;
+ opcode = hdr->opcode;
+
+ if (left < cmdlen)
+ return BadLength;
+
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ entry = &__glXRenderSizeTable[opcode];
+ proc = __glXSwapRenderTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
+ entry = &__glXRenderSizeTable_EXT[index];
+ proc = __glXSwapRenderTable_EXT[index];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = commandsDone;
+ return __glXBadRenderRequest;
+ }
+ if (!entry->bytes) {
+ /* unused opcode */
+ client->errorValue = commandsDone;
+ return __glXBadRenderRequest;
+ }
+
+ if (cmdlen < entry->bytes) {
+ return BadLength;
+ }
+
+ if (entry->varsize) {
+ /* variable size command */
+ extra = (*entry->varsize)(pc + __GLX_RENDER_HDR_SIZE, True,
+ left - __GLX_RENDER_HDR_SIZE);
+ if (extra < 0) {
+ return BadLength;
+ }
+ }
+ if (cmdlen != safe_pad(safe_add(entry->bytes, extra))) {
+ return BadLength;
+ }
+
+ /*
+ ** Skip over the header and execute the command. We allow the
+ ** caller to trash the command memory. This is useful especially
+ ** for things that require double alignment - they can just shift
+ ** the data towards lower memory (trashing the header) by 4 bytes
+ ** and achieve the required alignment.
+ */
+ (*proc)(pc + __GLX_RENDER_HDR_SIZE);
+ pc += cmdlen;
+ left -= cmdlen;
+ commandsDone++;
+ }
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+/*
+** Execute a large rendering request (one that spans multiple X requests).
+*/
+int __glXSwapRenderLarge(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderLargeReq *req;
+ ClientPtr client= cl->client;
+ size_t dataBytes;
+ void (*proc)(GLbyte *);
+ __GLXrenderLargeHeader *hdr;
+ __GLXcontext *cx;
+ int error;
+ CARD16 opcode;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ /*
+ ** NOTE: much of this code also appears in the nonswapping version of this
+ ** routine, __glXRenderLarge(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq);
+
+ req = (xGLXRenderLargeReq *) pc;
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+ __GLX_SWAP_INT(&req->dataBytes);
+ __GLX_SWAP_SHORT(&req->requestNumber);
+ __GLX_SWAP_SHORT(&req->requestTotal);
+ cx = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!cx) {
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return error;
+ }
+ if (safe_pad(req->dataBytes) < 0)
+ return BadLength;
+
+ dataBytes = req->dataBytes;
+
+ /*
+ ** Check the request length.
+ */
+ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) {
+ client->errorValue = req->length;
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return BadLength;
+ }
+ pc += sz_xGLXRenderLargeReq;
+
+ if (cl->largeCmdRequestsSoFar == 0) {
+ __GLXrenderSizeData *entry;
+ int extra = 0;
+ int left = (req->length << 2) - sz_xGLXRenderLargeReq;
+ size_t cmdlen;
+ /*
+ ** This is the first request of a multi request command.
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (req->requestNumber != 1) {
+ client->errorValue = req->requestNumber;
+ return __glXBadLargeRequest;
+ }
+ if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE)
+ return BadLength;
+
+ hdr = (__GLXrenderLargeHeader *) pc;
+ __GLX_SWAP_INT(&hdr->length);
+ __GLX_SWAP_INT(&hdr->opcode);
+ opcode = hdr->opcode;
+
+ if ((cmdlen = safe_pad(hdr->length)) < 0)
+ return BadLength;
+
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ entry = &__glXRenderSizeTable[opcode];
+ proc = __glXSwapRenderTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
+ entry = &__glXRenderSizeTable_EXT[index];
+ proc = __glXSwapRenderTable_EXT[index];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+
+ if (!entry->bytes) {
+ /* unused opcode */
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+ if (entry->varsize) {
+ /*
+ ** If it's a variable-size command (a command whose length must
+ ** be computed from its parameters), all the parameters needed
+ ** will be in the 1st request, so it's okay to do this.
+ */
+ extra = (*entry->varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, True,
+ left - __GLX_RENDER_LARGE_HDR_SIZE);
+ if (extra < 0) {
+ return BadLength;
+ }
+ }
+ /* the +4 is safe because we know entry->bytes is small */
+ if (cmdlen != safe_pad(safe_add(entry->bytes + 4, extra))) {
+ return BadLength;
+ }
+
+ /*
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (cl->largeCmdBufSize < cmdlen) {
+ if (!cl->largeCmdBuf) {
+ cl->largeCmdBuf = (GLbyte *) malloc(cmdlen);
+ } else {
+ cl->largeCmdBuf = (GLbyte *) realloc(cl->largeCmdBuf, cmdlen);
+ }
+ if (!cl->largeCmdBuf) {
+ return BadAlloc;
+ }
+ cl->largeCmdBufSize = cmdlen;
+ }
+ memcpy(cl->largeCmdBuf, pc, dataBytes);
+
+ cl->largeCmdBytesSoFar = dataBytes;
+ cl->largeCmdBytesTotal = cmdlen;
+ cl->largeCmdRequestsSoFar = 1;
+ cl->largeCmdRequestsTotal = req->requestTotal;
+ return Success;
+
+ } else {
+ /*
+ ** We are receiving subsequent (i.e. not the first) requests of a
+ ** multi request command.
+ */
+ int bytesSoFar; /* including this packet */
+
+ /*
+ ** Check the request number and the total request count.
+ */
+ if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
+ client->errorValue = req->requestNumber;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ if (req->requestTotal != cl->largeCmdRequestsTotal) {
+ client->errorValue = req->requestTotal;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Check that we didn't get too much data.
+ */
+ if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+
+ if (bytesSoFar > cl->largeCmdBytesTotal) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
+ cl->largeCmdBytesSoFar += dataBytes;
+ cl->largeCmdRequestsSoFar++;
+
+ if (req->requestNumber == cl->largeCmdRequestsTotal) {
+ /*
+ ** This is the last request; it must have enough bytes to complete
+ ** the command.
+ */
+ /* NOTE: the pad macro below is needed because the client library
+ ** pads the total byte count, but not the per-request byte counts.
+ ** The Protocol Encoding says the total byte count should not be
+ ** padded, so a proposal will be made to the ARB to relax the
+ ** padding constraint on the total byte count, thus preserving
+ ** backward compatibility. Meanwhile, the padding done below
+ ** fixes a bug that did not allow large commands of odd sizes to
+ ** be accepted by the server.
+ */
+
+ if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXBadLargeRequest;
+ }
+ hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
+ /*
+ ** The opcode and length field in the header had already been
+ ** swapped when the first request was received.
+ */
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ opcode = hdr->opcode;
+ if ( (opcode >= __GLX_MIN_RENDER_OPCODE) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE) ) {
+ proc = __glXSwapRenderTable[opcode];
+#if __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT
+ } else if ( (opcode >= __GLX_MIN_RENDER_OPCODE_EXT) &&
+ (opcode <= __GLX_MAX_RENDER_OPCODE_EXT) ) {
+ int index = opcode - __GLX_MIN_RENDER_OPCODE_EXT;
+ proc = __glXSwapRenderTable_EXT[index];
+#endif /* __GLX_MAX_RENDER_OPCODE_EXT > __GLX_MIN_RENDER_OPCODE_EXT */
+ } else {
+ client->errorValue = opcode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Skip over the header and execute the command.
+ */
+ (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+
+ /*
+ ** Reset for the next RenderLarge series.
+ */
+ __glXResetLargeCommandStatus(cl);
+ } else {
+ /*
+ ** This is neither the first nor the last request.
+ */
+ }
+ return Success;
+ }
+}
+
+/************************************************************************/
+
+/*
+** No support is provided for the vendor-private requests other than
+** allocating these entry points in the dispatch table.
+*/
+
+int __glXSwapVendorPrivate(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXVendorPrivateReq *req;
+ GLint vendorcode;
+
+ __GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq);
+
+ req = (xGLXVendorPrivateReq *) pc;
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+
+ vendorcode = req->vendorCode;
+
+#ifndef __DARWIN__
+ switch( vendorcode ) {
+ case X_GLvop_SampleMaskSGIS:
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_INT(pc + 8);
+ glSampleMaskSGIS(*(GLfloat *)(pc + 4),
+ *(GLboolean *)(pc + 8));
+ return Success;
+ case X_GLvop_SamplePatternSGIS:
+ __GLX_SWAP_INT(pc + 4);
+ glSamplePatternSGIS( *(GLenum *)(pc + 4));
+ return Success;
+ }
+#endif
+
+
+ if ((vendorcode >= __GLX_MIN_VENDPRIV_OPCODE_EXT) &&
+ (vendorcode <= __GLX_MAX_VENDPRIV_OPCODE_EXT)) {
+ (*__glXSwapVendorPrivTable_EXT[vendorcode-__GLX_MIN_VENDPRIV_OPCODE_EXT])(cl, (GLbyte*)req);
+ return Success;
+ }
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+}
+
+int __glXSwapVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXVendorPrivateWithReplyReq *req;
+ GLint vendorcode;
+
+ __GLX_DECLARE_SWAP_VARIABLES;
+ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq);
+
+ req = (xGLXVendorPrivateWithReplyReq *) pc;
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+
+ vendorcode = req->vendorCode;
+
+ switch (vendorcode) {
+ case X_GLXvop_QueryContextInfoEXT:
+ return __glXSwapQueryContextInfoEXT(cl, pc);
+ case X_GLXvop_MakeCurrentReadSGI:
+ return __glXSwapMakeCurrentReadSGI(cl, pc);
+ case X_GLXvop_GetFBConfigsSGIX:
+ return __glXSwapGetFBConfigsSGIX(cl, pc);
+ case X_GLXvop_CreateContextWithConfigSGIX:
+ return __glXSwapCreateContextWithConfigSGIX(cl, pc);
+ case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
+ return __glXSwapCreateGLXPixmapWithConfigSGIX(cl, pc);
+ default:
+ break;
+ }
+
+
+ if ((vendorcode >= __GLX_MIN_VENDPRIV_OPCODE_EXT) &&
+ (vendorcode <= __GLX_MAX_VENDPRIV_OPCODE_EXT)) {
+ return (*__glXSwapVendorPrivTable_EXT[vendorcode-__GLX_MIN_VENDPRIV_OPCODE_EXT])(cl, (GLbyte*)req);
+ }
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxcontext.h b/nx-X11/programs/Xserver/GL/glx/glxcontext.h
new file mode 100644
index 000000000..25f8daf44
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxcontext.h
@@ -0,0 +1,163 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_context_h_
+#define _GLX_context_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+typedef struct __GLXcontextRec __GLXcontext;
+
+/* XXX: should be defined somewhere globally */
+#define CAPI
+
+#include "GL/internal/glcore.h"
+
+struct __GLXcontextRec {
+ /*
+ ** list of context structs
+ */
+ struct __GLXcontextRec *last;
+ struct __GLXcontextRec *next;
+
+ /*
+ ** list of contexts bound to the same drawable
+ */
+ struct __GLXcontextRec *nextDrawPriv;
+ struct __GLXcontextRec *nextReadPriv;
+
+ /*
+ ** Opaque pointer the context object created by the GL that the
+ ** server is bound with. Never dereferenced by this code, but used
+ ** as a handle to feed to the routines in the screen info struct.
+ */
+ __GLinterface *gc;
+
+ /*
+ ** mode struct for this context
+ */
+ __GLcontextModes *modes;
+
+ /*
+ ** Pointer to screen info data for this context. This is set
+ ** when the context is created.
+ */
+ ScreenPtr pScreen;
+ __GLXscreenInfo *pGlxScreen;
+
+ /*
+ ** This context is created with respect to this visual.
+ */
+ VisualRec *pVisual;
+
+ /*
+ ** The XID of this context.
+ */
+ XID id;
+
+ /*
+ ** The XID of the shareList context.
+ */
+ XID share_id;
+
+ /*
+ ** Visual id.
+ */
+ VisualID vid;
+
+ /*
+ ** screen number.
+ */
+ GLint screen;
+
+ /*
+ ** Whether this context's ID still exists.
+ */
+ GLboolean idExists;
+
+ /*
+ ** Whether this context is current for some client.
+ */
+ GLboolean isCurrent;
+
+ /*
+ ** Whether this context is a direct rendering context.
+ */
+ GLboolean isDirect;
+
+ /*
+ ** Window pending state
+ */
+ GLuint pendingState;
+
+ /*
+ ** This flag keeps track of whether there are unflushed GL commands.
+ */
+ GLboolean hasUnflushedCommands;
+
+ /*
+ ** Current rendering mode for this context.
+ */
+ GLenum renderMode;
+
+ /*
+ ** Buffers for feedback and selection.
+ */
+ GLfloat *feedbackBuf;
+ GLint feedbackBufSize; /* number of elements allocated */
+ GLuint *selectBuf;
+ GLint selectBufSize; /* number of elements allocated */
+
+ /*
+ ** Set only if current drawable is a glx pixmap.
+ */
+ __GLXpixmap *drawPixmap;
+ __GLXpixmap *readPixmap;
+
+ /*
+ ** The drawable private this context is bound to
+ */
+ __GLXdrawablePrivate *drawPriv;
+ __GLXdrawablePrivate *readPriv;
+};
+
+/* pending state defines */
+#define __GLX_PENDING_RESIZE 0x1
+#define __GLX_PENDING_DESTROY 0x2
+#define __GLX_PENDING_SWAP 0x4
+
+#endif /* !__GLX_context_h__ */
diff --git a/nx-X11/programs/Xserver/GL/glx/glxdrawable.h b/nx-X11/programs/Xserver/GL/glx/glxdrawable.h
new file mode 100644
index 000000000..a7c975a44
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxdrawable.h
@@ -0,0 +1,111 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_drawable_h_
+#define _GLX_drawable_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+typedef struct {
+
+ DrawablePtr pDraw;
+ __GLcontextModes *modes;
+ __GLXscreenInfo *pGlxScreen;
+ ScreenPtr pScreen;
+ Bool idExists;
+ int refcnt;
+
+} __GLXpixmap;
+
+struct __GLXdrawablePrivateRec {
+ /*
+ ** list of drawable private structs
+ */
+ struct __GLXdrawablePrivateRec *last;
+ struct __GLXdrawablePrivateRec *next;
+
+ DrawablePtr pDraw;
+ XID drawId;
+ __GLXpixmap *pGlxPixmap;
+
+ /*
+ ** Either DRAWABLE_PIXMAP or DRAWABLE_WINDOW, copied from pDraw above.
+ ** Needed by the resource freer because pDraw might already have been
+ ** freed.
+ */
+ int type;
+
+ /*
+ ** Configuration of the visual to which this drawable was created.
+ */
+ __GLcontextModes *modes;
+
+ /*
+ ** cached drawable size and origin
+ */
+
+ GLint xorigin, yorigin;
+ GLint width, height;
+
+ /*
+ ** Lists of contexts bound to this drawable. There are two lists here.
+ ** One list is of the contexts that have this drawable bound for drawing,
+ ** and the other is the list of contexts that have this drawable bound
+ ** for reading.
+ */
+ struct __GLXcontextRec *drawGlxc;
+ struct __GLXcontextRec *readGlxc;
+
+ /*
+ ** "methods" that the drawble should be able to respond to.
+ */
+ void (*freeBuffers)(struct __GLXdrawablePrivateRec *);
+ void (*updatePalette)(struct __GLXdrawablePrivateRec *);
+ GLboolean (*swapBuffers)(struct __GLXdrawablePrivateRec *);
+
+ /*
+ ** The GL drawable (information shared between GLX and the GL core)
+ */
+ __GLdrawablePrivate glPriv;
+
+ /*
+ ** reference count
+ */
+ int refCount;
+};
+
+#endif /* !__GLX_drawable_h__ */
diff --git a/nx-X11/programs/Xserver/GL/glx/glxerror.h b/nx-X11/programs/Xserver/GL/glx/glxerror.h
new file mode 100644
index 000000000..44973fccb
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxerror.h
@@ -0,0 +1,57 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_error_h_
+#define _GLX_error_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+** Error codes. These have the extension error base added to them
+** when the extension initializes.
+*/
+extern int __glXBadContext;
+extern int __glXBadContextState;
+extern int __glXBadDrawable;
+extern int __glXBadPixmap;
+extern int __glXBadCurrentWindow;
+extern int __glXBadContextTag;
+extern int __glXBadRenderRequest;
+extern int __glXBadLargeRequest;
+extern int __glXUnsupportedPrivateRequest;
+
+#endif
diff --git a/nx-X11/programs/Xserver/GL/glx/glxext.c b/nx-X11/programs/Xserver/GL/glx/glxext.c
new file mode 100644
index 000000000..cb82dc609
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxext.c
@@ -0,0 +1,510 @@
+/*
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+ __glXFlushContextCache();
+ (*__glXExt->resetExtension)();
+ __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+ __GLXclientState *cl = __glXClients[clientIndex];
+
+ if (cl->returnBuf) free(cl->returnBuf);
+ if (cl->largeCmdBuf) free(cl->largeCmdBuf);
+ if (cl->currentContexts) free(cl->currentContexts);
+ memset(cl, 0, sizeof(__GLXclientState));
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ if (cl->GLClientextensions)
+ free(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+ cl->largeCmdBytesSoFar = 0;
+ cl->largeCmdBytesTotal = 0;
+ cl->largeCmdRequestsSoFar = 0;
+ cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called. In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+ cx->idExists = GL_FALSE;
+ if (!cx->isCurrent) {
+ __glXFreeContext(cx);
+ }
+
+ return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+ __GLXcontext *cx;
+ __GLXclientState *cl = __glXClients[clientIndex];
+ int i;
+
+ if (cl) {
+ /*
+ ** Free all the contexts that are current for this client.
+ */
+ for (i=0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ __glXDeassociateContext(cx);
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists) {
+ __glXFreeContext(cx);
+ }
+ }
+ }
+ /*
+ ** Re-initialize the client state structure. Don't free it because
+ ** we'll probably get another client with this index and use the struct
+ ** again. There is a maximum of MAXCLIENTS of these structures.
+ */
+ ResetClientState(clientIndex);
+ }
+
+ return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+ PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+ pGlxPixmap->idExists = False;
+ if (!pGlxPixmap->refcnt) {
+ /*
+ ** The DestroyPixmap routine should decrement the refcount and free
+ ** only if it's zero.
+ */
+ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+ free(pGlxPixmap);
+ }
+
+ return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+ if (cx->idExists || cx->isCurrent) return GL_FALSE;
+
+ if (!cx->isDirect) {
+ if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+ return GL_FALSE;
+ }
+ }
+ if (cx->feedbackBuf) free(cx->feedbackBuf);
+ if (cx->selectBuf) free(cx->selectBuf);
+ free(cx);
+ if (cx == __glXLastContext) {
+ __glXFlushContextCache();
+ }
+
+ return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+ if (__glXSwapBarrierFuncs &&
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+ }
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error. Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+ errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+ errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+ return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+ __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+ __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+ /*
+ ** Add extension to server extensions.
+ */
+ extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+ __GLX_NUMBER_ERRORS, __glXDispatch,
+ __glXSwapDispatch, ResetExtension,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ FatalError("__glXExtensionInit: AddExtensions failed\n");
+ return;
+ }
+ if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+ ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+ return;
+ }
+
+ __glXBadContext = extEntry->errorBase + GLXBadContext;
+ __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+ __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+ __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+ __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+ __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+ __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+ __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+ __glXUnsupportedPrivateRequest = extEntry->errorBase +
+ GLXUnsupportedPrivateRequest;
+
+ __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+ /*
+ ** Initialize table of client state. There is never a client 0.
+ */
+ for (i=1; i <= MAXCLIENTS; i++) {
+ __glXClients[i] = 0;
+ }
+
+ /*
+ ** Initialize screen specific data.
+ */
+ __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+ return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates)
+{
+ (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp,
+ int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB,
+ int preferredVis)
+{
+ Bool ret;
+
+ if (saveInitVisualsProc) {
+ ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ if (!ret)
+ return False;
+ }
+ (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB);
+ return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+ saveInitVisualsProc = *initVisProc;
+ *initVisProc = GlxInitVisuals;
+ /* HACK: this shouldn't be done here but it's the earliest time */
+ __glXExt = __glXglDDXExtensionInfo(); /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+ __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts). While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+ int *error)
+{
+ __GLXcontext *cx;
+
+ /*
+ ** See if the context tag is legal; it is managed by the extension,
+ ** so if it's invalid, we have an implementation error.
+ */
+ cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+ if (!cx) {
+ cl->client->errorValue = tag;
+ *error = __glXBadContextTag;
+ return 0;
+ }
+
+ if (!cx->isDirect) {
+ if (cx->drawPriv == NULL) {
+ /*
+ ** The drawable has vanished. It must be a window, because only
+ ** windows can be destroyed from under us; GLX pixmaps are
+ ** refcounted and don't go away until no one is using them.
+ */
+ *error = __glXBadCurrentWindow;
+ return 0;
+ }
+ }
+
+ if (cx == __glXLastContext) {
+ /* No need to re-bind */
+ return cx;
+ }
+
+ /* Make this context the current one for the GL. */
+ if (!cx->isDirect) {
+ if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+ /* Bind failed, and set the error code. Bummer */
+ cl->client->errorValue = cx->id;
+ *error = __glXBadContextState;
+ return 0;
+ }
+ }
+ __glXLastContext = cx;
+ return cx;
+}
+
+/************************************************************************/
+
+#ifndef NXAGENT_SERVER
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) malloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ memset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (void *)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** If we're expecting a glXRenderLarge request, this better be one.
+ */
+ if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+ client->errorValue = stuff->glxCode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) malloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ memset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (void *)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+#endif /* NXAGENT_SERVER */
+
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+ return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxext.h b/nx-X11/programs/Xserver/GL/glx/glxext.h
new file mode 100644
index 000000000..edb65a5f3
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxext.h
@@ -0,0 +1,130 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxext_h_
+#define _glxext_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+ * Added by VA Linux for XFree86 4.0.x
+ */
+typedef struct {
+ int type;
+ void (*resetExtension)(void);
+ Bool (*initVisuals)(
+ VisualPtr * visualp,
+ DepthPtr * depthp,
+ int * nvisualp,
+ int * ndepthp,
+ int * rootDepthp,
+ VisualID * defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB
+ );
+ void (*setVisualConfigs)(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **privates
+ );
+} __GLXextensionInfo;
+
+extern GLboolean __glXFreeContext(__GLXcontext *glxc);
+extern void __glXFlushContextCache(void);
+
+extern void __glXNoSuchRenderOpcode(GLbyte*);
+extern int __glXNoSuchSingleOpcode(__GLXclientState*, GLbyte*);
+extern void __glXErrorCallBack(__GLinterface *gc, GLenum code);
+extern void __glXClearErrorOccured(void);
+extern GLboolean __glXErrorOccured(void);
+extern void __glXResetLargeCommandStatus(__GLXclientState*);
+
+extern int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc);
+extern int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc);
+
+extern int DoMakeCurrent( __GLXclientState *cl, GLXDrawable drawId,
+ GLXDrawable readId, GLXContextID contextId, GLXContextTag tag );
+extern int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen,
+ GLboolean do_swap);
+extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
+ GLboolean do_swap);
+extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
+ GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
+extern int DoCreateGLXPixmap(__GLXclientState *cl, VisualID visual,
+ GLuint screenNum, XID pixmapId, XID glxpixmapId);
+
+extern void GlxExtensionInit(void);
+
+extern Bool __glXCoreType(void);
+
+extern const char GLServerVersion[];
+extern int DoGetString(__GLXclientState *cl, GLbyte *pc, GLboolean need_swap);
+
+extern int GlxInitVisuals(
+ VisualPtr * visualp,
+ DepthPtr * depthp,
+ int * nvisualp,
+ int * ndepthp,
+ int * rootDepthp,
+ VisualID * defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB,
+ int preferredVis
+);
+
+typedef struct {
+ void * (* queryHyperpipeNetworkFunc)(int, int *, int *);
+ void * (* queryHyperpipeConfigFunc)(int, int, int *, int *);
+ int (* destroyHyperpipeConfigFunc)(int, int);
+ void * (* hyperpipeConfigFunc)(int, int, int *, int *, void *);
+} __GLXHyperpipeExtensionFuncs;
+
+extern void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs);
+
+extern __GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs;
+
+typedef struct {
+ int (* bindSwapBarrierFunc)(int, XID, int);
+ int (* queryMaxSwapBarriersFunc)(int);
+} __GLXSwapBarrierExtensionFuncs;
+
+extern void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs);
+
+extern __GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs;
+
+#endif /* _glxext_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxfb.c b/nx-X11/programs/Xserver/GL/glx/glxfb.c
new file mode 100644
index 000000000..7248b6ffb
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxfb.c
@@ -0,0 +1,182 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+** An implementation of a buffer which is part of the front buffer
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxfb.h"
+
+#include <gcstruct.h>
+
+/* so we don't include glmath.h */
+extern GLuint __glFloorLog2(GLuint);
+
+typedef struct __GLFBbufferInfoRec {
+ GCPtr pGC;
+} __GLFBbufferInfo;
+
+extern PixmapPtr __glXPrivPixGetPtr(__GLdrawableBuffer *);
+
+/* ---------------------------------------------------------- */
+
+static GLboolean
+Resize(__GLdrawableBuffer *buf,
+ GLint x, GLint y, GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv, GLuint bufferMask)
+{
+ buf->width = width;
+ buf->height = height;
+ buf->byteWidth = width * buf->elementSize;
+ buf->outerWidth = width;
+
+ return GL_TRUE;
+}
+
+static void
+Lock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+static void
+Unlock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+/*
+** Do a swap buffer with
+** a memory surface as a back buffer
+** a FB surface as a front buffer
+*/
+GLboolean
+__glXFBMemSwapBuffers(__GLXdrawablePrivate *glxPriv)
+{
+ __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+ __GLdrawableBuffer *front = &glPriv->frontBuffer;
+ __GLdrawableBuffer *back = &glPriv->backBuffer;
+ __GLFBbufferInfo *bufferInfo;
+ GCPtr pGC;
+ GLint width, height, depth, pad;
+ GLubyte *buf;
+
+ bufferInfo = (__GLFBbufferInfo *) front->other;
+ pGC = bufferInfo->pGC;
+
+ width = back->width;
+ height = back->height;
+ depth = back->depth;
+ buf = back->base;
+ pad = back->outerWidth - back->width; /* back buffer padding */
+ /* adjust buffer padding. X wants left, GL has right */
+ buf -= pad;
+
+ ValidateGC(glxPriv->pDraw, pGC);
+ (*pGC->ops->PutImage)(glxPriv->pDraw, pGC,
+ depth,
+ 0, 0, width, height,
+ pad, ZPixmap,
+ buf);
+
+ return GL_TRUE;
+}
+
+static void
+Free(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+ __GLFBbufferInfo *bufferInfo;
+
+ bufferInfo = (__GLFBbufferInfo *) buf->other;
+
+ if (bufferInfo->pGC) {
+ FreeScratchGC(bufferInfo->pGC);
+ }
+
+ free(bufferInfo);
+ buf->other = NULL;
+}
+
+/*
+** function to return the X GC of this buffer (to be used by DDX)
+*/
+GCPtr __glXFBGetGC(__GLdrawableBuffer *buf)
+{
+ __GLFBbufferInfo *bufferInfo;
+
+ bufferInfo = (__GLFBbufferInfo *) buf->other;
+
+ if (bufferInfo) {
+ return bufferInfo->pGC;
+ } else {
+ return NULL;
+ }
+}
+
+
+void
+__glXInitFB(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv, GLint bits)
+{
+ __GLFBbufferInfo *bufferInfo;
+ __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *) glPriv->other;
+ GCPtr pGC;
+
+ buf->depth = bits;
+ buf->width = buf->height = 0; /* to be filled during Update */
+ buf->handle = buf->base = NULL; /* to be filled during Update */
+ buf->size = 0;
+ buf->byteWidth = 0;
+ buf->elementSize = ((bits-1) / 8) + 1;
+ buf->elementSizeLog2 = __glFloorLog2(buf->elementSize);
+
+ buf->resize = Resize;
+ buf->lock = Lock;
+ buf->unlock = Unlock;
+ buf->fill = NULL;
+ buf->free = Free;
+
+ /* allocate local information */
+ bufferInfo = (__GLFBbufferInfo *) malloc(sizeof(__GLFBbufferInfo));
+ buf->other = (void *) bufferInfo;
+
+ pGC = CreateScratchGC(glxPriv->pDraw->pScreen,
+ glxPriv->pDraw->depth);
+ bufferInfo->pGC = pGC;
+ (*pGC->funcs->ChangeClip)(pGC, CT_NONE, NULL, 0);
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxfb.h b/nx-X11/programs/Xserver/GL/glx/glxfb.h
new file mode 100644
index 000000000..f414728f3
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxfb.h
@@ -0,0 +1,51 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxfb_h_
+#define _glxfb_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void __glXInitFB(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv,
+ GLint bits);
+
+extern GCPtr __glXFBGetGC(__GLdrawableBuffer *buf);
+
+extern GLboolean __glXFBMemSwapBuffers(__GLXdrawablePrivate *glxPriv);
+
+#endif /* _glxfb_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glximports.c b/nx-X11/programs/Xserver/GL/glx/glximports.c
new file mode 100644
index 000000000..fb4d508a9
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glximports.c
@@ -0,0 +1,186 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "glxserver.h"
+#include "glxcontext.h"
+#include "glximports.h"
+
+void *__glXImpMalloc(__GLcontext *gc, size_t size)
+{
+ void *addr;
+
+ if (size == 0) {
+ return NULL;
+ }
+ addr = malloc(size);
+ if (addr == NULL) {
+ /* XXX: handle out of memory error */
+ return NULL;
+ }
+ return addr;
+}
+
+void *__glXImpCalloc(__GLcontext *gc, size_t numElements, size_t elementSize)
+{
+ void *addr;
+ size_t size;
+
+ if ((numElements == 0) || (elementSize == 0)) {
+ return NULL;
+ }
+ size = numElements * elementSize;
+ addr = malloc(size);
+ if (addr == NULL) {
+ /* XXX: handle out of memory error */
+ return NULL;
+ }
+ /* zero out memory */
+ memset(addr, 0, size);
+
+ return addr;
+}
+
+void __glXImpFree(__GLcontext *gc, void *addr)
+{
+ if (addr) {
+ free(addr);
+ }
+}
+
+void *__glXImpRealloc(__GLcontext *gc, void *addr, size_t newSize)
+{
+ void *newAddr;
+
+ if (addr) {
+ if (newSize == 0) {
+ free(addr);
+ return NULL;
+ }
+ newAddr = realloc(addr, newSize);
+ } else {
+ if (newSize == 0) {
+ return NULL;
+ }
+ newAddr = malloc(newSize);
+ }
+ if (newAddr == NULL) {
+ return NULL; /* XXX: out of memory error */
+ }
+
+ return newAddr;
+}
+
+void __glXImpWarning(__GLcontext *gc, char *msg)
+{
+ ErrorF("%s",(char *)msg);
+}
+
+void __glXImpFatal(__GLcontext *gc, char *msg)
+{
+ ErrorF("%s",(char *)msg);
+ abort();
+}
+
+char *__glXImpGetenv(__GLcontext *gc, const char *var)
+{
+ return getenv(var);
+}
+
+int __glXImpAtoi(__GLcontext *gc, const char *str)
+{
+ return atoi(str);
+}
+
+int __glXImpSprintf(__GLcontext *gc, char *str, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ /* have to deal with var args */
+ va_start(ap, fmt);
+ ret = vsprintf(str, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+void *__glXImpFopen(__GLcontext *gc, const char *path, const char *mode)
+{
+ return (void *) fopen(path, mode);
+}
+
+int __glXImpFclose(__GLcontext *gc, void *stream)
+{
+ return fclose((FILE *)stream);
+}
+
+int __glXImpFprintf(__GLcontext *gc, void *stream, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ /* have to deal with var args */
+ va_start(ap, fmt);
+ ret = vfprintf((FILE *)stream, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+
+__GLdrawablePrivate *__glXImpGetDrawablePrivate(__GLcontext *gc)
+{
+ __GLinterface *glci = (__GLinterface *) gc;
+ __GLXcontext *glrc = (__GLXcontext *) glci->imports.other;
+
+ return &glrc->drawPriv->glPriv;
+}
+
+
+__GLdrawablePrivate *__glXImpGetReadablePrivate(__GLcontext *gc)
+{
+ __GLinterface *glci = (__GLinterface *) gc;
+ __GLXcontext *glrc = (__GLXcontext *) glci->imports.other;
+
+ return &glrc->readPriv->glPriv;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glximports.h b/nx-X11/programs/Xserver/GL/glx/glximports.h
new file mode 100644
index 000000000..f57004b34
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glximports.h
@@ -0,0 +1,65 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glximports_h_
+#define _glximports_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void *__glXImpMalloc(__GLcontext *gc, size_t size);
+extern void *__glXImpCalloc(__GLcontext *gc, size_t nElem, size_t eSize);
+extern void *__glXImpRealloc(__GLcontext *gc, void *addr, size_t newSize);
+extern void __glXImpFree(__GLcontext *gc, void *addr);
+
+extern void __glXImpWarning(__GLcontext *gc, char *msg);
+extern void __glXImpFatal(__GLcontext *gc, char *msg);
+
+extern char *__glXImpGetenv(__GLcontext *gc, const char *var);
+extern int __glXImpAtoi(__GLcontext *gc, const char *str);
+extern int __glXImpSprintf(__GLcontext *gc, char *str, const char *fmt, ...);
+extern void *__glXImpFopen(__GLcontext *gc, const char *path,
+ const char *mode);
+extern int __glXImpFclose(__GLcontext *gc, void *stream);
+extern int __glXImpFprintf(__GLcontext *gc, void *stream,
+ const char *fmt, ...);
+
+extern __GLdrawablePrivate *__glXImpGetDrawablePrivate(__GLcontext *gc);
+extern __GLdrawablePrivate *__glXImpGetReadablePrivate(__GLcontext *gc);
+
+
+#endif /* _glximports_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxmem.c b/nx-X11/programs/Xserver/GL/glx/glxmem.c
new file mode 100644
index 000000000..e1487da94
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxmem.c
@@ -0,0 +1,150 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+** Implementation of a buffer in main memory
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxmem.h"
+#include "glxext.h"
+#include "GL/internal/glcore.h"
+
+/* don't want to include glmath.h */
+extern GLuint __glFloorLog2(GLuint);
+
+/* ---------------------------------------------------------- */
+
+#define BUF_ALIGN 32 /* x86 cache alignment (used for assembly paths) */
+#define BUF_ALIGN_MASK (BUF_ALIGN-1)
+
+static GLboolean
+Resize(__GLdrawableBuffer *buf,
+ GLint x, GLint y, GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv, GLuint bufferMask)
+{
+ GLuint newSize;
+ void *ubase;
+ GLint pixelWidth;
+ GLint alignedWidth;
+
+ /*
+ ** Note:
+ ** buf->handle : unaligned base
+ ** buf->base : aligned base
+ */
+
+ pixelWidth = BUF_ALIGN / buf->elementSize;
+ alignedWidth = (width & ~(pixelWidth-1)) + pixelWidth;
+
+ newSize = alignedWidth * height * buf->elementSize;
+
+ /*
+ ** Only allocate buffer space for the SGI core.
+ ** Mesa and Aqua handle their own buffer allocations.
+ */
+#if defined(__GL_BUFFER_SIZE_TRACKS_WINDOW)
+ if (__glXCoreType() == GL_CORE_SGI) {
+#else
+ if (newSize > buf->size && __glXCoreType() == GL_CORE_SGI) {
+#endif
+ if (buf->handle) {
+ ubase = (*glPriv->realloc)(buf->handle, newSize + BUF_ALIGN_MASK);
+ if (ubase == NULL) {
+ return GL_FALSE;
+ }
+ } else {
+ ubase = (*glPriv->malloc)(newSize + BUF_ALIGN_MASK);
+ if (ubase == NULL) {
+ return GL_FALSE;
+ }
+ }
+ buf->size = newSize;
+
+ buf->handle = ubase;
+ buf->base = (void *)(((size_t)ubase + BUF_ALIGN_MASK) &
+ (unsigned int) ~BUF_ALIGN_MASK);
+ assert(((size_t)buf->base % BUF_ALIGN) == 0);
+ }
+
+ buf->width = width;
+ buf->height = height;
+ buf->byteWidth = alignedWidth * buf->elementSize;
+ buf->outerWidth = alignedWidth;
+
+ return GL_TRUE;
+}
+
+static void
+Lock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+static void
+Unlock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+static void
+Free(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+ if (buf->handle) {
+ (*glPriv->free)(buf->handle);
+ buf->handle = NULL;
+ }
+}
+
+
+void
+__glXInitMem(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv, GLint bits)
+{
+ buf->width = buf->height = 0; /* to be filled during Update */
+ buf->depth = bits;
+ buf->size = 0;
+ buf->handle = buf->base = NULL; /* to be filled during Update */
+ buf->byteWidth = 0;
+ buf->elementSize = ((bits - 1) / 8) + 1;
+ buf->elementSizeLog2 = __glFloorLog2(buf->elementSize);
+
+ buf->resize = Resize;
+ buf->lock = Lock;
+ buf->unlock = Unlock;
+ buf->fill = NULL;
+ buf->free = Free;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxmem.h b/nx-X11/programs/Xserver/GL/glx/glxmem.h
new file mode 100644
index 000000000..b4116dfa9
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxmem.h
@@ -0,0 +1,47 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxmem_h_
+#define _glxmem_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void __glXInitMem(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv,
+ GLint bits);
+
+#endif /* _glxmem_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxpix.c b/nx-X11/programs/Xserver/GL/glx/glxpix.c
new file mode 100644
index 000000000..81e29a9c5
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxpix.c
@@ -0,0 +1,131 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+** An implementation of a glx pixmap buffer
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxpix.h"
+
+#include <gcstruct.h>
+
+/* don't want to include glmath.h */
+extern GLuint __glFloorLog2(GLuint);
+
+typedef struct __GLPixBufferInfoRec {
+ GCPtr pGC;
+} __GLPixBufferInfo;
+
+/* ---------------------------------------------------------- */
+
+static GLboolean
+Resize(__GLdrawableBuffer *buf,
+ GLint x, GLint y, GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv, GLuint bufferMask)
+{
+ buf->width = width;
+ buf->height = width;
+ buf->byteWidth = width * buf->elementSize;
+ buf->outerWidth = width;
+
+ return GL_TRUE;
+}
+
+static void
+Lock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+static void
+Unlock(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+}
+
+static void
+Free(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv)
+{
+ __GLPixBufferInfo *bufferInfo;
+
+ if (LookupIDByType((XID)(long)buf->handle, __glXPixmapRes)) {
+ FreeResource((XID)(long)buf->handle, FALSE);
+ buf->handle = NULL;
+ }
+
+ bufferInfo = (__GLPixBufferInfo *) buf->other;
+
+ if (bufferInfo->pGC) {
+ FreeScratchGC(bufferInfo->pGC);
+ }
+
+ free(bufferInfo);
+ buf->other = NULL;
+}
+
+void
+__glXInitPix(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv,
+ GLint bits, XID glxpixmapId, __GLXpixmap *pGlxPixmap)
+{
+ __GLPixBufferInfo *bufferInfo;
+
+ buf->width = buf->height = 0; /* to be filled during Update */
+ buf->depth = bits;
+ buf->size = 0;
+ buf->base = NULL;
+ buf->byteWidth = 0;
+ buf->elementSize = ((bits-1) / 8) + 1;
+ buf->elementSizeLog2 = __glFloorLog2(buf->elementSize);
+
+ buf->handle = (void *)(long) glxpixmapId;
+ pGlxPixmap->refcnt++;
+
+ buf->resize = Resize;
+ buf->lock = Lock;
+ buf->unlock = Unlock;
+ buf->fill = NULL;
+ buf->free = Free;
+
+ /* allocate local information */
+ bufferInfo = (__GLPixBufferInfo *) malloc(sizeof(__GLPixBufferInfo));
+ buf->other = (void *) bufferInfo;
+
+ bufferInfo->pGC = CreateScratchGC(pGlxPixmap->pDraw->pScreen,
+ pGlxPixmap->pDraw->depth);
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxpix.h b/nx-X11/programs/Xserver/GL/glx/glxpix.h
new file mode 100644
index 000000000..285cf490c
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxpix.h
@@ -0,0 +1,47 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxpix_h_
+#define _glxpix_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void __glXInitPix(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv,
+ GLint bits, XID glxpixmapId, __GLXpixmap *pGlxPixmap);
+
+#endif /* _glxpix_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxscreens.c b/nx-X11/programs/Xserver/GL/glx/glxscreens.c
new file mode 100644
index 000000000..1bff4bc3a
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxscreens.c
@@ -0,0 +1,373 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include <signal.h>
+
+#include <windowstr.h>
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxext.h"
+
+const char GLServerVersion[] = "1.2";
+static const char GLServerExtensions[] =
+ "GL_ARB_depth_texture "
+ "GL_ARB_imaging "
+ "GL_ARB_multitexture "
+ "GL_ARB_point_parameters "
+ "GL_ARB_point_sprite "
+ "GL_ARB_shadow "
+ "GL_ARB_shadow_ambient "
+ "GL_ARB_texture_border_clamp "
+ "GL_ARB_texture_cube_map "
+ "GL_ARB_texture_env_add "
+ "GL_ARB_texture_env_combine "
+ "GL_ARB_texture_env_crossbar "
+ "GL_ARB_texture_env_dot3 "
+ "GL_ARB_texture_mirrored_repeat "
+ "GL_ARB_transpose_matrix "
+ "GL_ARB_window_pos "
+ "GL_EXT_abgr "
+ "GL_EXT_bgra "
+ "GL_EXT_blend_color "
+ "GL_EXT_blend_func_separate "
+ "GL_EXT_blend_logic_op "
+ "GL_EXT_blend_minmax "
+ "GL_EXT_blend_subtract "
+ "GL_EXT_clip_volume_hint "
+ "GL_EXT_copy_texture "
+ "GL_EXT_draw_range_elements "
+ "GL_EXT_fog_coord "
+ "GL_EXT_multi_draw_arrays "
+ "GL_EXT_packed_pixels "
+ "GL_EXT_polygon_offset "
+ "GL_EXT_rescale_normal "
+ "GL_EXT_secondary_color "
+ "GL_EXT_separate_specular_color "
+ "GL_EXT_shadow_funcs "
+ "GL_EXT_stencil_two_side "
+ "GL_EXT_stencil_wrap "
+ "GL_EXT_subtexture "
+ "GL_EXT_texture "
+ "GL_EXT_texture3D "
+ "GL_EXT_texture_edge_clamp "
+ "GL_EXT_texture_env_add "
+ "GL_EXT_texture_env_combine "
+ "GL_EXT_texture_env_dot3 "
+ "GL_EXT_texture_lod "
+ "GL_EXT_texture_lod_bias "
+ "GL_EXT_texture_object "
+ "GL_EXT_texture_rectangle "
+ "GL_EXT_vertex_array "
+ "GL_APPLE_packed_pixels "
+ "GL_ATI_texture_mirror_once "
+ "GL_ATI_texture_env_combine3 "
+ "GL_HP_occlusion_test "
+ "GL_IBM_texture_mirrored_repeat "
+ "GL_MESA_pack_invert "
+ "GL_MESA_ycbcr_texture "
+ "GL_NV_blend_square "
+ "GL_NV_point_sprite "
+ "GL_NV_texgen_reflection "
+ "GL_NV_texture_rectangle "
+ "GL_SGIS_generate_mipmap "
+ "GL_SGIS_texture_border_clamp "
+ "GL_SGIS_texture_edge_clamp "
+ "GL_SGIS_texture_lod "
+ "GL_SGIX_depth_texture "
+ "GL_SGIX_shadow "
+ "GL_SGIX_shadow_ambient "
+ ;
+
+/*
+** We have made the simplifying assuption that the same extensions are
+** supported across all screens in a multi-screen system.
+*/
+static char GLXServerVendorName[] = "SGI";
+static char GLXServerVersion[] = "1.2";
+static char GLXServerExtensions[] =
+ "GLX_ARB_multisample "
+ "GLX_EXT_visual_info "
+ "GLX_EXT_visual_rating "
+ "GLX_EXT_import_context "
+ "GLX_OML_swap_method "
+ "GLX_SGI_make_current_read "
+#ifndef __DARWIN__
+ "GLX_SGIS_multisample "
+ "GLX_SGIX_hyperpipe "
+ "GLX_SGIX_swap_barrier "
+#endif
+ "GLX_SGIX_fbconfig "
+ ;
+
+/*
+ * __glDDXScreenInfo comes from GLcore, so we can't resolve this symbol at
+ * module open time. Leave a placeholder, and fill this in when we first
+ * need it (in __glXScreenInit). XXX Why make this an array?
+ */
+static __GLXscreenInfo *__glXScreens[] = {
+ NULL /* &__glDDXScreenInfo */ ,
+};
+
+static GLint __glXNumStaticScreens =
+ (sizeof __glXScreens / sizeof __glXScreens[0]);
+
+__GLXscreenInfo *__glXActiveScreens;
+GLint __glXNumActiveScreens;
+
+__GLXSwapBarrierExtensionFuncs *__glXSwapBarrierFuncs = NULL;
+static int __glXNumSwapBarrierFuncs = 0;
+__GLXHyperpipeExtensionFuncs *__glXHyperpipeFuncs = NULL;
+static int __glXNumHyperpipeFuncs = 0;
+
+
+RESTYPE __glXDrawableRes;
+
+__GLXscreenInfo *__glXgetActiveScreen(int num) {
+ return &__glXActiveScreens[num];
+}
+
+/*
+** Destroy routine that gets called when a drawable is freed. A drawable
+** contains the ancillary buffers needed for rendering.
+*/
+static Bool DrawableGone(__GLXdrawablePrivate *glxPriv, XID xid)
+{
+ __GLXcontext *cx, *cx1;
+
+ /*
+ ** Use glxPriv->type to figure out what kind of drawable this is. Don't
+ ** use glxPriv->pDraw->type because by the time this routine is called,
+ ** the pDraw might already have been freed.
+ */
+ if (glxPriv->type == DRAWABLE_WINDOW) {
+ /*
+ ** When a window is destroyed, notify all context bound to
+ ** it, that there are no longer bound to anything.
+ */
+ for (cx = glxPriv->drawGlxc; cx; cx = cx1) {
+ cx1 = cx->nextDrawPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
+ }
+
+ for (cx = glxPriv->readGlxc; cx; cx = cx1) {
+ cx1 = cx->nextReadPriv;
+ cx->pendingState |= __GLX_PENDING_DESTROY;
+ }
+ }
+
+ /*
+ ** set the size to 0, so that context that may still be using this
+ ** drawable not do anything harmful
+ */
+ glxPriv->xorigin = 0;
+ glxPriv->yorigin = 0;
+ glxPriv->width = 0;
+ glxPriv->height = 0;
+
+ __glXUnrefDrawablePrivate(glxPriv);
+
+ return True;
+}
+
+/*
+** This hook gets called when a window moves or changes size.
+*/
+static Bool PositionWindow(WindowPtr pWin, int x, int y)
+{
+ ScreenPtr pScreen;
+ __GLXcontext *glxc;
+ __GLXdrawablePrivate *glxPriv;
+ Bool ret;
+
+ /*
+ ** Call wrapped position window routine
+ */
+ pScreen = pWin->drawable.pScreen;
+ pScreen->PositionWindow =
+ __glXActiveScreens[pScreen->myNum].WrappedPositionWindow;
+ ret = (*pScreen->PositionWindow)(pWin, x, y);
+ pScreen->PositionWindow = PositionWindow;
+
+ /*
+ ** Tell all contexts rendering into this window that the window size
+ ** has changed.
+ */
+ glxPriv = (__GLXdrawablePrivate *) LookupIDByType(pWin->drawable.id,
+ __glXDrawableRes);
+ if (glxPriv == NULL) {
+ /*
+ ** This window is not being used by the OpenGL.
+ */
+ return ret;
+ }
+
+ /*
+ ** resize the drawable
+ */
+ /* first change the drawable size */
+ if (__glXResizeDrawableBuffers(glxPriv) == GL_FALSE) {
+ /* resize failed! */
+ /* XXX: what can we possibly do here? */
+ ret = False;
+ }
+
+ /* mark contexts as needing resize */
+
+ for (glxc = glxPriv->drawGlxc; glxc; glxc = glxc->nextDrawPriv) {
+ glxc->pendingState |= __GLX_PENDING_RESIZE;
+ }
+
+ for (glxc = glxPriv->readGlxc; glxc; glxc = glxc->nextReadPriv) {
+ glxc->pendingState |= __GLX_PENDING_RESIZE;
+ }
+
+ return ret;
+}
+
+/*
+** Wrap our own PositionWindow routine around the server's, so we can
+** be notified when a window changes size
+*/
+static void wrapPositionWindow(int screen)
+{
+ ScreenPtr pScreen = screenInfo.screens[screen];
+
+ __glXActiveScreens[screen].WrappedPositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = PositionWindow;
+}
+
+/*
+ * If your DDX driver wants to register support for swap barriers or hyperpipe
+ * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit()
+ * with a dispatch table of functions to handle the requests. In the XFree86
+ * DDX, for example, you would call these near the bottom of the driver's
+ * ScreenInit method, after DRI has been initialized.
+ *
+ * This should be replaced with a better method when we teach the server how
+ * to load DRI drivers.
+ */
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
+{
+ if (__glXNumHyperpipeFuncs < screen + 1) {
+ __glXHyperpipeFuncs = realloc(__glXHyperpipeFuncs,
+ (screen+1) * sizeof(__GLXHyperpipeExtensionFuncs));
+ __glXNumHyperpipeFuncs = screen + 1;
+ }
+
+ __glXHyperpipeFuncs[screen].queryHyperpipeNetworkFunc =
+ *funcs->queryHyperpipeNetworkFunc;
+ __glXHyperpipeFuncs[screen].queryHyperpipeConfigFunc =
+ *funcs->queryHyperpipeConfigFunc;
+ __glXHyperpipeFuncs[screen].destroyHyperpipeConfigFunc =
+ *funcs->destroyHyperpipeConfigFunc;
+ __glXHyperpipeFuncs[screen].hyperpipeConfigFunc =
+ *funcs->hyperpipeConfigFunc;
+}
+
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
+{
+ if (__glXNumSwapBarrierFuncs < screen + 1) {
+ __glXSwapBarrierFuncs = realloc(__glXSwapBarrierFuncs,
+ (screen+1) * sizeof(__GLXSwapBarrierExtensionFuncs));
+ __glXNumSwapBarrierFuncs = screen + 1;
+ }
+
+ __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc =
+ funcs->bindSwapBarrierFunc;
+ __glXSwapBarrierFuncs[screen].queryMaxSwapBarriersFunc =
+ funcs->queryMaxSwapBarriersFunc;
+}
+
+void __glXScreenInit(GLint numscreens)
+{
+ GLint i,j;
+
+ __glXScreens[0] = __glXglDDXScreenInfo(); /* from GLcore */
+
+ /*
+ ** This alloc has to work or else the server might as well core dump.
+ */
+ __glXActiveScreens =
+ (__GLXscreenInfo *) malloc(sizeof(__GLXscreenInfo) * numscreens);
+
+ for (i=0; i < numscreens; i++) {
+ /*
+ ** Probe each static screen to see which exists.
+ */
+ for (j=0; j < __glXNumStaticScreens; j++) {
+ if ((*__glXScreens[j]->screenProbe)(i)) {
+ __glXActiveScreens[i] = *__glXScreens[j];
+
+ __glXActiveScreens[i].numUsableVisuals = __glXActiveScreens[i].numVisuals;
+ __glXActiveScreens[i].GLextensions = strdup(GLServerExtensions);
+ __glXActiveScreens[i].GLXvendor = strdup(GLXServerVendorName);
+ __glXActiveScreens[i].GLXversion = strdup(GLXServerVersion);
+ __glXActiveScreens[i].GLXextensions = strdup(GLXServerExtensions);
+
+ __glXDrawableRes = CreateNewResourceType((DeleteType)DrawableGone);
+ wrapPositionWindow(i);
+ }
+ }
+ }
+ __glXNumActiveScreens = numscreens;
+}
+
+void __glXScreenReset(void)
+{
+ int i;
+
+ for (i = 0; i < __glXNumActiveScreens; i++) {
+ free(__glXActiveScreens[i].GLXvendor);
+ free(__glXActiveScreens[i].GLXversion);
+ free(__glXActiveScreens[i].GLXextensions);
+ free(__glXActiveScreens[i].GLextensions);
+ }
+ free(__glXActiveScreens);
+ free(__glXHyperpipeFuncs);
+ free(__glXSwapBarrierFuncs);
+ __glXNumHyperpipeFuncs = 0;
+ __glXNumSwapBarrierFuncs = 0;
+ __glXHyperpipeFuncs = NULL;
+ __glXSwapBarrierFuncs = NULL;
+ __glXActiveScreens = NULL;
+ __glXNumActiveScreens = 0;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/glxscreens.h b/nx-X11/programs/Xserver/GL/glx/glxscreens.h
new file mode 100644
index 000000000..dae21e9c9
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxscreens.h
@@ -0,0 +1,102 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_screens_h_
+#define _GLX_screens_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/* XXX: should be defined somewhere globally */
+#define CAPI
+
+#include "GL/internal/glcore.h"
+
+/*
+** Screen dependent data. These methods are the interface between the DIX
+** and DDX layers of the GLX server extension. The methods provide an
+** interface for context management on a screen.
+*/
+typedef struct {
+ /*
+ ** Probe the screen and see if it supports GL rendering. It will
+ ** return GL_FALSE if it doesn't, GL_TRUE otherwise.
+ */
+ Bool (*screenProbe)(int screen);
+
+ /*
+ ** Create a context using configuration information from modes.
+ ** Use imports as callbacks back to the OS. Return an opaque handle
+ ** on the context (NULL if failure).
+ */
+ __GLinterface *(*createContext)(__GLimports *imports,
+ __GLcontextModes *modes,
+ __GLinterface *shareGC);
+
+ /*
+ ** Create a buffer using information from glxPriv. This routine
+ ** sets up any wrappers necessary to resize, swap or destroy the
+ ** buffer.
+ */
+ void (*createBuffer)(__GLXdrawablePrivate *glxPriv);
+
+ /**
+ * Linked list of valid context modes for this screen.
+ */
+ __GLcontextModes *modes;
+
+ void **pVisualPriv;
+ GLint numVisuals;
+ GLint numUsableVisuals;
+
+ char *GLextensions;
+
+ char *GLXvendor;
+ char *GLXversion;
+ char *GLXextensions;
+
+ /*
+ ** Things that are not statically set.
+ */
+ Bool (*WrappedPositionWindow)(WindowPtr pWin, int x, int y);
+
+} __GLXscreenInfo;
+
+
+extern void __glXScreenInit(GLint);
+extern void __glXScreenReset(void);
+
+#endif /* !__GLX_screens_h__ */
diff --git a/nx-X11/programs/Xserver/GL/glx/glxserver.h b/nx-X11/programs/Xserver/GL/glx/glxserver.h
new file mode 100644
index 000000000..2debc8435
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxserver.h
@@ -0,0 +1,326 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_server_h_
+#define _GLX_server_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xmd.h>
+#include <misc.h>
+#include <dixstruct.h>
+#include <pixmapstr.h>
+#include <gcstruct.h>
+#include <extnsionst.h>
+#include <resource.h>
+#include <scrnintstr.h>
+#include "protocol-versions.h"
+
+#include <limits.h>
+/*
+** The X header misc.h defines these math functions.
+*/
+#undef abs
+#undef fabs
+
+#define GL_GLEXT_PROTOTYPES /* we want prototypes */
+#include <GL/gl.h>
+#include <GL/glxproto.h>
+#include <GL/glxint.h>
+
+/* For glxscreens.h */
+typedef struct __GLXdrawablePrivateRec __GLXdrawablePrivate;
+
+#include "glxscreens.h"
+#include "glxdrawable.h"
+#include "glxcontext.h"
+#include "glxerror.h"
+
+
+#define GLX_SERVER_MAJOR_VERSION SERVER_GLX_MAJOR_VERSION
+#define GLX_SERVER_MINOR_VERSION SERVER_GLX_MINOR_VERSION
+
+#ifndef True
+#define True 1
+#endif
+#ifndef False
+#define False 0
+#endif
+
+/*
+** GLX resources.
+*/
+typedef XID GLXContextID;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+
+typedef struct __GLXcontextRec *GLXContext;
+typedef struct __GLXclientStateRec __GLXclientState;
+
+extern __GLXscreenInfo *__glXActiveScreens;
+extern GLint __glXNumActiveScreens;
+extern __GLXscreenInfo *__glXgetActiveScreen(int num);
+
+/************************************************************************/
+
+/*
+** The last context used (from the server's persective) is cached.
+*/
+extern __GLXcontext *__glXLastContext;
+extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*);
+
+/*
+** Macros to set, unset, and retrieve the flag that says whether a context
+** has unflushed commands.
+*/
+#define __GLX_NOTE_UNFLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_TRUE
+#define __GLX_NOTE_FLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_FALSE
+#define __GLX_HAS_UNFLUSHED_CMDS(glxc) (glxc->hasUnflushedCommands)
+
+/************************************************************************/
+
+/*
+** State kept per client.
+*/
+struct __GLXclientStateRec {
+ /*
+ ** Whether this structure is currently being used to support a client.
+ */
+ Bool inUse;
+
+ /*
+ ** Buffer for returned data.
+ */
+ GLbyte *returnBuf;
+ GLint returnBufSize;
+
+ /*
+ ** Keep track of large rendering commands, which span multiple requests.
+ */
+ GLint largeCmdBytesSoFar; /* bytes received so far */
+ GLint largeCmdBytesTotal; /* total bytes expected */
+ GLint largeCmdRequestsSoFar; /* requests received so far */
+ GLint largeCmdRequestsTotal; /* total requests expected */
+ GLbyte *largeCmdBuf;
+ GLint largeCmdBufSize;
+
+ /*
+ ** Keep a list of all the contexts that are current for this client's
+ ** threads.
+ */
+ __GLXcontext **currentContexts;
+ GLint numCurrentContexts;
+
+ /* Back pointer to X client record */
+ ClientPtr client;
+
+ int GLClientmajorVersion;
+ int GLClientminorVersion;
+ char *GLClientextensions;
+};
+
+extern __GLXclientState *__glXClients[];
+
+/************************************************************************/
+
+/*
+** Dispatch tables.
+*/
+typedef void (*__GLXdispatchRenderProcPtr)(GLbyte *);
+typedef int (*__GLXdispatchSingleProcPtr)(__GLXclientState *, GLbyte *);
+typedef int (*__GLXdispatchVendorPrivProcPtr)(__GLXclientState *, GLbyte *);
+
+/*
+ * Dispatch for GLX commands.
+ */
+typedef int (*__GLXprocPtr)(__GLXclientState *, char *pc);
+extern __GLXprocPtr __glXProcTable[];
+
+/*
+ * Tables for computing the size of each rendering command.
+ */
+typedef struct {
+ int bytes;
+ int (*varsize)(GLbyte *pc, Bool swap, int left);
+} __GLXrenderSizeData;
+extern __GLXrenderSizeData __glXRenderSizeTable[];
+extern __GLXrenderSizeData __glXRenderSizeTable_EXT[];
+
+/************************************************************************/
+
+/*
+** X resources.
+*/
+extern RESTYPE __glXContextRes;
+extern RESTYPE __glXClientRes;
+extern RESTYPE __glXPixmapRes;
+extern RESTYPE __glXDrawableRes;
+
+/************************************************************************/
+
+/*
+** Prototypes.
+*/
+
+extern char *__glXcombine_strings(const char *, const char *);
+
+/*
+** Routines for sending swapped replies.
+*/
+
+extern void __glXSwapMakeCurrentReply(ClientPtr client,
+ xGLXMakeCurrentReply *reply);
+extern void __glXSwapIsDirectReply(ClientPtr client,
+ xGLXIsDirectReply *reply);
+extern void __glXSwapQueryVersionReply(ClientPtr client,
+ xGLXQueryVersionReply *reply);
+extern void __glXSwapQueryContextInfoEXTReply(ClientPtr client,
+ xGLXQueryContextInfoEXTReply *reply,
+ int *buf);
+extern void glxSwapQueryExtensionsStringReply(ClientPtr client,
+ xGLXQueryExtensionsStringReply *reply, char *buf);
+extern void glxSwapQueryServerStringReply(ClientPtr client,
+ xGLXQueryServerStringReply *reply, char *buf);
+
+
+/*
+ * Routines for computing the size of variably-sized rendering commands.
+ */
+static __inline__ int
+safe_add(int a, int b)
+{
+ if (a < 0 || b < 0)
+ return -1;
+
+ if (INT_MAX - a < b)
+ return -1;
+
+ return a + b;
+}
+
+static __inline__ int
+safe_mul(int a, int b)
+{
+ if (a < 0 || b < 0)
+ return -1;
+
+ if (a == 0 || b == 0)
+ return 0;
+
+ if (a > INT_MAX / b)
+ return -1;
+
+ return a * b;
+}
+
+static __inline__ int
+safe_pad(int a)
+{
+ int ret;
+
+ if (a < 0)
+ return -1;
+
+ if ((ret = safe_add(a, 3)) < 0)
+ return -1;
+
+ return ret & (GLuint)~3;
+}
+
+extern int __glXTypeSize(GLenum enm);
+extern int __glXImageSize(GLenum format, GLenum type,
+ GLenum target, GLsizei w, GLsizei h, GLsizei d,
+ GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows,
+ GLint alignment);
+
+extern int __glXCallListsReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXBitmapReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXFogfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXFogivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXLightfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXLightivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXLightModelfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXLightModelivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMaterialfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMaterialivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexParameterivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexImage1DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexImage2DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexEnvfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexEnvivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexGendvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexGenfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexGenivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMap1dReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMap1fReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMap2dReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXMap2fReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXPixelMapfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXPixelMapuivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXPixelMapusvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXDrawPixelsReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXDrawArraysSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXPrioritizeTexturesReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexSubImage1DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexSubImage2DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXTexImage3DReqSize(GLbyte *pc, Bool swap, int reqlen );
+extern int __glXTexSubImage3DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXConvolutionFilter1DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXConvolutionFilter2DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXConvolutionParameterivReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXConvolutionParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXSeparableFilter2DReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXColorTableReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXColorSubTableReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXColorTableParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXColorTableParameterivReqSize(GLbyte *pc, Bool swap, int reqlen);
+
+/*
+ * Routines for computing the size of returned data.
+ */
+extern int __glXConvolutionParameterivSize(GLenum pname);
+extern int __glXConvolutionParameterfvSize(GLenum pname);
+extern int __glXColorTableParameterfvSize(GLenum pname);
+extern int __glXColorTableParameterivSize(GLenum pname);
+
+extern int __glXPointParameterfvARBReqSize(GLbyte *pc, Bool swap, int reqlen);
+extern int __glXPointParameterivReqSize(GLbyte *pc, Bool swap, int reqlen);
+
+#endif /* !__GLX_server_h__ */
diff --git a/nx-X11/programs/Xserver/GL/glx/glxutil.c b/nx-X11/programs/Xserver/GL/glx/glxutil.c
new file mode 100644
index 000000000..b4cd10a84
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxutil.c
@@ -0,0 +1,433 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#define FONT_PCF
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "glxserver.h"
+#include <GL/glxtokens.h>
+#include <unpack.h>
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "glxutil.h"
+#include "glxbuf.h"
+#include "GL/internal/glcore.h"
+#include "GL/glxint.h"
+#include "glcontextmodes.h"
+
+/************************************************************************/
+
+void __glXNop(void) {}
+
+/************************************************************************/
+
+/* Context stuff */
+
+/*
+** associate a context with a drawable
+*/
+void
+__glXAssociateContext(__GLXcontext *glxc)
+{
+ glxc->nextDrawPriv = glxc->drawPriv->drawGlxc;
+ glxc->drawPriv->drawGlxc = glxc;
+
+ __glXRefDrawablePrivate(glxc->drawPriv);
+
+
+ glxc->nextReadPriv = glxc->readPriv->readGlxc;
+ glxc->readPriv->readGlxc = glxc;
+
+ __glXRefDrawablePrivate(glxc->readPriv);
+}
+
+/*
+** Deassociate a context from a drawable
+*/
+void
+__glXDeassociateContext(__GLXcontext *glxc)
+{
+ __GLXcontext *curr, *prev;
+
+ prev = NULL;
+ for ( curr = glxc->drawPriv->drawGlxc
+ ; curr != NULL
+ ; prev = curr, curr = curr->nextDrawPriv ) {
+ if (curr == glxc) {
+ /* found context. Deassociate. */
+ if (prev == NULL) {
+ glxc->drawPriv->drawGlxc = curr->nextDrawPriv;
+ } else {
+ prev->nextDrawPriv = curr->nextDrawPriv;
+ }
+ curr->nextDrawPriv = NULL;
+ __glXUnrefDrawablePrivate(glxc->drawPriv);
+ break;
+ }
+ }
+
+
+ prev = NULL;
+ for ( curr = glxc->readPriv->readGlxc
+ ; curr != NULL
+ ; prev = curr, curr = curr->nextReadPriv ) {
+ if (curr == glxc) {
+ /* found context. Deassociate. */
+ if (prev == NULL) {
+ glxc->readPriv->readGlxc = curr->nextReadPriv;
+ } else {
+ prev->nextReadPriv = curr->nextReadPriv;
+ }
+ curr->nextReadPriv = NULL;
+ __glXUnrefDrawablePrivate(glxc->readPriv);
+ break;
+ }
+ }
+}
+
+/************************************************************************/
+
+void
+__glXGetDrawableSize(__GLdrawablePrivate *glPriv,
+ GLint *x, GLint *y, GLuint *width, GLuint *height)
+{
+ __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
+
+ if (glxPriv) {
+ *x = glxPriv->xorigin;
+ *y = glxPriv->yorigin;
+ *width = glxPriv->width;
+ *height = glxPriv->height;
+ } else {
+ *x = *y = *width = *height = 0;
+ }
+}
+
+GLboolean
+__glXResizeDrawable(__GLdrawablePrivate *glPriv)
+{
+ /* nothing to be done here */
+ return GL_TRUE;
+}
+
+
+/*****************************************************************************/
+/* accessing the drawable private */
+
+static void
+LockDP(__GLdrawablePrivate *glPriv, __GLcontext *gc)
+{
+ __GLinterface *glci = (__GLinterface *) gc;
+ __GLXcontext *glxc = (__GLXcontext *) glci->imports.other;
+
+ /* quick exit test */
+ if ((glxc->pendingState &
+ (__GLX_PENDING_RESIZE |
+ __GLX_PENDING_DESTROY |
+ __GLX_PENDING_SWAP)) == 0x0)
+ return;
+
+ /* some pending state. Deal with it */
+ if (glxc->pendingState & __GLX_PENDING_RESIZE) {
+ glxc->pendingState &= ~__GLX_PENDING_RESIZE;
+
+ (*glci->exports.notifyResize)(gc);
+ assert((glxc->pendingState & __GLX_PENDING_RESIZE) == 0x0);
+ }
+ if (glxc->pendingState & __GLX_PENDING_DESTROY) {
+ glxc->pendingState &= ~__GLX_PENDING_DESTROY;
+
+ assert(glxc->drawPriv->xorigin == 0);
+ assert(glxc->drawPriv->yorigin == 0);
+ assert(glxc->drawPriv->width == 0);
+ assert(glxc->drawPriv->height == 0);
+ assert(glxc->readPriv->xorigin == 0);
+ assert(glxc->readPriv->yorigin == 0);
+ assert(glxc->readPriv->width == 0);
+ assert(glxc->readPriv->height == 0);
+ (*glci->exports.notifyDestroy)(gc);
+ __glXDeassociateContext(glxc);
+ assert((glxc->pendingState & __GLX_PENDING_DESTROY) == 0x0);
+ }
+ if (glxc->pendingState & __GLX_PENDING_SWAP) {
+
+ glxc->pendingState &= ~__GLX_PENDING_SWAP;
+
+ (*glci->exports.notifySwapBuffers)(gc);
+ assert((glxc->pendingState & __GLX_PENDING_SWAP) == 0x0);
+ }
+}
+
+static void
+UnlockDP(__GLdrawablePrivate *glPriv)
+{
+}
+
+/*****************************************************************************/
+/* Drawable private stuff */
+
+void
+__glXRefDrawablePrivate(__GLXdrawablePrivate *glxPriv)
+{
+ glxPriv->refCount++;
+}
+
+void
+__glXUnrefDrawablePrivate(__GLXdrawablePrivate *glxPriv)
+{
+ glxPriv->refCount--;
+ if (glxPriv->refCount == 0) {
+ __glXDestroyDrawablePrivate(glxPriv);
+ }
+}
+
+__GLXdrawablePrivate *
+__glXCreateDrawablePrivate(DrawablePtr pDraw, XID drawId,
+ __GLcontextModes *modes)
+{
+ __GLXdrawablePrivate *glxPriv;
+ __GLdrawablePrivate *glPriv;
+ __GLXscreenInfo *pGlxScreen;
+
+ glxPriv = (__GLXdrawablePrivate *) malloc(sizeof(*glxPriv));
+ memset(glxPriv, 0, sizeof(__GLXdrawablePrivate));
+
+ glxPriv->type = pDraw->type;
+ glxPriv->pDraw = pDraw;
+ glxPriv->drawId = drawId;
+
+ /* if not a pixmap, lookup will fail, so pGlxPixmap will be NULL */
+ glxPriv->pGlxPixmap = (__GLXpixmap *)
+ LookupIDByType(drawId, __glXPixmapRes);
+ /* since we are creating the drawablePrivate, drawId should be new */
+ if (!AddResource(drawId, __glXDrawableRes, glxPriv)) {
+ /* oops! */
+ free(glxPriv);
+ return NULL;
+ }
+
+ /* fill up glPriv */
+ glPriv = &glxPriv->glPriv;
+ glPriv->modes = (__GLcontextModes *) malloc(sizeof(__GLcontextModes));
+ *glPriv->modes = *modes;
+ glPriv->malloc = malloc;
+ glPriv->calloc = calloc;
+ glPriv->realloc = realloc;
+ glPriv->free = free;
+ glPriv->addSwapRect = NULL;
+ glPriv->setClipRect = (void (*)(__GLdrawablePrivate *, GLint, GLint, GLsizei, GLsizei)) __glXNop;
+ glPriv->lockDP = LockDP;
+ glPriv->unlockDP = UnlockDP;
+ glPriv->getDrawableSize = __glXGetDrawableSize;
+ glPriv->resize = __glXResizeDrawable;
+ glPriv->other = glxPriv;
+
+ /* allocate a one-rect ownership region */
+ glPriv->ownershipRegion.rects =
+ (__GLregionRect *)calloc(1, sizeof(__GLregionRect));
+ glPriv->ownershipRegion.numRects = 1;
+
+ glxPriv->freeBuffers = __glXFreeBuffers;
+ glxPriv->updatePalette = (void (*)(__GLXdrawablePrivate *)) __glXNop;
+
+ pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum];
+
+ if (glxPriv->type == DRAWABLE_WINDOW) {
+ VisualID vid = wVisual((WindowPtr)pDraw);
+
+ glxPriv->modes = _gl_context_modes_find_visual( pGlxScreen->modes, vid );
+ __glXFBInitDrawable(glxPriv, modes);
+ } else {
+ glxPriv->modes = glxPriv->pGlxPixmap->modes;
+ __glXPixInitDrawable(glxPriv, modes);
+ }
+
+ /* initialize the core's private buffer information */
+ (*pGlxScreen->createBuffer)(glxPriv);
+
+ return glxPriv;
+}
+
+GLboolean
+__glXDestroyDrawablePrivate(__GLXdrawablePrivate *glxPriv)
+{
+ __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+
+ /* remove the drawable from the drawable list */
+ FreeResourceByType(glxPriv->drawId, __glXDrawableRes, FALSE);
+
+ /* Have the core free any memory it may have attached to the drawable */
+ if (glPriv->freePrivate) {
+ (*glPriv->freePrivate)(glPriv);
+ }
+
+ /* Free any framebuffer memory attached to the drawable */
+ if (glxPriv->freeBuffers) {
+ (*glxPriv->freeBuffers)(glxPriv);
+ }
+
+ /* Free the drawable Private */
+ free(glxPriv->glPriv.modes);
+ free(glxPriv->glPriv.ownershipRegion.rects);
+ free(glxPriv);
+
+ return GL_TRUE;
+}
+
+__GLXdrawablePrivate *
+__glXFindDrawablePrivate(XID drawId)
+{
+ __GLXdrawablePrivate *glxPriv;
+
+ glxPriv = (__GLXdrawablePrivate *)LookupIDByType(drawId, __glXDrawableRes);
+
+ return glxPriv;
+}
+
+__GLXdrawablePrivate *
+__glXGetDrawablePrivate(DrawablePtr pDraw, XID drawId,
+ __GLcontextModes *modes)
+{
+ __GLXdrawablePrivate *glxPriv;
+
+ glxPriv = __glXFindDrawablePrivate(drawId);
+
+ if (glxPriv == NULL) {
+ glxPriv = __glXCreateDrawablePrivate(pDraw, drawId, modes);
+ if (glxPriv) {
+ __glXRefDrawablePrivate(glxPriv);
+ }
+ }
+
+ return glxPriv;
+}
+
+void
+__glXCacheDrawableSize(__GLXdrawablePrivate *glxPriv)
+{
+ if (glxPriv) {
+ if (glxPriv->pDraw) {
+ glxPriv->xorigin = glxPriv->pDraw->x;
+ glxPriv->yorigin = glxPriv->pDraw->y;
+ glxPriv->width = glxPriv->pDraw->width;
+ glxPriv->height = glxPriv->pDraw->height;
+ }
+ }
+}
+
+/*
+** resize/move the drawable. Called during the actual resize callback
+** to update the drawable side of the buffers
+*/
+GLboolean
+__glXResizeDrawableBuffers(__GLXdrawablePrivate *glxPriv)
+{
+ __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+ GLint x, y;
+ GLuint w, h;
+#if defined(__GL_ALIGNED_BUFFERS)
+ GLint xAlignment, yAlignment;
+ GLint xOffset, yOffset;
+ GLint xStart, xEnd;
+ GLint yStart, yEnd;
+ GLuint xAlignedMask, yAlignedMask;
+#endif
+ GLboolean status = GL_TRUE;
+
+ __glXCacheDrawableSize(glxPriv);
+
+ w = glxPriv->width;
+ h = glxPriv->height;
+ x = glxPriv->xorigin;
+ y = glxPriv->yorigin;
+
+#if defined(__GL_ALIGNED_BUFFERS)
+ xAlignment = glPriv->xAlignment;
+ yAlignment = glPriv->yAlignment;
+
+ xOffset = x & (xAlignment-1);
+ yOffset = y & (yAlignment-1);
+
+ xAlignedMask = ~(xAlignment-1);
+ yAlignedMask = ~(yAlignment-1);
+
+ xStart = x; xEnd = x+w;
+ yStart = y; yEnd = y+h;
+
+ xStart &= xAlignedMask;
+ if (xEnd & ~xAlignedMask) {
+ xEnd = (xEnd&xAlignedMask) + xAlignment;
+ }
+ yStart &= yAlignedMask;
+ if (yEnd & ~yAlignedMask) {
+ yEnd = (yEnd&yAlignedMask) + yAlignment;
+ }
+
+ x = xStart; y = yStart;
+ w = xEnd-xStart; h = yEnd-yStart;
+#endif
+
+ if ((x != glPriv->xOrigin) ||
+ (y != glPriv->yOrigin) ||
+#if defined(__GL_ALIGNED_BUFFERS)
+ (xOffset != glPriv->xOffset) ||
+ (yOffset != glPriv->yOffset) ||
+#endif
+ (w != glPriv->width) ||
+ (h != glPriv->height) ||
+ (!w && !h)) {
+ /* set up the glPriv info */
+ glPriv->width = w;
+ glPriv->height = h;
+ glPriv->xOrigin = x;
+ glPriv->yOrigin = y;
+#if defined(__GL_ALIGNED_BUFFERS)
+ glPriv->xOffset = xOffset;
+ glPriv->yOffset = yOffset;
+#endif
+
+ /* notify the buffers */
+ status = __glXResizeBuffers(glPriv, x, y, w, h);
+ }
+
+ return status;
+}
+
+/************************************************************************/
+
diff --git a/nx-X11/programs/Xserver/GL/glx/glxutil.h b/nx-X11/programs/Xserver/GL/glx/glxutil.h
new file mode 100644
index 000000000..a0a2e57b7
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/glxutil.h
@@ -0,0 +1,77 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _glxcmds_h_
+#define _glxcmds_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+extern void __glXNop(void);
+
+/* relate contexts with drawables */
+extern void __glXAssociateContext(__GLXcontext *glxc);
+extern void __glXDeassociateContext(__GLXcontext *glxc);
+
+/* drawable operation */
+extern void __glXGetDrawableSize(__GLdrawablePrivate *glPriv,
+ GLint *x, GLint *y,
+ GLuint *width, GLuint *height);
+extern GLboolean __glXResizeDrawable(__GLdrawablePrivate *glPriv);
+extern GLboolean __glXResizeDrawableBuffers(__GLXdrawablePrivate *glxPriv);
+
+/* drawable management */
+extern void __glXRefDrawablePrivate(__GLXdrawablePrivate *glxPriv);
+extern void __glXUnrefDrawablePrivate(__GLXdrawablePrivate *glxPriv);
+extern __GLXdrawablePrivate *__glXCreateDrawablePrivate(DrawablePtr pDraw,
+ XID glxpixmapId,
+ __GLcontextModes *modes);
+extern GLboolean __glXDestroyDrawablePrivate(__GLXdrawablePrivate *glxPriv);
+extern __GLXdrawablePrivate *__glXFindDrawablePrivate(XID glxpixmapId);
+extern __GLXdrawablePrivate *__glXGetDrawablePrivate(DrawablePtr pDraw,
+ XID glxpixmapId,
+ __GLcontextModes *modes);
+extern void __glXCacheDrawableSize(__GLXdrawablePrivate *glxPriv);
+
+/* context helper routines */
+extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag);
+
+/* init helper routines */
+extern void *__glXglDDXScreenInfo(void);
+extern void *__glXglDDXExtensionInfo(void);
+
+#endif /* _glxcmds_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/impsize.h b/nx-X11/programs/Xserver/GL/glx/impsize.h
new file mode 100644
index 000000000..53777c6e3
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/impsize.h
@@ -0,0 +1,55 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _impsize_h_
+#define _impsize_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+/*
+** These are defined in libsampleGL.a. They are not technically part of
+** the defined interface between libdixGL.a and libsampleGL.a (that interface
+** being the functions in the __glXScreenInfo structure, plus the OpenGL API
+** itself), but we thought it was better to call these routines than to
+** replicate the code in here.
+*/
+
+#include "indirect_size.h"
+
+extern int __glDrawPixels_size(GLenum format, GLenum type, GLsizei w,GLsizei h);
+
+#endif /* _impsize_h_ */
diff --git a/nx-X11/programs/Xserver/GL/glx/render2.c b/nx-X11/programs/Xserver/GL/glx/render2.c
new file mode 100644
index 000000000..1336e2591
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/render2.c
@@ -0,0 +1,269 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <glxserver.h>
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "indirect_size.h"
+
+void __glXDisp_Map1f(GLbyte *pc)
+{
+ GLint order, k;
+ GLfloat u1, u2, *points;
+ GLenum target;
+
+ target = *(GLenum *)(pc + 0);
+ order = *(GLint *)(pc + 12);
+ u1 = *(GLfloat *)(pc + 4);
+ u2 = *(GLfloat *)(pc + 8);
+ points = (GLfloat *)(pc + 16);
+ k = __glMap1f_size(target);
+
+ glMap1f(target, u1, u2, k, order, points);
+}
+
+void __glXDisp_Map2f(GLbyte *pc)
+{
+ GLint uorder, vorder, ustride, vstride, k;
+ GLfloat u1, u2, v1, v2, *points;
+ GLenum target;
+
+ target = *(GLenum *)(pc + 0);
+ uorder = *(GLint *)(pc + 12);
+ vorder = *(GLint *)(pc + 24);
+ u1 = *(GLfloat *)(pc + 4);
+ u2 = *(GLfloat *)(pc + 8);
+ v1 = *(GLfloat *)(pc + 16);
+ v2 = *(GLfloat *)(pc + 20);
+ points = (GLfloat *)(pc + 28);
+
+ k = __glMap2f_size(target);
+ ustride = vorder * k;
+ vstride = k;
+
+ glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void __glXDisp_Map1d(GLbyte *pc)
+{
+ GLint order, k;
+#ifdef __GLX_ALIGN64
+ GLint compsize;
+#endif
+ GLenum target;
+ GLdouble u1, u2, *points;
+
+ target = *(GLenum*) (pc + 16);
+ order = *(GLint*) (pc + 20);
+ k = __glMap1d_size(target);
+
+#ifdef __GLX_ALIGN64
+ if (order < 0 || k < 0) {
+ compsize = 0;
+ } else {
+ compsize = order * k;
+ }
+#endif
+
+ __GLX_GET_DOUBLE(u1,pc);
+ __GLX_GET_DOUBLE(u2,pc+8);
+ pc += 24;
+
+#ifdef __GLX_ALIGN64
+ if (((unsigned long)pc) & 7) {
+ /*
+ ** Copy the doubles up 4 bytes, trashing the command but aligning
+ ** the data in the process
+ */
+ __GLX_MEM_COPY(pc-4, pc, compsize*8);
+ points = (GLdouble*) (pc - 4);
+ } else {
+ points = (GLdouble*) pc;
+ }
+#else
+ points = (GLdouble*) pc;
+#endif
+ glMap1d(target, u1, u2, k, order, points);
+}
+
+void __glXDisp_Map2d(GLbyte *pc)
+{
+ GLdouble u1, u2, v1, v2, *points;
+ GLint uorder, vorder, ustride, vstride, k;
+#ifdef __GLX_ALIGN64
+ GLint compsize;
+#endif
+ GLenum target;
+
+ target = *(GLenum *)(pc + 32);
+ uorder = *(GLint *)(pc + 36);
+ vorder = *(GLint *)(pc + 40);
+ k = __glMap2d_size(target);
+
+#ifdef __GLX_ALIGN64
+ if (vorder < 0 || uorder < 0 || k < 0) {
+ compsize = 0;
+ } else {
+ compsize = uorder * vorder * k;
+ }
+#endif
+
+ __GLX_GET_DOUBLE(u1,pc);
+ __GLX_GET_DOUBLE(u2,pc+8);
+ __GLX_GET_DOUBLE(v1,pc+16);
+ __GLX_GET_DOUBLE(v2,pc+24);
+ pc += 44;
+
+ ustride = vorder * k;
+ vstride = k;
+
+#ifdef __GLX_ALIGN64
+ if (((unsigned long)pc) & 7) {
+ /*
+ ** Copy the doubles up 4 bytes, trashing the command but aligning
+ ** the data in the process
+ */
+ __GLX_MEM_COPY(pc-4, pc, compsize*8);
+ points = (GLdouble*) (pc - 4);
+ } else {
+ points = (GLdouble*) pc;
+ }
+#else
+ points = (GLdouble*) pc;
+#endif
+ glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void __glXDisp_CallLists(GLbyte *pc)
+{
+ GLenum type;
+ GLsizei n;
+
+ type = *(GLenum *)(pc + 4);
+ n = *(GLsizei *)(pc + 0);
+ glCallLists(n, type, pc + 8);
+}
+
+void __glXDisp_DrawArrays(GLbyte *pc)
+{
+ __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *)pc;
+ __GLXdispatchDrawArraysComponentHeader *compHeader;
+ GLint numVertexes = hdr->numVertexes;
+ GLint numComponents = hdr->numComponents;
+ GLenum primType = hdr->primType;
+ GLint stride = 0;
+ int i;
+
+ pc += sizeof(__GLXdispatchDrawArraysHeader);
+ compHeader = (__GLXdispatchDrawArraysComponentHeader *)pc;
+
+ /* compute stride (same for all component arrays) */
+ for (i = 0; i < numComponents; i++) {
+ GLenum datatype = compHeader[i].datatype;
+ GLint numVals = compHeader[i].numVals;
+
+ stride += __GLX_PAD(numVals * __glXTypeSize(datatype));
+ }
+
+ pc += numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader);
+
+ /* set up component arrays */
+ for (i = 0; i < numComponents; i++) {
+ GLenum datatype = compHeader[i].datatype;
+ GLint numVals = compHeader[i].numVals;
+ GLenum component = compHeader[i].component;
+
+ switch (component) {
+ case GL_VERTEX_ARRAY:
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_NORMAL_ARRAY:
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(datatype, stride, pc);
+ break;
+ case GL_COLOR_ARRAY:
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_INDEX_ARRAY:
+ glEnableClientState(GL_INDEX_ARRAY);
+ glIndexPointer(datatype, stride, pc);
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ glEnableClientState(GL_EDGE_FLAG_ARRAY);
+ glEdgeFlagPointer(stride, (const GLboolean *)pc);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY:
+ glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
+ glSecondaryColorPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_FOG_COORD_ARRAY:
+ glEnableClientState(GL_FOG_COORD_ARRAY);
+ glFogCoordPointer(datatype, stride, pc);
+ break;
+ default:
+ break;
+ }
+
+ pc += __GLX_PAD(numVals * __glXTypeSize(datatype));
+ }
+
+ glDrawArrays(primType, 0, numVertexes);
+
+ /* turn off anything we might have turned on */
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_INDEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_EDGE_FLAG_ARRAY);
+ glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
+ glDisableClientState(GL_FOG_COORD_ARRAY);
+}
+
+void __glXDisp_DrawArraysEXT(GLbyte *pc)
+{
+ __glXDisp_DrawArrays(pc);
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/render2swap.c b/nx-X11/programs/Xserver/GL/glx/render2swap.c
new file mode 100644
index 000000000..ea35d514d
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/render2swap.c
@@ -0,0 +1,391 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+#include "indirect_size.h"
+
+void __glXDispSwap_Map1f(GLbyte *pc)
+{
+ GLint order, k;
+ GLfloat u1, u2, *points;
+ GLenum target;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+
+ target = *(GLenum *)(pc + 0);
+ order = *(GLint *)(pc + 12);
+ u1 = *(GLfloat *)(pc + 4);
+ u2 = *(GLfloat *)(pc + 8);
+ points = (GLfloat *)(pc + 16);
+ k = __glMap1f_size(target);
+
+ if (order <= 0 || k < 0) {
+ /* Erroneous command. */
+ compsize = 0;
+ } else {
+ compsize = order * k;
+ }
+ __GLX_SWAP_FLOAT_ARRAY(points, compsize);
+
+ glMap1f(target, u1, u2, k, order, points);
+}
+
+void __glXDispSwap_Map2f(GLbyte *pc)
+{
+ GLint uorder, vorder, ustride, vstride, k;
+ GLfloat u1, u2, v1, v2, *points;
+ GLenum target;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 0);
+ __GLX_SWAP_INT(pc + 12);
+ __GLX_SWAP_INT(pc + 24);
+ __GLX_SWAP_FLOAT(pc + 4);
+ __GLX_SWAP_FLOAT(pc + 8);
+ __GLX_SWAP_FLOAT(pc + 16);
+ __GLX_SWAP_FLOAT(pc + 20);
+
+ target = *(GLenum *)(pc + 0);
+ uorder = *(GLint *)(pc + 12);
+ vorder = *(GLint *)(pc + 24);
+ u1 = *(GLfloat *)(pc + 4);
+ u2 = *(GLfloat *)(pc + 8);
+ v1 = *(GLfloat *)(pc + 16);
+ v2 = *(GLfloat *)(pc + 20);
+ points = (GLfloat *)(pc + 28);
+
+ k = __glMap2f_size(target);
+ ustride = vorder * k;
+ vstride = k;
+
+ if (vorder <= 0 || uorder <= 0 || k < 0) {
+ /* Erroneous command. */
+ compsize = 0;
+ } else {
+ compsize = uorder * vorder * k;
+ }
+ __GLX_SWAP_FLOAT_ARRAY(points, compsize);
+
+ glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void __glXDispSwap_Map1d(GLbyte *pc)
+{
+ GLint order, k, compsize;
+ GLenum target;
+ GLdouble u1, u2, *points;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_INT(pc + 16);
+ __GLX_SWAP_INT(pc + 20);
+
+ target = *(GLenum*) (pc + 16);
+ order = *(GLint*) (pc + 20);
+ k = __glMap1d_size(target);
+ if (order <= 0 || k < 0) {
+ /* Erroneous command. */
+ compsize = 0;
+ } else {
+ compsize = order * k;
+ }
+ __GLX_GET_DOUBLE(u1,pc);
+ __GLX_GET_DOUBLE(u2,pc+8);
+ __GLX_SWAP_DOUBLE_ARRAY(pc+24, compsize);
+ pc += 24;
+
+#ifdef __GLX_ALIGN64
+ if (((unsigned long)pc) & 7) {
+ /*
+ ** Copy the doubles up 4 bytes, trashing the command but aligning
+ ** the data in the process
+ */
+ __GLX_MEM_COPY(pc-4, pc, compsize*8);
+ points = (GLdouble*) (pc - 4);
+ } else {
+ points = (GLdouble*) pc;
+ }
+#else
+ points = (GLdouble*) pc;
+#endif
+ glMap1d(target, u1, u2, k, order, points);
+}
+
+void __glXDispSwap_Map2d(GLbyte *pc)
+{
+ GLdouble u1, u2, v1, v2, *points;
+ GLint uorder, vorder, ustride, vstride, k, compsize;
+ GLenum target;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_DOUBLE(pc + 0);
+ __GLX_SWAP_DOUBLE(pc + 8);
+ __GLX_SWAP_DOUBLE(pc + 16);
+ __GLX_SWAP_DOUBLE(pc + 24);
+ __GLX_SWAP_INT(pc + 32);
+ __GLX_SWAP_INT(pc + 36);
+ __GLX_SWAP_INT(pc + 40);
+
+ target = *(GLenum *)(pc + 32);
+ uorder = *(GLint *)(pc + 36);
+ vorder = *(GLint *)(pc + 40);
+ k = __glMap2d_size(target);
+ if (vorder <= 0 || uorder <= 0 || k < 0) {
+ /* Erroneous command. */
+ compsize = 0;
+ } else {
+ compsize = uorder * vorder * k;
+ }
+ __GLX_GET_DOUBLE(u1,pc);
+ __GLX_GET_DOUBLE(u2,pc+8);
+ __GLX_GET_DOUBLE(v1,pc+16);
+ __GLX_GET_DOUBLE(v2,pc+24);
+ __GLX_SWAP_DOUBLE_ARRAY(pc+44, compsize);
+ pc += 44;
+ ustride = vorder * k;
+ vstride = k;
+
+#ifdef __GLX_ALIGN64
+ if (((unsigned long)pc) & 7) {
+ /*
+ ** Copy the doubles up 4 bytes, trashing the command but aligning
+ ** the data in the process
+ */
+ __GLX_MEM_COPY(pc-4, pc, compsize*8);
+ points = (GLdouble*) (pc - 4);
+ } else {
+ points = (GLdouble*) pc;
+ }
+#else
+ points = (GLdouble*) pc;
+#endif
+ glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void __glXDispSwap_CallLists(GLbyte *pc)
+{
+ GLenum type;
+ GLsizei n;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + 0);
+ type = *(GLenum *)(pc + 4);
+ n = *(GLsizei *)(pc + 0);
+
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_2_BYTES:
+ case GL_3_BYTES:
+ case GL_4_BYTES:
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ __GLX_SWAP_SHORT_ARRAY(pc+8, n);
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ __GLX_SWAP_INT_ARRAY(pc+8, n);
+ break;
+ case GL_FLOAT:
+ __GLX_SWAP_FLOAT_ARRAY(pc+8, n);
+ break;
+ }
+
+ glCallLists(n, type, pc+8);
+}
+
+static void swapArray(GLint numVals, GLenum datatype,
+ GLint stride, GLint numVertexes, GLbyte *pc)
+{
+ int i,j;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ switch (datatype) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ /* don't need to swap */
+ return;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ for (i=0; i<numVertexes; i++) {
+ GLshort *pVal = (GLshort *) pc;
+ for (j=0; j<numVals; j++) {
+ __GLX_SWAP_SHORT(&pVal[j]);
+ }
+ pc += stride;
+ }
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ for (i=0; i<numVertexes; i++) {
+ GLint *pVal = (GLint *) pc;
+ for (j=0; j<numVals; j++) {
+ __GLX_SWAP_INT(&pVal[j]);
+ }
+ pc += stride;
+ }
+ break;
+ case GL_FLOAT:
+ for (i=0; i<numVertexes; i++) {
+ GLfloat *pVal = (GLfloat *) pc;
+ for (j=0; j<numVals; j++) {
+ __GLX_SWAP_FLOAT(&pVal[j]);
+ }
+ pc += stride;
+ }
+ break;
+ case GL_DOUBLE:
+ for (i=0; i<numVertexes; i++) {
+ GLdouble *pVal = (GLdouble *) pc;
+ for (j=0; j<numVals; j++) {
+ __GLX_SWAP_DOUBLE(&pVal[j]);
+ }
+ pc += stride;
+ }
+ break;
+ default:
+ return;
+ }
+}
+
+void __glXDispSwap_DrawArrays(GLbyte *pc)
+{
+ __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *)pc;
+ __GLXdispatchDrawArraysComponentHeader *compHeader;
+ GLint numVertexes = hdr->numVertexes;
+ GLint numComponents = hdr->numComponents;
+ GLenum primType = hdr->primType;
+ GLint stride = 0;
+ int i;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT(&numVertexes);
+ __GLX_SWAP_INT(&numComponents);
+ __GLX_SWAP_INT(&primType);
+
+ pc += sizeof(__GLXdispatchDrawArraysHeader);
+ compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
+
+ /* compute stride (same for all component arrays) */
+ for (i=0; i<numComponents; i++) {
+ GLenum datatype = compHeader[i].datatype;
+ GLint numVals = compHeader[i].numVals;
+ GLenum component = compHeader[i].component;
+
+ __GLX_SWAP_INT(&datatype);
+ __GLX_SWAP_INT(&numVals);
+ __GLX_SWAP_INT(&component);
+
+ stride += __GLX_PAD(numVals * __glXTypeSize(datatype));
+ }
+
+ pc += numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader);
+
+ /* set up component arrays */
+ for (i=0; i<numComponents; i++) {
+ GLenum datatype = compHeader[i].datatype;
+ GLint numVals = compHeader[i].numVals;
+ GLenum component = compHeader[i].component;
+
+ swapArray(numVals, datatype, stride, numVertexes, pc);
+
+ switch (component) {
+ case GL_VERTEX_ARRAY:
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_NORMAL_ARRAY:
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glNormalPointer(datatype, stride, pc);
+ break;
+ case GL_COLOR_ARRAY:
+ glEnableClientState(GL_COLOR_ARRAY);
+ glColorPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_INDEX_ARRAY:
+ glEnableClientState(GL_INDEX_ARRAY);
+ glIndexPointer(datatype, stride, pc);
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(numVals, datatype, stride, pc);
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ glEnableClientState(GL_EDGE_FLAG_ARRAY);
+ glEdgeFlagPointer(stride, (const GLboolean *)pc);
+ break;
+ default:
+ break;
+ }
+
+ pc += __GLX_PAD(numVals * __glXTypeSize(datatype));
+ }
+
+ glDrawArrays(primType, 0, numVertexes);
+
+ /* turn off anything we might have turned on */
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_INDEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisableClientState(GL_EDGE_FLAG_ARRAY);
+}
+
+void __glXDispSwap_DrawArraysEXT(GLbyte *pc)
+{
+ __glXDispSwap_DrawArrays(pc);
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/renderpix.c b/nx-X11/programs/Xserver/GL/glx/renderpix.c
new file mode 100644
index 000000000..d1997b5ad
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/renderpix.c
@@ -0,0 +1,310 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+
+void __glXDisp_PolygonStipple(GLbyte *pc)
+{
+ __GLXpixelHeader *hdr = (__GLXpixelHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glPolygonStipple((GLubyte *)(hdr+1));
+}
+
+void __glXDisp_Bitmap(GLbyte *pc)
+{
+ __GLXdispatchBitmapHeader *hdr = (__GLXdispatchBitmapHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glBitmap((GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ (GLfloat) hdr->xorig,
+ (GLfloat) hdr->yorig,
+ (GLfloat) hdr->xmove,
+ (GLfloat) hdr->ymove,
+ (GLubyte *)(hdr+1));
+}
+
+void __glXDisp_TexImage1D(GLbyte *pc)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexImage1D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->components,
+ (GLsizei) hdr->width,
+ (GLint) hdr->border,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_TexImage2D(GLbyte *pc)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexImage2D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->components,
+ (GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ (GLint) hdr->border,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_TexImage3D(GLbyte *pc)
+{
+ __GLXdispatchTexImage3DHeader *hdr = (__GLXdispatchTexImage3DHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, hdr->imageHeight);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_IMAGES, hdr->skipImages);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glTexImage3D(hdr->target, hdr->level, hdr->internalformat, hdr->width,
+ hdr->height, hdr->depth, hdr->border, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_DrawPixels(GLbyte *pc)
+{
+ __GLXdispatchDrawPixelsHeader *hdr = (__GLXdispatchDrawPixelsHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glDrawPixels((GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_TexSubImage1D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexSubImage1D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->xoffset,
+ (GLsizei) hdr->width,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_TexSubImage2D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexSubImage2D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->xoffset,
+ (GLint) hdr->yoffset,
+ (GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_TexSubImage3D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImage3DHeader *hdr =
+ (__GLXdispatchTexSubImage3DHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, hdr->imageHeight);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_IMAGES, hdr->skipImages);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glTexSubImage3D(hdr->target, hdr->level, hdr->xoffset, hdr->yoffset,
+ hdr->zoffset, hdr->width, hdr->height, hdr->depth,
+ hdr->format, hdr->type, (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_ColorTable(GLbyte *pc)
+{
+ __GLXdispatchColorTableHeader *hdr =
+ (__GLXdispatchColorTableHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glColorTable(hdr->target, hdr->internalformat,
+ hdr->width, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_ColorSubTable(GLbyte *pc)
+{
+ __GLXdispatchColorSubTableHeader *hdr =
+ (__GLXdispatchColorSubTableHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glColorSubTable(hdr->target, hdr->start, hdr->count, hdr->format,
+ hdr->type, (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_ConvolutionFilter1D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glConvolutionFilter1D(hdr->target, hdr->internalformat,
+ hdr->width, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_ConvolutionFilter2D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glConvolutionFilter2D(hdr->target, hdr->internalformat,
+ hdr->width, hdr->height, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDisp_SeparableFilter2D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+ GLint hdrlen, image1len;
+
+ hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_DISPATCH_HDR_SIZE);
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ /* XXX check this usage - internal code called
+ ** a version without the packing parameters
+ */
+ image1len = __glXImageSize(hdr->format, hdr->type, 0, hdr->width, 1, 1,
+ 0, hdr->rowLength, 0, hdr->skipRows,
+ hdr->alignment);
+ image1len = __GLX_PAD(image1len);
+
+ glSeparableFilter2D(hdr->target, hdr->internalformat,
+ hdr->width, hdr->height, hdr->format, hdr->type,
+ ((GLubyte *)hdr+hdrlen), ((GLubyte *)hdr+hdrlen+image1len));
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/renderpixswap.c b/nx-X11/programs/Xserver/GL/glx/renderpixswap.c
new file mode 100644
index 000000000..a527a859a
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/renderpixswap.c
@@ -0,0 +1,553 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+
+void __glXDispSwap_PolygonStipple(GLbyte *pc)
+{
+ __GLXpixelHeader *hdr = (__GLXpixelHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glPolygonStipple((GLubyte *)(hdr+1));
+}
+
+void __glXDispSwap_Bitmap(GLbyte *pc)
+{
+ __GLXdispatchBitmapHeader *hdr = (__GLXdispatchBitmapHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_FLOAT((GLbyte *)&hdr->xorig);
+ __GLX_SWAP_FLOAT((GLbyte *)&hdr->yorig);
+ __GLX_SWAP_FLOAT((GLbyte *)&hdr->xmove);
+ __GLX_SWAP_FLOAT((GLbyte *)&hdr->ymove);
+
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glBitmap((GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ (GLfloat) hdr->xorig,
+ (GLfloat) hdr->yorig,
+ (GLfloat) hdr->xmove,
+ (GLfloat) hdr->ymove,
+ (GLubyte *)(hdr+1));
+}
+
+void __glXDispSwap_TexImage1D(GLbyte *pc)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->components);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->border);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexImage1D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->components,
+ (GLsizei) hdr->width,
+ (GLint) hdr->border,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_TexImage2D(GLbyte *pc)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->components);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->border);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexImage2D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->components,
+ (GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ (GLint) hdr->border,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_TexImage3D(GLbyte *pc)
+{
+ __GLXdispatchTexImage3DHeader *hdr = (__GLXdispatchTexImage3DHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->imageHeight);
+ __GLX_SWAP_INT((GLbyte *)&hdr->imageDepth);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipImages);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipVolumes);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->internalformat);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->depth);
+ __GLX_SWAP_INT((GLbyte *)&hdr->size4d);
+ __GLX_SWAP_INT((GLbyte *)&hdr->border);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, hdr->imageHeight);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_IMAGES, hdr->skipImages);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glTexImage3D(hdr->target, hdr->level, hdr->internalformat, hdr->width,
+ hdr->height, hdr->depth, hdr->border, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_DrawPixels(GLbyte *pc)
+{
+ __GLXdispatchDrawPixelsHeader *hdr = (__GLXdispatchDrawPixelsHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glDrawPixels((GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_TexSubImage1D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->xoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexSubImage1D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->xoffset,
+ (GLsizei) hdr->width,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_TexSubImage2D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->xoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->yoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) hdr->alignment);
+
+ glTexSubImage2D(hdr->target,
+ (GLint) hdr->level,
+ (GLint) hdr->xoffset,
+ (GLint) hdr->yoffset,
+ (GLsizei) hdr->width,
+ (GLsizei) hdr->height,
+ hdr->format,
+ hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_TexSubImage3D(GLbyte *pc)
+{
+ __GLXdispatchTexSubImage3DHeader *hdr =
+ (__GLXdispatchTexSubImage3DHeader *) pc;
+
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->imageHeight);
+ __GLX_SWAP_INT((GLbyte *)&hdr->imageDepth);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipImages);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipVolumes);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->level);
+ __GLX_SWAP_INT((GLbyte *)&hdr->xoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->yoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->zoffset);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->depth);
+ __GLX_SWAP_INT((GLbyte *)&hdr->size4d);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, hdr->imageHeight);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_IMAGES, hdr->skipImages);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glTexSubImage3D(hdr->target, hdr->level, hdr->xoffset, hdr->yoffset,
+ hdr->zoffset, hdr->width, hdr->height, hdr->depth,
+ hdr->format, hdr->type, (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_ColorTable(GLbyte *pc)
+{
+ __GLXdispatchColorTableHeader *hdr =
+ (__GLXdispatchColorTableHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->internalformat);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glColorTable(hdr->target, hdr->internalformat,
+ hdr->width, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_ColorSubTable(GLbyte *pc)
+{
+ __GLXdispatchColorSubTableHeader *hdr =
+ (__GLXdispatchColorSubTableHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->start);
+ __GLX_SWAP_INT((GLbyte *)&hdr->count);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glColorSubTable(hdr->target, hdr->start, hdr->count, hdr->format,
+ hdr->type, (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_ConvolutionFilter1D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->internalformat);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glConvolutionFilter2D(hdr->target, hdr->internalformat,
+ hdr->width, 1, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_ConvolutionFilter2D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->internalformat);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ glConvolutionFilter2D(hdr->target, hdr->internalformat,
+ hdr->width, hdr->height, hdr->format, hdr->type,
+ (GLvoid *)(hdr+1));
+}
+
+void __glXDispSwap_SeparableFilter2D(GLbyte *pc)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+ GLint hdrlen, image1len;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ hdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->rowLength);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipRows);
+ __GLX_SWAP_INT((GLbyte *)&hdr->skipPixels);
+ __GLX_SWAP_INT((GLbyte *)&hdr->alignment);
+
+ __GLX_SWAP_INT((GLbyte *)&hdr->target);
+ __GLX_SWAP_INT((GLbyte *)&hdr->internalformat);
+ __GLX_SWAP_INT((GLbyte *)&hdr->width);
+ __GLX_SWAP_INT((GLbyte *)&hdr->height);
+ __GLX_SWAP_INT((GLbyte *)&hdr->format);
+ __GLX_SWAP_INT((GLbyte *)&hdr->type);
+
+ /*
+ ** Just invert swapBytes flag; the GL will figure out if it needs to swap
+ ** the pixel data.
+ */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, !hdr->swapBytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, hdr->rowLength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, hdr->skipRows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, hdr->skipPixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, hdr->alignment);
+
+ /* XXX check this usage - internal code called
+ ** a version without the packing parameters
+ */
+ image1len = __glXImageSize(hdr->format, hdr->type, 0, hdr->width, 1, 1,
+ 0, hdr->rowLength, 0, hdr->skipRows,
+ hdr->alignment);
+ image1len = __GLX_PAD(image1len);
+
+
+ glSeparableFilter2D(hdr->target, hdr->internalformat,
+ hdr->width, hdr->height, hdr->format, hdr->type,
+ ((GLubyte *)hdr+hdrlen), ((GLubyte *)hdr+hdrlen+image1len));
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/rensize.c b/nx-X11/programs/Xserver/GL/glx/rensize.c
new file mode 100644
index 000000000..d3a819cd5
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/rensize.c
@@ -0,0 +1,1001 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <GL/gl.h>
+#include "glxserver.h"
+#include "GL/glxproto.h"
+#include "unpack.h"
+#include "impsize.h"
+
+#define SWAPL(a) \
+ (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
+ ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
+
+int __glXCallListsReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLsizei n = *(GLsizei *)(pc + 0);
+ GLenum type = *(GLenum *)(pc + 4);
+
+ if (swap) {
+ n = SWAPL( n );
+ type = SWAPL( type );
+ }
+ return n * __glCallLists_size( type );
+}
+
+int __glXFogivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 0);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glFogiv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXFogfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXFogivReqSize( pc, swap, reqlen);
+}
+
+int __glXLightfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glLightfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXLightivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXLightfvReqSize( pc, swap, reqlen);
+}
+
+int __glXLightModelfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 0);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glLightModelfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXLightModelivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXLightModelfvReqSize( pc, swap, reqlen);
+}
+
+int __glXMaterialfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glMaterialfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXMaterialivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXMaterialfvReqSize( pc, swap, reqlen);
+}
+
+int __glXTexGendvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 8 * __glTexGendv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXTexGenfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glTexGenfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXTexGenivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXTexGenfvReqSize( pc, swap, reqlen);
+}
+
+int __glXTexParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glTexParameterfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXTexParameterivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXTexParameterfvReqSize( pc, swap, reqlen);
+}
+
+int __glXTexEnvfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glTexEnvfv_size( pname ); /* defined in samplegl lib */
+}
+
+int __glXTexEnvivReqSize(GLbyte *pc, Bool swap, int reqlen )
+{
+ return __glXTexEnvfvReqSize( pc, swap, reqlen);
+}
+
+int __glXMap1dReqSize(GLbyte *pc, Bool swap, int reqlen )
+{
+ GLenum target;
+ GLint order;
+
+ target = *(GLenum*) (pc + 16);
+ order = *(GLint*) (pc + 20);
+ if (swap) {
+ target = SWAPL( target );
+ order = SWAPL( order );
+ }
+ if (order < 1)
+ return -1;
+ return safe_mul(8, safe_mul(__glMap1d_size(target), order));
+}
+
+int __glXMap1fReqSize(GLbyte *pc, Bool swap, int reqlen )
+{
+ GLenum target;
+ GLint order;
+
+ target = *(GLenum *)(pc + 0);
+ order = *(GLint *)(pc + 12);
+ if (swap) {
+ target = SWAPL( target );
+ order = SWAPL( order );
+ }
+ if (order < 1)
+ return -1;
+ return safe_mul(4, safe_mul(__glMap1f_size(target), order));
+}
+
+static int Map2Size(int k, int majorOrder, int minorOrder)
+{
+ if (majorOrder < 1 || minorOrder < 1) return -1;
+ return safe_mul(k, safe_mul(majorOrder, minorOrder));
+}
+
+int __glXMap2dReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum target;
+ GLint uorder, vorder;
+
+ target = *(GLenum *)(pc + 32);
+ uorder = *(GLint *)(pc + 36);
+ vorder = *(GLint *)(pc + 40);
+ if (swap) {
+ target = SWAPL( target );
+ uorder = SWAPL( uorder );
+ vorder = SWAPL( vorder );
+ }
+ return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder));
+}
+
+int __glXMap2fReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum target;
+ GLint uorder, vorder;
+
+ target = *(GLenum *)(pc + 0);
+ uorder = *(GLint *)(pc + 12);
+ vorder = *(GLint *)(pc + 24);
+ if (swap) {
+ target = SWAPL( target );
+ uorder = SWAPL( uorder );
+ vorder = SWAPL( vorder );
+ }
+ return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder));
+}
+
+int __glXPixelMapfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLint mapsize;
+ mapsize = *(GLint *)(pc + 4);
+ if (swap) {
+ mapsize = SWAPL( mapsize );
+ }
+ return 4 * mapsize;
+}
+
+int __glXPixelMapuivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXPixelMapfvReqSize( pc, swap, reqlen);
+}
+
+int __glXPixelMapusvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLint mapsize;
+ mapsize = *(GLint *)(pc + 4);
+ if (swap) {
+ mapsize = SWAPL( mapsize );
+ }
+ return 2 * mapsize;
+}
+
+/**
+ * Calculate the size of an image.
+ *
+ * The size of an image sent to the server from the client or sent from the
+ * server to the client is calculated. The size is based on the dimensions
+ * of the image, the type of pixel data, padding in the image, and the
+ * alignment requirements of the image.
+ *
+ * \param format Format of the pixels. Same as the \c format parameter
+ * to \c glTexImage1D
+ * \param type Type of the pixel data. Same as the \c type parameter
+ * to \c glTexImage1D
+ * \param target Typically the texture target of the image. If the
+ * target is one of \c GL_PROXY_*, the size returned is
+ * always zero. For uses that do not have a texture target
+ * (e.g, glDrawPixels), zero should be specified.
+ * \param w Width of the image data. Must be >= 1.
+ * \param h Height of the image data. Must be >= 1, even for 1D
+ * images.
+ * \param d Depth of the image data. Must be >= 1, even for 1D or
+ * 2D images.
+ * \param imageHeight If non-zero, defines the true height of a volumetric
+ * image. This value will be used instead of \c h for
+ * calculating the size of the image.
+ * \param rowLength If non-zero, defines the true width of an image. This
+ * value will be used instead of \c w for calculating the
+ * size of the image.
+ * \param skipImages Number of extra layers of image data in a volumtric
+ * image that are to be skipped before the real data.
+ * \param skipRows Number of extra rows of image data in an image that are
+ * to be skipped before the real data.
+ * \param alignment Specifies the alignment for the start of each pixel row
+ * in memory. This value must be one of 1, 2, 4, or 8.
+ *
+ * \returns
+ * The size of the image is returned. If the specified \c format and \c type
+ * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero
+ * is returned.
+ */
+int __glXImageSize( GLenum format, GLenum type, GLenum target,
+ GLsizei w, GLsizei h, GLsizei d,
+ GLint imageHeight, GLint rowLength,
+ GLint skipImages, GLint skipRows, GLint alignment )
+{
+ GLint bytesPerElement, elementsPerGroup, groupsPerRow;
+ GLint groupSize, rowSize, padding, imageSize;
+
+ if (w == 0 || h == 0 || d == 0)
+ return 0;
+
+ if (w < 0 || h < 0 || d < 0 ||
+ (type == GL_BITMAP &&
+ (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
+ return -1;
+ }
+
+ /* proxy targets have no data */
+ switch( target ) {
+ case GL_PROXY_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_4D_SGIS:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_PROXY_TEXTURE_RECTANGLE_ARB:
+ case GL_PROXY_HISTOGRAM:
+ case GL_PROXY_COLOR_TABLE:
+ case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
+ case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
+ case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
+ case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
+ return 0;
+ }
+
+ /* real data has to have real sizes */
+ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0)
+ return -1;
+ if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8)
+ return -1;
+
+ if (type == GL_BITMAP) {
+ if (rowLength > 0) {
+ groupsPerRow = rowLength;
+ } else {
+ groupsPerRow = w;
+ }
+ rowSize = (groupsPerRow + 7) >> 3;
+ if (rowSize < 0)
+ return -1;
+ padding = (rowSize % alignment);
+ if (padding) {
+ rowSize += alignment - padding;
+ }
+ return safe_mul(safe_add(h, skipRows), rowSize);
+ } else {
+ switch(format) {
+ case GL_COLOR_INDEX:
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_COMPONENT:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_INTENSITY:
+ elementsPerGroup = 1;
+ break;
+ case GL_422_EXT:
+ case GL_422_REV_EXT:
+ case GL_422_AVERAGE_EXT:
+ case GL_422_REV_AVERAGE_EXT:
+ case GL_DEPTH_STENCIL_NV:
+ case GL_DEPTH_STENCIL_MESA:
+ case GL_YCBCR_MESA:
+ case GL_LUMINANCE_ALPHA:
+ elementsPerGroup = 2;
+ break;
+ case GL_RGB:
+ case GL_BGR:
+ elementsPerGroup = 3;
+ break;
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ elementsPerGroup = 4;
+ break;
+ default:
+ return -1;
+ }
+ switch(type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ bytesPerElement = 1;
+ break;
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ bytesPerElement = 1;
+ elementsPerGroup = 1;
+ break;
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ bytesPerElement = 2;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL_UNSIGNED_SHORT_8_8_APPLE:
+ case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
+ case GL_UNSIGNED_SHORT_15_1_MESA:
+ case GL_UNSIGNED_SHORT_1_15_REV_MESA:
+ bytesPerElement = 2;
+ elementsPerGroup = 1;
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ bytesPerElement = 4;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_24_8_NV:
+ case GL_UNSIGNED_INT_24_8_MESA:
+ case GL_UNSIGNED_INT_8_24_REV_MESA:
+ bytesPerElement = 4;
+ elementsPerGroup = 1;
+ break;
+ default:
+ return -1;
+ }
+ /* known safe by the switches above, not checked */
+ groupSize = bytesPerElement * elementsPerGroup;
+ if (rowLength > 0) {
+ groupsPerRow = rowLength;
+ } else {
+ groupsPerRow = w;
+ }
+ if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0)
+ return -1;
+ padding = (rowSize % alignment);
+ if (padding) {
+ rowSize += alignment - padding;
+ }
+ if (imageHeight > 0)
+ h = imageHeight;
+ h = safe_add(h, skipRows);
+
+ imageSize = safe_mul(h, rowSize);
+ return safe_mul(safe_add(d, skipImages), imageSize);
+ }
+}
+
+
+int __glXDrawPixelsReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchDrawPixelsHeader *hdr = (__GLXdispatchDrawPixelsHeader *) pc;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ return __glXImageSize( format, type, 0, w, h, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXBitmapReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchBitmapHeader *hdr = (__GLXdispatchBitmapHeader *) pc;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ return __glXImageSize( GL_COLOR_INDEX, GL_BITMAP, 0, w, h, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXTexImage1DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+ GLenum target = hdr->target;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ target = SWAPL( target );
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ if (target == GL_PROXY_TEXTURE_1D) {
+ return 0;
+ } else if (format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT) {
+ return -1;
+ }
+ return __glXImageSize( format, type, 0, w, 1, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXTexImage2DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexImageHeader *hdr = (__GLXdispatchTexImageHeader *) pc;
+ GLenum target = hdr->target;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ target = SWAPL( target );
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ if (target == GL_PROXY_TEXTURE_2D || target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
+ return 0;
+ } else if (format == GL_STENCIL_INDEX || format == GL_DEPTH_COMPONENT) {
+ return -1;
+ }
+ return __glXImageSize( format, type, 0, w, h, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+/* XXX this is used elsewhere - should it be exported from glxserver.h? */
+int __glXTypeSize(GLenum enm)
+{
+ switch(enm) {
+ case GL_BYTE: return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ case GL_SHORT: return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+ case GL_INT: return sizeof(GLint);
+ case GL_UNSIGNED_INT: return sizeof(GLint);
+ case GL_FLOAT: return sizeof(GLfloat);
+ case GL_DOUBLE: return sizeof(GLdouble);
+ default: return -1;
+ }
+}
+
+int __glXDrawArraysSize( GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
+ __GLXdispatchDrawArraysComponentHeader *compHeader;
+ GLint numVertexes = hdr->numVertexes;
+ GLint numComponents = hdr->numComponents;
+ GLint arrayElementSize = 0;
+ GLint x, size;
+ int i;
+
+ if (swap) {
+ numVertexes = SWAPL( numVertexes );
+ numComponents = SWAPL( numComponents );
+ }
+
+ pc += sizeof(__GLXdispatchDrawArraysHeader);
+ reqlen -= sizeof(__GLXdispatchDrawArraysHeader);
+
+ size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader),
+ numComponents);
+ if (size < 0 || reqlen < 0 || reqlen < size)
+ return -1;
+
+ compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
+
+ for (i=0; i<numComponents; i++) {
+ GLenum datatype = compHeader[i].datatype;
+ GLint numVals = compHeader[i].numVals;
+ GLint component = compHeader[i].component;
+
+ if (swap) {
+ datatype = SWAPL( datatype );
+ numVals = SWAPL( numVals );
+ component = SWAPL( component );
+ }
+
+ switch (component) {
+ case GL_VERTEX_ARRAY:
+ case GL_COLOR_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY:
+ break;
+ case GL_SECONDARY_COLOR_ARRAY:
+ case GL_NORMAL_ARRAY:
+ if (numVals != 3) {
+ /* bad size */
+ return -1;
+ }
+ break;
+ case GL_FOG_COORD_ARRAY:
+ case GL_INDEX_ARRAY:
+ if (numVals != 1) {
+ /* bad size */
+ return -1;
+ }
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) {
+ /* bad size or bad type */
+ return -1;
+ }
+ break;
+ default:
+ /* unknown component type */
+ return -1;
+ }
+
+ x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype)));
+ if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0)
+ return -1;
+
+ pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
+ }
+
+ return safe_add(size, safe_mul(numVertexes, arrayElementSize));
+}
+
+int __glXPrioritizeTexturesReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLint n = *(GLsizei *)(pc + 0);
+ if (swap) n = SWAPL(n);
+ return(8*n); /* 4*n for textures, 4*n for priorities */
+}
+
+int __glXTexSubImage1DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ return __glXImageSize( format, type, 0, w, 1, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXTexSubImage2DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexSubImageHeader *hdr = (__GLXdispatchTexSubImageHeader *) pc;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ return __glXImageSize( format, type, 0, w, h, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXTexImage3DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexImage3DHeader *hdr = (__GLXdispatchTexImage3DHeader *) pc;
+ GLenum target = hdr->target;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint d = hdr->depth;
+ GLint imageHeight = hdr->imageHeight;
+ GLint rowLength = hdr->rowLength;
+ GLint skipImages = hdr->skipImages;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+ GLint nullImage = hdr->nullimage;
+
+ if (swap) {
+ target = SWAPL( target );
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ d = SWAPL( d );
+ imageHeight = SWAPL( imageHeight );
+ rowLength = SWAPL( rowLength );
+ skipImages = SWAPL( skipImages );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ if (target == GL_PROXY_TEXTURE_3D || nullImage) {
+ return 0;
+ } else {
+ return __glXImageSize( format, type, target, w, h, d, imageHeight,
+ rowLength, skipImages, skipRows, alignment );
+ }
+}
+
+int __glXTexSubImage3DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchTexSubImage3DHeader *hdr =
+ (__GLXdispatchTexSubImage3DHeader *) pc;
+ GLenum target = hdr->target;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint d = hdr->depth;
+ GLint imageHeight = hdr->imageHeight;
+ GLint rowLength = hdr->rowLength;
+ GLint skipImages = hdr->skipImages;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ target = SWAPL( target );
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ d = SWAPL( d );
+ imageHeight = SWAPL( imageHeight );
+ rowLength = SWAPL( rowLength );
+ skipImages = SWAPL( skipImages );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+ if (target == GL_PROXY_TEXTURE_3D) {
+ return 0;
+ } else {
+ return __glXImageSize( format, type, target, w, h, d, imageHeight,
+ rowLength, skipImages, skipRows, alignment );
+ }
+}
+
+int __glXConvolutionFilter1DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint rowLength = hdr->rowLength;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ rowLength = SWAPL( rowLength );
+ alignment = SWAPL( alignment );
+ }
+
+ return __glXImageSize( format, type, 0, w, 1, 1,
+ 0, rowLength, 0, 0, alignment );
+}
+
+int __glXConvolutionFilter2DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint skipRows = hdr->skipRows;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ skipRows = SWAPL( skipRows );
+ alignment = SWAPL( alignment );
+ }
+
+ return __glXImageSize( format, type, 0, w, h, 1,
+ 0, rowLength, 0, skipRows, alignment );
+}
+
+int __glXConvolutionParameterivSize(GLenum pname)
+{
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ case GL_CONVOLUTION_FILTER_SCALE:
+ case GL_CONVOLUTION_FILTER_BIAS:
+ return 4;
+ case GL_CONVOLUTION_BORDER_MODE:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+int __glXConvolutionParameterfvSize(GLenum pname)
+{
+ return __glXConvolutionParameterivSize(pname);
+}
+
+int __glXConvolutionParameterivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glXConvolutionParameterivSize( pname );
+}
+
+int __glXConvolutionParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ return __glXConvolutionParameterivReqSize( pc, swap, reqlen);
+}
+
+int __glXSeparableFilter2DReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchConvolutionFilterHeader *hdr =
+ (__GLXdispatchConvolutionFilterHeader *) pc;
+
+ GLint image1size, image2size;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint h = hdr->height;
+ GLint rowLength = hdr->rowLength;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ h = SWAPL( h );
+ rowLength = SWAPL( rowLength );
+ alignment = SWAPL( alignment );
+ }
+
+ /* XXX Should rowLength be used for either or both image? */
+ image1size = __glXImageSize( format, type, 0, w, 1, 1,
+ 0, rowLength, 0, 0, alignment );
+ image2size = __glXImageSize( format, type, 0, h, 1, 1,
+ 0, rowLength, 0, 0, alignment );
+ return safe_add(safe_pad(image1size), image2size);
+
+}
+
+int __glXColorTableParameterfvSize(GLenum pname)
+{
+ /* currently, only scale and bias are supported; return RGBA */
+ switch(pname) {
+ case GL_COLOR_TABLE_SCALE:
+ case GL_COLOR_TABLE_BIAS:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+int __glXColorTableParameterivSize(GLenum pname)
+{
+ /* fv and iv are the same in this context */
+ return __glXColorTableParameterfvSize(pname);
+}
+
+int __glXColorTableReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchColorTableHeader *hdr =
+ (__GLXdispatchColorTableHeader *) pc;
+
+ GLenum target = hdr->target;
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint w = hdr->width;
+ GLint rowLength = hdr->rowLength;
+ GLint alignment = hdr->alignment;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_3D:
+ case GL_PROXY_COLOR_TABLE:
+ case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
+ case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
+ return 0;
+ }
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ w = SWAPL( w );
+ rowLength = SWAPL( rowLength );
+ alignment = SWAPL( alignment );
+ }
+
+ return __glXImageSize( format, type, 0, w, 1, 1,
+ 0, rowLength, 0, 0, alignment );
+}
+
+int __glXColorSubTableReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ __GLXdispatchColorSubTableHeader *hdr =
+ (__GLXdispatchColorSubTableHeader *) pc;
+
+ GLenum format = hdr->format;
+ GLenum type = hdr->type;
+ GLint count = hdr->count;
+ GLint rowLength = hdr->rowLength;
+ GLint alignment = hdr->alignment;
+
+ if (swap) {
+ format = SWAPL( format );
+ type = SWAPL( type );
+ count = SWAPL( count );
+ rowLength = SWAPL( rowLength );
+ alignment = SWAPL( alignment );
+ }
+
+ return __glXImageSize( format, type, 0, count, 1, 1,
+ 0, rowLength, 0, 0, alignment );
+}
+
+int __glXColorTableParameterfvReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 4);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glXColorTableParameterfvSize(pname);
+}
+
+int __glXColorTableParameterivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ /* no difference between fv and iv versions */
+ return __glXColorTableParameterfvReqSize(pc, swap, reqlen);
+}
+
+int __glXPointParameterfvARBReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ GLenum pname = *(GLenum *)(pc + 0);
+ if (swap) {
+ pname = SWAPL( pname );
+ }
+ return 4 * __glPointParameterfvEXT_size( pname );
+}
+
+int __glXPointParameterivReqSize(GLbyte *pc, Bool swap, int reqlen)
+{
+ /* no difference between fv and iv versions */
+ return __glXPointParameterfvARBReqSize(pc, swap, reqlen);
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/rensizetab.c b/nx-X11/programs/Xserver/GL/glx/rensizetab.c
new file mode 100644
index 000000000..9d5abe844
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/rensizetab.c
@@ -0,0 +1,2447 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "g_disptab_EXT.h"
+
+__GLXrenderSizeData __glXRenderSizeTable[__GLX_MAX_RENDER_OPCODE_EXT - __GLX_MIN_RENDER_OPCODE_EXT + 1] = {
+ /* no such opcode */ { 0, 0 },
+ /* CallList */ { 8, 0 },
+ /* CallLists */ { 12, __glXCallListsReqSize },
+ /* ListBase */ { 8, 0 },
+ /* Begin */ { 8, 0 },
+ /* Bitmap */ { 48, __glXBitmapReqSize },
+ /* Color3bv */ { 8, 0 },
+ /* Color3dv */ { 28, 0 },
+ /* Color3fv */ { 16, 0 },
+ /* Color3iv */ { 16, 0 },
+ /* Color3sv */ { 12, 0 },
+ /* Color3ubv */ { 8, 0 },
+ /* Color3uiv */ { 16, 0 },
+ /* Color3usv */ { 12, 0 },
+ /* Color4bv */ { 8, 0 },
+ /* Color4dv */ { 36, 0 },
+ /* Color4fv */ { 20, 0 },
+ /* Color4iv */ { 20, 0 },
+ /* Color4sv */ { 12, 0 },
+ /* Color4ubv */ { 8, 0 },
+ /* Color4uiv */ { 20, 0 },
+ /* Color4usv */ { 12, 0 },
+ /* EdgeFlagv */ { 8, 0 },
+ /* End */ { 4, 0 },
+ /* Indexdv */ { 12, 0 },
+ /* Indexfv */ { 8, 0 },
+ /* Indexiv */ { 8, 0 },
+ /* Indexsv */ { 8, 0 },
+ /* Normal3bv */ { 8, 0 },
+ /* Normal3dv */ { 28, 0 },
+ /* Normal3fv */ { 16, 0 },
+ /* Normal3iv */ { 16, 0 },
+ /* Normal3sv */ { 12, 0 },
+ /* RasterPos2dv */ { 20, 0 },
+ /* RasterPos2fv */ { 12, 0 },
+ /* RasterPos2iv */ { 12, 0 },
+ /* RasterPos2sv */ { 8, 0 },
+ /* RasterPos3dv */ { 28, 0 },
+ /* RasterPos3fv */ { 16, 0 },
+ /* RasterPos3iv */ { 16, 0 },
+ /* RasterPos3sv */ { 12, 0 },
+ /* RasterPos4dv */ { 36, 0 },
+ /* RasterPos4fv */ { 20, 0 },
+ /* RasterPos4iv */ { 20, 0 },
+ /* RasterPos4sv */ { 12, 0 },
+ /* Rectdv */ { 36, 0 },
+ /* Rectfv */ { 20, 0 },
+ /* Rectiv */ { 20, 0 },
+ /* Rectsv */ { 12, 0 },
+ /* TexCoord1dv */ { 12, 0 },
+ /* TexCoord1fv */ { 8, 0 },
+ /* TexCoord1iv */ { 8, 0 },
+ /* TexCoord1sv */ { 8, 0 },
+ /* TexCoord2dv */ { 20, 0 },
+ /* TexCoord2fv */ { 12, 0 },
+ /* TexCoord2iv */ { 12, 0 },
+ /* TexCoord2sv */ { 8, 0 },
+ /* TexCoord3dv */ { 28, 0 },
+ /* TexCoord3fv */ { 16, 0 },
+ /* TexCoord3iv */ { 16, 0 },
+ /* TexCoord3sv */ { 12, 0 },
+ /* TexCoord4dv */ { 36, 0 },
+ /* TexCoord4fv */ { 20, 0 },
+ /* TexCoord4iv */ { 20, 0 },
+ /* TexCoord4sv */ { 12, 0 },
+ /* Vertex2dv */ { 20, 0 },
+ /* Vertex2fv */ { 12, 0 },
+ /* Vertex2iv */ { 12, 0 },
+ /* Vertex2sv */ { 8, 0 },
+ /* Vertex3dv */ { 28, 0 },
+ /* Vertex3fv */ { 16, 0 },
+ /* Vertex3iv */ { 16, 0 },
+ /* Vertex3sv */ { 12, 0 },
+ /* Vertex4dv */ { 36, 0 },
+ /* Vertex4fv */ { 20, 0 },
+ /* Vertex4iv */ { 20, 0 },
+ /* Vertex4sv */ { 12, 0 },
+ /* ClipPlane */ { 40, 0 },
+ /* ColorMaterial */ { 12, 0 },
+ /* CullFace */ { 8, 0 },
+ /* Fogf */ { 12, 0 },
+ /* Fogfv */ { 8, __glXFogfvReqSize },
+ /* Fogi */ { 12, 0 },
+ /* Fogiv */ { 8, __glXFogivReqSize },
+ /* FrontFace */ { 8, 0 },
+ /* Hint */ { 12, 0 },
+ /* Lightf */ { 16, 0 },
+ /* Lightfv */ { 12, __glXLightfvReqSize },
+ /* Lighti */ { 16, 0 },
+ /* Lightiv */ { 12, __glXLightivReqSize },
+ /* LightModelf */ { 12, 0 },
+ /* LightModelfv */ { 8, __glXLightModelfvReqSize },
+ /* LightModeli */ { 12, 0 },
+ /* LightModeliv */ { 8, __glXLightModelivReqSize },
+ /* LineStipple */ { 12, 0 },
+ /* LineWidth */ { 8, 0 },
+ /* Materialf */ { 16, 0 },
+ /* Materialfv */ { 12, __glXMaterialfvReqSize },
+ /* Materiali */ { 16, 0 },
+ /* Materialiv */ { 12, __glXMaterialivReqSize },
+ /* PointSize */ { 8, 0 },
+ /* PolygonMode */ { 12, 0 },
+ /* PolygonStipple */ { 152, 0 },
+ /* Scissor */ { 20, 0 },
+ /* ShadeModel */ { 8, 0 },
+ /* TexParameterf */ { 16, 0 },
+ /* TexParameterfv */ { 12, __glXTexParameterfvReqSize },
+ /* TexParameteri */ { 16, 0 },
+ /* TexParameteriv */ { 12, __glXTexParameterivReqSize },
+ /* TexImage1D */ { 56, __glXTexImage1DReqSize },
+ /* TexImage2D */ { 56, __glXTexImage2DReqSize },
+ /* TexEnvf */ { 16, 0 },
+ /* TexEnvfv */ { 12, __glXTexEnvfvReqSize },
+ /* TexEnvi */ { 16, 0 },
+ /* TexEnviv */ { 12, __glXTexEnvivReqSize },
+ /* TexGend */ { 20, 0 },
+ /* TexGendv */ { 12, __glXTexGendvReqSize },
+ /* TexGenf */ { 16, 0 },
+ /* TexGenfv */ { 12, __glXTexGenfvReqSize },
+ /* TexGeni */ { 16, 0 },
+ /* TexGeniv */ { 12, __glXTexGenivReqSize },
+ /* InitNames */ { 4, 0 },
+ /* LoadName */ { 8, 0 },
+ /* PassThrough */ { 8, 0 },
+ /* PopName */ { 4, 0 },
+ /* PushName */ { 8, 0 },
+ /* DrawBuffer */ { 8, 0 },
+ /* Clear */ { 8, 0 },
+ /* ClearAccum */ { 20, 0 },
+ /* ClearIndex */ { 8, 0 },
+ /* ClearColor */ { 20, 0 },
+ /* ClearStencil */ { 8, 0 },
+ /* ClearDepth */ { 12, 0 },
+ /* StencilMask */ { 8, 0 },
+ /* ColorMask */ { 8, 0 },
+ /* DepthMask */ { 8, 0 },
+ /* IndexMask */ { 8, 0 },
+ /* Accum */ { 12, 0 },
+ /* Disable */ { 8, 0 },
+ /* Enable */ { 8, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* PopAttrib */ { 4, 0 },
+ /* PushAttrib */ { 8, 0 },
+ /* Map1d */ { 28, __glXMap1dReqSize },
+ /* Map1f */ { 20, __glXMap1fReqSize },
+ /* Map2d */ { 48, __glXMap2dReqSize },
+ /* Map2f */ { 32, __glXMap2fReqSize },
+ /* MapGrid1d */ { 24, 0 },
+ /* MapGrid1f */ { 16, 0 },
+ /* MapGrid2d */ { 44, 0 },
+ /* MapGrid2f */ { 28, 0 },
+ /* EvalCoord1dv */ { 12, 0 },
+ /* EvalCoord1fv */ { 8, 0 },
+ /* EvalCoord2dv */ { 20, 0 },
+ /* EvalCoord2fv */ { 12, 0 },
+ /* EvalMesh1 */ { 16, 0 },
+ /* EvalPoint1 */ { 8, 0 },
+ /* EvalMesh2 */ { 24, 0 },
+ /* EvalPoint2 */ { 12, 0 },
+ /* AlphaFunc */ { 12, 0 },
+ /* BlendFunc */ { 12, 0 },
+ /* LogicOp */ { 8, 0 },
+ /* StencilFunc */ { 16, 0 },
+ /* StencilOp */ { 16, 0 },
+ /* DepthFunc */ { 8, 0 },
+ /* PixelZoom */ { 12, 0 },
+ /* PixelTransferf */ { 12, 0 },
+ /* PixelTransferi */ { 12, 0 },
+ /* PixelMapfv */ { 12, __glXPixelMapfvReqSize },
+ /* PixelMapuiv */ { 12, __glXPixelMapuivReqSize },
+ /* PixelMapusv */ { 12, __glXPixelMapusvReqSize },
+ /* ReadBuffer */ { 8, 0 },
+ /* CopyPixels */ { 24, 0 },
+ /* DrawPixels */ { 40, __glXDrawPixelsReqSize },
+ /* DepthRange */ { 20, 0 },
+ /* Frustum */ { 52, 0 },
+ /* LoadIdentity */ { 4, 0 },
+ /* LoadMatrixf */ { 68, 0 },
+ /* LoadMatrixd */ { 132, 0 },
+ /* MatrixMode */ { 8, 0 },
+ /* MultMatrixf */ { 68, 0 },
+ /* MultMatrixd */ { 132, 0 },
+ /* Ortho */ { 52, 0 },
+ /* PopMatrix */ { 4, 0 },
+ /* PushMatrix */ { 4, 0 },
+ /* Rotated */ { 36, 0 },
+ /* Rotatef */ { 20, 0 },
+ /* Scaled */ { 28, 0 },
+ /* Scalef */ { 16, 0 },
+ /* Translated */ { 28, 0 },
+ /* Translatef */ { 16, 0 },
+ /* Viewport */ { 20, 0 },
+ /* PolygonOffset */ { 12, 0 },
+ /* DrawArrays */ { 16, __glXDrawArraysSize },
+ /* Indexubv */ { 8, 0 },
+ /* ColorSubTable */ { 44, __glXColorSubTableReqSize },
+ /* CopyColorSubTable */ { 24, 0 },
+ /* ActiveTextureARB */ { 8, 0 },
+ /* MultiTexCoord1dvARB */ { 16, 0 },
+ /* MultiTexCoord1fvARB */ { 12, 0 },
+ /* MultiTexCoord1ivARB */ { 12, 0 },
+ /* MultiTexCoord1svARB */ { 12, 0 },
+ /* MultiTexCoord2dvARB */ { 24, 0 },
+ /* MultiTexCoord2fvARB */ { 16, 0 },
+ /* MultiTexCoord2ivARB */ { 16, 0 },
+ /* MultiTexCoord2svARB */ { 12, 0 },
+ /* MultiTexCoord3dvARB */ { 32, 0 },
+ /* MultiTexCoord3fvARB */ { 20, 0 },
+ /* MultiTexCoord3ivARB */ { 20, 0 },
+ /* MultiTexCoord3svARB */ { 16, 0 },
+ /* MultiTexCoord4dvARB */ { 40, 0 },
+ /* MultiTexCoord4fvARB */ { 24, 0 },
+ /* MultiTexCoord4ivARB */ { 24, 0 },
+ /* MultiTexCoord4svARB 213 */ { 16, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode 220 */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* WindowPos3fARB 230 */ { 16, 0 },
+};
+__GLXrenderSizeData __glXRenderSizeTable_EXT[__GLX_MAX_RENDER_OPCODE_EXT - __GLX_MIN_RENDER_OPCODE_EXT + 1] = {
+ /* ColorTable 2053 */ { 44, __glXColorTableReqSize },
+ /* ColorTableParameterfv */ { 12, __glXColorTableParameterfvReqSize },
+ /* ColorTableParameteriv */ { 12, __glXColorTableParameterivReqSize },
+ /* CopyColorTable */ { 24, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* PointParameterfARB 2065 */ { 12, 0 },
+ /* PointParameterfvARB 2066 */ { 8, __glXPointParameterfvARBReqSize },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* BlendColor */ { 20, 0 },
+ /* BlendEquation */ { 8, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* TexSubImage1D */ { 60, __glXTexSubImage1DReqSize },
+ /* TexSubImage2D */ { 60, __glXTexSubImage2DReqSize },
+ /* ConvolutionFilter1D */ { 48, __glXConvolutionFilter1DReqSize },
+ /* ConvolutionFilter2D */ { 48, __glXConvolutionFilter2DReqSize },
+ /* ConvolutionParameterf */ { 16, 0 },
+ /* ConvolutionParameterfv */ { 12, __glXConvolutionParameterfvReqSize },
+ /* ConvolutionParameteri */ { 16, 0 },
+ /* ConvolutionParameteriv */ { 12, __glXConvolutionParameterivReqSize },
+ /* CopyConvolutionFilter1D */ { 24, },
+ /* CopyConvolutionFilter2D */ { 28, },
+ /* SeparableFilter2D */ { 48, __glXSeparableFilter2DReqSize },
+ /* Histogram */ { 20, },
+ /* Minmax */ { 16, },
+ /* ResetHistogram */ { 8, },
+ /* ResetMinmax */ { 8, },
+ /* TexImage3D */ { 84, __glXTexImage3DReqSize },
+ /* TexSubImage3D */ { 92, __glXTexSubImage3DReqSize },
+ /* DrawArrays */ { 16, __glXDrawArraysSize },
+ /* BindTexture */ { 12, 0 },
+ /* PrioritizeTextures */ { 8, __glXPrioritizeTexturesReqSize },
+ /* CopyTexImage1D */ { 32, 0 },
+ /* CopyTexImage2D */ { 36, 0 },
+ /* CopyTexSubImage1D */ { 28, 0 },
+ /* CopyTexSubImage2D */ { 36, 0 },
+ /* CopyTexSubImage3D 4123 */ { 40, 0 },
+ /* FogCoordfv 4124 */ { 8, 0 },
+ /* FogCoorddv 4125 */ { 12, 0 },
+ /* SecondaryColor3bv 4126 */ { 8, 0 },
+ /* SecondaryColor3sv 4127 */ { 12, 0 },
+ /* SecondaryColor3iv 4128 */ { 16, 0 },
+ /* SecondaryColor3fv 4129 */ { 16, 0 },
+ /* SecondaryColor3dv 4130 */ { 28, 0 },
+ /* SecondaryColor3ubv 4131 */ { 8, 0 },
+ /* SecondaryColor3usv 4132 */ { 12, 0 },
+ /* SecondaryColor3uiv 4133 */ { 16, 0 },
+ /* BlendFuncSeparate 4134 */ { 20, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* no such opcode */ { 0, 0 },
+ /* ActiveStencilFaceEXT 4220 */ { 8, 0 },
+ /* PointParameteri 4221 */ { 12, 0 },
+ /* PointParameteriv 4222 */ { 8, __glXPointParameterivReqSize },
+};
diff --git a/nx-X11/programs/Xserver/GL/glx/single2.c b/nx-X11/programs/Xserver/GL/glx/single2.c
new file mode 100644
index 000000000..47ba628af
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/single2.c
@@ -0,0 +1,425 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "unpack.h"
+#include "g_disptab.h"
+
+int __glXDisp_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ GLsizei size;
+ GLenum type;
+ __GLXcontext *cx;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ size = *(GLsizei *)(pc+0);
+ type = *(GLenum *)(pc+4);
+ if (cx->feedbackBufSize < size) {
+ cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
+ (size_t)size
+ * __GLX_SIZE_FLOAT32);
+ if (!cx->feedbackBuf) {
+ cl->client->errorValue = size;
+ return BadAlloc;
+ }
+ cx->feedbackBufSize = size;
+ }
+ glFeedbackBuffer(size, type, cx->feedbackBuf);
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_SelectBuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ GLsizei size;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ size = *(GLsizei *)(pc+0);
+ if (cx->selectBufSize < size) {
+ cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
+ (size_t) size
+ * __GLX_SIZE_CARD32);
+ if (!cx->selectBuf) {
+ cl->client->errorValue = size;
+ return BadAlloc;
+ }
+ cx->selectBufSize = size;
+ }
+ glSelectBuffer(size, cx->selectBuf);
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_RenderMode(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXRenderModeReply reply;
+ __GLXcontext *cx;
+ GLint nitems=0, retBytes=0, retval, newModeCheck;
+ GLubyte *retBuffer = NULL;
+ GLenum newMode;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ newMode = *(GLenum*) pc;
+ retval = glRenderMode(newMode);
+
+ /* Check that render mode worked */
+ glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
+ if (newModeCheck != newMode) {
+ /* Render mode change failed. Bail */
+ newMode = newModeCheck;
+ goto noChangeAllowed;
+ }
+
+ /*
+ ** Render mode might have still failed if we get here. But in this
+ ** case we can't really tell, nor does it matter. If it did fail, it
+ ** will return 0, and thus we won't send any data across the wire.
+ */
+
+ switch (cx->renderMode) {
+ case GL_RENDER:
+ cx->renderMode = newMode;
+ break;
+ case GL_FEEDBACK:
+ if (retval < 0) {
+ /* Overflow happened. Copy the entire buffer */
+ nitems = cx->feedbackBufSize;
+ } else {
+ nitems = retval;
+ }
+ retBytes = nitems * __GLX_SIZE_FLOAT32;
+ retBuffer = (GLubyte*) cx->feedbackBuf;
+ cx->renderMode = newMode;
+ break;
+ case GL_SELECT:
+ if (retval < 0) {
+ /* Overflow happened. Copy the entire buffer */
+ nitems = cx->selectBufSize;
+ } else {
+ GLuint *bp = cx->selectBuf;
+ GLint i;
+
+ /*
+ ** Figure out how many bytes of data need to be sent. Parse
+ ** the selection buffer to determine this fact as the
+ ** return value is the number of hits, not the number of
+ ** items in the buffer.
+ */
+ nitems = 0;
+ i = retval;
+ while (--i >= 0) {
+ GLuint n;
+
+ /* Parse select data for this hit */
+ n = *bp;
+ bp += 3 + n;
+ }
+ nitems = bp - cx->selectBuf;
+ }
+ retBytes = nitems * __GLX_SIZE_CARD32;
+ retBuffer = (GLubyte*) cx->selectBuf;
+ cx->renderMode = newMode;
+ break;
+ }
+
+ /*
+ ** First reply is the number of elements returned in the feedback or
+ ** selection array, as per the API for glRenderMode itself.
+ */
+ noChangeAllowed:;
+ reply.length = nitems;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.retval = retval;
+ reply.size = nitems;
+ reply.newMode = newMode;
+ WriteToClient(client, sz_xGLXRenderModeReply, &reply);
+ if (retBytes) {
+ WriteToClient(client, retBytes, retBuffer);
+ }
+ return Success;
+}
+
+int __glXDisp_Flush(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ int error;
+
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ glFlush();
+ __GLX_NOTE_FLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDisp_Finish(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ int error;
+
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ /* Do a local glFinish */
+ glFinish();
+ __GLX_NOTE_FLUSHED_CMDS(cx);
+
+ /* Send empty reply packet to indicate finish is finished */
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ return Success;
+}
+
+#define SEPARATOR " "
+
+char *__glXcombine_strings(const char *cext_string, const char *sext_string)
+{
+ size_t clen, slen;
+ char *combo_string, *token, *s1;
+ const char *s2, *end;
+
+ /* safeguard to prevent potentially fatal errors in the string functions */
+ if (!cext_string)
+ cext_string = "";
+ if (!sext_string)
+ sext_string = "";
+
+ /*
+ ** String can't be longer than min(cstring, sstring)
+ ** pull tokens out of shortest string
+ ** include space in combo_string for final separator and null terminator
+ */
+ clen = strlen(cext_string);
+ slen = strlen(sext_string);
+ if (clen > slen) {
+ combo_string = (char *) malloc(slen + 2);
+ s1 = (char *) malloc(slen + 2);
+ strcpy(s1, sext_string);
+ s2 = cext_string;
+ } else {
+ combo_string = (char *) malloc(clen + 2);
+ s1 = (char *) malloc(clen + 2);
+ strcpy(s1, cext_string);
+ s2 = sext_string;
+ }
+ if (!combo_string || !s1) {
+ if (combo_string)
+ free(combo_string);
+ if (s1)
+ free(s1);
+ return NULL;
+ }
+ combo_string[0] = '\0';
+
+ /* Get first extension token */
+ token = strtok( s1, SEPARATOR);
+ while ( token != NULL ) {
+
+ /*
+ ** if token in second string then save it
+ ** beware of extension names which are prefixes of other extension names
+ */
+ const char *p = s2;
+ end = p + strlen(p);
+ while (p < end) {
+ size_t n = strcspn(p, SEPARATOR);
+ if ((strlen(token) == n) && (strncmp(token, p, n) == 0)) {
+ combo_string = strcat(combo_string, token);
+ combo_string = strcat(combo_string, SEPARATOR);
+ }
+ p += (n + 1);
+ }
+
+ /* Get next extension token */
+ token = strtok( NULL, SEPARATOR);
+ }
+ free(s1);
+ return combo_string;
+}
+
+int DoGetString(__GLXclientState *cl, GLbyte *pc, GLboolean need_swap)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ GLenum name;
+ const char *string;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ int error;
+ char *buf = NULL, *buf1 = NULL;
+ GLint length = 0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
+ /* If the client has the opposite byte order, swap the contextTag and
+ * the name.
+ */
+ if ( need_swap ) {
+ __GLX_SWAP_INT(pc + 4);
+ __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE);
+ }
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ name = *(GLenum *)(pc + 0);
+ string = (const char *)glGetString(name);
+
+ /*
+ ** Restrict extensions to those that are supported by both the
+ ** implementation and the connection. That is, return the
+ ** intersection of client, server, and core extension strings.
+ */
+ if (name == GL_EXTENSIONS) {
+ buf1 = __glXcombine_strings(string,
+ cl->GLClientextensions);
+ buf = __glXcombine_strings(buf1,
+ cx->pGlxScreen->GLextensions);
+ if (buf1 != NULL) {
+ free(buf1);
+ }
+ string = buf;
+ }
+ else if ( name == GL_VERSION ) {
+ if ( atof( string ) > atof( GLServerVersion ) ) {
+ buf = malloc( strlen( string ) + strlen( GLServerVersion ) + 4 );
+ if ( buf == NULL ) {
+ string = GLServerVersion;
+ }
+ else {
+ sprintf( buf, "%s (%s)", GLServerVersion, string );
+ string = buf;
+ }
+ }
+ }
+ if (string) {
+ length = strlen((const char *) string) + 1;
+ }
+
+ __GLX_BEGIN_REPLY(length);
+ __GLX_PUT_SIZE(length);
+
+ if ( need_swap ) {
+ __GLX_SWAP_REPLY_SIZE();
+ __GLX_SWAP_REPLY_HEADER();
+ }
+
+ __GLX_SEND_HEADER();
+ WriteToClient(client, length, string);
+ if (buf != NULL) {
+ free(buf);
+ }
+ return Success;
+}
+
+int __glXDisp_GetString(__GLXclientState *cl, GLbyte *pc)
+{
+ return DoGetString(cl, pc, GL_FALSE);
+}
+
+int __glXDisp_GetClipPlane(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answer[4];
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+
+ __glXClearErrorOccured();
+ glGetClipPlane(*(GLenum *)(pc + 0), answer);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(32);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(4);
+ }
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/single2swap.c b/nx-X11/programs/Xserver/GL/glx/single2swap.c
new file mode 100644
index 000000000..6fdc7e7f2
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/single2swap.c
@@ -0,0 +1,307 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "unpack.h"
+#include "g_disptab.h"
+
+int __glXDispSwap_FeedbackBuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ GLsizei size;
+ GLenum type;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLXcontext *cx;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 8);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ size = *(GLsizei *)(pc+0);
+ type = *(GLenum *)(pc+4);
+ if (cx->feedbackBufSize < size) {
+ cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf,
+ (size_t) size
+ * __GLX_SIZE_FLOAT32);
+ if (!cx->feedbackBuf) {
+ cl->client->errorValue = size;
+ return BadAlloc;
+ }
+ cx->feedbackBufSize = size;
+ }
+ glFeedbackBuffer(size, type, cx->feedbackBuf);
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_SelectBuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ GLsizei size;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ size = *(GLsizei *)(pc+0);
+ if (cx->selectBufSize < size) {
+ cx->selectBuf = (GLuint *) realloc(cx->selectBuf,
+ (size_t) size
+ * __GLX_SIZE_CARD32);
+ if (!cx->selectBuf) {
+ cl->client->errorValue = size;
+ return BadAlloc;
+ }
+ cx->selectBufSize = size;
+ }
+ glSelectBuffer(size, cx->selectBuf);
+ __GLX_NOTE_UNFLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_RenderMode(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ xGLXRenderModeReply reply;
+ GLint nitems=0, retBytes=0, retval, newModeCheck;
+ GLubyte *retBuffer = NULL;
+ GLenum newMode;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+ int error;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc);
+ newMode = *(GLenum*) pc;
+ retval = glRenderMode(newMode);
+
+ /* Check that render mode worked */
+ glGetIntegerv(GL_RENDER_MODE, &newModeCheck);
+ if (newModeCheck != newMode) {
+ /* Render mode change failed. Bail */
+ newMode = newModeCheck;
+ goto noChangeAllowed;
+ }
+
+ /*
+ ** Render mode might have still failed if we get here. But in this
+ ** case we can't really tell, nor does it matter. If it did fail, it
+ ** will return 0, and thus we won't send any data across the wire.
+ */
+
+ switch (cx->renderMode) {
+ case GL_RENDER:
+ cx->renderMode = newMode;
+ break;
+ case GL_FEEDBACK:
+ if (retval < 0) {
+ /* Overflow happened. Copy the entire buffer */
+ nitems = cx->feedbackBufSize;
+ } else {
+ nitems = retval;
+ }
+ retBytes = nitems * __GLX_SIZE_FLOAT32;
+ retBuffer = (GLubyte*) cx->feedbackBuf;
+ __GLX_SWAP_FLOAT_ARRAY((GLbyte *)retBuffer, nitems);
+ cx->renderMode = newMode;
+ break;
+ case GL_SELECT:
+ if (retval < 0) {
+ /* Overflow happened. Copy the entire buffer */
+ nitems = cx->selectBufSize;
+ } else {
+ GLuint *bp = cx->selectBuf;
+ GLint i;
+
+ /*
+ ** Figure out how many bytes of data need to be sent. Parse
+ ** the selection buffer to determine this fact as the
+ ** return value is the number of hits, not the number of
+ ** items in the buffer.
+ */
+ nitems = 0;
+ i = retval;
+ while (--i >= 0) {
+ GLuint n;
+
+ /* Parse select data for this hit */
+ n = *bp;
+ bp += 3 + n;
+ }
+ nitems = bp - cx->selectBuf;
+ }
+ retBytes = nitems * __GLX_SIZE_CARD32;
+ retBuffer = (GLubyte*) cx->selectBuf;
+ __GLX_SWAP_INT_ARRAY((GLbyte *)retBuffer, nitems);
+ cx->renderMode = newMode;
+ break;
+ }
+
+ /*
+ ** First reply is the number of elements returned in the feedback or
+ ** selection array, as per the API for glRenderMode itself.
+ */
+ noChangeAllowed:;
+ reply.length = nitems;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.retval = retval;
+ reply.size = nitems;
+ reply.newMode = newMode;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.retval);
+ __GLX_SWAP_INT(&reply.size);
+ __GLX_SWAP_INT(&reply.newMode);
+ WriteToClient(client, sz_xGLXRenderModeReply, &reply);
+ if (retBytes) {
+ WriteToClient(client, retBytes, retBuffer);
+ }
+ return Success;
+}
+
+int __glXDispSwap_Flush(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ glFlush();
+ __GLX_NOTE_FLUSHED_CMDS(cx);
+ return Success;
+}
+
+int __glXDispSwap_Finish(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *cx;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ REQUEST_SIZE_MATCH(xGLXSingleReq);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ /* Do a local glFinish */
+ glFinish();
+ __GLX_NOTE_FLUSHED_CMDS(cx);
+
+ /* Send empty reply packet to indicate finish is finished */
+ __GLX_BEGIN_REPLY(0);
+ __GLX_PUT_RETVAL(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+
+ return Success;
+}
+
+int __glXDispSwap_GetString(__GLXclientState *cl, GLbyte *pc)
+{
+ return DoGetString(cl, pc, GL_TRUE);
+}
+
+int __glXDispSwap_GetClipPlane(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLdouble answer[4];
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc + 0);
+
+ __glXClearErrorOccured();
+ glGetClipPlane(*(GLenum *)(pc + 0), answer);
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_SWAP_DOUBLE_ARRAY((GLbyte *)answer, 4);
+ __GLX_BEGIN_REPLY(32);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_DOUBLE_ARRAY(4);
+ }
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/singlepix.c b/nx-X11/programs/Xserver/GL/glx/singlepix.c
new file mode 100644
index 000000000..9e3e36333
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/singlepix.c
@@ -0,0 +1,469 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "singlesize.h"
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+
+int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei width, height;
+ GLenum format, type;
+ GLboolean swapBytes, lsbFirst;
+ GLint compsize;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ width = *(GLsizei *)(pc + 8);
+ height = *(GLsizei *)(pc + 12);
+ format = *(GLenum *)(pc + 16);
+ type = *(GLenum *)(pc + 20);
+ swapBytes = *(GLboolean *)(pc + 24);
+ lsbFirst = *(GLboolean *)(pc + 25);
+ compsize = __glReadPixels_size(format,type,width,height);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glReadPixels(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12),
+ *(GLenum *)(pc + 16),
+ *(GLenum *)(pc + 20),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetTexImage(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint level, compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0, depth=1;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 20);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ level = *(GLint *)(pc + 4);
+ format = *(GLenum *)(pc + 8);
+ type = *(GLenum *)(pc + 12);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 16);
+
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+ if ( target == GL_TEXTURE_3D) {
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
+ }
+ /*
+ * The three queries above might fail if we're in a state where queries
+ * are illegal, but then width, height, and depth would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,level,format,type,width,height,depth);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetTexImage(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLenum *)(pc + 12),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ ((xGLXGetTexImageReply *)&__glXReply)->width = width;
+ ((xGLXGetTexImageReply *)&__glXReply)->height = height;
+ ((xGLXGetTexImageReply *)&__glXReply)->depth = depth;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDisp_GetPolygonStipple(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean lsbFirst;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLubyte answerBuffer[200];
+ char *answer;
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ lsbFirst = *(GLboolean *)(pc + 0);
+
+ glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,128,1);
+
+ __glXClearErrorOccured();
+ glGetPolygonStipple(
+ (GLubyte *) answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(128);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(128);
+ }
+ return Success;
+}
+
+int __glXDisp_GetSeparableFilter(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize, compsize2;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ /* target must be SEPARABLE_2D, however I guess we can let the GL
+ barf on this one.... */
+
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
+ /*
+ * The two queries above might fail if we're in a state where queries
+ * are illegal, but then width and height would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ compsize2 = __glGetTexImage_size(target,1,format,type,height,1,1);
+
+ if ((compsize = safe_pad(compsize)) < 0) return BadLength;
+ if ((compsize2 = safe_pad(compsize2)) < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,safe_add(compsize, compsize2),1);
+ __glXClearErrorOccured();
+ glGetSeparableFilter(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer,
+ answer + compsize,
+ NULL
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize + compsize2);
+ ((xGLXGetSeparableFilterReply *)&__glXReply)->width = width;
+ ((xGLXGetSeparableFilterReply *)&__glXReply)->height = height;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize + compsize2);
+ }
+
+ return Success;
+}
+
+int __glXDisp_GetConvolutionFilter(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
+ if (target == GL_CONVOLUTION_1D) {
+ height = 1;
+ } else {
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
+ }
+ /*
+ * The two queries above might fail if we're in a state where queries
+ * are illegal, but then width and height would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,height,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetConvolutionFilter(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ ((xGLXGetConvolutionFilterReply *)&__glXReply)->width = width;
+ ((xGLXGetConvolutionFilterReply *)&__glXReply)->height = height;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDisp_GetHistogram(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes, reset;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+ reset = *(GLboolean *)(pc + 13);
+
+ glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width);
+ /*
+ * The one query above might fail if we're in a state where queries
+ * are illegal, but then width would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetHistogram( target, reset, format, type, answer);
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ ((xGLXGetHistogramReply *)&__glXReply)->width = width;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDisp_GetMinmax(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes, reset;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+ reset = *(GLboolean *)(pc + 13);
+
+ compsize = __glGetTexImage_size(target,1,format,type,2,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetMinmax( target, reset, format, type, answer);
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDisp_GetColorTable(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ target = *(GLenum *)(pc + 0);
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width);
+ /*
+ * The one query above might fail if we're in a state where queries
+ * are illegal, but then width would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetColorTable(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ ((xGLXGetColorTableReply *)&__glXReply)->width = width;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/singlepixswap.c b/nx-X11/programs/Xserver/GL/glx/singlepixswap.c
new file mode 100644
index 000000000..f029fd602
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/singlepixswap.c
@@ -0,0 +1,523 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "singlesize.h"
+#include "unpack.h"
+#include "g_disptab.h"
+#include "g_disptab_EXT.h"
+
+int __glXDispSwap_ReadPixels(__GLXclientState *cl, GLbyte *pc)
+{
+ GLsizei width, height;
+ GLenum format, type;
+ GLboolean swapBytes, lsbFirst;
+ GLint compsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 28);
+
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+ __GLX_SWAP_INT(pc+12);
+ __GLX_SWAP_INT(pc+16);
+ __GLX_SWAP_INT(pc+20);
+
+ width = *(GLsizei *)(pc + 8);
+ height = *(GLsizei *)(pc + 12);
+ format = *(GLenum *)(pc + 16);
+ type = *(GLenum *)(pc + 20);
+ swapBytes = *(GLboolean *)(pc + 24);
+ lsbFirst = *(GLboolean *)(pc + 25);
+ compsize = __glReadPixels_size(format,type,width,height);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glReadPixels(
+ *(GLint *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLsizei *)(pc + 8),
+ *(GLsizei *)(pc + 12),
+ *(GLenum *)(pc + 16),
+ *(GLenum *)(pc + 20),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint level, compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0, depth=1;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 24);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+ __GLX_SWAP_INT(pc+12);
+
+ level = *(GLint *)(pc + 4);
+ format = *(GLenum *)(pc + 8);
+ type = *(GLenum *)(pc + 12);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 16);
+
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+ if ( target == GL_TEXTURE_3D) {
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
+ }
+ /*
+ * The three queries above might fail if we're in a state where queries
+ * are illegal, but then width, height, and depth would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,level,format,type,width,height,depth);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetTexImage(
+ *(GLenum *)(pc + 0),
+ *(GLint *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ *(GLenum *)(pc + 12),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SWAP_INT(&width);
+ __GLX_SWAP_INT(&height);
+ __GLX_SWAP_INT(&depth);
+ ((xGLXGetTexImageReply *)&__glXReply)->width = width;
+ ((xGLXGetTexImageReply *)&__glXReply)->height = height;
+ ((xGLXGetTexImageReply *)&__glXReply)->depth = depth;
+ __GLX_SEND_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetPolygonStipple(__GLXclientState *cl, GLbyte *pc)
+{
+ GLboolean lsbFirst;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ GLubyte answerBuffer[200];
+ char *answer;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 4);
+ __GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+ pc += __GLX_SINGLE_HDR_SIZE;
+ lsbFirst = *(GLboolean *)(pc + 0);
+
+ glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,128,1);
+
+ __glXClearErrorOccured();
+ glGetPolygonStipple(
+ (GLubyte *) answer
+ );
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(128);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_HEADER();
+ __GLX_SEND_BYTE_ARRAY(128);
+ }
+ return Success;
+}
+
+int __glXDispSwap_GetSeparableFilter(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize, compsize2;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ /* target must be SEPARABLE_2D, however I guess we can let the GL
+ barf on this one.... */
+
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
+ /*
+ * The two queries above might fail if we're in a state where queries
+ * are illegal, but then width and height would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ compsize2 = __glGetTexImage_size(target,1,format,type,height,1,1);
+
+ if ((compsize = safe_pad(compsize)) < 0) return BadLength;
+ if ((compsize2 = safe_pad(compsize2)) < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,safe_add(compsize, compsize2),1);
+ __glXClearErrorOccured();
+ glGetSeparableFilter(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer,
+ answer + compsize,
+ NULL
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize + compsize2);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SWAP_INT(&width);
+ __GLX_SWAP_INT(&height);
+ ((xGLXGetSeparableFilterReply *)&__glXReply)->width = width;
+ ((xGLXGetSeparableFilterReply *)&__glXReply)->height = height;
+ __GLX_SEND_VOID_ARRAY(compsize + compsize2);
+ }
+
+ return Success;
+}
+
+int __glXDispSwap_GetConvolutionFilter(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ char *answer, answerBuffer[200];
+ GLint width=0, height=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_WIDTH, &width);
+ if (target == GL_CONVOLUTION_2D) {
+ height = 1;
+ } else {
+ glGetConvolutionParameteriv(target, GL_CONVOLUTION_HEIGHT, &height);
+ }
+ /*
+ * The two queries above might fail if we're in a state where queries
+ * are illegal, but then width and height would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,height,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetConvolutionFilter(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SWAP_INT(&width);
+ __GLX_SWAP_INT(&height);
+ ((xGLXGetConvolutionFilterReply *)&__glXReply)->width = width;
+ ((xGLXGetConvolutionFilterReply *)&__glXReply)->height = height;
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDispSwap_GetHistogram(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes, reset;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ char *answer, answerBuffer[200];
+ GLint width=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+ reset = *(GLboolean *)(pc + 13);
+
+ glGetHistogramParameteriv(target, GL_HISTOGRAM_WIDTH, &width);
+ /*
+ * The one query above might fail if we're in a state where queries
+ * are illegal, but then width would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetHistogram( target, reset, format, type, answer);
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SWAP_INT(&width);
+ ((xGLXGetHistogramReply *)&__glXReply)->width = width;
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDispSwap_GetMinmax(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes, reset;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ char *answer, answerBuffer[200];
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+ reset = *(GLboolean *)(pc + 13);
+
+ compsize = __glGetTexImage_size(target,1,format,type,2,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetMinmax( target, reset, format, type, answer);
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
+
+int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc)
+{
+ GLint compsize;
+ GLenum format, type, target;
+ GLboolean swapBytes;
+ __GLXcontext *cx;
+ ClientPtr client = cl->client;
+ int error;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ char *answer, answerBuffer[200];
+ GLint width=0;
+
+ REQUEST_FIXED_SIZE(xGLXSingleReq, 16);
+ cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);
+ if (!cx) {
+ return error;
+ }
+
+ pc += __GLX_SINGLE_HDR_SIZE;
+ __GLX_SWAP_INT(pc+0);
+ __GLX_SWAP_INT(pc+4);
+ __GLX_SWAP_INT(pc+8);
+
+ format = *(GLenum *)(pc + 4);
+ type = *(GLenum *)(pc + 8);
+ target = *(GLenum *)(pc + 0);
+ swapBytes = *(GLboolean *)(pc + 12);
+
+ glGetColorTableParameteriv(target, GL_COLOR_TABLE_WIDTH, &width);
+ /*
+ * The one query above might fail if we're in a state where queries
+ * are illegal, but then width would still be zero anyway.
+ */
+ compsize = __glGetTexImage_size(target,1,format,type,width,1,1);
+ if (compsize < 0) return BadLength;
+
+ glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes);
+ __GLX_GET_ANSWER_BUFFER(answer,cl,compsize,1);
+ __glXClearErrorOccured();
+ glGetColorTable(
+ *(GLenum *)(pc + 0),
+ *(GLenum *)(pc + 4),
+ *(GLenum *)(pc + 8),
+ answer
+ );
+
+ if (__glXErrorOccured()) {
+ __GLX_BEGIN_REPLY(0);
+ __GLX_SWAP_REPLY_HEADER();
+ } else {
+ __GLX_BEGIN_REPLY(compsize);
+ __GLX_SWAP_REPLY_HEADER();
+ __GLX_SWAP_INT(&width);
+ ((xGLXGetColorTableReply *)&__glXReply)->width = width;
+ __GLX_SEND_VOID_ARRAY(compsize);
+ }
+
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/GL/glx/singlesize.c b/nx-X11/programs/Xserver/GL/glx/singlesize.c
new file mode 100644
index 000000000..6d77f8be9
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/singlesize.c
@@ -0,0 +1,1221 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <GL/gl.h>
+#include "glxserver.h"
+#include "singlesize.h"
+
+/*
+** These routines compute the size of variable-size returned parameters.
+** Unlike the similar routines that do the same thing for variable-size
+** incoming parameters, the samplegl library itself doesn't use these routines.
+** Hence, they are located here, in the GLX extension library.
+*/
+
+GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h)
+{
+ return __glXImageSize( format, type, 0, w, h, 1, 0, 0, 0, 0, 4 );
+}
+
+/**
+ * Determine the number of data elements that go with the specified \c pname
+ * to a \c glGetTexEnvfv or \c glGetTexEnviv call.
+ *
+ * \todo
+ * Replace this function with a call to \c __glTexEnvfv_size. Make that there
+ * aren't any values of \c pname that are valid for one but not the other.
+ */
+GLint __glGetTexEnvfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ case GL_TEXTURE_LOD_BIAS:
+ case GL_COMBINE_RGB:
+ case GL_COMBINE_ALPHA:
+ case GL_SOURCE0_RGB:
+ case GL_SOURCE1_RGB:
+ case GL_SOURCE2_RGB:
+ case GL_SOURCE0_ALPHA:
+ case GL_SOURCE1_ALPHA:
+ case GL_SOURCE2_ALPHA:
+ case GL_OPERAND0_RGB:
+ case GL_OPERAND1_RGB:
+ case GL_OPERAND2_RGB:
+ case GL_OPERAND0_ALPHA:
+ case GL_OPERAND1_ALPHA:
+ case GL_OPERAND2_ALPHA:
+ case GL_RGB_SCALE:
+ case GL_ALPHA_SCALE:
+
+ /* GL_ARB_point_sprite / GL_NV_point_sprite */
+ case GL_COORD_REPLACE_ARB:
+
+ /* GL_NV_texture_env_combine4 */
+ case GL_SOURCE3_RGB_NV:
+ case GL_SOURCE3_ALPHA_NV:
+ case GL_OPERAND3_RGB_NV:
+ case GL_OPERAND3_ALPHA_NV:
+ return 1;
+
+ case GL_TEXTURE_ENV_COLOR:
+ return 4;
+ default:
+ return -1;
+ }
+}
+
+
+GLint __glGetTexEnviv_size(GLenum pname)
+{
+ return __glGetTexEnvfv_size(pname);
+}
+
+GLint __glGetTexGenfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ return 1;
+ case GL_OBJECT_PLANE:
+ return 4;
+ case GL_EYE_PLANE:
+ return 4;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetTexGendv_size(GLenum pname)
+{
+ return __glGetTexGenfv_size(pname);
+}
+
+GLint __glGetTexGeniv_size(GLenum pname)
+{
+ return __glGetTexGenfv_size(pname);
+}
+
+GLint __glGetTexParameterfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_TEXTURE_BORDER_COLOR:
+ return 4;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_PRIORITY:
+ case GL_TEXTURE_RESIDENT:
+
+ /* GL_SGIS_texture_lod / GL_EXT_texture_lod / GL 1.2 */
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+
+ /* GL_SGIX_texture_lod_bias */
+ case GL_TEXTURE_LOD_BIAS_S_SGIX:
+ case GL_TEXTURE_LOD_BIAS_T_SGIX:
+ case GL_TEXTURE_LOD_BIAS_R_SGIX:
+
+ /* GL_ARB_shadow / GL 1.4 */
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+
+ /* GL_SGIS_generate_mipmap / GL 1.4 */
+ case GL_GENERATE_MIPMAP:
+
+ /* GL_ARB_depth_texture / GL 1.4 */
+ case GL_DEPTH_TEXTURE_MODE:
+
+ /* GL_EXT_texture_lod_bias / GL 1.4 */
+ case GL_TEXTURE_LOD_BIAS:
+
+ /* GL_SGIX_shadow_ambient / GL_ARB_shadow_ambient */
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+
+ /* GL_SGIX_shadow */
+ case GL_TEXTURE_COMPARE_SGIX:
+ case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
+
+ /* GL_SGIX_texture_coordinate_clamp */
+ case GL_TEXTURE_MAX_CLAMP_S_SGIX:
+ case GL_TEXTURE_MAX_CLAMP_T_SGIX:
+ case GL_TEXTURE_MAX_CLAMP_R_SGIX:
+
+ /* GL_EXT_texture_filter_anisotropic */
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+
+ /* GL_NV_texture_expand_normal */
+ case GL_TEXTURE_UNSIGNED_REMAP_MODE_NV:
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetTexParameteriv_size(GLenum pname)
+{
+ return __glGetTexParameterfv_size(pname);
+}
+
+GLint __glGetLightfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_AMBIENT:
+ return 4;
+ case GL_DIFFUSE:
+ return 4;
+ case GL_SPECULAR:
+ return 4;
+ case GL_POSITION:
+ return 4;
+ case GL_SPOT_DIRECTION:
+ return 3;
+ case GL_SPOT_EXPONENT:
+ return 1;
+ case GL_SPOT_CUTOFF:
+ return 1;
+ case GL_CONSTANT_ATTENUATION:
+ return 1;
+ case GL_LINEAR_ATTENUATION:
+ return 1;
+ case GL_QUADRATIC_ATTENUATION:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetLightiv_size(GLenum pname)
+{
+ return __glGetLightfv_size(pname);
+}
+
+GLint __glGetMap_size(GLenum target, GLenum query)
+{
+ GLint k, order=0, majorMinor[2];
+
+ /*
+ ** Assume target and query are both valid.
+ */
+ switch (target) {
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_INDEX:
+ case GL_MAP1_TEXTURE_COORD_1:
+ case GL_MAP1_TEXTURE_COORD_2:
+ case GL_MAP1_TEXTURE_COORD_3:
+ case GL_MAP1_TEXTURE_COORD_4:
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_VERTEX_4:
+ switch (query) {
+ case GL_COEFF:
+ k = __glMap1d_size(target);
+ glGetMapiv(target, GL_ORDER, &order);
+ /*
+ ** The query above might fail, but then order will be zero anyway.
+ */
+ return (order * k);
+ case GL_DOMAIN:
+ return 2;
+ case GL_ORDER:
+ return 1;
+ }
+ break;
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_INDEX:
+ case GL_MAP2_TEXTURE_COORD_1:
+ case GL_MAP2_TEXTURE_COORD_2:
+ case GL_MAP2_TEXTURE_COORD_3:
+ case GL_MAP2_TEXTURE_COORD_4:
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_VERTEX_4:
+ switch (query) {
+ case GL_COEFF:
+ k = __glMap2d_size(target);
+ majorMinor[0] = majorMinor[1] = 0;
+ glGetMapiv(target, GL_ORDER, majorMinor);
+ /*
+ ** The query above might fail, but then majorMinor will be zeroes
+ */
+ return (majorMinor[0] * majorMinor[1] * k);
+ case GL_DOMAIN:
+ return 4;
+ case GL_ORDER:
+ return 2;
+ }
+ break;
+ }
+ return -1;
+}
+
+GLint __glGetMapdv_size(GLenum target, GLenum query)
+{
+ return __glGetMap_size(target, query);
+}
+
+GLint __glGetMapfv_size(GLenum target, GLenum query)
+{
+ return __glGetMap_size(target, query);
+}
+
+GLint __glGetMapiv_size(GLenum target, GLenum query)
+{
+ return __glGetMap_size(target, query);
+}
+
+GLint __glGetMaterialfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_SHININESS:
+ return 1;
+ case GL_COLOR_INDEXES:
+ return 3;
+ case GL_EMISSION:
+ return 4;
+ case GL_AMBIENT:
+ return 4;
+ case GL_DIFFUSE:
+ return 4;
+ case GL_SPECULAR:
+ return 4;
+ case GL_AMBIENT_AND_DIFFUSE:
+ return 4;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetMaterialiv_size(GLenum pname)
+{
+ return __glGetMaterialfv_size(pname);
+}
+
+GLint __glGetPixelMap_size(GLenum map)
+{
+ GLint size;
+ GLenum query;
+
+ switch (map) {
+ case GL_PIXEL_MAP_I_TO_I:
+ query = GL_PIXEL_MAP_I_TO_I_SIZE;
+ break;
+ case GL_PIXEL_MAP_S_TO_S:
+ query = GL_PIXEL_MAP_S_TO_S_SIZE;
+ break;
+ case GL_PIXEL_MAP_I_TO_R:
+ query = GL_PIXEL_MAP_I_TO_R_SIZE;
+ break;
+ case GL_PIXEL_MAP_I_TO_G:
+ query = GL_PIXEL_MAP_I_TO_G_SIZE;
+ break;
+ case GL_PIXEL_MAP_I_TO_B:
+ query = GL_PIXEL_MAP_I_TO_B_SIZE;
+ break;
+ case GL_PIXEL_MAP_I_TO_A:
+ query = GL_PIXEL_MAP_I_TO_A_SIZE;
+ break;
+ case GL_PIXEL_MAP_R_TO_R:
+ query = GL_PIXEL_MAP_R_TO_R_SIZE;
+ break;
+ case GL_PIXEL_MAP_G_TO_G:
+ query = GL_PIXEL_MAP_G_TO_G_SIZE;
+ break;
+ case GL_PIXEL_MAP_B_TO_B:
+ query = GL_PIXEL_MAP_B_TO_B_SIZE;
+ break;
+ case GL_PIXEL_MAP_A_TO_A:
+ query = GL_PIXEL_MAP_A_TO_A_SIZE;
+ break;
+ default:
+ return -1;
+ }
+ glGetIntegerv(query, &size);
+ return size;
+}
+
+GLint __glGetPixelMapfv_size(GLenum map)
+{
+ return __glGetPixelMap_size(map);
+}
+
+GLint __glGetPixelMapuiv_size(GLenum map)
+{
+ return __glGetPixelMap_size(map);
+}
+
+GLint __glGetPixelMapusv_size(GLenum map)
+{
+ return __glGetPixelMap_size(map);
+}
+
+/*
+** Return the number of words needed to pass back the requested
+** value.
+*/
+GLint __glGet_size(GLenum sq)
+{
+ switch (sq) {
+ case GL_MAX_TEXTURE_SIZE:
+ return 1;
+ case GL_SUBPIXEL_BITS:
+ return 1;
+ case GL_MAX_LIST_NESTING:
+ return 1;
+ case GL_MAP1_COLOR_4:
+ case GL_MAP1_INDEX:
+ case GL_MAP1_NORMAL:
+ case GL_MAP1_TEXTURE_COORD_1:
+ case GL_MAP1_TEXTURE_COORD_2:
+ case GL_MAP1_TEXTURE_COORD_3:
+ case GL_MAP1_TEXTURE_COORD_4:
+ case GL_MAP1_VERTEX_3:
+ case GL_MAP1_VERTEX_4:
+ return 1;
+ case GL_MAP2_COLOR_4:
+ case GL_MAP2_INDEX:
+ case GL_MAP2_NORMAL:
+ case GL_MAP2_TEXTURE_COORD_1:
+ case GL_MAP2_TEXTURE_COORD_2:
+ case GL_MAP2_TEXTURE_COORD_3:
+ case GL_MAP2_TEXTURE_COORD_4:
+ case GL_MAP2_VERTEX_3:
+ case GL_MAP2_VERTEX_4:
+ return 1;
+ case GL_AUTO_NORMAL:
+ return 1;
+ case GL_CURRENT_COLOR:
+ return 4;
+ case GL_CURRENT_INDEX:
+ return 1;
+ case GL_CURRENT_NORMAL:
+ return 3;
+ case GL_CURRENT_TEXTURE_COORDS:
+ return 4;
+ case GL_CURRENT_RASTER_INDEX:
+ return 1;
+ case GL_CURRENT_RASTER_COLOR:
+ return 4;
+ case GL_CURRENT_RASTER_TEXTURE_COORDS:
+ return 4;
+ case GL_CURRENT_RASTER_POSITION:
+ return 4;
+ case GL_CURRENT_RASTER_POSITION_VALID:
+ return 1;
+ case GL_CURRENT_RASTER_DISTANCE:
+ return 1;
+ case GL_POINT_SIZE:
+ return 1;
+ case GL_POINT_SIZE_RANGE:
+ /* case GL_SMOOTH_POINT_SIZE_RANGE: */ /* alias */
+ return 2;
+ case GL_POINT_SIZE_GRANULARITY:
+ /* case GL_SMOOTH_POINT_SIZE_GRANULARITY: */ /* alias */
+ return 1;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ return 2;
+ case GL_POINT_SMOOTH:
+ return 1;
+ case GL_LINE_SMOOTH:
+ return 1;
+ case GL_LINE_WIDTH:
+ return 1;
+ case GL_LINE_WIDTH_RANGE:
+ /* case GL_SMOOTH_LINE_WIDTH_RANGE: */ /* alias */
+ return 2;
+ case GL_LINE_WIDTH_GRANULARITY:
+ /* case GL_SMOOTH_LINE_WIDTH_GRANULARITY: */ /* alias */
+ return 1;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ return 2;
+ case GL_LINE_STIPPLE_PATTERN:
+ return 1;
+ case GL_LINE_STIPPLE_REPEAT:
+ return 1;
+ case GL_LINE_STIPPLE:
+ return 1;
+ case GL_POLYGON_MODE:
+ return 2;
+ case GL_POLYGON_SMOOTH:
+ return 1;
+ case GL_POLYGON_STIPPLE:
+ return 1;
+ case GL_EDGE_FLAG:
+ return 1;
+ case GL_CULL_FACE:
+ return 1;
+ case GL_CULL_FACE_MODE:
+ return 1;
+ case GL_FRONT_FACE:
+ return 1;
+ case GL_LIGHTING:
+ return 1;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ return 1;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ return 1;
+ case GL_LIGHT_MODEL_AMBIENT:
+ return 4;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ return 1;
+ case GL_COLOR_MATERIAL:
+ return 1;
+ case GL_COLOR_MATERIAL_FACE:
+ return 1;
+ case GL_COLOR_MATERIAL_PARAMETER:
+ return 1;
+ case GL_SHADE_MODEL:
+ return 1;
+ case GL_FOG:
+ return 1;
+ case GL_FOG_INDEX:
+ return 1;
+ case GL_FOG_DENSITY:
+ return 1;
+ case GL_FOG_START:
+ return 1;
+ case GL_FOG_END:
+ return 1;
+ case GL_FOG_MODE:
+ return 1;
+ case GL_FOG_COLOR:
+ return 4;
+ case GL_DEPTH_RANGE:
+ return 2;
+ case GL_DEPTH_TEST:
+ return 1;
+ case GL_DEPTH_WRITEMASK:
+ return 1;
+ case GL_DEPTH_CLEAR_VALUE:
+ return 1;
+ case GL_DEPTH_FUNC:
+ return 1;
+ case GL_ACCUM_CLEAR_VALUE:
+ return 4;
+ case GL_STENCIL_TEST:
+ return 1;
+ case GL_STENCIL_CLEAR_VALUE:
+ return 1;
+ case GL_STENCIL_FUNC:
+ return 1;
+ case GL_STENCIL_VALUE_MASK:
+ return 1;
+ case GL_STENCIL_FAIL:
+ return 1;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ return 1;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ return 1;
+ case GL_STENCIL_REF:
+ return 1;
+ case GL_STENCIL_WRITEMASK:
+ return 1;
+ case GL_MATRIX_MODE:
+ return 1;
+ case GL_NORMALIZE:
+ return 1;
+ case GL_VIEWPORT:
+ return 4;
+ case GL_ATTRIB_STACK_DEPTH:
+ return 1;
+ case GL_MODELVIEW_STACK_DEPTH:
+ return 1;
+ case GL_PROJECTION_STACK_DEPTH:
+ return 1;
+ case GL_TEXTURE_STACK_DEPTH:
+ return 1;
+ case GL_MODELVIEW_MATRIX:
+ return 16;
+ case GL_PROJECTION_MATRIX:
+ return 16;
+ case GL_TEXTURE_MATRIX:
+ return 16;
+ case GL_ALPHA_TEST:
+ return 1;
+ case GL_ALPHA_TEST_FUNC:
+ return 1;
+ case GL_ALPHA_TEST_REF:
+ return 1;
+ case GL_DITHER:
+ return 1;
+ case GL_BLEND_DST:
+ return 1;
+ case GL_BLEND_SRC:
+ return 1;
+ case GL_BLEND:
+ return 1;
+ case GL_LOGIC_OP_MODE:
+ return 1;
+ case GL_LOGIC_OP:
+ return 1;
+ case GL_DRAW_BUFFER:
+ return 1;
+ case GL_READ_BUFFER:
+ return 1;
+ case GL_SCISSOR_TEST:
+ return 1;
+ case GL_SCISSOR_BOX:
+ return 4;
+ case GL_INDEX_CLEAR_VALUE:
+ return 1;
+ case GL_INDEX_MODE:
+ return 1;
+ case GL_INDEX_WRITEMASK:
+ return 1;
+ case GL_COLOR_CLEAR_VALUE:
+ return 4;
+ case GL_RGBA_MODE:
+ return 1;
+ case GL_COLOR_WRITEMASK:
+ return 4;
+ case GL_RENDER_MODE:
+ return 1;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ return 1;
+ case GL_POINT_SMOOTH_HINT:
+ return 1;
+ case GL_LINE_SMOOTH_HINT:
+ return 1;
+ case GL_POLYGON_SMOOTH_HINT:
+ return 1;
+ case GL_FOG_HINT:
+ return 1;
+ case GL_LIST_BASE:
+ return 1;
+ case GL_LIST_INDEX:
+ return 1;
+ case GL_LIST_MODE:
+ return 1;
+ case GL_TEXTURE_GEN_S:
+ return 1;
+ case GL_TEXTURE_GEN_T:
+ return 1;
+ case GL_TEXTURE_GEN_R:
+ return 1;
+ case GL_TEXTURE_GEN_Q:
+ return 1;
+ case GL_PACK_SWAP_BYTES:
+ return 1;
+ case GL_PACK_LSB_FIRST:
+ return 1;
+ case GL_PACK_ROW_LENGTH:
+ return 1;
+ case GL_PACK_IMAGE_HEIGHT:
+ return 1;
+ case GL_PACK_SKIP_ROWS:
+ return 1;
+ case GL_PACK_SKIP_PIXELS:
+ return 1;
+ case GL_PACK_SKIP_IMAGES:
+ return 1;
+ case GL_PACK_ALIGNMENT:
+ return 1;
+ case GL_UNPACK_SWAP_BYTES:
+ return 1;
+ case GL_UNPACK_LSB_FIRST:
+ return 1;
+ case GL_UNPACK_ROW_LENGTH:
+ return 1;
+ case GL_UNPACK_IMAGE_HEIGHT:
+ return 1;
+ case GL_UNPACK_SKIP_ROWS:
+ return 1;
+ case GL_UNPACK_SKIP_PIXELS:
+ return 1;
+ case GL_UNPACK_SKIP_IMAGES:
+ return 1;
+ case GL_UNPACK_ALIGNMENT:
+ return 1;
+ case GL_MAP_COLOR:
+ return 1;
+ case GL_MAP_STENCIL:
+ return 1;
+ case GL_INDEX_SHIFT:
+ return 1;
+ case GL_INDEX_OFFSET:
+ return 1;
+ case GL_RED_SCALE:
+ case GL_GREEN_SCALE:
+ case GL_BLUE_SCALE:
+ case GL_ALPHA_SCALE:
+ case GL_DEPTH_SCALE:
+ return 1;
+ case GL_RED_BIAS:
+ case GL_GREEN_BIAS:
+ case GL_BLUE_BIAS:
+ case GL_ALPHA_BIAS:
+ case GL_DEPTH_BIAS:
+ return 1;
+ case GL_ZOOM_X:
+ case GL_ZOOM_Y:
+ return 1;
+ case GL_PIXEL_MAP_I_TO_I_SIZE: case GL_PIXEL_MAP_S_TO_S_SIZE:
+ case GL_PIXEL_MAP_I_TO_R_SIZE: case GL_PIXEL_MAP_I_TO_G_SIZE:
+ case GL_PIXEL_MAP_I_TO_B_SIZE: case GL_PIXEL_MAP_I_TO_A_SIZE:
+ case GL_PIXEL_MAP_R_TO_R_SIZE: case GL_PIXEL_MAP_G_TO_G_SIZE:
+ case GL_PIXEL_MAP_B_TO_B_SIZE: case GL_PIXEL_MAP_A_TO_A_SIZE:
+ return 1;
+ case GL_MAX_EVAL_ORDER:
+ return 1;
+ case GL_MAX_LIGHTS:
+ return 1;
+ case GL_MAX_CLIP_PLANES:
+ return 1;
+ case GL_MAX_PIXEL_MAP_TABLE:
+ return 1;
+ case GL_MAX_ATTRIB_STACK_DEPTH:
+ return 1;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ return 1;
+ case GL_MAX_NAME_STACK_DEPTH:
+ return 1;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ return 1;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ return 1;
+ case GL_INDEX_BITS:
+ return 1;
+ case GL_RED_BITS:
+ return 1;
+ case GL_GREEN_BITS:
+ return 1;
+ case GL_BLUE_BITS:
+ return 1;
+ case GL_ALPHA_BITS:
+ return 1;
+ case GL_DEPTH_BITS:
+ return 1;
+ case GL_STENCIL_BITS:
+ return 1;
+ case GL_ACCUM_RED_BITS:
+ case GL_ACCUM_GREEN_BITS:
+ case GL_ACCUM_BLUE_BITS:
+ case GL_ACCUM_ALPHA_BITS:
+ return 1;
+ case GL_MAP1_GRID_DOMAIN:
+ return 2;
+ case GL_MAP1_GRID_SEGMENTS:
+ return 1;
+ case GL_MAP2_GRID_DOMAIN:
+ return 4;
+ case GL_MAP2_GRID_SEGMENTS:
+ return 2;
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ return 1;
+ case GL_NAME_STACK_DEPTH:
+ return 1;
+ case GL_MAX_VIEWPORT_DIMS:
+ return 2;
+ case GL_DOUBLEBUFFER:
+ return 1;
+ case GL_AUX_BUFFERS:
+ return 1;
+ case GL_STEREO:
+ return 1;
+ case GL_CLIP_PLANE0: case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2: case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4: case GL_CLIP_PLANE5:
+ return 1;
+ case GL_LIGHT0: case GL_LIGHT1:
+ case GL_LIGHT2: case GL_LIGHT3:
+ case GL_LIGHT4: case GL_LIGHT5:
+ case GL_LIGHT6: case GL_LIGHT7:
+ return 1;
+ case GL_VERTEX_ARRAY:
+ case GL_VERTEX_ARRAY_SIZE:
+ case GL_VERTEX_ARRAY_TYPE:
+ case GL_VERTEX_ARRAY_STRIDE:
+ case GL_NORMAL_ARRAY:
+ case GL_NORMAL_ARRAY_TYPE:
+ case GL_NORMAL_ARRAY_STRIDE:
+ case GL_COLOR_ARRAY:
+ case GL_COLOR_ARRAY_SIZE:
+ case GL_COLOR_ARRAY_TYPE:
+ case GL_COLOR_ARRAY_STRIDE:
+ case GL_INDEX_ARRAY:
+ case GL_INDEX_ARRAY_TYPE:
+ case GL_INDEX_ARRAY_STRIDE:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ case GL_EDGE_FLAG_ARRAY:
+ case GL_EDGE_FLAG_ARRAY_STRIDE:
+ return 1;
+ case GL_TEXTURE_BINDING_1D:
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_3D:
+ return 1;
+ case GL_BLEND_COLOR:
+ return 4;
+ case GL_BLEND_EQUATION:
+ return 1;
+ case GL_COLOR_MATRIX:
+ return 16;
+ case GL_COLOR_MATRIX_STACK_DEPTH:
+ return 1;
+ case GL_COLOR_TABLE:
+ case GL_POST_CONVOLUTION_COLOR_TABLE:
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+ case GL_CONVOLUTION_1D:
+ case GL_CONVOLUTION_2D:
+ case GL_SEPARABLE_2D:
+ case GL_HISTOGRAM:
+ case GL_MINMAX:
+ return 1;
+ case GL_POLYGON_OFFSET_FACTOR:
+ case GL_POLYGON_OFFSET_UNITS:
+ return 1;
+ case GL_POST_CONVOLUTION_RED_SCALE:
+ case GL_POST_CONVOLUTION_GREEN_SCALE:
+ case GL_POST_CONVOLUTION_BLUE_SCALE:
+ case GL_POST_CONVOLUTION_ALPHA_SCALE:
+ case GL_POST_CONVOLUTION_RED_BIAS:
+ case GL_POST_CONVOLUTION_GREEN_BIAS:
+ case GL_POST_CONVOLUTION_BLUE_BIAS:
+ case GL_POST_CONVOLUTION_ALPHA_BIAS:
+ return 1;
+ case GL_POST_COLOR_MATRIX_RED_SCALE:
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE:
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE:
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
+ case GL_POST_COLOR_MATRIX_RED_BIAS:
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS:
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS:
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
+ return 1;
+ case GL_RESCALE_NORMAL:
+ return 1;
+ case GL_MAX_ELEMENTS_INDICES:
+ case GL_MAX_ELEMENTS_VERTICES:
+ return 1;
+ case GL_ACTIVE_TEXTURE_ARB:
+ case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+ case GL_MAX_TEXTURE_UNITS_ARB:
+ return 1;
+ case GL_MAX_COLOR_MATRIX_STACK_DEPTH:
+ case GL_MAX_CONVOLUTION_WIDTH:
+ case GL_MAX_CONVOLUTION_HEIGHT:
+ return 1;
+ case GL_OCCLUSION_TEST_RESULT_HP:
+ case GL_OCCLUSION_TEST_HP:
+ return 1;
+ case GL_PACK_INVERT_MESA:
+ return 1;
+ case GL_CULL_VERTEX_IBM:
+ return 1;
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ return 1;
+
+ /* GL_ARB_texture_cube_map / GL 1.3 */
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+
+ /* GL_ARB_multisample / GL 1.3 */
+ case GL_MULTISAMPLE:
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL_SAMPLE_ALPHA_TO_ONE:
+ case GL_SAMPLE_COVERAGE:
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ case GL_SAMPLE_COVERAGE_VALUE:
+ case GL_SAMPLE_COVERAGE_INVERT:
+
+ /* GL_ARB_texture_comrpession / GL 1.3 */
+ case GL_TEXTURE_COMPRESSION_HINT:
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+
+ /* GL_EXT_blend_func_separate / GL 1.4 */
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_SRC_ALPHA:
+
+ /* GL_EXT_fog_coord / GL 1.4 */
+ case GL_CURRENT_FOG_COORD:
+ case GL_FOG_COORD_ARRAY_TYPE:
+ case GL_FOG_COORD_ARRAY_STRIDE:
+ case GL_FOG_COORD_ARRAY:
+ case GL_FOG_COORD_SRC:
+
+ /* GL_EXT_secondary_color / GL 1.4 */
+ case GL_COLOR_SUM:
+ case GL_SECONDARY_COLOR_ARRAY_SIZE:
+ case GL_SECONDARY_COLOR_ARRAY_TYPE:
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE:
+ case GL_SECONDARY_COLOR_ARRAY:
+
+ /* GL_EXT_texture_lod_bias / GL 1.4 */
+ case GL_MAX_TEXTURE_LOD_BIAS:
+
+ /* GL_ARB_point_sprite */
+ case GL_POINT_SPRITE_ARB:
+
+ /* GL_ARB_vertex_blend */
+ case GL_MAX_VERTEX_UNITS_ARB:
+ case GL_ACTIVE_VERTEX_UNITS_ARB:
+ case GL_WEIGHT_SUM_UNITY_ARB:
+ case GL_VERTEX_BLEND_ARB:
+ case GL_CURRENT_WEIGHT_ARB:
+ case GL_WEIGHT_ARRAY_ARB:
+ case GL_WEIGHT_ARRAY_TYPE_ARB:
+ case GL_WEIGHT_ARRAY_STRIDE_ARB:
+ case GL_WEIGHT_ARRAY_SIZE_ARB:
+
+ /* GL_ARB_matrix_palette */
+ case GL_MATRIX_PALETTE_ARB:
+ case GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB:
+ case GL_MAX_PALETTE_MATRICES_ARB:
+ case GL_CURRENT_PALETTE_MATRIX_ARB:
+ case GL_CURRENT_MATRIX_INDEX_ARB:
+ case GL_MATRIX_INDEX_ARRAY_ARB:
+ case GL_MATRIX_INDEX_ARRAY_SIZE_ARB:
+ case GL_MATRIX_INDEX_ARRAY_TYPE_ARB:
+ case GL_MATRIX_INDEX_ARRAY_STRIDE_ARB:
+
+ /* GL_EXT_clip_volume_hint */
+ case GL_CLIP_VOLUME_CLIPPING_HINT_EXT:
+
+ /* GL_EXT_depth_bounds_test */
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+
+ /* GL_EXT_stencil_two_size */
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ case GL_ACTIVE_STENCIL_FACE_EXT:
+
+ /* GL_EXT_vertex_weighting */
+ case GL_VERTEX_WEIGHTING_EXT:
+ case GL_MODELVIEW0_EXT:
+ case GL_MODELVIEW1_EXT:
+ case GL_CURRENT_VERTEX_WEIGHT_EXT:
+ case GL_VERTEX_WEIGHT_ARRAY_EXT:
+ case GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT:
+ case GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT:
+ case GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT:
+ /* case GL_MODELVIEW0_STACK_DEPTH_EXT: */ /* alias */
+ case GL_MODELVIEW1_STACK_DEPTH_EXT:
+
+ /* GL_EXT_blend_equation_separate */
+ /* case GL_BLEND_EQUATION_RGB_EXT: */ /* alias */
+ case GL_BLEND_EQUATION_ALPHA_EXT:
+
+ /* GL_ATI_vertex_streams */
+ case GL_MAX_VERTEX_STREAMS_ATI:
+
+ /* GL_ATI_draw_buffers */
+ case GL_MAX_DRAW_BUFFERS_ATI:
+ case GL_DRAW_BUFFER0_ATI:
+ case GL_DRAW_BUFFER1_ATI:
+ case GL_DRAW_BUFFER2_ATI:
+ case GL_DRAW_BUFFER3_ATI:
+ case GL_DRAW_BUFFER4_ATI:
+ case GL_DRAW_BUFFER5_ATI:
+ case GL_DRAW_BUFFER6_ATI:
+ case GL_DRAW_BUFFER7_ATI:
+ case GL_DRAW_BUFFER8_ATI:
+ case GL_DRAW_BUFFER9_ATI:
+ case GL_DRAW_BUFFER10_ATI:
+ case GL_DRAW_BUFFER11_ATI:
+ case GL_DRAW_BUFFER12_ATI:
+ case GL_DRAW_BUFFER13_ATI:
+ case GL_DRAW_BUFFER14_ATI:
+ case GL_DRAW_BUFFER15_ATI:
+
+ /* GL_ATI_separate_stencil */
+ case GL_STENCIL_BACK_FUNC_ATI:
+ case GL_STENCIL_BACK_FAIL_ATI:
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI:
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI:
+
+ /* GL_NV_depth_clamp */
+ case GL_DEPTH_CLAMP_NV:
+
+ /* GL_NV_fog_distance */
+ case GL_FOG_DISTANCE_MODE_NV:
+
+ /* GL_NV_light_max_exponent */
+ case GL_MAX_SHININESS_NV:
+ case GL_MAX_SPOT_EXPONENT_NV:
+
+ /* GL_NV_multisample_filter_hint */
+ case GL_MULTISAMPLE_FILTER_HINT_NV:
+
+ /* GL_NV_point_sprite */
+ /* case GL_POINT_SPRITE_NV: */ /* alias */
+ case GL_POINT_SPRITE_R_MODE_NV:
+
+ /* GL_NV_primitive_restart */
+ case GL_PRIMITIVE_RESTART_NV:
+ case GL_PRIMITIVE_RESTART_INDEX_NV:
+
+ /* GL_NV_register_combiners */
+ case GL_REGISTER_COMBINERS_NV:
+ case GL_NUM_GENERAL_COMBINERS_NV:
+ case GL_COLOR_SUM_CLAMP_NV:
+ case GL_MAX_GENERAL_COMBINERS_NV:
+
+ /* GL_NV_register_combiners2 */
+ case GL_PER_STAGE_CONSTANTS_NV:
+
+ /* GL_NV_texture_rectangle */
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_BINDING_RECTANGLE_NV:
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:
+ return 1;
+
+ /* GL_EXT_depth_bounds_test */
+ case GL_DEPTH_BOUNDS_EXT:
+ return 2;
+
+ /* GL_EXT_secondary_color / GL 1.4 */
+ case GL_CURRENT_SECONDARY_COLOR:
+
+ /* GL_NV_register_combiners */
+ case GL_CONSTANT_COLOR0_NV:
+ case GL_CONSTANT_COLOR1_NV:
+ return 4;
+
+ /* GL_ARB_vertex_blend */
+ /* case GL_MODELVIEW0_ARB: */ /* alias */
+ /* case GL_MODELVIEW1_ARB: */ /* alias */
+ case GL_MODELVIEW2_ARB:
+ case GL_MODELVIEW3_ARB:
+ case GL_MODELVIEW4_ARB:
+ case GL_MODELVIEW5_ARB:
+ case GL_MODELVIEW6_ARB:
+ case GL_MODELVIEW7_ARB:
+ case GL_MODELVIEW8_ARB:
+ case GL_MODELVIEW9_ARB:
+ case GL_MODELVIEW10_ARB:
+ case GL_MODELVIEW11_ARB:
+ case GL_MODELVIEW12_ARB:
+ case GL_MODELVIEW13_ARB:
+ case GL_MODELVIEW14_ARB:
+ case GL_MODELVIEW15_ARB:
+ case GL_MODELVIEW16_ARB:
+ case GL_MODELVIEW17_ARB:
+ case GL_MODELVIEW18_ARB:
+ case GL_MODELVIEW19_ARB:
+ case GL_MODELVIEW20_ARB:
+ case GL_MODELVIEW21_ARB:
+ case GL_MODELVIEW22_ARB:
+ case GL_MODELVIEW23_ARB:
+ case GL_MODELVIEW24_ARB:
+ case GL_MODELVIEW25_ARB:
+ case GL_MODELVIEW26_ARB:
+ case GL_MODELVIEW27_ARB:
+ case GL_MODELVIEW28_ARB:
+ case GL_MODELVIEW29_ARB:
+ case GL_MODELVIEW30_ARB:
+ case GL_MODELVIEW31_ARB:
+
+ /* GL_EXT_vertex_weighting */
+ /* case GL_MODELVIEW0_MATRIX_EXT: */ /* alias */
+ case GL_MODELVIEW1_MATRIX_EXT:
+ return 32;
+
+ /* GL_ARB_texture_comrpession / GL 1.3 */
+ case GL_COMPRESSED_TEXTURE_FORMATS: {
+ GLint temp;
+
+ glGetIntegerv( GL_NUM_COMPRESSED_TEXTURE_FORMATS, & temp );
+ return temp;
+ }
+
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetDoublev_size(GLenum sq)
+{
+ return __glGet_size(sq);
+}
+
+GLint __glGetFloatv_size(GLenum sq)
+{
+ return __glGet_size(sq);
+}
+
+GLint __glGetIntegerv_size(GLenum sq)
+{
+ return __glGet_size(sq);
+}
+
+GLint __glGetBooleanv_size(GLenum sq)
+{
+ return __glGet_size(sq);
+}
+
+GLint __glGetTexLevelParameterfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_TEXTURE_WIDTH:
+ case GL_TEXTURE_HEIGHT:
+ case GL_TEXTURE_DEPTH:
+ case GL_TEXTURE_COMPONENTS:
+ case GL_TEXTURE_BORDER:
+ case GL_TEXTURE_RED_SIZE:
+ case GL_TEXTURE_GREEN_SIZE:
+ case GL_TEXTURE_BLUE_SIZE:
+ case GL_TEXTURE_ALPHA_SIZE:
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ case GL_TEXTURE_INTENSITY_SIZE:
+
+ /* GL_ARB_texture_compression / GL 1.3 */
+ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
+ case GL_TEXTURE_COMPRESSED:
+
+ /* GL_ARB_depth_texture / GL 1.4 */
+ case GL_TEXTURE_DEPTH_SIZE:
+ return 1;
+
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetTexLevelParameteriv_size(GLenum pname)
+{
+ return __glGetTexLevelParameterfv_size(pname);
+}
+
+GLint __glGetTexImage_size(GLenum target, GLint level, GLenum format,
+ GLenum type, GLint width, GLint height, GLint depth)
+{
+ return __glXImageSize( format, type, target, width, height, depth,
+ 0, 0, 0, 0, 4 );
+}
+
+GLint __glGetConvolutionParameteriv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_CONVOLUTION_BORDER_COLOR:
+ case GL_CONVOLUTION_FILTER_SCALE:
+ case GL_CONVOLUTION_FILTER_BIAS:
+ return 4;
+ case GL_CONVOLUTION_BORDER_MODE:
+ case GL_CONVOLUTION_FORMAT:
+ case GL_CONVOLUTION_WIDTH:
+ case GL_CONVOLUTION_HEIGHT:
+ case GL_MAX_CONVOLUTION_WIDTH:
+ case GL_MAX_CONVOLUTION_HEIGHT:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetConvolutionParameterfv_size(GLenum pname)
+{
+ return __glGetConvolutionParameteriv_size(pname);
+}
+
+
+GLint __glGetHistogramParameterfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_HISTOGRAM_WIDTH:
+ case GL_HISTOGRAM_FORMAT:
+ case GL_HISTOGRAM_RED_SIZE:
+ case GL_HISTOGRAM_GREEN_SIZE:
+ case GL_HISTOGRAM_BLUE_SIZE:
+ case GL_HISTOGRAM_ALPHA_SIZE:
+ case GL_HISTOGRAM_LUMINANCE_SIZE:
+ case GL_HISTOGRAM_SINK:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetHistogramParameteriv_size(GLenum pname)
+{
+ return __glGetHistogramParameterfv_size(pname);
+}
+
+GLint __glGetMinmaxParameterfv_size(GLenum pname)
+{
+ switch (pname) {
+ case GL_MINMAX_FORMAT:
+ case GL_MINMAX_SINK:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+GLint __glGetMinmaxParameteriv_size(GLenum pname)
+{
+ return __glGetMinmaxParameterfv_size(pname);
+}
+
+GLint __glGetColorTableParameterfv_size(GLenum pname)
+{
+ switch(pname) {
+
+ case GL_COLOR_TABLE_SCALE: /* return RGBA */
+ case GL_COLOR_TABLE_BIAS:
+ return 4;
+ case GL_COLOR_TABLE_FORMAT:
+ case GL_COLOR_TABLE_WIDTH:
+ case GL_COLOR_TABLE_RED_SIZE:
+ case GL_COLOR_TABLE_GREEN_SIZE:
+ case GL_COLOR_TABLE_BLUE_SIZE:
+ case GL_COLOR_TABLE_ALPHA_SIZE:
+ case GL_COLOR_TABLE_LUMINANCE_SIZE:
+ case GL_COLOR_TABLE_INTENSITY_SIZE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+GLint __glGetColorTableParameteriv_size(GLenum pname)
+{
+ return __glGetColorTableParameterfv_size(pname);
+}
+
diff --git a/nx-X11/programs/Xserver/GL/glx/singlesize.h b/nx-X11/programs/Xserver/GL/glx/singlesize.h
new file mode 100644
index 000000000..7cd52eae8
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/singlesize.h
@@ -0,0 +1,86 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _singlesize_h_
+#define _singlesize_h_
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#include "indirect_size.h"
+
+extern GLint __glReadPixels_size(GLenum format, GLenum type,
+ GLint width, GLint height);
+extern GLint __glGetTexEnvfv_size(GLenum pname);
+extern GLint __glGetTexEnviv_size(GLenum pname);
+extern GLint __glGetTexGenfv_size(GLenum pname);
+extern GLint __glGetTexGendv_size(GLenum pname);
+extern GLint __glGetTexGeniv_size(GLenum pname);
+extern GLint __glGetTexParameterfv_size(GLenum pname);
+extern GLint __glGetTexParameteriv_size(GLenum pname);
+extern GLint __glGetLightfv_size(GLenum pname);
+extern GLint __glGetLightiv_size(GLenum pname);
+extern GLint __glGetMap_size(GLenum pname, GLenum query);
+extern GLint __glGetMapdv_size(GLenum target, GLenum query);
+extern GLint __glGetMapfv_size(GLenum target, GLenum query);
+extern GLint __glGetMapiv_size(GLenum target, GLenum query);
+extern GLint __glGetMaterialfv_size(GLenum pname);
+extern GLint __glGetMaterialiv_size(GLenum pname);
+extern GLint __glGetPixelMap_size(GLenum map);
+extern GLint __glGetPixelMapfv_size(GLenum map);
+extern GLint __glGetPixelMapuiv_size(GLenum map);
+extern GLint __glGetPixelMapusv_size(GLenum map);
+extern GLint __glGet_size(GLenum sq);
+extern GLint __glGetDoublev_size(GLenum sq);
+extern GLint __glGetFloatv_size(GLenum sq);
+extern GLint __glGetIntegerv_size(GLenum sq);
+extern GLint __glGetBooleanv_size(GLenum sq);
+extern GLint __glGetTexLevelParameterfv_size(GLenum pname);
+extern GLint __glGetTexLevelParameteriv_size(GLenum pname);
+extern GLint __glGetTexImage_size(GLenum target, GLint level, GLenum format,
+ GLenum type, GLint width, GLint height,
+ GLint depth);
+extern GLint __glGetColorTableParameterfv_size(GLenum pname);
+extern GLint __glGetColorTableParameteriv_size(GLenum pname);
+extern GLint __glGetConvolutionParameterfv_size(GLenum pname);
+extern GLint __glGetConvolutionParameteriv_size(GLenum pname);
+extern GLint __glGetHistogramParameterfv_size(GLenum pname);
+extern GLint __glGetHistogramParameteriv_size(GLenum pname);
+extern GLint __glGetMinmaxParameterfv_size(GLenum pname);
+extern GLint __glGetMinmaxParameteriv_size(GLenum pname);
+
+#endif /* _singlesize_h_ */
+
diff --git a/nx-X11/programs/Xserver/GL/glx/unpack.h b/nx-X11/programs/Xserver/GL/glx/unpack.h
new file mode 100644
index 000000000..7d84ff575
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/unpack.h
@@ -0,0 +1,240 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef __GLX_unpack_h__
+#define __GLX_unpack_h__
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#define __GLX_PAD(s) (((s)+3) & (GLuint)~3)
+
+/*
+** Fetch the context-id out of a SingleReq request pointed to by pc.
+*/
+#define __GLX_GET_SINGLE_CONTEXT_TAG(pc) (((xGLXSingleReq*)pc)->contextTag)
+#define __GLX_GET_VENDPRIV_CONTEXT_TAG(pc) (((xGLXVendorPrivateReq*)pc)->contextTag)
+
+/*
+** Fetch a double from potentially unaligned memory.
+*/
+#ifdef __GLX_ALIGN64
+#define __GLX_MEM_COPY(dst,src,n) if (src && dst) memcpy(dst,src,n)
+#define __GLX_GET_DOUBLE(dst,src) __GLX_MEM_COPY(&dst,src,8)
+#else
+#define __GLX_GET_DOUBLE(dst,src) (dst) = *((GLdouble*)(src))
+#endif
+
+extern void __glXMemInit(void);
+
+extern xGLXSingleReply __glXReply;
+
+#define __GLX_BEGIN_REPLY(size) \
+ __glXReply.length = __GLX_PAD(size) >> 2; \
+ __glXReply.type = X_Reply; \
+ __glXReply.sequenceNumber = client->sequence;
+
+#define __GLX_SEND_HEADER() \
+ WriteToClient( client, sz_xGLXSingleReply, &__glXReply);
+
+#define __GLX_PUT_RETVAL(a) \
+ __glXReply.retval = (a);
+
+#define __GLX_PUT_SIZE(a) \
+ __glXReply.size = (a);
+
+#define __GLX_PUT_RENDERMODE(m) \
+ __glXReply.pad3 = (m)
+
+/*
+** Get a buffer to hold returned data, with the given alignment. If we have
+** to realloc, allocate size+align, in case the pointer has to be bumped for
+** alignment. The answerBuffer should already be aligned.
+**
+** NOTE: the cast (long)res below assumes a long is large enough to hold a
+** pointer.
+*/
+#define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \
+ if (size < 0) return BadLength; \
+ else if ((size) > sizeof(answerBuffer)) { \
+ int bump; \
+ if ((cl)->returnBufSize < (size)+(align)) { \
+ (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \
+ (size)+(align)); \
+ if (!(cl)->returnBuf) { \
+ return BadAlloc; \
+ } \
+ (cl)->returnBufSize = (size)+(align); \
+ } \
+ res = (char*)cl->returnBuf; \
+ bump = (long)(res) % (align); \
+ if (bump) res += (align) - (bump); \
+ } else { \
+ res = (char *)answerBuffer; \
+ }
+
+#define __GLX_PUT_BYTE() \
+ *(GLbyte *)&__glXReply.pad3 = *(GLbyte *)answer
+
+#define __GLX_PUT_SHORT() \
+ *(GLshort *)&__glXReply.pad3 = *(GLshort *)answer
+
+#define __GLX_PUT_INT() \
+ *(GLint *)&__glXReply.pad3 = *(GLint *)answer
+
+#define __GLX_PUT_FLOAT() \
+ *(GLfloat *)&__glXReply.pad3 = *(GLfloat *)answer
+
+#define __GLX_PUT_DOUBLE() \
+ *(GLdouble *)&__glXReply.pad3 = *(GLdouble *)answer
+
+#define __GLX_SEND_BYTE_ARRAY(len) \
+ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT8), answer)
+
+#define __GLX_SEND_SHORT_ARRAY(len) \
+ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT16), answer)
+
+#define __GLX_SEND_INT_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_INT32, answer)
+
+#define __GLX_SEND_FLOAT_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_FLOAT32, answer)
+
+#define __GLX_SEND_DOUBLE_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_FLOAT64, answer)
+
+
+#define __GLX_SEND_VOID_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
+#define __GLX_SEND_UBYTE_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
+#define __GLX_SEND_USHORT_ARRAY(len) __GLX_SEND_SHORT_ARRAY(len)
+#define __GLX_SEND_UINT_ARRAY(len) __GLX_SEND_INT_ARRAY(len)
+
+/*
+** PERFORMANCE NOTE:
+** Machine dependent optimizations abound here; these swapping macros can
+** conceivably be replaced with routines that do the job faster.
+*/
+#define __GLX_DECLARE_SWAP_VARIABLES \
+ GLbyte sw
+
+#define __GLX_DECLARE_SWAP_ARRAY_VARIABLES \
+ GLbyte *swapPC; \
+ GLbyte *swapEnd
+
+
+#define __GLX_SWAP_INT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = sw;
+
+#define __GLX_SWAP_SHORT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = sw;
+
+#define __GLX_SWAP_DOUBLE(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[7]; \
+ ((GLbyte *)(pc))[7] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[6]; \
+ ((GLbyte *)(pc))[6] = sw; \
+ sw = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = ((GLbyte *)(pc))[5]; \
+ ((GLbyte *)(pc))[5] = sw; \
+ sw = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = ((GLbyte *)(pc))[4]; \
+ ((GLbyte *)(pc))[4] = sw;
+
+#define __GLX_SWAP_FLOAT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = sw;
+
+#define __GLX_SWAP_INT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT32;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_INT(swapPC); \
+ swapPC += __GLX_SIZE_INT32; \
+ }
+
+#define __GLX_SWAP_SHORT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT16;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_SHORT(swapPC); \
+ swapPC += __GLX_SIZE_INT16; \
+ }
+
+#define __GLX_SWAP_DOUBLE_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT64;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_DOUBLE(swapPC); \
+ swapPC += __GLX_SIZE_FLOAT64; \
+ }
+
+#define __GLX_SWAP_FLOAT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT32;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_FLOAT(swapPC); \
+ swapPC += __GLX_SIZE_FLOAT32; \
+ }
+
+#define __GLX_SWAP_REPLY_HEADER() \
+ __GLX_SWAP_SHORT(&__glXReply.sequenceNumber); \
+ __GLX_SWAP_INT(&__glXReply.length);
+
+#define __GLX_SWAP_REPLY_RETVAL() \
+ __GLX_SWAP_INT(&__glXReply.retval)
+
+#define __GLX_SWAP_REPLY_SIZE() \
+ __GLX_SWAP_INT(&__glXReply.size)
+
+#endif /* !__GLX_unpack_h__ */
+
+
+
+
+
diff --git a/nx-X11/programs/Xserver/GL/glx/xfont.c b/nx-X11/programs/Xserver/GL/glx/xfont.c
new file mode 100644
index 000000000..780183609
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/glx/xfont.c
@@ -0,0 +1,193 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "g_disptab.h"
+#include <unpack.h>
+#include <GL/gl.h>
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include <dixfontstr.h>
+
+extern XID clientErrorValue; /* imported kludge from dix layer */
+
+/*
+** Make a single GL bitmap from a single X glyph
+*/
+static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci)
+{
+ int i, j;
+ int widthPadded; /* width of glyph in bytes, as padded by X */
+ int allocBytes; /* bytes to allocate to store bitmap */
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ register unsigned char *pglyph;
+ register unsigned char *p;
+ unsigned char *allocbuf;
+#define __GL_CHAR_BUF_SIZE 2048
+ unsigned char buf[__GL_CHAR_BUF_SIZE];
+
+ w = GLYPHWIDTHPIXELS(pci);
+ h = GLYPHHEIGHTPIXELS(pci);
+ widthPadded = GLYPHWIDTHBYTESPADDED(pci);
+
+ /*
+ ** Use the local buf if possible, otherwise malloc.
+ */
+ allocBytes = widthPadded * h;
+ if (allocBytes <= __GL_CHAR_BUF_SIZE) {
+ p = buf;
+ allocbuf = 0;
+ } else {
+ p = (unsigned char *) malloc(allocBytes);
+ if (!p)
+ return BadAlloc;
+ allocbuf = p;
+ }
+
+ /*
+ ** We have to reverse the picture, top to bottom
+ */
+
+ pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded;
+ for (j=0; j < h; j++) {
+ for (i=0; i < widthPadded; i++) {
+ p[i] = pglyph[i];
+ }
+ pglyph -= widthPadded;
+ p += widthPadded;
+ }
+ glBitmap(w, h, -pci->metrics.leftSideBearing, pci->metrics.descent,
+ pci->metrics.characterWidth, 0, allocbuf ? allocbuf : buf);
+
+ if (allocbuf) {
+ free(allocbuf);
+ }
+ return Success;
+#undef __GL_CHAR_BUF_SIZE
+}
+
+/*
+** Create a GL bitmap for each character in the X font. The bitmap is stored
+** in a display list.
+*/
+
+static int
+MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base)
+{
+ unsigned long i, nglyphs;
+ CARD8 chs[2]; /* the font index we are going after */
+ CharInfoPtr pci;
+ int rv; /* return value */
+ int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit;
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, GLYPHPADBYTES);
+ for (i=0; i < count; i++) {
+ chs[0] = (first + i) >> 8; /* high byte is first byte */
+ chs[1] = first + i;
+
+ (*pFont->get_glyphs)(pFont, 1, chs, (FontEncoding)encoding,
+ &nglyphs, &pci);
+
+ /*
+ ** Define a display list containing just a glBitmap() call.
+ */
+ glNewList(list_base + i, GL_COMPILE);
+ if (nglyphs ) {
+ rv = __glXMakeBitmapFromGlyph(pFont, pci);
+ if (rv) {
+ return rv;
+ }
+ }
+ glEndList();
+ }
+ return Success;
+}
+
+/************************************************************************/
+
+int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXUseXFontReq *req;
+ FontPtr pFont;
+ GC *pGC;
+ GLuint currentListIndex;
+ __GLXcontext *cx;
+ int error;
+
+ req = (xGLXUseXFontReq *) pc;
+ cx = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!cx) {
+ return error;
+ }
+
+ glGetIntegerv(GL_LIST_INDEX, (GLint*) &currentListIndex);
+ if (currentListIndex != 0) {
+ /*
+ ** A display list is currently being made. It is an error
+ ** to try to make a font during another lists construction.
+ */
+ client->errorValue = cx->id;
+ return __glXBadContextState;
+ }
+
+ /*
+ ** Font can actually be either the ID of a font or the ID of a GC
+ ** containing a font.
+ */
+ pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
+ if (!pFont) {
+ pGC = (GC *)LookupIDByType(req->font, RT_GC);
+ if (!pGC) {
+ client->errorValue = req->font;
+ return BadFont;
+ }
+ pFont = pGC->font;
+ }
+
+ return MakeBitmapsFromFont(pFont, req->first, req->count,
+ req->listBase);
+}
diff --git a/nx-X11/programs/Xserver/GL/mesa/GLcore/Imakefile b/nx-X11/programs/Xserver/GL/mesa/GLcore/Imakefile
new file mode 100644
index 000000000..5fb93b364
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/GLcore/Imakefile
@@ -0,0 +1,52 @@
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define MesaInXServer
+#define MesaBuildDir ../main/
+#define MesaACBuildDir ../array_cache/
+#define MesaMathBuildDir ../math/
+#define MesaSwrastBuildDir ../swrast/
+#define MesaSwrastSetupBuildDir ../swrast_setup/
+#define MesaTnlBuildDir ../tnl/
+#define MesaShaderBuildDir ../shader/
+#define MesaGrammarBuildDir ../shader/grammar/
+#define MesaSlangBuildDir ../shader/slang/
+#define MesaXBuildDir ../X/
+
+#include "../array_cache/Imakefile.inc"
+#include "../swrast/Imakefile.inc"
+#include "../swrast_setup/Imakefile.inc"
+#include "../tnl/Imakefile.inc"
+#include "../main/Imakefile.inc"
+#include "../math/Imakefile.inc"
+#include "../shader/Imakefile.inc"
+#include "../shader/grammar/Imakefile.inc"
+#include "../shader/slang/Imakefile.inc"
+#include "../X/Imakefile.inc"
+#include "../Imakefile.inc"
+
+ XOBJS = ../X/?*.o
+
+ OBJS = $(COREMESAOBJS) $(MOBJS)
+
+ DONES = ../main/DONE ../X/DONE ../array_cache/DONE \
+ ../math/DONE ../swrast/DONE ../swrast_setup/DONE \
+ ../tnl/DONE ../shader/DONE ../shader/grammar/DONE \
+ ../shader/slang/DONE
+
+ INCLUDES = -I$(INCLUDESRC) -I$(XINCLUDESRC) -I$(EXTINCSRC) \
+ -I$(MESASRCDIR)/include \
+ -I$(MESASRCDIR)/src/mesa \
+ -I$(SERVERSRC)/include
+
+ DEFINES = $(GLX_DEFINES)
+
+NormalDepLibraryTarget(GLcore, $(DONES) $(OBJS), $(OBJS) $(XOBJS))
+NormalLibraryObjectRule()
+
+InstallDriverSDKLibraryModule(GLcore,$(DRIVERSDKMODULEDIR),extensions)
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
diff --git a/nx-X11/programs/Xserver/GL/mesa/Imakefile b/nx-X11/programs/Xserver/GL/mesa/Imakefile
new file mode 100644
index 000000000..f1dbbe101
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/Imakefile
@@ -0,0 +1,26 @@
+#define IHaveSubdirs
+ SUBDIRS = main math array_cache swrast swrast_setup tnl shader X GLcore $(MODSUBDIR)
+
+#include <Server.tmpl>
+
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaBuildDir /**/
+#include "Imakefile.inc"
+
+ INCLUDES = -I$(INCLUDESRC) -I$(XINCLUDESRC) -I$(EXTINCSRC) \
+ -I$(MESASRCDIR)/include -I$(GLXLIBSRC)/include \
+ -I$(MESASRCDIR)/src/mesa \
+ -I$(SERVERSRC)/include
+
+ DEFINES = $(GLX_DEFINES)
+
+NormalLibraryObjectRule()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/GL/mesa/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/Imakefile.inc
new file mode 100644
index 000000000..1bff5782e
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/Imakefile.inc
@@ -0,0 +1,51 @@
+MESABUILDDIR = MesaBuildDir
+
+COREMESASRCS = $(COREMESABASESRCS) \
+ $(MESA_AC_SRCS) \
+ $(MESA_MATH_SRCS) \
+ $(MESA_SWRAST_SRCS) \
+ $(MESA_SWR_SETUP_SRCS) \
+ $(MESA_TNL_SRCS) \
+ $(MESA_SHADER_SRCS) \
+ $(MESA_GRAMMAR_SRCS) \
+ $(MESA_SLANG_SRCS)
+
+COREMESAOBJS = $(COREMESABASEOBJS) \
+ $(MESA_AC_OBJS) \
+ $(MESA_MATH_OBJS) \
+ $(MESA_SWRAST_OBJS) \
+ $(MESA_SWR_SETUP_OBJS) \
+ $(MESA_TNL_OBJS) \
+ $(MESA_SHADER_OBJS) \
+ $(MESA_GRAMMAR_OBJS) \
+ $(MESA_SLANG_OBJS)
+
+COREMESAUOBJS = $(COREMESABASEUOBJS) \
+ $(MESA_AC_UOBJS) \
+ $(MESA_MATH_UOBJS) \
+ $(MESA_SWRAST_UOBJS) \
+ $(MESA_SWR_SETUP_UOBJS) \
+ $(MESA_TNL_UOBJS) \
+ $(MESA_SHADER_UOBJS) \
+ $(MESA_GRAMMAR_UOBJS) \
+ $(MESA_SLANG_UOBJS)
+
+COREMESADOBJS = $(COREMESABASEDOBJS) \
+ $(MESA_AC_DOBJS) \
+ $(MESA_MATH_DOBJS) \
+ $(MESA_SWRAST_DOBJS) \
+ $(MESA_SWR_SETUP_DOBJS) \
+ $(MESA_TNL_DOBJS) \
+ $(MESA_SHADER_DOBJS) \
+ $(MESA_GRAMMAR_DOBJS) \
+ $(MESA_SLANG_DOBJS)
+
+COREMESAPOBJS = $(COREMESABASEPOBJS) \
+ $(MESA_AC_POBJS) \
+ $(MESA_MATH_POBJS) \
+ $(MESA_SWRAST_POBJS) \
+ $(MESA_SWR_SETUP_POBJS) \
+ $(MESA_TNL_POBJS) \
+ $(MESA_SHADER_POBJS) \
+ $(MESA_GRAMMAR_POBJS) \
+ $(MESA_SLANG_POBJS)
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/Imakefile b/nx-X11/programs/Xserver/GL/mesa/X/Imakefile
new file mode 100644
index 000000000..f8812e096
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/Imakefile
@@ -0,0 +1,63 @@
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaXBuildDir /**/
+#define MesaInXServer
+#include "Imakefile.inc"
+
+
+LinkSourceFile(compsize.c,$(MESASRCDIR)/src/glx/x11)
+
+ DRIVER_SRCS = $(XMESA_SRCS)
+ DRIVER_OBJS = $(XMESA_OBJS)
+
+ COMMON_SRCS = driverfuncs.c
+ COMMON_OBJS = driverfuncs.o
+
+ GLX_SRCS = xf86glx.c xf86glx_util.c compsize.c
+ GLX_OBJS = xf86glx.o xf86glx_util.o compsize.o
+
+ SRCS = $(DRIVER_SRCS) $(GLX_SRCS) $(COMMON_SRCS)
+ OBJS = $(DRIVER_OBJS) $(GLX_OBJS) $(COMMON_OBJS)
+
+ INCLUDES = -I$(SERVERSRC)/GL/mesa/X -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC) \
+ -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src -I$(MESASRCDIR)/src/mesa/drivers/x11 \
+ -I$(MESASRCDIR)/include \
+ -I$(LIBSRC)/GL/glx -I$(LIBSRC)/GL/include \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/GL/include \
+ -I$(SERVERSRC)/GL/glx \
+ -I$(XF86OSSRC) \
+ -I$(DRMSRCDIR)/shared-core \
+ `pkg-config --cflags-only-I pixman-1`
+
+ DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+
+#ifndef MesaDrvSrcDir
+#define MesaDrvSrcDir $(MESASRCDIR)/src/mesa/drivers/dri
+#endif
+
+MESADRVSRCDIR = MesaDrvSrcDir
+
+
+LinkSourceFile(driverfuncs.c, $(MESADRVSRCDIR)/../common)
+LinkSourceFile(driverfuncs.h, $(MESADRVSRCDIR)/../common)
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/X/Imakefile.inc
new file mode 100644
index 000000000..67eaf7804
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/Imakefile.inc
@@ -0,0 +1,98 @@
+MESAXBUILDDIR = MesaXBuildDir
+
+#ifndef MesaInXServer
+XMESA_GLX_SRCS = $(MESAXBUILDDIR)fakeglx.c \
+ $(MESAXBUILDDIR)glxapi.c \
+ $(MESAXBUILDDIR)realglx.c \
+ $(MESAXBUILDDIR)xfonts.c
+#endif
+
+ XMESA_SRCS = $(XMESA_GLX_SRCS) \
+ $(MESAXBUILDDIR)xm_api.c \
+ $(MESAXBUILDDIR)xm_buffer.c \
+ $(MESAXBUILDDIR)xm_dd.c \
+ $(MESAXBUILDDIR)xm_line.c \
+ $(MESAXBUILDDIR)xm_span.c \
+ $(MESAXBUILDDIR)xm_tri.c
+
+#ifdef NeedToLinkMesaSrc
+#ifndef MesaInXServer
+LinkSourceFile(fakeglx.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(glxapi.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(glxapi.h, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(realglx.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xfonts.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+#endif
+LinkSourceFile(xm_api.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xm_buffer.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xm_dd.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xm_line.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xm_span.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+LinkSourceFile(xm_tri.c, $(MESASRCDIR)/src/mesa/drivers/x11)
+#endif
+
+#ifndef MesaInXServer
+XMESA_GLX_OBJS = $(MESAXBUILDDIR)fakeglx.o \
+ $(MESAXBUILDDIR)glxapi.o \
+ $(MESAXBUILDDIR)realglx.o \
+ $(MESAXBUILDDIR)xfonts.o
+#endif
+
+ XMESA_OBJS = $(XMESA_GLX_OBJS) \
+ $(MESAXBUILDDIR)xm_api.o \
+ $(MESAXBUILDDIR)xm_buffer.o \
+ $(MESAXBUILDDIR)xm_dd.o \
+ $(MESAXBUILDDIR)xm_line.o \
+ $(MESAXBUILDDIR)xm_span.o \
+ $(MESAXBUILDDIR)xm_tri.o
+
+#if defined(DoSharedLib) && DoSharedLib
+#ifndef MesaInXServer
+XMESA_GLX_UOBJS = $(MESAXBUILDDIR)unshared/fakeglx.o \
+ $(MESAXBUILDDIR)unshared/glxapi.o \
+ $(MESAXBUILDDIR)unshared/realglx.o \
+ $(MESAXBUILDDIR)unshared/xfonts.o
+#endif
+
+ XMESA_UOBJS = $(XMESA_GLX_UOBJS) \
+ $(MESAXBUILDDIR)unshared/xm_api.o \
+ $(MESAXBUILDDIR)unshared/xm_buffer.o \
+ $(MESAXBUILDDIR)unshared/xm_dd.o \
+ $(MESAXBUILDDIR)unshared/xm_line.o \
+ $(MESAXBUILDDIR)unshared/xm_span.o \
+ $(MESAXBUILDDIR)unshared/xm_tri.o
+#else
+XMESA_GLX_UOBJS = $(XMESA_GLX_OBJS)
+ XMESA_UOBJS = $(XMESA_OBJS)
+#endif
+
+#ifndef MesaInXServer
+XMESA_GLX_DOBJS = $(MESAXBUILDDIR)debugger/fakeglx.o \
+ $(MESAXBUILDDIR)debugger/glxapi.o \
+ $(MESAXBUILDDIR)debugger/realglx.o \
+ $(MESAXBUILDDIR)debugger/xfonts.o
+#endif
+
+ XMESA_DOBJS = $(XMESA_GLX_DOBJS) \
+ $(MESAXBUILDDIR)debugger/xm_api.o \
+ $(MESAXBUILDDIR)debugger/xm_buffer.o \
+ $(MESAXBUILDDIR)debugger/xm_dd.o \
+ $(MESAXBUILDDIR)debugger/xm_line.o \
+ $(MESAXBUILDDIR)debugger/xm_span.o \
+ $(MESAXBUILDDIR)debugger/xm_tri.o
+
+#ifndef MesaInXServer
+XMESA_GLX_POBJS = $(MESAXBUILDDIR)profiled/fakeglx.o \
+ $(MESAXBUILDDIR)profiled/glxapi.o \
+ $(MESAXBUILDDIR)profiled/realglx.o \
+ $(MESAXBUILDDIR)profiled/xfonts.o
+#endif
+
+ XMESA_POBJS = $(XMESA_GLX_POBJS) \
+ $(MESAXBUILDDIR)profiled/xm_api.o \
+ $(MESAXBUILDDIR)profiled/xm_buffer.o \
+ $(MESAXBUILDDIR)profiled/xm_dd.o \
+ $(MESAXBUILDDIR)profiled/xm_line.o \
+ $(MESAXBUILDDIR)profiled/xm_span.o \
+ $(MESAXBUILDDIR)profiled/xm_tri.o
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c
new file mode 100644
index 000000000..da0e77134
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c
@@ -0,0 +1,950 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian E. Paul <brian@precisioninsight.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <regionstr.h>
+#include <resource.h>
+#include <GL/gl.h>
+#include <GL/glxint.h>
+#include <GL/glxtokens.h>
+#include <scrnintstr.h>
+#include <config.h>
+#include <glxserver.h>
+#include <glxscreens.h>
+#include <glxdrawable.h>
+#include <glxcontext.h>
+#include <glxext.h>
+#include <glxutil.h>
+#include "xf86glxint.h"
+#include "context.h"
+#include "xmesaP.h"
+#include "context.h"
+
+/*
+ * This define is for the glcore.h header file.
+ * If you add it here, then make sure you also add it in
+ * ../../../glx/Imakefile.
+ */
+#if 0
+#define DEBUG
+#include <GL/internal/glcore.h>
+#undef DEBUG
+#else
+#include <GL/internal/glcore.h>
+#endif
+
+#include "glcontextmodes.h"
+
+#ifdef NXAGENT_SERVER
+#include "../main/WSDrawBuffer.h"
+#endif
+
+/*
+ * This structure is statically allocated in the __glXScreens[]
+ * structure. This struct is not used anywhere other than in
+ * __glXScreenInit to initialize each of the active screens
+ * (__glXActiveScreens[]). Several of the fields must be initialized by
+ * the screenProbe routine before they are copied to the active screens
+ * struct. In particular, the contextCreate, pGlxVisual, numVisuals,
+ * and numUsableVisuals fields must be initialized.
+ */
+static __GLXscreenInfo __glDDXScreenInfo = {
+ __MESA_screenProbe, /* Must be generic and handle all screens */
+ __MESA_createContext, /* Substitute screen's createContext routine */
+ __MESA_createBuffer, /* Substitute screen's createBuffer routine */
+ NULL, /* Set up modes in probe */
+ NULL, /* Set up pVisualPriv in probe */
+ 0, /* Set up numVisuals in probe */
+ 0, /* Set up numUsableVisuals in probe */
+ NULL, /* GLextensions is overwritten by __glXScreenInit */
+ "Vendor String", /* GLXvendor is overwritten by __glXScreenInit */
+ "Version String", /* GLXversion is overwritten by __glXScreenInit */
+ "Extensions String", /* GLXextensions is overwritten by __glXScreenInit */
+ NULL /* WrappedPositionWindow is overwritten */
+};
+
+#ifdef NXAGENT_SERVER
+WSDrawBufferPtr pWSDrawBuffer = NULL;
+
+void AddWSDrawBuffer(GLframebuffer *mesa_buffer)
+{
+ WSDrawBufferPtr prevWSDB;
+ WSDrawBufferPtr newWSDB;
+ WSDrawBufferPtr p;
+
+ prevWSDB = NULL;
+ newWSDB = NULL;
+ p = pWSDrawBuffer;
+ while (p != NULL) {
+ prevWSDB = p;
+ if (prevWSDB -> DrawBuffer == mesa_buffer) {
+ return;
+ }
+ p = p -> next;
+ }
+ newWSDB = malloc(sizeof(WSDrawBufferRec));
+ newWSDB -> DrawBuffer = mesa_buffer;
+ newWSDB -> next = NULL;
+
+ if (pWSDrawBuffer == NULL)
+ pWSDrawBuffer = newWSDB;
+ else
+ prevWSDB -> next = newWSDB;
+}
+#endif
+
+void *__glXglDDXScreenInfo(void) {
+ return &__glDDXScreenInfo;
+}
+
+static __GLXextensionInfo __glDDXExtensionInfo = {
+ GL_CORE_MESA,
+ __MESA_resetExtension,
+ __MESA_initVisuals,
+ __MESA_setVisualConfigs
+};
+
+void *__glXglDDXExtensionInfo(void) {
+ return &__glDDXExtensionInfo;
+}
+
+static __MESA_screen MESAScreens[MAXSCREENS];
+static __GLcontext *MESA_CC = NULL;
+
+static int numConfigs = 0;
+static __GLXvisualConfig *visualConfigs = NULL;
+static void **visualPrivates = NULL;
+
+
+static int count_bits(unsigned int n)
+{
+ int bits = 0;
+
+ while (n > 0) {
+ if (n & 1) bits++;
+ n >>= 1;
+ }
+ return bits;
+}
+
+
+static XMesaVisual find_mesa_visual(int screen, VisualID vid)
+{
+ __MESA_screen * const pMScr = &MESAScreens[screen];
+ const __GLcontextModes *modes;
+ unsigned i = 0;
+
+ for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
+ if ( modes->visualID == vid ) {
+ break;
+ }
+
+ i++;
+ }
+
+ return (modes != NULL) ? pMScr->xm_vis[i] : NULL;
+}
+
+
+/*
+ * In the case the driver defines no GLX visuals we'll use these.
+ * Note that for TrueColor and DirectColor visuals, bufferSize is the
+ * sum of redSize, greenSize, blueSize and alphaSize, which may be larger
+ * than the nplanes/rootDepth of the server's X11 visuals
+ */
+#define NUM_FALLBACK_CONFIGS 5
+static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = {
+ /* [0] = RGB, double buffered, Z */
+ {
+ -1, /* vid */
+ -1, /* class */
+ True, /* rgba */
+ -1, -1, -1, 0, /* rgba sizes */
+ -1, -1, -1, 0, /* rgba masks */
+ 0, 0, 0, 0, /* rgba accum sizes */
+ True, /* doubleBuffer */
+ False, /* stereo */
+ -1, /* bufferSize */
+ 16, /* depthSize */
+ 0, /* stencilSize */
+ 0, /* auxBuffers */
+ 0, /* level */
+ GLX_NONE, /* visualRating */
+ GLX_NONE, /* transparentPixel */
+ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
+ 0 /* transparentIndex */
+ },
+ /* [1] = RGB, double buffered, Z, stencil, accum */
+ {
+ -1, /* vid */
+ -1, /* class */
+ True, /* rgba */
+ -1, -1, -1, 0, /* rgba sizes */
+ -1, -1, -1, 0, /* rgba masks */
+ 16, 16, 16, 0, /* rgba accum sizes */
+ True, /* doubleBuffer */
+ False, /* stereo */
+ -1, /* bufferSize */
+ 16, /* depthSize */
+ 8, /* stencilSize */
+ 0, /* auxBuffers */
+ 0, /* level */
+ GLX_NONE, /* visualRating */
+ GLX_NONE, /* transparentPixel */
+ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
+ 0 /* transparentIndex */
+ },
+ /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */
+ {
+ -1, /* vid */
+ -1, /* class */
+ True, /* rgba */
+ -1, -1, -1, 8, /* rgba sizes */
+ -1, -1, -1, -1, /* rgba masks */
+ 16, 16, 16, 16, /* rgba accum sizes */
+ True, /* doubleBuffer */
+ False, /* stereo */
+ -1, /* bufferSize */
+ 16, /* depthSize */
+ 8, /* stencilSize */
+ 0, /* auxBuffers */
+ 0, /* level */
+ GLX_NONE, /* visualRating */
+ GLX_NONE, /* transparentPixel */
+ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
+ 0 /* transparentIndex */
+ },
+ /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */
+ {
+ -1, /* vid */
+ -1, /* class */
+ True, /* rgba */
+ -1, -1, -1, 8, /* rgba sizes */
+ -1, -1, -1, -1, /* rgba masks */
+ 16, 16, 16, 16, /* rgba accum sizes */
+ False, /* doubleBuffer */
+ False, /* stereo */
+ -1, /* bufferSize */
+ 16, /* depthSize */
+ 8, /* stencilSize */
+ 0, /* auxBuffers */
+ 0, /* level */
+ GLX_NONE, /* visualRating */
+ GLX_NONE, /* transparentPixel */
+ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
+ 0 /* transparentIndex */
+ },
+ /* [4] = CI, double buffered, Z */
+ {
+ -1, /* vid */
+ -1, /* class */
+ False, /* rgba? (false = color index) */
+ -1, -1, -1, 0, /* rgba sizes */
+ -1, -1, -1, 0, /* rgba masks */
+ 0, 0, 0, 0, /* rgba accum sizes */
+ True, /* doubleBuffer */
+ False, /* stereo */
+ -1, /* bufferSize */
+ 16, /* depthSize */
+ 0, /* stencilSize */
+ 0, /* auxBuffers */
+ 0, /* level */
+ GLX_NONE, /* visualRating */
+ GLX_NONE, /* transparentPixel */
+ 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */
+ 0 /* transparentIndex */
+ },
+};
+
+
+static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
+ VisualID *defaultVisp,
+ int ndepth, DepthPtr pdepth,
+ int rootDepth)
+{
+ int numRGBconfigs;
+ int numCIconfigs;
+ int numVisuals = *nvisualp;
+ int numNewVisuals;
+ int numNewConfigs;
+ VisualPtr pVisual = *visualp;
+ VisualPtr pVisualNew = NULL;
+ VisualID *orig_vid = NULL;
+ __GLcontextModes *modes;
+ __GLXvisualConfig *pNewVisualConfigs = NULL;
+ void **glXVisualPriv;
+ void **pNewVisualPriv;
+ int found_default;
+ int i, j, k;
+
+ if (numConfigs > 0)
+ numNewConfigs = numConfigs;
+ else
+ numNewConfigs = NUM_FALLBACK_CONFIGS;
+
+ /* Alloc space for the list of new GLX visuals */
+ pNewVisualConfigs = (__GLXvisualConfig *)
+ malloc(numNewConfigs * sizeof(__GLXvisualConfig));
+ if (!pNewVisualConfigs) {
+ return FALSE;
+ }
+
+ /* Alloc space for the list of new GLX visual privates */
+ pNewVisualPriv = (void **) malloc(numNewConfigs * sizeof(void *));
+ if (!pNewVisualPriv) {
+ free(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /*
+ ** If SetVisualConfigs was not called, then use default GLX
+ ** visual configs.
+ */
+ if (numConfigs == 0) {
+ memcpy(pNewVisualConfigs, FallbackConfigs,
+ NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig));
+ memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *));
+ }
+ else {
+ /* copy driver's visual config info */
+ for (i = 0; i < numConfigs; i++) {
+ pNewVisualConfigs[i] = visualConfigs[i];
+ pNewVisualPriv[i] = visualPrivates[i];
+ }
+ }
+
+ /* Count the number of RGB and CI visual configs */
+ numRGBconfigs = 0;
+ numCIconfigs = 0;
+ for (i = 0; i < numNewConfigs; i++) {
+ if (pNewVisualConfigs[i].rgba)
+ numRGBconfigs++;
+ else
+ numCIconfigs++;
+ }
+
+ /* Count the total number of visuals to compute */
+ numNewVisuals = 0;
+ for (i = 0; i < numVisuals; i++) {
+ numNewVisuals +=
+ (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
+ ? numRGBconfigs : numCIconfigs;
+ }
+
+ /* Reset variables for use with the next screen/driver's visual configs */
+ visualConfigs = NULL;
+ numConfigs = 0;
+
+ /* Alloc temp space for the list of orig VisualIDs for each new visual */
+ orig_vid = (VisualID *)malloc(numNewVisuals * sizeof(VisualID));
+ if (!orig_vid) {
+ free(pNewVisualPriv);
+ free(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the list of glXVisuals */
+ modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes));
+ if (modes == NULL) {
+ free(orig_vid);
+ free(pNewVisualPriv);
+ free(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the list of glXVisualPrivates */
+ glXVisualPriv = (void **)malloc(numNewVisuals * sizeof(void *));
+ if (!glXVisualPriv) {
+ _gl_context_modes_destroy( modes );
+ free(orig_vid);
+ free(pNewVisualPriv);
+ free(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the new list of the X server's visuals */
+ pVisualNew = (VisualPtr)malloc(numNewVisuals * sizeof(VisualRec));
+ if (!pVisualNew) {
+ free(glXVisualPriv);
+ _gl_context_modes_destroy( modes );
+ free(orig_vid);
+ free(pNewVisualPriv);
+ free(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Initialize the new visuals */
+ found_default = FALSE;
+ MESAScreens[screenInfo.numScreens-1].modes = modes;
+ for (i = j = 0; i < numVisuals; i++) {
+ int is_rgb = (pVisual[i].class == TrueColor ||
+ pVisual[i].class == DirectColor);
+
+ for (k = 0; k < numNewConfigs; k++) {
+ if (pNewVisualConfigs[k].rgba != is_rgb)
+ continue;
+
+ assert( modes != NULL );
+
+ /* Initialize the new visual */
+ pVisualNew[j] = pVisual[i];
+ pVisualNew[j].vid = FakeClientID(0);
+
+ /* Check for the default visual */
+ if (!found_default && pVisual[i].vid == *defaultVisp) {
+ *defaultVisp = pVisualNew[j].vid;
+ found_default = TRUE;
+ }
+
+ /* Save the old VisualID */
+ orig_vid[j] = pVisual[i].vid;
+
+ /* Initialize the glXVisual */
+ _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] );
+ modes->visualID = pVisualNew[j].vid;
+
+ /*
+ * If the class is -1, then assume the X visual information
+ * is identical to what GLX needs, and take them from the X
+ * visual. NOTE: if class != -1, then all other fields MUST
+ * be initialized.
+ */
+ if (modes->visualType == GLX_NONE) {
+ modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class );
+ modes->redBits = count_bits(pVisual[i].redMask);
+ modes->greenBits = count_bits(pVisual[i].greenMask);
+ modes->blueBits = count_bits(pVisual[i].blueMask);
+ modes->alphaBits = modes->alphaBits;
+ modes->redMask = pVisual[i].redMask;
+ modes->greenMask = pVisual[i].greenMask;
+ modes->blueMask = pVisual[i].blueMask;
+ modes->alphaMask = modes->alphaMask;
+ modes->rgbBits = (is_rgb)
+ ? (modes->redBits + modes->greenBits +
+ modes->blueBits + modes->alphaBits)
+ : rootDepth;
+ }
+
+ /* Save the device-dependent private for this visual */
+ glXVisualPriv[j] = pNewVisualPriv[k];
+
+ j++;
+ modes = modes->next;
+ }
+ }
+
+ assert(j <= numNewVisuals);
+
+ /* Save the GLX visuals in the screen structure */
+ MESAScreens[screenInfo.numScreens-1].num_vis = numNewVisuals;
+ MESAScreens[screenInfo.numScreens-1].private = glXVisualPriv;
+
+ /* Set up depth's VisualIDs */
+ for (i = 0; i < ndepth; i++) {
+ int numVids = 0;
+ VisualID *pVids = NULL;
+ int k, n = 0;
+
+ /* Count the new number of VisualIDs at this depth */
+ for (j = 0; j < pdepth[i].numVids; j++)
+ for (k = 0; k < numNewVisuals; k++)
+ if (pdepth[i].vids[j] == orig_vid[k])
+ numVids++;
+
+ /* Allocate a new list of VisualIDs for this depth */
+ pVids = (VisualID *)malloc(numVids * sizeof(VisualID));
+
+ /* Initialize the new list of VisualIDs for this depth */
+ for (j = 0; j < pdepth[i].numVids; j++)
+ for (k = 0; k < numNewVisuals; k++)
+ if (pdepth[i].vids[j] == orig_vid[k])
+ pVids[n++] = pVisualNew[k].vid;
+
+ /* Update this depth's list of VisualIDs */
+ free(pdepth[i].vids);
+ pdepth[i].vids = pVids;
+ pdepth[i].numVids = numVids;
+ }
+
+ /* Update the X server's visuals */
+ *nvisualp = numNewVisuals;
+ *visualp = pVisualNew;
+
+ /* Free the old list of the X server's visuals */
+ free(pVisual);
+
+ /* Clean up temporary allocations */
+ free(orig_vid);
+ free(pNewVisualPriv);
+ free(pNewVisualConfigs);
+
+ /* Free the private list created by DDX HW driver */
+ if (visualPrivates)
+ free(visualPrivates);
+ visualPrivates = NULL;
+
+ return TRUE;
+}
+
+void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
+ void **privates)
+{
+ numConfigs = nconfigs;
+ visualConfigs = configs;
+ visualPrivates = privates;
+}
+
+Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp, int *rootDepthp,
+ VisualID *defaultVisp, unsigned long sizes,
+ int bitsPerRGB)
+{
+ /*
+ * Setup the visuals supported by this particular screen.
+ */
+ return init_visuals(nvisualp, visualp, defaultVisp,
+ *ndepthp, *depthp, *rootDepthp);
+}
+
+static void fixup_visuals(int screen)
+{
+ ScreenPtr pScreen = screenInfo.screens[screen];
+ __MESA_screen *pMScr = &MESAScreens[screen];
+ int j;
+ __GLcontextModes *modes;
+
+ for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) {
+ const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
+ const int nplanes = (modes->rgbBits - modes->alphaBits);
+ const VisualPtr pVis = pScreen->visuals;
+
+ /* Find a visual that matches the GLX visual's class and size */
+ for (j = 0; j < pScreen->numVisuals; j++) {
+ if (pVis[j].class == vis_class &&
+ pVis[j].nplanes == nplanes) {
+
+ /* Fixup the masks */
+ modes->redMask = pVis[j].redMask;
+ modes->greenMask = pVis[j].greenMask;
+ modes->blueMask = pVis[j].blueMask;
+
+ /* Recalc the sizes */
+ modes->redBits = count_bits(modes->redMask);
+ modes->greenBits = count_bits(modes->greenMask);
+ modes->blueBits = count_bits(modes->blueMask);
+ }
+ }
+ }
+}
+
+static void init_screen_visuals(int screen)
+{
+ ScreenPtr pScreen = screenInfo.screens[screen];
+ __GLcontextModes *modes;
+ XMesaVisual *pXMesaVisual;
+ int *used;
+ int i, j;
+
+ /* Alloc space for the list of XMesa visuals */
+ pXMesaVisual = (XMesaVisual *)malloc(MESAScreens[screen].num_vis *
+ sizeof(XMesaVisual));
+ memset(pXMesaVisual, 0,
+ MESAScreens[screen].num_vis * sizeof(XMesaVisual));
+
+ /* FIXME: Change 'used' to be a array of bits (rather than of ints),
+ * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less
+ * FIXME: than 64 or 128 the stack array can be used instead of calling
+ * FIXME: malloc / free. If nothing else, convert 'used' to
+ * FIXME: array of bytes instead of ints!
+ */
+ used = (int *)malloc(pScreen->numVisuals * sizeof(int));
+ memset(used, 0, pScreen->numVisuals * sizeof(int));
+
+ i = 0;
+ for ( modes = MESAScreens[screen].modes
+ ; modes != NULL
+ ; modes = modes->next ) {
+ const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
+ const int nplanes = (modes->rgbBits - modes->alphaBits);
+ const VisualPtr pVis = pScreen->visuals;
+
+ for (j = 0; j < pScreen->numVisuals; j++) {
+ if (pVis[j].class == vis_class &&
+ pVis[j].nplanes == nplanes &&
+ pVis[j].redMask == modes->redMask &&
+ pVis[j].greenMask == modes->greenMask &&
+ pVis[j].blueMask == modes->blueMask &&
+ !used[j]) {
+
+ /* Create the XMesa visual */
+ pXMesaVisual[i] =
+ XMesaCreateVisual(pScreen,
+ pVis,
+ modes->rgbMode,
+ (modes->alphaBits > 0),
+ modes->doubleBufferMode,
+ modes->stereoMode,
+ GL_TRUE, /* ximage_flag */
+ modes->depthBits,
+ modes->stencilBits,
+ modes->accumRedBits,
+ modes->accumGreenBits,
+ modes->accumBlueBits,
+ modes->accumAlphaBits,
+ modes->samples,
+ modes->level,
+ modes->visualRating);
+ /* Set the VisualID */
+ modes->visualID = pVis[j].vid;
+
+ /* Mark this visual used */
+ used[j] = 1;
+ break;
+ }
+ }
+
+ if ( j == pScreen->numVisuals ) {
+ ErrorF("No matching visual for __GLcontextMode with "
+ "visual class = %d (%d), nplanes = %u\n",
+ vis_class,
+ modes->visualType,
+ (modes->rgbBits - modes->alphaBits) );
+ }
+ else if ( modes->visualID == -1 ) {
+ FatalError( "Matching visual found, but visualID still -1!\n" );
+ }
+
+ i++;
+ }
+
+ free(used);
+
+ MESAScreens[screen].xm_vis = pXMesaVisual;
+}
+
+Bool __MESA_screenProbe(int screen)
+{
+ /*
+ * Set up the current screen's visuals.
+ */
+ __glDDXScreenInfo.modes = MESAScreens[screen].modes;
+ __glDDXScreenInfo.pVisualPriv = MESAScreens[screen].private;
+ __glDDXScreenInfo.numVisuals =
+ __glDDXScreenInfo.numUsableVisuals = MESAScreens[screen].num_vis;
+
+ /*
+ * Set the current screen's createContext routine. This could be
+ * wrapped by a DDX GLX context creation routine.
+ */
+ __glDDXScreenInfo.createContext = __MESA_createContext;
+
+ /*
+ * The ordering of the rgb compenents might have been changed by the
+ * driver after mi initialized them.
+ */
+ fixup_visuals(screen);
+
+ /*
+ * Find the GLX visuals that are supported by this screen and create
+ * XMesa's visuals.
+ */
+ init_screen_visuals(screen);
+
+ return TRUE;
+}
+
+extern void __MESA_resetExtension(void)
+{
+ int i, j;
+
+ XMesaReset();
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ for (j = 0; j < MESAScreens[i].num_vis; j++) {
+ if (MESAScreens[i].xm_vis[j]) {
+ XMesaDestroyVisual(MESAScreens[i].xm_vis[j]);
+ MESAScreens[i].xm_vis[j] = NULL;
+ }
+ }
+ _gl_context_modes_destroy( MESAScreens[i].modes );
+ MESAScreens[i].modes = NULL;
+ free(MESAScreens[i].private);
+ MESAScreens[i].private = NULL;
+ free(MESAScreens[i].xm_vis);
+ MESAScreens[i].xm_vis = NULL;
+ MESAScreens[i].num_vis = 0;
+ }
+ __glDDXScreenInfo.modes = NULL;
+ MESA_CC = NULL;
+}
+
+void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv)
+{
+ DrawablePtr pDraw = glxPriv->pDraw;
+ XMesaVisual xm_vis = find_mesa_visual(pDraw->pScreen->myNum,
+ glxPriv->modes->visualID);
+ __GLdrawablePrivate *glPriv = &glxPriv->glPriv;
+ __MESA_buffer buf;
+
+ if (xm_vis == NULL) {
+ ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
+ glxPriv->modes->visualID);
+ }
+ buf = (__MESA_buffer)malloc(sizeof(struct __MESA_bufferRec));
+
+ /* Create Mesa's buffers */
+ if (glxPriv->type == DRAWABLE_WINDOW) {
+ buf->xm_buf = (void *)XMesaCreateWindowBuffer(xm_vis,
+ (WindowPtr)pDraw);
+ } else {
+ buf->xm_buf = (void *)XMesaCreatePixmapBuffer(xm_vis,
+ (PixmapPtr)pDraw, 0);
+ }
+
+ /* Wrap the front buffer's resize routine */
+ buf->fbresize = glPriv->frontBuffer.resize;
+ glPriv->frontBuffer.resize = __MESA_resizeBuffers;
+
+ /* Wrap the swap buffers routine */
+ buf->fbswap = glxPriv->swapBuffers;
+ glxPriv->swapBuffers = __MESA_swapBuffers;
+
+ /* Save Mesa's private buffer structure */
+ glPriv->private = (void *)buf;
+ glPriv->freePrivate = __MESA_destroyBuffer;
+}
+
+GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buffer,
+ GLint x, GLint y,
+ GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv,
+ GLuint bufferMask)
+{
+ __MESA_buffer buf = (__MESA_buffer)glPriv->private;
+
+ if (buf->xm_buf)
+ XMesaResizeBuffers(buf->xm_buf);
+
+ return (*buf->fbresize)(buffer, x, y, width, height, glPriv, bufferMask);
+}
+
+GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv)
+{
+ __MESA_buffer buf = (__MESA_buffer)glxPriv->glPriv.private;
+
+ /*
+ ** Do not call the wrapped swap buffers routine since Mesa has
+ ** already done the swap.
+ */
+ XMesaSwapBuffers(buf->xm_buf);
+
+ return GL_TRUE;
+}
+
+void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv)
+{
+ __MESA_buffer buf = (__MESA_buffer)glPriv->private;
+ __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
+
+#ifdef NXAGENT_SERVER
+ AddWSDrawBuffer(& (buf -> xm_buf -> mesa_buffer) );
+#endif
+
+ /* Destroy Mesa's buffers */
+ if (buf->xm_buf)
+ XMesaDestroyBuffer(buf->xm_buf);
+
+ /* Unwrap these routines */
+ glxPriv->swapBuffers = buf->fbswap;
+ glPriv->frontBuffer.resize = buf->fbresize;
+
+ free(glPriv->private);
+ glPriv->private = NULL;
+}
+
+__GLinterface *__MESA_createContext(__GLimports *imports,
+ __GLcontextModes *modes,
+ __GLinterface *shareGC)
+{
+ __GLcontext *gl_ctx = NULL;
+ __GLcontext *m_share = NULL;
+ __GLXcontext *glxc = (__GLXcontext *)imports->other;
+ XMesaVisual xm_vis;
+
+ if (shareGC)
+ m_share = (__GLcontext *)shareGC;
+
+ xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->modes->visualID);
+ if (xm_vis) {
+ XMesaContext xmshare = m_share ? m_share->DriverCtx : 0;
+ XMesaContext xmctx = XMesaCreateContext(xm_vis, xmshare);
+ gl_ctx = xmctx ? &xmctx->mesa : 0;
+ }
+ else {
+ ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n",
+ glxc->modes->visualID);
+ }
+
+
+ if (!gl_ctx)
+ return NULL;
+
+ gl_ctx->imports = *imports;
+ gl_ctx->exports.destroyContext = __MESA_destroyContext;
+ gl_ctx->exports.loseCurrent = __MESA_loseCurrent;
+ gl_ctx->exports.makeCurrent = __MESA_makeCurrent;
+ gl_ctx->exports.shareContext = __MESA_shareContext;
+ gl_ctx->exports.copyContext = __MESA_copyContext;
+ gl_ctx->exports.forceCurrent = __MESA_forceCurrent;
+ gl_ctx->exports.notifyResize = __MESA_notifyResize;
+ gl_ctx->exports.notifyDestroy = __MESA_notifyDestroy;
+ gl_ctx->exports.notifySwapBuffers = __MESA_notifySwapBuffers;
+ gl_ctx->exports.dispatchExec = __MESA_dispatchExec;
+ gl_ctx->exports.beginDispatchOverride = __MESA_beginDispatchOverride;
+ gl_ctx->exports.endDispatchOverride = __MESA_endDispatchOverride;
+
+ return (__GLinterface *)gl_ctx;
+}
+
+GLboolean __MESA_destroyContext(__GLcontext *gc)
+{
+ XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
+ XMesaDestroyContext( xmesa );
+ return GL_TRUE;
+}
+
+GLboolean __MESA_loseCurrent(__GLcontext *gc)
+{
+ XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
+ MESA_CC = NULL;
+ __glXLastContext = NULL;
+ return XMesaLoseCurrent(xmesa);
+}
+
+GLboolean __MESA_makeCurrent(__GLcontext *gc)
+{
+ __GLdrawablePrivate *drawPriv = gc->imports.getDrawablePrivate( gc );
+ __MESA_buffer drawBuf = (__MESA_buffer)drawPriv->private;
+ __GLdrawablePrivate *readPriv = gc->imports.getReadablePrivate( gc );
+ __MESA_buffer readBuf = (__MESA_buffer)readPriv->private;
+ XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
+
+ MESA_CC = gc;
+ return XMesaMakeCurrent2(xmesa, drawBuf->xm_buf, readBuf->xm_buf);
+}
+
+GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare)
+{
+ /* NOT_DONE */
+ /* XXX I don't see where/how this could ever be called */
+ ErrorF("__MESA_shareContext\n");
+ return GL_FALSE;
+}
+
+GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
+ GLuint mask)
+{
+ XMesaContext xm_dst = (XMesaContext) dst->DriverCtx;
+ const XMesaContext xm_src = (const XMesaContext) src->DriverCtx;
+ _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask);
+ return GL_TRUE;
+}
+
+GLboolean __MESA_forceCurrent(__GLcontext *gc)
+{
+ XMesaContext xmesa = (XMesaContext) gc->DriverCtx;
+ MESA_CC = gc;
+ return XMesaForceCurrent(xmesa);
+}
+
+GLboolean __MESA_notifyResize(__GLcontext *gc)
+{
+ /* NOT_DONE */
+ ErrorF("__MESA_notifyResize\n");
+ return GL_FALSE;
+}
+
+void __MESA_notifyDestroy(__GLcontext *gc)
+{
+ /* NOT_DONE */
+ ErrorF("__MESA_notifyDestroy\n");
+ return;
+}
+
+void __MESA_notifySwapBuffers(__GLcontext *gc)
+{
+ _mesa_notifySwapBuffers(gc);
+}
+
+struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc)
+{
+ /* NOT_DONE */
+ ErrorF("__MESA_dispatchExec\n");
+ return NULL;
+}
+
+void __MESA_beginDispatchOverride(__GLcontext *gc)
+{
+ /* NOT_DONE */
+ ErrorF("__MESA_beginDispatchOverride\n");
+ return;
+}
+
+void __MESA_endDispatchOverride(__GLcontext *gc)
+{
+ /* NOT_DONE */
+ ErrorF("__MESA_endDispatchOverride\n");
+ return;
+}
+
+
+/*
+ * Server-side GLX uses these functions which are normally defined
+ * in the OpenGL SI.
+ */
+
+GLuint __glFloorLog2(GLuint val)
+{
+ int c = 0;
+
+ while (val > 1) {
+ c++;
+ val >>= 1;
+ }
+ return c;
+}
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.c b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.c
new file mode 100644
index 000000000..fad84ec7e
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.c
@@ -0,0 +1,151 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <gcstruct.h>
+#include "pixmapstr.h"
+#include "xf86glx_util.h"
+#include <nx-X11/Xmd.h>
+
+#ifdef ROUNDUP
+#undef ROUNDUP
+#endif
+
+#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
+
+XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data)
+{
+ XMesaImage *image;
+
+ image = (XMesaImage *)malloc(sizeof(XMesaImage));
+
+ if (image) {
+ image->width = width;
+ image->height = height;
+ image->data = data;
+ /* Always pad to 32 bits */
+ image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32);
+ image->bits_per_pixel = bitsPerPixel;
+ }
+
+ return image;
+}
+
+void XMesaDestroyImage(XMesaImage *image)
+{
+ if (image->data)
+ free(image->data);
+ free(image);
+}
+
+unsigned long XMesaGetPixel(XMesaImage *image, int x, int y)
+{
+ CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
+ CARD8 *i8;
+ CARD16 *i16;
+ CARD32 *i32;
+ switch (image->bits_per_pixel) {
+ case 8:
+ i8 = (CARD8 *)row;
+ return i8[x];
+ break;
+ case 15:
+ case 16:
+ i16 = (CARD16 *)row;
+ return i16[x];
+ break;
+ case 24: /* WARNING: architecture specific code */
+ i8 = (CARD8 *)row;
+ return (((CARD32)i8[x*3]) |
+ (((CARD32)i8[x*3+1])<<8) |
+ (((CARD32)i8[x*3+2])<<16));
+ break;
+ case 32:
+ i32 = (CARD32 *)row;
+ return i32[x];
+ break;
+ }
+ return 0;
+}
+
+#ifndef XMESA_USE_PUTPIXEL_MACRO
+void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel)
+{
+ CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line);
+ CARD8 *i8;
+ CARD16 *i16;
+ CARD32 *i32;
+ switch (image->bits_per_pixel) {
+ case 8:
+ i8 = (CARD8 *)row;
+ i8[x] = (CARD8)pixel;
+ break;
+ case 15:
+ case 16:
+ i16 = (CARD16 *)row;
+ i16[x] = (CARD16)pixel;
+ break;
+ case 24: /* WARNING: architecture specific code */
+ i8 = (CARD8 *)__row;
+ i8[x*3] = (CARD8)(p);
+ i8[x*3+1] = (CARD8)(p>>8);
+ i8[x*3+2] = (CARD8)(p>>16);
+ case 32:
+ i32 = (CARD32 *)row;
+ i32[x] = (CARD32)pixel;
+ break;
+ }
+}
+#endif
+
+void XMesaPutImageHelper(ScreenPtr display,
+ DrawablePtr d, GCPtr gc,
+ XMesaImage *image,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ unsigned int width, unsigned int height)
+{
+ /* NOT_DONE: Verify that the following works for all depths */
+ char *src = (image->data +
+ src_y * image->bytes_per_line +
+ ((src_x * image->bits_per_pixel) >> 3));
+
+ ValidateGC(d, gc);
+ (*gc->ops->PutImage)(d, gc, d->depth, dest_x, dest_y, width, height,
+ 0, ZPixmap, src);
+}
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.h b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.h
new file mode 100644
index 000000000..bb314128d
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/xf86glx_util.h
@@ -0,0 +1,105 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ * Brian Paul <brian@precisioninsight.com>
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XF86GLX_UTIL_H_
+#define _XF86GLX_UTIL_H_
+
+#ifdef __CYGWIN__
+#undef WIN32
+#undef _WIN32
+#endif
+
+#include <screenint.h>
+#include <pixmap.h>
+#include <gc.h>
+#include "GL/xmesa.h"
+
+#define XMESA_USE_PUTPIXEL_MACRO
+
+struct _XMesaImageRec {
+ int width, height;
+ char *data;
+ int bytes_per_line; /* Padded to 32 bits */
+ int bits_per_pixel;
+};
+
+extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height,
+ char *data);
+extern void XMesaDestroyImage(XMesaImage *image);
+extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y);
+#ifdef XMESA_USE_PUTPIXEL_MACRO
+#define XMesaPutPixel(__i,__x,__y,__p) \
+{ \
+ CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \
+ CARD8 *__i8; \
+ CARD16 *__i16; \
+ CARD32 *__i32; \
+ switch (__i->bits_per_pixel) { \
+ case 8: \
+ __i8 = (CARD8 *)__row; \
+ __i8[__x] = (CARD8)__p; \
+ break; \
+ case 15: \
+ case 16: \
+ __i16 = (CARD16 *)__row; \
+ __i16[__x] = (CARD16)__p; \
+ break; \
+ case 24: /* WARNING: architecture specific code */ \
+ __i8 = (CARD8 *)__row; \
+ __i8[__x*3] = (CARD8)(__p); \
+ __i8[__x*3+1] = (CARD8)(__p>>8); \
+ __i8[__x*3+2] = (CARD8)(__p>>16); \
+ break; \
+ case 32: \
+ __i32 = (CARD32 *)__row; \
+ __i32[__x] = (CARD32)__p; \
+ break; \
+ } \
+}
+#else
+extern void XMesaPutPixel(XMesaImage *image, int x, int y,
+ unsigned long pixel);
+#endif
+
+extern void XMesaPutImageHelper(ScreenPtr display,
+ DrawablePtr d, GCPtr gc,
+ XMesaImage *image,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ unsigned int width, unsigned int height);
+
+#endif /* _XF86GLX_UTIL_H_ */
diff --git a/nx-X11/programs/Xserver/GL/mesa/X/xf86glxint.h b/nx-X11/programs/Xserver/GL/mesa/X/xf86glxint.h
new file mode 100644
index 000000000..4784566a4
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/X/xf86glxint.h
@@ -0,0 +1,101 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XF86GLXINT_H_
+#define _XF86GLXINT_H_
+
+#include <miscstruct.h>
+#include <GL/gl.h>
+#include <GL/xmesa.h>
+
+typedef struct __MESA_screenRec __MESA_screen;
+struct __MESA_screenRec {
+ int num_vis;
+ __GLcontextModes *modes;
+ XMesaVisual *xm_vis;
+ void **private;
+};
+
+typedef struct __MESA_bufferRec *__MESA_buffer;
+struct __MESA_bufferRec {
+ XMesaBuffer xm_buf;
+ GLboolean (*fbresize)(__GLdrawableBuffer *buf,
+ GLint x, GLint y, GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv, GLuint bufferMask);
+ GLboolean (*fbswap)(__GLXdrawablePrivate *glxPriv);
+};
+
+extern void __MESA_setVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
+ void **privates);
+extern Bool __MESA_initVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp, int *rootDepthp,
+ VisualID *defaultVisp, unsigned long sizes,
+ int bitsPerRGB);
+extern Bool __MESA_screenProbe(int screen);
+
+extern void __MESA_resetExtension(void);
+
+extern void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv);
+extern GLboolean __MESA_resizeBuffers(__GLdrawableBuffer *buf,
+ GLint x, GLint y,
+ GLuint width, GLuint height,
+ __GLdrawablePrivate *glPriv,
+ GLuint bufferMask);
+extern GLboolean __MESA_swapBuffers(__GLXdrawablePrivate *glxPriv);
+extern void __MESA_destroyBuffer(__GLdrawablePrivate *glPriv);
+
+extern __GLinterface *__MESA_createContext(__GLimports *imports,
+ __GLcontextModes *modes,
+ __GLinterface *shareGC);
+extern GLboolean __MESA_destroyContext(__GLcontext *gc);
+extern GLboolean __MESA_loseCurrent(__GLcontext *gc);
+extern GLboolean __MESA_makeCurrent(__GLcontext *gc);
+extern GLboolean __MESA_shareContext(__GLcontext *gc, __GLcontext *gcShare);
+extern GLboolean __MESA_copyContext(__GLcontext *dst, const __GLcontext *src,
+ GLuint mask);
+extern GLboolean __MESA_forceCurrent(__GLcontext *gc);
+
+extern GLboolean __MESA_notifyResize(__GLcontext *gc);
+extern void __MESA_notifyDestroy(__GLcontext *gc);
+extern void __MESA_notifySwapBuffers(__GLcontext *gc);
+extern struct __GLdispatchStateRec *__MESA_dispatchExec(__GLcontext *gc);
+extern void __MESA_beginDispatchOverride(__GLcontext *gc);
+extern void __MESA_endDispatchOverride(__GLcontext *gc);
+
+extern GLuint __glFloorLog2(GLuint val);
+
+#endif /* _XF86GLXINT_H_ */
diff --git a/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile b/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile
new file mode 100644
index 000000000..474710747
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile
@@ -0,0 +1,36 @@
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaACBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_AC_SRCS)
+ OBJS = $(MESA_AC_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/array_cache \
+ -I$(MESASRCDIR)/src/mesa/math \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile.inc
new file mode 100644
index 000000000..39f6e2400
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/array_cache/Imakefile.inc
@@ -0,0 +1,28 @@
+MESAACBUILDDIR = MesaACBuildDir
+
+ MESA_AC_SRCS = $(MESAACBUILDDIR)ac_context.c \
+ $(MESAACBUILDDIR)ac_import.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(acache.h, $(MESASRCDIR)/src/mesa/array_cache)
+LinkSourceFile(ac_context.c, $(MESASRCDIR)/src/mesa/array_cache)
+LinkSourceFile(ac_context.h, $(MESASRCDIR)/src/mesa/array_cache)
+LinkSourceFile(ac_import.c, $(MESASRCDIR)/src/mesa/array_cache)
+#endif
+
+ MESA_AC_OBJS = $(MESAACBUILDDIR)ac_context.o \
+ $(MESAACBUILDDIR)ac_import.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_AC_UOBJS = $(MESAACBUILDDIR)unshared/ac_context.o \
+ $(MESAACBUILDDIR)unshared/ac_import.o
+#else
+ MESA_AC_UOBJS = $(MESA_AC_OBJS)
+#endif
+
+ MESA_AC_DOBJS = $(MESAACBUILDDIR)debugger/ac_context.o \
+ $(MESAACBUILDDIR)debugger/ac_import.o
+
+ MESA_AC_POBJS = $(MESAACBUILDDIR)profiled/ac_context.o \
+ $(MESAACBUILDDIR)profiled/ac_import.o
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/main/Imakefile b/nx-X11/programs/Xserver/GL/mesa/main/Imakefile
new file mode 100644
index 000000000..d6e914b89
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/main/Imakefile
@@ -0,0 +1,40 @@
+/* Large PIC tables needed for Solaris/SPARC builds */
+#if defined(SunArchitecture) && defined(SparcArchitecture) && defined(LargePositionIndependentCFlags)
+ PICFLAGS = LargePositionIndependentCFlags
+#endif
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(COREMESABASESRCS)
+ OBJS = $(COREMESABASEOBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/main/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/main/Imakefile.inc
new file mode 100644
index 000000000..3e98f9149
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/main/Imakefile.inc
@@ -0,0 +1,481 @@
+/* gcc on ppc64 defines this, causes macro recursion with pixel below */
+#undef pixel
+
+MESABUILDDIR = MesaBuildDir
+
+#ifdef NeedAllMesaSrc
+ DISPATCHSRCS = $(MESABUILDDIR)dispatch.c
+ GLAPISRCS = $(MESABUILDDIR)glapi.c
+ GLTHREADSRCS = $(MESABUILDDIR)glthread.c
+#endif
+
+MESA_CORE_INCLUDES = -I$(MESASRCDIR)/src/array_cache \
+ -I$(MESASRCDIR)/src/math -I$(MESASRCDIR)/src/shader \
+ -I$(MESASRCDIR)/src/swrast -I$(MESASRCDIR)/src/swrast_setup \
+ -I$(MESASRCDIR)/src/tnl -I$(MESASRCDIR)/src/tnl_dd
+
+COREMESABASESRCS = \
+ $(MESABUILDDIR)api_arrayelt.c \
+ $(MESABUILDDIR)api_loopback.c \
+ $(MESABUILDDIR)api_noop.c \
+ $(MESABUILDDIR)api_validate.c \
+ $(MESABUILDDIR)accum.c \
+ $(MESABUILDDIR)attrib.c \
+ $(MESABUILDDIR)blend.c \
+ $(MESABUILDDIR)bufferobj.c \
+ $(MESABUILDDIR)buffers.c \
+ $(MESABUILDDIR)clip.c \
+ $(MESABUILDDIR)colortab.c \
+ $(MESABUILDDIR)context.c \
+ $(MESABUILDDIR)convolve.c \
+ $(MESABUILDDIR)debug.c \
+ $(MESABUILDDIR)depth.c \
+ $(MESABUILDDIR)dlist.c \
+ $(MESABUILDDIR)drawpix.c \
+ $(MESABUILDDIR)enable.c \
+ $(MESABUILDDIR)enums.c \
+ $(MESABUILDDIR)eval.c \
+ $(MESABUILDDIR)execmem.c \
+ $(MESABUILDDIR)extensions.c \
+ $(MESABUILDDIR)feedback.c \
+ $(MESABUILDDIR)fbobject.c \
+ $(MESABUILDDIR)fog.c \
+ $(MESABUILDDIR)framebuffer.c \
+ $(MESABUILDDIR)get.c \
+ $(MESABUILDDIR)getstring.c \
+ $(MESABUILDDIR)hash.c \
+ $(MESABUILDDIR)hint.c \
+ $(MESABUILDDIR)histogram.c \
+ $(MESABUILDDIR)image.c \
+ $(MESABUILDDIR)imports.c \
+ $(MESABUILDDIR)light.c \
+ $(MESABUILDDIR)lines.c \
+ $(MESABUILDDIR)matrix.c \
+ $(MESABUILDDIR)mm.c \
+ $(MESABUILDDIR)occlude.c \
+ $(MESABUILDDIR)pixel.c \
+ $(MESABUILDDIR)points.c \
+ $(MESABUILDDIR)polygon.c \
+ $(MESABUILDDIR)rastpos.c \
+ $(MESABUILDDIR)renderbuffer.c \
+ $(MESABUILDDIR)state.c \
+ $(MESABUILDDIR)stencil.c \
+ $(MESABUILDDIR)texcompress.c \
+ $(MESABUILDDIR)texcompress_fxt1.c \
+ $(MESABUILDDIR)texcompress_s3tc.c \
+ $(MESABUILDDIR)texenvprogram.c \
+ $(MESABUILDDIR)texformat.c \
+ $(MESABUILDDIR)teximage.c \
+ $(MESABUILDDIR)texobj.c \
+ $(MESABUILDDIR)texrender.c \
+ $(MESABUILDDIR)texstate.c \
+ $(MESABUILDDIR)texstore.c \
+ $(MESABUILDDIR)varray.c \
+ $(MESABUILDDIR)vtxfmt.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(api_arrayelt.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_arrayelt.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_eval.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_loopback.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_loopback.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_noop.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_noop.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_validate.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(api_validate.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(accum.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(accum.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(attrib.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(attrib.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(blend.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(blend.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(bufferobj.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(bufferobj.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(buffers.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(buffers.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(clip.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(clip.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(colormac.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(colortab.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(colortab.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(config.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(context.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(context.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(convolve.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(convolve.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(dd.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(debug.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(debug.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(depth.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(depth.h, $(MESASRCDIR)/src/mesa/main)
+#ifdef NeedAllMesaSrc
+LinkSourceFile(dispatch.c, $(MESASRCDIR)/src/mesa/main)
+#endif
+LinkSourceFile(dlist.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(dlist.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(drawpix.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(drawpix.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(enable.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(enable.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(enums.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(enums.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(eval.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(eval.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(execmem.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(extensions.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(extensions.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(fbobject.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(fbobject.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(feedback.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(feedback.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(fog.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(fog.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(framebuffer.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(framebuffer.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(get.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(get.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(getstring.c, $(MESASRCDIR)/src/mesa/main)
+#ifdef NeedAllMesaSrc
+LinkSourceFile(glapi.c, $(MESASRCDIR)/src/mesa/glapi)
+LinkSourceFile(glthread.c, $(MESASRCDIR)/src/mesa/glapi)
+#endif
+LinkSourceFile(glheader.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(hash.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(hash.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(hint.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(hint.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(histogram.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(histogram.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(image.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(image.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(imports.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(imports.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(light.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(light.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(lines.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(lines.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(macros.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(matrix.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(matrix.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(mm.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(mm.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(mtypes.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(occlude.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(occlude.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(pixel.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(pixel.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(points.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(points.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(polygon.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(polygon.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(rastpos.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(rastpos.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(renderbuffer.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(renderbuffer.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(simple_list.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(state.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(state.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(stencil.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(stencil.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texcompress.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texcompress_fxt1.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texcompress_s3tc.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texcompress.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texenvprogram.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texenvprogram.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texformat.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texformat.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texformat_tmp.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(teximage.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(teximage.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texobj.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texobj.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texrender.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texrender.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texstate.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texstate.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texstore.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(texstore.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(varray.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(varray.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(version.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(vtxfmt.c, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(vtxfmt.h, $(MESASRCDIR)/src/mesa/main)
+LinkSourceFile(vtxfmt_tmp.h, $(MESASRCDIR)/src/mesa/main)
+#endif
+
+#ifdef NeedAllMesaSrc
+ DISPATCHOBJS = $(MESABUILDDIR)dispatch.o
+ GLAPIOBJS = $(MESABUILDDIR)glapi.o
+ GLTHREADOBJS = $(MESABUILDDIR)glthread.o
+#endif
+
+COREMESABASEOBJS = \
+ $(DISPATCHOBJS) \
+ $(GLAPIOBJS) \
+ $(GLTHREADOBJS) \
+ $(MESABUILDDIR)api_arrayelt.o \
+ $(MESABUILDDIR)api_loopback.o \
+ $(MESABUILDDIR)api_noop.o \
+ $(MESABUILDDIR)api_validate.o \
+ $(MESABUILDDIR)accum.o \
+ $(MESABUILDDIR)attrib.o \
+ $(MESABUILDDIR)blend.o \
+ $(MESABUILDDIR)bufferobj.o \
+ $(MESABUILDDIR)buffers.o \
+ $(MESABUILDDIR)clip.o \
+ $(MESABUILDDIR)colortab.o \
+ $(MESABUILDDIR)context.o \
+ $(MESABUILDDIR)convolve.o \
+ $(MESABUILDDIR)debug.o \
+ $(MESABUILDDIR)depth.o \
+ $(MESABUILDDIR)dlist.o \
+ $(MESABUILDDIR)drawpix.o \
+ $(MESABUILDDIR)enable.o \
+ $(MESABUILDDIR)enums.o \
+ $(MESABUILDDIR)eval.o \
+ $(MESABUILDDIR)execmem.o \
+ $(MESABUILDDIR)extensions.o \
+ $(MESABUILDDIR)fbobject.o \
+ $(MESABUILDDIR)feedback.o \
+ $(MESABUILDDIR)fog.o \
+ $(MESABUILDDIR)framebuffer.o \
+ $(MESABUILDDIR)get.o \
+ $(MESABUILDDIR)getstring.o \
+ $(MESABUILDDIR)hash.o \
+ $(MESABUILDDIR)hint.o \
+ $(MESABUILDDIR)histogram.o \
+ $(MESABUILDDIR)image.o \
+ $(MESABUILDDIR)imports.o \
+ $(MESABUILDDIR)light.o \
+ $(MESABUILDDIR)lines.o \
+ $(MESABUILDDIR)matrix.o \
+ $(MESABUILDDIR)mm.o \
+ $(MESABUILDDIR)occlude.o \
+ $(MESABUILDDIR)pixel.o \
+ $(MESABUILDDIR)points.o \
+ $(MESABUILDDIR)polygon.o \
+ $(MESABUILDDIR)rastpos.o \
+ $(MESABUILDDIR)renderbuffer.o \
+ $(MESABUILDDIR)state.o \
+ $(MESABUILDDIR)stencil.o \
+ $(MESABUILDDIR)texcompress.o \
+ $(MESABUILDDIR)texcompress_fxt1.o \
+ $(MESABUILDDIR)texcompress_s3tc.o \
+ $(MESABUILDDIR)texenvprogram.o \
+ $(MESABUILDDIR)texformat.o \
+ $(MESABUILDDIR)teximage.o \
+ $(MESABUILDDIR)texrender.o \
+ $(MESABUILDDIR)texobj.o \
+ $(MESABUILDDIR)texstate.o \
+ $(MESABUILDDIR)texstore.o \
+ $(MESABUILDDIR)varray.o \
+ $(MESABUILDDIR)vtxfmt.o
+
+#ifdef NeedAllMesaSrc
+ DISPATCHUOBJS = $(MESABUILDDIR)unshared/dispatch.o
+ GLAPIUOBJS = $(MESABUILDDIR)unshared/glapi.o
+ GLTHREADUOBJS = $(MESABUILDDIR)unshared/glthread.o
+#endif
+
+#if defined(DoSharedLib) && DoSharedLib
+COREMESABASEUOBJS = \
+ $(DISPATCHUOBJS) \
+ $(GLAPIUOBJS) \
+ $(GLTHREADUOBJS) \
+ $(MESABUILDDIR)unshared/api_arrayelt.o \
+ $(MESABUILDDIR)unshared/api_loopback.o \
+ $(MESABUILDDIR)unshared/api_noop.o \
+ $(MESABUILDDIR)unshared/api_validate.o \
+ $(MESABUILDDIR)unshared/accum.o \
+ $(MESABUILDDIR)unshared/attrib.o \
+ $(MESABUILDDIR)unshared/blend.o \
+ $(MESABUILDDIR)unshared/bufferobj.o \
+ $(MESABUILDDIR)unshared/buffers.o \
+ $(MESABUILDDIR)unshared/clip.o \
+ $(MESABUILDDIR)unshared/colortab.o \
+ $(MESABUILDDIR)unshared/context.o \
+ $(MESABUILDDIR)unshared/convolve.o \
+ $(MESABUILDDIR)unshared/debug.o \
+ $(MESABUILDDIR)unshared/depth.o \
+ $(MESABUILDDIR)unshared/dlist.o \
+ $(MESABUILDDIR)unshared/drawpix.o \
+ $(MESABUILDDIR)unshared/enable.o \
+ $(MESABUILDDIR)unshared/enums.o \
+ $(MESABUILDDIR)unshared/eval.o \
+ $(MESABUILDDIR)unshared/execmem.o \
+ $(MESABUILDDIR)unshared/extensions.o \
+ $(MESABUILDDIR)unshared/fbobject.o \
+ $(MESABUILDDIR)unshared/feedback.o \
+ $(MESABUILDDIR)unshared/fog.o \
+ $(MESABUILDDIR)unshared/framebuffer.o \
+ $(MESABUILDDIR)unshared/get.o \
+ $(MESABUILDDIR)unshared/getstring.o \
+ $(MESABUILDDIR)unshared/hash.o \
+ $(MESABUILDDIR)unshared/hint.o \
+ $(MESABUILDDIR)unshared/histogram.o \
+ $(MESABUILDDIR)unshared/image.o \
+ $(MESABUILDDIR)unshared/imports.o \
+ $(MESABUILDDIR)unshared/light.o \
+ $(MESABUILDDIR)unshared/lines.o \
+ $(MESABUILDDIR)unshared/matrix.o \
+ $(MESABUILDDIR)unshared/mm.o \
+ $(MESABUILDDIR)unshared/occlude.o \
+ $(MESABUILDDIR)unshared/pixel.o \
+ $(MESABUILDDIR)unshared/points.o \
+ $(MESABUILDDIR)unshared/polygon.o \
+ $(MESABUILDDIR)unshared/rastpos.o \
+ $(MESABUILDDIR)unshared/renderbuffer.o \
+ $(MESABUILDDIR)unshared/state.o \
+ $(MESABUILDDIR)unshared/stencil.o \
+ $(MESABUILDDIR)unshared/texcompress.o \
+ $(MESABUILDDIR)unshared/texcompress_fxt1.o \
+ $(MESABUILDDIR)unshared/texcompress_s3tc.o \
+ $(MESABUILDDIR)unshared/texenvprogram.o \
+ $(MESABUILDDIR)unshared/texformat.o \
+ $(MESABUILDDIR)unshared/teximage.o \
+ $(MESABUILDDIR)unshared/texobj.o \
+ $(MESABUILDDIR)unshared/texrender.o \
+ $(MESABUILDDIR)unshared/texstate.o \
+ $(MESABUILDDIR)unshared/texstore.o \
+ $(MESABUILDDIR)unshared/varray.o \
+ $(MESABUILDDIR)unshared/vtxfmt.o
+#else
+COREMESABASEUOBJS = $(COREMESABASEOBJS)
+#endif
+
+#ifdef NeedAllMesaSrc
+ DISPATCHDOBJS = $(MESABUILDDIR)debugger/dispatch.o
+ GLAPIDOBJS = $(MESABUILDDIR)debugger/glapi.o
+ GLTHREADDOBJS = $(MESABUILDDIR)debugger/glthread.o
+#endif
+
+COREMESABASEDOBJS = \
+ $(DISPATCHDOBJS) \
+ $(GLAPIDOBJS) \
+ $(GLTHREADDOBJS) \
+ $(MESABUILDDIR)debugger/api_arrayelt.o \
+ $(MESABUILDDIR)debugger/api_loopback.o \
+ $(MESABUILDDIR)debugger/api_noop.o \
+ $(MESABUILDDIR)debugger/api_validate.o \
+ $(MESABUILDDIR)debugger/accum.o \
+ $(MESABUILDDIR)debugger/attrib.o \
+ $(MESABUILDDIR)debugger/blend.o \
+ $(MESABUILDDIR)debugger/bufferobj.o \
+ $(MESABUILDDIR)debugger/buffers.o \
+ $(MESABUILDDIR)debugger/clip.o \
+ $(MESABUILDDIR)debugger/colortab.o \
+ $(MESABUILDDIR)debugger/context.o \
+ $(MESABUILDDIR)debugger/convolve.o \
+ $(MESABUILDDIR)debugger/debug.o \
+ $(MESABUILDDIR)debugger/depth.o \
+ $(MESABUILDDIR)debugger/dlist.o \
+ $(MESABUILDDIR)debugger/drawpix.o \
+ $(MESABUILDDIR)debugger/enable.o \
+ $(MESABUILDDIR)debugger/enums.o \
+ $(MESABUILDDIR)debugger/eval.o \
+ $(MESABUILDDIR)debugger/execmem.o \
+ $(MESABUILDDIR)debugger/extensions.o \
+ $(MESABUILDDIR)debugger/fbobject.o \
+ $(MESABUILDDIR)debugger/feedback.o \
+ $(MESABUILDDIR)debugger/fog.o \
+ $(MESABUILDDIR)debugger/framebuffer.o \
+ $(MESABUILDDIR)debugger/get.o \
+ $(MESABUILDDIR)debugger/getstring.o \
+ $(MESABUILDDIR)debugger/hash.o \
+ $(MESABUILDDIR)debugger/hint.o \
+ $(MESABUILDDIR)debugger/histogram.o \
+ $(MESABUILDDIR)debugger/image.o \
+ $(MESABUILDDIR)debugger/imports.o \
+ $(MESABUILDDIR)debugger/light.o \
+ $(MESABUILDDIR)debugger/lines.o \
+ $(MESABUILDDIR)debugger/matrix.o \
+ $(MESABUILDDIR)debugger/mm.o \
+ $(MESABUILDDIR)debugger/occlude.o \
+ $(MESABUILDDIR)debugger/pixel.o \
+ $(MESABUILDDIR)debugger/points.o \
+ $(MESABUILDDIR)debugger/polygon.o \
+ $(MESABUILDDIR)debugger/rastpos.o \
+ $(MESABUILDDIR)debugger/renderbuffer.o \
+ $(MESABUILDDIR)debugger/state.o \
+ $(MESABUILDDIR)debugger/stencil.o \
+ $(MESABUILDDIR)debugger/texcompress.o \
+ $(MESABUILDDIR)debugger/texcompress_fxt1.o \
+ $(MESABUILDDIR)debugger/texcompress_s3tc.o \
+ $(MESABUILDDIR)debugger/texenvprogram.o \
+ $(MESABUILDDIR)debugger/texformat.o \
+ $(MESABUILDDIR)debugger/teximage.o \
+ $(MESABUILDDIR)debugger/texobj.o \
+ $(MESABUILDDIR)debugger/texrender.o \
+ $(MESABUILDDIR)debugger/texstate.o \
+ $(MESABUILDDIR)debugger/texstore.o \
+ $(MESABUILDDIR)debugger/varray.o \
+ $(MESABUILDDIR)debugger/vtxfmt.o
+
+#ifdef NeedAllMesaSrc
+ DISPATCHPOBJS = $(MESABUILDDIR)profiled/dispatch.o
+ GLAPIPOBJS = $(MESABUILDDIR)profiled/glapi.o
+ GLTHREADPOBJS = $(MESABUILDDIR)profiled/glthread.o
+#endif
+
+COREMESABASEPOBJS = \
+ $(DISPATCHPOBJS) \
+ $(GLAPIPOBJS) \
+ $(GLTHREADPOBJS) \
+ $(MESABUILDDIR)profiled/api_arrayelt.o \
+ $(MESABUILDDIR)profiled/api_loopback.o \
+ $(MESABUILDDIR)profiled/api_noop.o \
+ $(MESABUILDDIR)profiled/api_validate.o \
+ $(MESABUILDDIR)profiled/accum.o \
+ $(MESABUILDDIR)profiled/attrib.o \
+ $(MESABUILDDIR)profiled/blend.o \
+ $(MESABUILDDIR)profiled/bufferobj.o \
+ $(MESABUILDDIR)profiled/buffers.o \
+ $(MESABUILDDIR)profiled/clip.o \
+ $(MESABUILDDIR)profiled/colortab.o \
+ $(MESABUILDDIR)profiled/context.o \
+ $(MESABUILDDIR)profiled/convolve.o \
+ $(MESABUILDDIR)profiled/debug.o \
+ $(MESABUILDDIR)profiled/depth.o \
+ $(MESABUILDDIR)profiled/dlist.o \
+ $(MESABUILDDIR)profiled/drawpix.o \
+ $(MESABUILDDIR)profiled/enable.o \
+ $(MESABUILDDIR)profiled/enums.o \
+ $(MESABUILDDIR)profiled/eval.o \
+ $(MESABUILDDIR)profiled/execmem.o \
+ $(MESABUILDDIR)profiled/extensions.o \
+ $(MESABUILDDIR)profiled/fbobject.o \
+ $(MESABUILDDIR)profiled/feedback.o \
+ $(MESABUILDDIR)profiled/fog.o \
+ $(MESABUILDDIR)profiled/framebuffer.o \
+ $(MESABUILDDIR)profiled/get.o \
+ $(MESABUILDDIR)profiled/getstring.o \
+ $(MESABUILDDIR)profiled/hash.o \
+ $(MESABUILDDIR)profiled/hint.o \
+ $(MESABUILDDIR)profiled/histogram.o \
+ $(MESABUILDDIR)profiled/image.o \
+ $(MESABUILDDIR)profiled/imports.o \
+ $(MESABUILDDIR)profiled/light.o \
+ $(MESABUILDDIR)profiled/lines.o \
+ $(MESABUILDDIR)profiled/matrix.o \
+ $(MESABUILDDIR)profiled/mm.o \
+ $(MESABUILDDIR)profiled/occlude.o \
+ $(MESABUILDDIR)profiled/pixel.o \
+ $(MESABUILDDIR)profiled/points.o \
+ $(MESABUILDDIR)profiled/polygon.o \
+ $(MESABUILDDIR)profiled/rastpos.o \
+ $(MESABUILDDIR)profiled/renderbuffer.o \
+ $(MESABUILDDIR)profiled/state.o \
+ $(MESABUILDDIR)profiled/stencil.o \
+ $(MESABUILDDIR)profiled/texcompress.o \
+ $(MESABUILDDIR)profiled/texcompress_fxt1.o \
+ $(MESABUILDDIR)profiled/texcompress_s3tc.o \
+ $(MESABUILDDIR)profiled/texenvprogram.o \
+ $(MESABUILDDIR)profiled/texformat.o \
+ $(MESABUILDDIR)profiled/teximage.o \
+ $(MESABUILDDIR)profiled/texobj.o \
+ $(MESABUILDDIR)profiled/texrender.o \
+ $(MESABUILDDIR)profiled/texstate.o \
+ $(MESABUILDDIR)profiled/texstore.o \
+ $(MESABUILDDIR)profiled/varray.o \
+ $(MESABUILDDIR)profiled/vtxfmt.o
diff --git a/nx-X11/programs/Xserver/GL/mesa/math/Imakefile b/nx-X11/programs/Xserver/GL/mesa/math/Imakefile
new file mode 100644
index 000000000..6af3a0a0c
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/math/Imakefile
@@ -0,0 +1,35 @@
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaMathBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_MATH_SRCS)
+ OBJS = $(MESA_MATH_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/math \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/math/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/math/Imakefile.inc
new file mode 100644
index 000000000..bc9a1f326
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/math/Imakefile.inc
@@ -0,0 +1,76 @@
+MESAMATHBUILDDIR = MesaMathBuildDir
+
+ MESA_MATH_SRCS = $(MESAMATHBUILDDIR)m_debug_clip.c \
+ $(MESAMATHBUILDDIR)m_debug_norm.c \
+ $(MESAMATHBUILDDIR)m_debug_xform.c \
+ $(MESAMATHBUILDDIR)m_eval.c \
+ $(MESAMATHBUILDDIR)m_matrix.c \
+ $(MESAMATHBUILDDIR)m_translate.c \
+ $(MESAMATHBUILDDIR)m_vector.c \
+ $(MESAMATHBUILDDIR)m_xform.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(mathmod.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_clip_tmp.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_copy_tmp.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_debug_clip.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_debug.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_debug_util.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_debug_norm.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_debug_xform.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_dotprod_tmp.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_eval.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_eval.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_matrix.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_matrix.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_norm_tmp.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_translate.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_translate.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_trans_tmp.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_vector.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_vector.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_xform.c, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_xform.h, $(MESASRCDIR)/src/mesa/math)
+LinkSourceFile(m_xform_tmp.h, $(MESASRCDIR)/src/mesa/math)
+#endif
+
+ MESA_MATH_OBJS = $(MESAMATHBUILDDIR)m_debug_clip.o \
+ $(MESAMATHBUILDDIR)m_debug_norm.o \
+ $(MESAMATHBUILDDIR)m_debug_xform.o \
+ $(MESAMATHBUILDDIR)m_eval.o \
+ $(MESAMATHBUILDDIR)m_matrix.o \
+ $(MESAMATHBUILDDIR)m_translate.o \
+ $(MESAMATHBUILDDIR)m_vector.o \
+ $(MESAMATHBUILDDIR)m_xform.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_MATH_UOBJS = $(MESAMATHBUILDDIR)unshared/m_debug_clip.o \
+ $(MESAMATHBUILDDIR)unshared/m_debug_norm.o \
+ $(MESAMATHBUILDDIR)unshared/m_debug_xform.o \
+ $(MESAMATHBUILDDIR)unshared/m_eval.o \
+ $(MESAMATHBUILDDIR)unshared/m_matrix.o \
+ $(MESAMATHBUILDDIR)unshared/m_translate.o \
+ $(MESAMATHBUILDDIR)unshared/m_vector.o \
+ $(MESAMATHBUILDDIR)unshared/m_xform.o
+#else
+ MATH_MESA_UOBJS = $(MESA_MATH_OBJS)
+#endif
+
+ MESA_MATH_DOBJS = $(MESAMATHBUILDDIR)debugger/m_debug_clip.o \
+ $(MESAMATHBUILDDIR)debugger/m_debug_norm.o \
+ $(MESAMATHBUILDDIR)debugger/m_debug_xform.o \
+ $(MESAMATHBUILDDIR)debugger/m_eval.o \
+ $(MESAMATHBUILDDIR)debugger/m_matrix.o \
+ $(MESAMATHBUILDDIR)debugger/m_translate.o \
+ $(MESAMATHBUILDDIR)debugger/m_vector.o \
+ $(MESAMATHBUILDDIR)debugger/m_xform.o
+
+ MESA_MATH_POBJS = $(MESAMATHBUILDDIR)profiled/m_debug_clip.o \
+ $(MESAMATHBUILDDIR)profiled/m_debug_norm.o \
+ $(MESAMATHBUILDDIR)profiled/m_debug_xform.o \
+ $(MESAMATHBUILDDIR)profiled/m_eval.o \
+ $(MESAMATHBUILDDIR)profiled/m_matrix.o \
+ $(MESAMATHBUILDDIR)profiled/m_translate.o \
+ $(MESAMATHBUILDDIR)profiled/m_vector.o \
+ $(MESAMATHBUILDDIR)profiled/m_xform.o
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile b/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile
new file mode 100644
index 000000000..bf3acd4f6
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile
@@ -0,0 +1,40 @@
+
+#define IHaveSubdirs
+ SUBDIRS = grammar slang
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaShaderBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_SHADER_SRCS)
+ OBJS = $(MESA_SHADER_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/shader/grammar \
+ -I$(MESASRCDIR)/src/mesa/shader/slang \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile.inc
new file mode 100644
index 000000000..185103996
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/Imakefile.inc
@@ -0,0 +1,100 @@
+MESASHADERBUILDDIR = MesaShaderBuildDir
+
+ MESA_SHADER_SRCS = $(MESASHADERBUILDDIR)arbprogparse.c \
+ $(MESASHADERBUILDDIR)arbprogram.c \
+ $(MESASHADERBUILDDIR)arbfragparse.c \
+ $(MESASHADERBUILDDIR)arbvertparse.c \
+ $(MESASHADERBUILDDIR)atifragshader.c \
+ $(MESASHADERBUILDDIR)nvprogram.c \
+ $(MESASHADERBUILDDIR)nvfragparse.c \
+ $(MESASHADERBUILDDIR)nvvertexec.c \
+ $(MESASHADERBUILDDIR)nvvertparse.c \
+ $(MESASHADERBUILDDIR)program.c \
+ $(MESASHADERBUILDDIR)shaderobjects.c \
+ $(MESASHADERBUILDDIR)shaderobjects_3dlabs.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(arbprogparse.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbprogram.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbfragparse.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbvertparse.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbfragparse.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbprogparse.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbprogram.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbprogram_syn.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(arbvertparse.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(atifragshader.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(atifragshader.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvfragparse.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvfragprog.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvprogram.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvprogram.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvfragparse.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvvertexec.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvvertexec.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvvertparse.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvvertparse.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(nvvertprog.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(program.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(program.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(shaderobjects.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(shaderobjects.h, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(shaderobjects_3dlabs.c, $(MESASRCDIR)/src/mesa/shader)
+LinkSourceFile(shaderobjects_3dlabs.h, $(MESASRCDIR)/src/mesa/shader)
+#endif
+
+ MESA_SHADER_OBJS = $(MESASHADERBUILDDIR)arbprogparse.o \
+ $(MESASHADERBUILDDIR)arbprogram.o \
+ $(MESASHADERBUILDDIR)arbfragparse.o \
+ $(MESASHADERBUILDDIR)arbvertparse.o \
+ $(MESASHADERBUILDDIR)atifragshader.o \
+ $(MESASHADERBUILDDIR)nvprogram.o \
+ $(MESASHADERBUILDDIR)nvfragparse.o \
+ $(MESASHADERBUILDDIR)nvvertexec.o \
+ $(MESASHADERBUILDDIR)nvvertparse.o \
+ $(MESASHADERBUILDDIR)program.o \
+ $(MESASHADERBUILDDIR)shaderobjects.o \
+ $(MESASHADERBUILDDIR)shaderobjects_3dlabs.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_SHADER_UOBJS = $(MESASHADERBUILDDIR)unshared/arbprogparse.o \
+ $(MESASHADERBUILDDIR)unshared/arbprogram.o \
+ $(MESASHADERBUILDDIR)unshared/arbfragparse.o \
+ $(MESASHADERBUILDDIR)unshared/arbvertparse.o \
+ $(MESASHADERBUILDDIR)unshared/atifragshader.o \
+ $(MESASHADERBUILDDIR)unshared/nvprogram.o \
+ $(MESASHADERBUILDDIR)unshared/nvfragparse.o \
+ $(MESASHADERBUILDDIR)unshared/nvvertexec.o \
+ $(MESASHADERBUILDDIR)unshared/nvvertparse.o \
+ $(MESASHADERBUILDDIR)unshared/program.o \
+ $(MESASHADERBUILDDIR)unshared/shaderobjects.o \
+ $(MESASHADERBUILDDIR)unshared/shaderobjects_3dlabs.o
+#else
+ MESA_SHADER_UOBJS = $(MESA_SHADER_OBJS)
+#endif
+
+ MESA_SHADER_DOBJS = $(MESASHADERBUILDDIR)debugger/arbprogparse.o \
+ $(MESASHADERBUILDDIR)debugger/arbprogram.o \
+ $(MESASHADERBUILDDIR)debugger/arbfragparse.o \
+ $(MESASHADERBUILDDIR)debugger/arbvertparse.o \
+ $(MESASHADERBUILDDIR)debugger/atifragshader.o \
+ $(MESASHADERBUILDDIR)debugger/nvprogram.o \
+ $(MESASHADERBUILDDIR)debugger/nvfragparse.o \
+ $(MESASHADERBUILDDIR)debugger/nvvertexec.o \
+ $(MESASHADERBUILDDIR)debugger/nvvertparse.o \
+ $(MESASHADERBUILDDIR)debugger/program.o \
+ $(MESASHADERBUILDDIR)debugger/shaderobjects.o \
+ $(MESASHADERBUILDDIR)debugger/shaderobjects_3dlabs.o
+
+ MESA_SHADER_POBJS = $(MESASHADERBUILDDIR)profiled/arbprogparse.o \
+ $(MESASHADERBUILDDIR)profiled/arbprogram.o \
+ $(MESASHADERBUILDDIR)profiled/arbfragparse.o \
+ $(MESASHADERBUILDDIR)profiled/arbvertparse.o \
+ $(MESASHADERBUILDDIR)profiled/atifragshader.o \
+ $(MESASHADERBUILDDIR)profiled/nvprogram.o \
+ $(MESASHADERBUILDDIR)profiled/nvfragparse.o \
+ $(MESASHADERBUILDDIR)profiled/nvvertexec.o \
+ $(MESASHADERBUILDDIR)profiled/nvvertparse.o \
+ $(MESASHADERBUILDDIR)profiled/program.o \
+ $(MESASHADERBUILDDIR)profiled/shaderobjects.o \
+ $(MESASHADERBUILDDIR)profiled/shaderobjects_3dlabs.o
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile b/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile
new file mode 100644
index 000000000..3fe604f2e
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile
@@ -0,0 +1,37 @@
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaGrammarBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_GRAMMAR_SRCS)
+ OBJS = $(MESA_GRAMMAR_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/shader/grammar \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile.inc
new file mode 100644
index 000000000..4f91af9c1
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/grammar/Imakefile.inc
@@ -0,0 +1,23 @@
+MESAGRAMMARBUILDDIR=MesaGrammarBuildDir
+
+ MESA_GRAMMAR_SRCS = $(MESAGRAMMARBUILDDIR)grammar_mesa.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(grammar.c, $(MESASRCDIR)/src/mesa/shader/grammar)
+LinkSourceFile(grammar.h, $(MESASRCDIR)/src/mesa/shader/grammar)
+LinkSourceFile(grammar_syn.h, $(MESASRCDIR)/src/mesa/shader/grammar)
+LinkSourceFile(grammar_mesa.c, $(MESASRCDIR)/src/mesa/shader/grammar)
+LinkSourceFile(grammar_mesa.h, $(MESASRCDIR)/src/mesa/shader/grammar)
+#endif
+
+ MESA_GRAMMAR_OBJS = $(MESAGRAMMARBUILDDIR)grammar_mesa.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_GRAMMAR_UOBJS = $(MESAGRAMMARBUILDDIR)unshared/grammar_mesa.o
+#else
+ MESA_GRAMMAR_UOBJS = $(MESA_GRAMMAR_OBJS)
+#endif
+
+ MESA_GRAMMAR_DOBJS = $(MESAGRAMMARBUILDDIR)debugger/grammar_mesa.o
+
+ MESA_GRAMMAR_POBJS = $(MESAGRAMMARBUILDDIR)profiled/grammar_mesa.o
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile b/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile
new file mode 100644
index 000000000..d5ec4d6cf
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile
@@ -0,0 +1,40 @@
+
+#define IHaveSubdirs
+ SUBDIRS = library
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaSlangBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_SLANG_SRCS)
+ OBJS = $(MESA_SLANG_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/shader/grammar \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile.inc
new file mode 100644
index 000000000..4ffa7805f
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/slang/Imakefile.inc
@@ -0,0 +1,84 @@
+MESASLANGBUILDDIR=MesaSlangBuildDir
+
+ MESA_SLANG_SRCS = $(MESASLANGBUILDDIR)slang_assemble_assignment.c \
+ $(MESASLANGBUILDDIR)slang_assemble.c \
+ $(MESASLANGBUILDDIR)slang_assemble_conditional.c \
+ $(MESASLANGBUILDDIR)slang_assemble_constructor.c \
+ $(MESASLANGBUILDDIR)slang_assemble_typeinfo.c \
+ $(MESASLANGBUILDDIR)slang_compile.c \
+ $(MESASLANGBUILDDIR)slang_execute.c \
+ $(MESASLANGBUILDDIR)slang_preprocess.c \
+ $(MESASLANGBUILDDIR)slang_storage.c \
+ $(MESASLANGBUILDDIR)slang_utility.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(slang_assemble_assignment.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_assignment.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_conditional.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_conditional.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_constructor.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_constructor.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_typeinfo.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_assemble_typeinfo.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_compile.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_compile.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_execute.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_execute.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_preprocess.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_preprocess.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_storage.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_storage.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_utility.c, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(slang_utility.h, $(MESASRCDIR)/src/mesa/shader/slang)
+LinkSourceFile(traverse_wrap.h, $(MESASRCDIR)/src/mesa/shader/slang)
+#endif
+
+ MESA_SLANG_OBJS = $(MESASLANGBUILDDIR)slang_assemble_assignment.o \
+ $(MESASLANGBUILDDIR)slang_assemble.o \
+ $(MESASLANGBUILDDIR)slang_assemble_conditional.o \
+ $(MESASLANGBUILDDIR)slang_assemble_constructor.o \
+ $(MESASLANGBUILDDIR)slang_assemble_typeinfo.o \
+ $(MESASLANGBUILDDIR)slang_compile.o \
+ $(MESASLANGBUILDDIR)slang_execute.o \
+ $(MESASLANGBUILDDIR)slang_preprocess.o \
+ $(MESASLANGBUILDDIR)slang_storage.o \
+ $(MESASLANGBUILDDIR)slang_utility.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_SLANG_UOBJS = $(MESASLANGBUILDDIR)unshared/slang_assemble_assignment.o \
+ $(MESASLANGBUILDDIR)unshared/slang_assemble.o \
+ $(MESASLANGBUILDDIR)unshared/slang_assemble_conditional.o \
+ $(MESASLANGBUILDDIR)unshared/slang_assemble_constructor.o \
+ $(MESASLANGBUILDDIR)unshared/slang_assemble_typeinfo.o \
+ $(MESASLANGBUILDDIR)unshared/slang_compile.o \
+ $(MESASLANGBUILDDIR)unshared/slang_execute.o \
+ $(MESASLANGBUILDDIR)unshared/slang_preprocess.o \
+ $(MESASLANGBUILDDIR)unshared/slang_storage.o \
+ $(MESASLANGBUILDDIR)unshared/slang_utility.o
+#else
+ MESA_SLANG_UOBJS = $(MESA_SLANG_OBJS)
+#endif
+
+ MESA_SLANG_DOBJS = $(MESASLANGBUILDDIR)debuggerslang_assemble_assignment.o \
+ $(MESASLANGBUILDDIR)debuggerslang_assemble.o \
+ $(MESASLANGBUILDDIR)debuggerslang_assemble_conditional.o \
+ $(MESASLANGBUILDDIR)debuggerslang_assemble_constructor.o \
+ $(MESASLANGBUILDDIR)debuggerslang_assemble_typeinfo.o \
+ $(MESASLANGBUILDDIR)debuggerslang_compile.o \
+ $(MESASLANGBUILDDIR)debuggerslang_execute.o \
+ $(MESASLANGBUILDDIR)debuggerslang_preprocess.o \
+ $(MESASLANGBUILDDIR)debuggerslang_storage.o \
+ $(MESASLANGBUILDDIR)debuggerslang_utility.o
+
+ MESA_SLANG_POBJS = $(MESASLANGBUILDDIR)profiled/slang_assemble_assignment.o \
+ $(MESASLANGBUILDDIR)profiled/slang_assemble.o \
+ $(MESASLANGBUILDDIR)profiled/slang_assemble_conditional.o \
+ $(MESASLANGBUILDDIR)profiled/slang_assemble_constructor.o \
+ $(MESASLANGBUILDDIR)profiled/slang_assemble_typeinfo.o \
+ $(MESASLANGBUILDDIR)profiled/slang_compile.o \
+ $(MESASLANGBUILDDIR)profiled/slang_execute.o \
+ $(MESASLANGBUILDDIR)profiled/slang_preprocess.o \
+ $(MESASLANGBUILDDIR)profiled/slang_storage.o \
+ $(MESASLANGBUILDDIR)profiled/slang_utility.o
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile b/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile
new file mode 100644
index 000000000..8c216804d
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile
@@ -0,0 +1,30 @@
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaLibraryBuildDir /**/
+#include "Imakefile.inc"
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/shader/grammar \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile.inc
new file mode 100644
index 000000000..06b530063
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/shader/slang/library/Imakefile.inc
@@ -0,0 +1,12 @@
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(slang_common_builtin_gc_bin.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_common_builtin_gc.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_core_gc_bin.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_core_gc.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_fragment_builtin_gc_bin.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_fragment_builtin_gc.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_shader_syn.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_version_syn.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_vertex_builtin_gc_bin.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+LinkSourceFile(slang_vertex_builtin_gc.h, $(MESASRCDIR)/src/mesa/shader/slang/library)
+#endif
diff --git a/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile b/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile
new file mode 100644
index 000000000..df47a1caa
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile
@@ -0,0 +1,42 @@
+/* Large PIC tables needed for Solaris/SPARC builds */
+#if defined(SunArchitecture) && defined(SparcArchitecture) && defined(LargePositionIndependentCFlags)
+ PICFLAGS = LargePositionIndependentCFlags
+#endif
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaSwrastBuildDir /**/
+#include "Imakefile.inc"
+
+
+ SRCS = $(MESA_SWRAST_SRCS)
+ OBJS = $(MESA_SWRAST_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/src/mesa/swrast \
+ -I$(MESASRCDIR)/src/mesa/swrast_setup \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
diff --git a/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile.inc
new file mode 100644
index 000000000..f573098c1
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/swrast/Imakefile.inc
@@ -0,0 +1,212 @@
+MESASWRASTBUILDDIR = MesaSwrastBuildDir
+
+ MESA_SWRAST_SRCS = $(MESASWRASTBUILDDIR)s_aaline.c \
+ $(MESASWRASTBUILDDIR)s_aatriangle.c \
+ $(MESASWRASTBUILDDIR)s_accum.c \
+ $(MESASWRASTBUILDDIR)s_alpha.c \
+ $(MESASWRASTBUILDDIR)s_atifragshader.c \
+ $(MESASWRASTBUILDDIR)s_bitmap.c \
+ $(MESASWRASTBUILDDIR)s_blend.c \
+ $(MESASWRASTBUILDDIR)s_buffers.c \
+ $(MESASWRASTBUILDDIR)s_context.c \
+ $(MESASWRASTBUILDDIR)s_copypix.c \
+ $(MESASWRASTBUILDDIR)s_depth.c \
+ $(MESASWRASTBUILDDIR)s_drawpix.c \
+ $(MESASWRASTBUILDDIR)s_feedback.c \
+ $(MESASWRASTBUILDDIR)s_fog.c \
+ $(MESASWRASTBUILDDIR)s_imaging.c \
+ $(MESASWRASTBUILDDIR)s_lines.c \
+ $(MESASWRASTBUILDDIR)s_logic.c \
+ $(MESASWRASTBUILDDIR)s_masking.c \
+ $(MESASWRASTBUILDDIR)s_nvfragprog.c \
+ $(MESASWRASTBUILDDIR)s_pixeltex.c \
+ $(MESASWRASTBUILDDIR)s_points.c \
+ $(MESASWRASTBUILDDIR)s_readpix.c \
+ $(MESASWRASTBUILDDIR)s_span.c \
+ $(MESASWRASTBUILDDIR)s_stencil.c \
+ $(MESASWRASTBUILDDIR)s_texstore.c \
+ $(MESASWRASTBUILDDIR)s_texture.c \
+ $(MESASWRASTBUILDDIR)s_triangle.c \
+ $(MESASWRASTBUILDDIR)s_zoom.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(s_aaline.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_aaline.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_aalinetemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_aatriangle.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_aatriangle.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_aatritemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_accum.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_accum.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_alpha.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_alpha.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_atifragshader.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_atifragshader.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_bitmap.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_blend.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_blend.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_buffers.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_context.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_context.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_copypix.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_depth.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_depth.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_drawpix.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_drawpix.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_feedback.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_feedback.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_fog.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_fog.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_imaging.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_lines.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_lines.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_linetemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_logic.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_logic.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_masking.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_masking.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_nvfragprog.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_nvfragprog.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_pixeltex.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_pixeltex.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_points.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_points.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_pointtemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_readpix.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_span.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_span.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_spantemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_stencil.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_stencil.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_texstore.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_texture.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_texture.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_triangle.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_triangle.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_trispan.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_tritemp.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_zoom.c, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(s_zoom.h, $(MESASRCDIR)/src/mesa/swrast)
+LinkSourceFile(swrast.h, $(MESASRCDIR)/src/mesa/swrast)
+#endif
+
+ MESA_SWRAST_OBJS = $(MESASWRASTBUILDDIR)s_aaline.o \
+ $(MESASWRASTBUILDDIR)s_aatriangle.o \
+ $(MESASWRASTBUILDDIR)s_accum.o \
+ $(MESASWRASTBUILDDIR)s_alpha.o \
+ $(MESASWRASTBUILDDIR)s_atifragshader.o \
+ $(MESASWRASTBUILDDIR)s_bitmap.o \
+ $(MESASWRASTBUILDDIR)s_blend.o \
+ $(MESASWRASTBUILDDIR)s_buffers.o \
+ $(MESASWRASTBUILDDIR)s_context.o \
+ $(MESASWRASTBUILDDIR)s_copypix.o \
+ $(MESASWRASTBUILDDIR)s_depth.o \
+ $(MESASWRASTBUILDDIR)s_drawpix.o \
+ $(MESASWRASTBUILDDIR)s_feedback.o \
+ $(MESASWRASTBUILDDIR)s_fog.o \
+ $(MESASWRASTBUILDDIR)s_imaging.o \
+ $(MESASWRASTBUILDDIR)s_lines.o \
+ $(MESASWRASTBUILDDIR)s_logic.o \
+ $(MESASWRASTBUILDDIR)s_masking.o \
+ $(MESASWRASTBUILDDIR)s_nvfragprog.o \
+ $(MESASWRASTBUILDDIR)s_pixeltex.o \
+ $(MESASWRASTBUILDDIR)s_points.o \
+ $(MESASWRASTBUILDDIR)s_readpix.o \
+ $(MESASWRASTBUILDDIR)s_span.o \
+ $(MESASWRASTBUILDDIR)s_stencil.o \
+ $(MESASWRASTBUILDDIR)s_texstore.o \
+ $(MESASWRASTBUILDDIR)s_texture.o \
+ $(MESASWRASTBUILDDIR)s_triangle.o \
+ $(MESASWRASTBUILDDIR)s_zoom.o
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_SWRAST_UOBJS = $(MESASWRASTBUILDDIR)unshared/s_aaline.o \
+ $(MESASWRASTBUILDDIR)unshared/s_aatriangle.o \
+ $(MESASWRASTBUILDDIR)unshared/s_accum.o \
+ $(MESASWRASTBUILDDIR)unshared/s_alpha.o \
+ $(MESASWRASTBUILDDIR)unshared/s_atifragshader.o \
+ $(MESASWRASTBUILDDIR)unshared/s_bitmap.o \
+ $(MESASWRASTBUILDDIR)unshared/s_blend.o \
+ $(MESASWRASTBUILDDIR)unshared/s_buffers.o \
+ $(MESASWRASTBUILDDIR)unshared/s_context.o \
+ $(MESASWRASTBUILDDIR)unshared/s_copypix.o \
+ $(MESASWRASTBUILDDIR)unshared/s_depth.o \
+ $(MESASWRASTBUILDDIR)unshared/s_drawpix.o \
+ $(MESASWRASTBUILDDIR)unshared/s_feedback.o \
+ $(MESASWRASTBUILDDIR)unshared/s_fog.o \
+ $(MESASWRASTBUILDDIR)unshared/s_imaging.o \
+ $(MESASWRASTBUILDDIR)unshared/s_lines.o \
+ $(MESASWRASTBUILDDIR)unshared/s_logic.o \
+ $(MESASWRASTBUILDDIR)unshared/s_masking.o \
+ $(MESASWRASTBUILDDIR)unshared/s_nvfragprog.o \
+ $(MESASWRASTBUILDDIR)unshared/s_pixeltex.o \
+ $(MESASWRASTBUILDDIR)unshared/s_points.o \
+ $(MESASWRASTBUILDDIR)unshared/s_readpix.o \
+ $(MESASWRASTBUILDDIR)unshared/s_span.o \
+ $(MESASWRASTBUILDDIR)unshared/s_stencil.o \
+ $(MESASWRASTBUILDDIR)unshared/s_texstore.o \
+ $(MESASWRASTBUILDDIR)unshared/s_texture.o \
+ $(MESASWRASTBUILDDIR)unshared/s_triangle.o \
+ $(MESASWRASTBUILDDIR)unshared/s_zoom.o
+#else
+ MESA_SWRAST_UOBJS = $(MESA_SWRAST_OBJS)
+#endif
+
+ MESA_SWRAST_DOBJS = $(MESASWRASTBUILDDIR)debugger/s_aaline.o \
+ $(MESASWRASTBUILDDIR)debugger/s_aatriangle.o \
+ $(MESASWRASTBUILDDIR)debugger/s_accum.o \
+ $(MESASWRASTBUILDDIR)debugger/s_alpha.o \
+ $(MESASWRASTBUILDDIR)debugger/s_atifragshader.o \
+ $(MESASWRASTBUILDDIR)debugger/s_bitmap.o \
+ $(MESASWRASTBUILDDIR)debugger/s_blend.o \
+ $(MESASWRASTBUILDDIR)debugger/s_buffers.o \
+ $(MESASWRASTBUILDDIR)debugger/s_context.o \
+ $(MESASWRASTBUILDDIR)debugger/s_copypix.o \
+ $(MESASWRASTBUILDDIR)debugger/s_depth.o \
+ $(MESASWRASTBUILDDIR)debugger/s_drawpix.o \
+ $(MESASWRASTBUILDDIR)debugger/s_feedback.o \
+ $(MESASWRASTBUILDDIR)debugger/s_fog.o \
+ $(MESASWRASTBUILDDIR)debugger/s_imaging.o \
+ $(MESASWRASTBUILDDIR)debugger/s_lines.o \
+ $(MESASWRASTBUILDDIR)debugger/s_logic.o \
+ $(MESASWRASTBUILDDIR)debugger/s_masking.o \
+ $(MESASWRASTBUILDDIR)debugger/s_nvfragprog.o \
+ $(MESASWRASTBUILDDIR)debugger/s_pixeltex.o \
+ $(MESASWRASTBUILDDIR)debugger/s_points.o \
+ $(MESASWRASTBUILDDIR)debugger/s_readpix.o \
+ $(MESASWRASTBUILDDIR)debugger/s_span.o \
+ $(MESASWRASTBUILDDIR)debugger/s_stencil.o \
+ $(MESASWRASTBUILDDIR)debugger/s_texstore.o \
+ $(MESASWRASTBUILDDIR)debugger/s_texture.o \
+ $(MESASWRASTBUILDDIR)debugger/s_triangle.o \
+ $(MESASWRASTBUILDDIR)debugger/s_zoom.o
+
+ MESA_SWRAST_POBJS = $(MESASWRASTBUILDDIR)profiled/s_aaline.o \
+ $(MESASWRASTBUILDDIR)profiled/s_aatriangle.o \
+ $(MESASWRASTBUILDDIR)profiled/s_accum.o \
+ $(MESASWRASTBUILDDIR)profiled/s_alpha.o \
+ $(MESASWRASTBUILDDIR)profiled/s_atifragshader.o \
+ $(MESASWRASTBUILDDIR)profiled/s_bitmap.o \
+ $(MESASWRASTBUILDDIR)profiled/s_blend.o \
+ $(MESASWRASTBUILDDIR)profiled/s_buffers.o \
+ $(MESASWRASTBUILDDIR)profiled/s_context.o \
+ $(MESASWRASTBUILDDIR)profiled/s_copypix.o \
+ $(MESASWRASTBUILDDIR)profiled/s_depth.o \
+ $(MESASWRASTBUILDDIR)profiled/s_drawpix.o \
+ $(MESASWRASTBUILDDIR)profiled/s_feedback.o \
+ $(MESASWRASTBUILDDIR)profiled/s_fog.o \
+ $(MESASWRASTBUILDDIR)profiled/s_imaging.o \
+ $(MESASWRASTBUILDDIR)profiled/s_lines.o \
+ $(MESASWRASTBUILDDIR)profiled/s_logic.o \
+ $(MESASWRASTBUILDDIR)profiled/s_masking.o \
+ $(MESASWRASTBUILDDIR)profiled/s_nvfragprog.o \
+ $(MESASWRASTBUILDDIR)profiled/s_pixeltex.o \
+ $(MESASWRASTBUILDDIR)profiled/s_points.o \
+ $(MESASWRASTBUILDDIR)profiled/s_readpix.o \
+ $(MESASWRASTBUILDDIR)profiled/s_span.o \
+ $(MESASWRASTBUILDDIR)profiled/s_stencil.o \
+ $(MESASWRASTBUILDDIR)profiled/s_texstore.o \
+ $(MESASWRASTBUILDDIR)profiled/s_texture.o \
+ $(MESASWRASTBUILDDIR)profiled/s_triangle.o \
+ $(MESASWRASTBUILDDIR)profiled/s_zoom.o
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile b/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile
new file mode 100644
index 000000000..be2ce62a4
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile
@@ -0,0 +1,34 @@
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaSwrastSetupBuildDir /**/
+#include "Imakefile.inc"
+
+ SRCS = $(MESA_SWR_SETUP_SRCS)
+ OBJS = $(MESA_SWR_SETUP_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/src/mesa/swrast_setup \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
diff --git a/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile.inc
new file mode 100644
index 000000000..567ad65b8
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/swrast_setup/Imakefile.inc
@@ -0,0 +1,30 @@
+MESASWRSETUPDIR = MesaSwrastSetupBuildDir
+
+ MESA_SWR_SETUP_SRCS = $(MESASWRSETUPDIR)ss_context.c \
+ $(MESASWRSETUPDIR)ss_triangle.c
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(ss_context.c, $(MESASRCDIR)/src/mesa/swrast_setup)
+LinkSourceFile(ss_context.h, $(MESASRCDIR)/src/mesa/swrast_setup)
+LinkSourceFile(ss_triangle.c, $(MESASRCDIR)/src/mesa/swrast_setup)
+LinkSourceFile(ss_triangle.h, $(MESASRCDIR)/src/mesa/swrast_setup)
+LinkSourceFile(ss_tritmp.h, $(MESASRCDIR)/src/mesa/swrast_setup)
+LinkSourceFile(swrast_setup.h, $(MESASRCDIR)/src/mesa/swrast_setup)
+#endif
+
+ MESA_SWR_SETUP_OBJS = $(MESASWRSETUPDIR)ss_context.o \
+ $(MESASWRSETUPDIR)ss_triangle.o
+
+#if defined(DoSharedLib) && DoSharedLib
+MESA_SWR_SETUP_UOBJS = $(MESASWRSETUPDIR)unshared/ss_context.o \
+ $(MESASWRSETUPDIR)unshared/ss_triangle.o
+#else
+MESA_SWR_SETUP_UOBJS = $(MESA_SWR_SETUP_OBJS)
+#endif
+
+MESA_SWR_SETUP_DOBJS = $(MESASWRSETUPDIR)debugger/ss_context.o \
+ $(MESASWRSETUPDIR)debugger/ss_triangle.o
+
+MESA_SWR_SETUP_POBJS = $(MESASWRSETUPDIR)profiled/ss_context.o \
+ $(MESASWRSETUPDIR)profiled/ss_triangle.o
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile b/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile
new file mode 100644
index 000000000..b36454259
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile
@@ -0,0 +1,45 @@
+/* Large PIC tables needed for Solaris/SPARC builds */
+#if defined(SunArchitecture) && defined(SparcArchitecture) && defined(LargePositionIndependentCFlags)
+ PICFLAGS = LargePositionIndependentCFlags
+#endif
+
+
+#include <Server.tmpl>
+
+#define NeedAllMesaSrc
+#define NeedToLinkMesaSrc
+#define MesaTnlBuildDir /**/
+#include "Imakefile.inc"
+
+
+ SRCS = $(MESA_TNL_SRCS)
+ OBJS = $(MESA_TNL_OBJS)
+
+ INCLUDES = -I$(MESASRCDIR)/src/mesa \
+ -I$(MESASRCDIR)/src/mesa/array_cache \
+ -I$(MESASRCDIR)/src/mesa/math \
+ -I$(MESASRCDIR)/src/mesa/main \
+ -I$(MESASRCDIR)/src/mesa/glapi \
+ -I$(MESASRCDIR)/src/mesa/shader \
+ -I$(MESASRCDIR)/src/mesa/tnl \
+ -I$(MESASRCDIR)/include \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/GL/glx \
+ -I$(LIBSRC)/GL/include \
+ -I$(XF86SRC) -I$(INCLUDESRC)
+
+ DEFINES = $(GLX_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+
+NormalLibraryObjectRule()
+
+SubdirLibraryRule($(OBJS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
diff --git a/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile.inc b/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile.inc
new file mode 100644
index 000000000..a6c8f923e
--- /dev/null
+++ b/nx-X11/programs/Xserver/GL/mesa/tnl/Imakefile.inc
@@ -0,0 +1,219 @@
+MESATNLBUILDDIR = MesaTnlBuildDir
+
+ MESA_TNL_SRCS = $(MESATNLBUILDDIR)t_array_api.c \
+ $(MESATNLBUILDDIR)t_array_import.c \
+ $(MESATNLBUILDDIR)t_context.c \
+ $(MESATNLBUILDDIR)t_pipeline.c \
+ $(MESATNLBUILDDIR)t_save_api.c \
+ $(MESATNLBUILDDIR)t_save_loopback.c \
+ $(MESATNLBUILDDIR)t_save_playback.c \
+ $(MESATNLBUILDDIR)t_vb_arbprogram.c \
+ $(MESATNLBUILDDIR)t_vb_arbprogram_sse.c \
+ $(MESATNLBUILDDIR)t_vb_fog.c \
+ $(MESATNLBUILDDIR)t_vb_cull.c \
+ $(MESATNLBUILDDIR)t_vb_light.c \
+ $(MESATNLBUILDDIR)t_vb_normals.c \
+ $(MESATNLBUILDDIR)t_vb_points.c \
+ $(MESATNLBUILDDIR)t_vb_program.c \
+ $(MESATNLBUILDDIR)t_vb_render.c \
+ $(MESATNLBUILDDIR)t_vb_texgen.c \
+ $(MESATNLBUILDDIR)t_vb_texmat.c \
+ $(MESATNLBUILDDIR)t_vb_vertex.c \
+ $(MESATNLBUILDDIR)t_vertex.c \
+ $(MESATNLBUILDDIR)t_vertex_generic.c \
+ $(MESATNLBUILDDIR)t_vertex_sse.c \
+ $(MESATNLBUILDDIR)t_vp_build.c \
+ $(MESATNLBUILDDIR)t_vtx_api.c \
+ $(MESATNLBUILDDIR)t_vtx_eval.c \
+ $(MESATNLBUILDDIR)t_vtx_exec.c \
+ $(MESATNLBUILDDIR)t_vtx_generic.c
+
+#if defined(i386Architecture) && MesaUseX86Asm
+ MESA_TNL_SRCS += MesaTnlAsmSrcs $(MESATNLBUILDDIR)t_vtx_x86.c \
+ $(MESATNLBUILDDIR)t_vtx_x86_gcc.S
+#endif
+
+#ifdef NeedToLinkMesaSrc
+LinkSourceFile(t_array_api.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_array_api.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_array_import.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_array_import.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_context.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_context.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(tnl.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_pipeline.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_pipeline.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_save_api.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_save_api.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_save_loopback.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_save_playback.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_arbprogram.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_arbprogram.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_arbprogram_sse.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_cliptmp.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_fog.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_cull.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_light.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_lighttmp.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_normals.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_points.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_program.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_render.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_rendertmp.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_texgen.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_texmat.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vb_vertex.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vertex.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vertex.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vertex_generic.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vertex_sse.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vp_build.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vp_build.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_api.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_api.h, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_eval.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_exec.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_generic.c, $(MESASRCDIR)/src/mesa/tnl)
+#if defined(i386Architecture) && MesaUseX86Asm
+LinkSourceFile(t_vtx_x86.c, $(MESASRCDIR)/src/mesa/tnl)
+LinkSourceFile(t_vtx_x86_gcc.S, $(MESASRCDIR)/src/mesa/tnl)
+#endif
+#endif
+
+ MESA_TNL_OBJS = $(MESATNLBUILDDIR)t_array_api.o \
+ $(MESATNLBUILDDIR)t_array_import.o \
+ $(MESATNLBUILDDIR)t_context.o \
+ $(MESATNLBUILDDIR)t_pipeline.o \
+ $(MESATNLBUILDDIR)t_save_api.o \
+ $(MESATNLBUILDDIR)t_save_loopback.o \
+ $(MESATNLBUILDDIR)t_save_playback.o \
+ $(MESATNLBUILDDIR)t_vb_arbprogram.o \
+ $(MESATNLBUILDDIR)t_vb_arbprogram_sse.o \
+ $(MESATNLBUILDDIR)t_vb_fog.o \
+ $(MESATNLBUILDDIR)t_vb_cull.o \
+ $(MESATNLBUILDDIR)t_vb_light.o \
+ $(MESATNLBUILDDIR)t_vb_normals.o \
+ $(MESATNLBUILDDIR)t_vb_points.o \
+ $(MESATNLBUILDDIR)t_vb_program.o \
+ $(MESATNLBUILDDIR)t_vb_render.o \
+ $(MESATNLBUILDDIR)t_vb_texgen.o \
+ $(MESATNLBUILDDIR)t_vb_texmat.o \
+ $(MESATNLBUILDDIR)t_vb_vertex.o \
+ $(MESATNLBUILDDIR)t_vertex.o \
+ $(MESATNLBUILDDIR)t_vertex_generic.o \
+ $(MESATNLBUILDDIR)t_vertex_sse.o \
+ $(MESATNLBUILDDIR)t_vp_build.o \
+ $(MESATNLBUILDDIR)t_vtx_api.o \
+ $(MESATNLBUILDDIR)t_vtx_eval.o \
+ $(MESATNLBUILDDIR)t_vtx_exec.o \
+ $(MESATNLBUILDDIR)t_vtx_generic.o
+
+#if defined(i386Architecture) && MesaUseX86Asm
+ MESA_TNL_OBJS += $(MESATNLBUILDDIR)t_vtx_x86.o \
+ $(MESATNLBUILDDIR)t_vtx_x86_gcc.o
+#endif
+
+#if defined(DoSharedLib) && DoSharedLib
+ MESA_TNL_UOBJS = $(MESATNLBUILDDIR)unshared/t_array_api.o \
+ $(MESATNLBUILDDIR)unshared/t_array_import.o \
+ $(MESATNLBUILDDIR)unshared/t_context.o \
+ $(MESATNLBUILDDIR)unshared/t_pipeline.o \
+ $(MESATNLBUILDDIR)unshared/t_save_api.o \
+ $(MESATNLBUILDDIR)unshared/t_save_loopback.o \
+ $(MESATNLBUILDDIR)unshared/t_save_playback.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_arbprogram.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_arbprogram_sse.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_fog.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_cull.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_light.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_normals.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_points.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_program.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_render.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_texgen.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_texmat.o \
+ $(MESATNLBUILDDIR)unshared/t_vb_vertex.o \
+ $(MESATNLBUILDDIR)unshared/t_vertex.o \
+ $(MESATNLBUILDDIR)unshared/t_vertex_generic.o \
+ $(MESATNLBUILDDIR)unshared/t_vertex_sse.o \
+ $(MESATNLBUILDDIR)unshared/t_vp_build.o \
+ $(MESATNLBUILDDIR)unshared/t_vtx_api.o \
+ $(MESATNLBUILDDIR)unshared/t_vtx_eval.o \
+ $(MESATNLBUILDDIR)unshared/t_vtx_exec.o \
+ $(MESATNLBUILDDIR)unshared/t_vtx_generic.o
+
+#if defined(i386Architecture) && MesaUseX86Asm
+ MESA_TNL_UOBJS += $(MESATNLBUILDDIR)unshared/t_vtx_x86.o \
+ $(MESATNLBUILDDIR)t_vtx_x86_gcc.o
+#endif
+
+#else
+ MESA_TNL_UOBJS = $(MESA_TNL_OBJS)
+#endif
+
+ MESA_TNL_DOBJS = $(MESATNLBUILDDIR)debugger/t_array_api.o \
+ $(MESATNLBUILDDIR)debugger/t_array_import.o \
+ $(MESATNLBUILDDIR)debugger/t_context.o \
+ $(MESATNLBUILDDIR)debugger/t_pipeline.o \
+ $(MESATNLBUILDDIR)debugger/t_save_api.o \
+ $(MESATNLBUILDDIR)debugger/t_save_loopback.o \
+ $(MESATNLBUILDDIR)debugger/t_save_playback.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_arbprogram.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_arbprogram_sse.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_fog.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_cull.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_light.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_normals.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_points.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_program.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_render.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_texgen.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_texmat.o \
+ $(MESATNLBUILDDIR)debugger/t_vb_vertex.o \
+ $(MESATNLBUILDDIR)debugger/t_vertex.o \
+ $(MESATNLBUILDDIR)debugger/t_vertex_generic.o \
+ $(MESATNLBUILDDIR)debugger/t_vertex_sse.o \
+ $(MESATNLBUILDDIR)debugger/t_vp_build.o \
+ $(MESATNLBUILDDIR)debugger/t_vtx_api.o \
+ $(MESATNLBUILDDIR)debugger/t_vtx_eval.o \
+ $(MESATNLBUILDDIR)debugger/t_vtx_exec.o \
+ $(MESATNLBUILDDIR)debugger/t_vtx_generic.o
+
+#if defined(i386Architecture) && MesaUseX86Asm
+ MESA_TNL_DOBJS += $(MESATNLBUILDDIR)debugger/t_vtx_x86.o \
+ $(MESATNLBUILDDIR)debugger/t_vtx_x86_gcc.o
+#endif
+
+ MESA_TNL_POBJS = $(MESATNLBUILDDIR)profiled/t_array_api.o \
+ $(MESATNLBUILDDIR)profiled/t_array_import.o \
+ $(MESATNLBUILDDIR)profiled/t_context.o \
+ $(MESATNLBUILDDIR)profiled/t_pipeline.o \
+ $(MESATNLBUILDDIR)profiled/t_save_api.o \
+ $(MESATNLBUILDDIR)profiled/t_save_loopback.o \
+ $(MESATNLBUILDDIR)profiled/t_save_playback.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_arbprogram.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_arbprogram_sse.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_fog.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_cull.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_light.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_normals.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_points.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_program.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_render.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_texgen.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_texmat.o \
+ $(MESATNLBUILDDIR)profiled/t_vb_vertex.o \
+ $(MESATNLBUILDDIR)profiled/t_vertex.o \
+ $(MESATNLBUILDDIR)profiled/t_vertex_generic.o \
+ $(MESATNLBUILDDIR)profiled/t_vertex_sse.o \
+ $(MESATNLBUILDDIR)profiled/t_vp_build.o \
+ $(MESATNLBUILDDIR)profiled/t_vtx_api.o \
+ $(MESATNLBUILDDIR)profiled/t_vtx_eval.o \
+ $(MESATNLBUILDDIR)profiled/t_vtx_exec.o \
+ $(MESATNLBUILDDIR)profiled/t_vtx_generic.o
+
+#if defined(i386Architecture) && MesaUseX86Asm
+ MESA_TNL_POBJS += $(MESATNLBUILDDIR)profiled/t_vtx_x86.o \
+ $(MESATNLBUILDDIR)profiled/t_vtx_x86_gcc.o
+#endif
+
diff --git a/nx-X11/programs/Xserver/Imakefile b/nx-X11/programs/Xserver/Imakefile
new file mode 100644
index 000000000..c5bbbeb75
--- /dev/null
+++ b/nx-X11/programs/Xserver/Imakefile
@@ -0,0 +1,573 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Server Master Makefile
+ */
+
+NULL =
+
+#include <Server.tmpl>
+
+/* On most systems the linker requires the libraries in dependency order.
+ But we have no real order because there are cycles. We fix this by adding
+ some libraries twice on the commandline. dependLib will add the
+ dependency library to the commandline if the link order is important */
+#if 1 /* This is currently enabled for all systems */
+#define dependLib(x) x
+#else
+#define dependLib(x)
+#endif
+
+#if defined(XorgVersion)
+/* Do not strip server binaries */
+INSTPGMFLAGS =
+#endif
+
+#define PreFbLibs $(DIX) $(OS) $(XPDDX)
+#define BarePostFbLibs $(XPFBLIBS) $(MI)
+#define PostFbLibs BarePostFbLibs $(EXTENSIONS)
+
+#if !BuildXinerama
+#define FbPostFbLibs $(FB) BarePostFbLibs $(EXTENSIONS)
+#else
+#define FbPostFbLibs $(FB) $(EXTENSIONS) BarePostFbLibs $(EXTENSIONS)
+#endif
+
+#define FBLibs PreFbLibs FbPostFbLibs
+
+#define MiExtLibs $(SHADOW)
+
+#define AllFBLibs PreFbLibs $(FB) PostFbLibs
+
+#if BuildGlxExt
+ GLXLIB = GL/glx/ModuleLibraryTargetName(glx) \
+ GL/mesa/GLcore/ModuleLibraryTargetName(GLcore)
+ GLXDIR = GL
+ GLXEXT = $(GLXLIB)
+#endif
+
+#if BuildXInputExt
+ XINPUTEXT = Xi/LibraryTargetName(xinput)
+ XIDIR = Xi
+#endif
+#if BuildXKB
+ XKBEXT = xkb/LibraryTargetName(xkb) dependLib($(OS))
+ XKBDIR = xkb
+#if defined(XorgVersion)
+ XF86XKBOBJS = xkb/xf86KillSrv.o xkb/xf86VT.o xkb/xf86Private.o
+#endif
+#endif
+#if BuildDBE
+ DBEEXT = dbe/LibraryTargetName(dbe)
+#endif
+#if BuildDBE
+ DBEDIR = dbe
+#endif
+#if BuildRECORD
+ RECORDEXT = record/LibraryTargetName(record)
+#endif
+#if BuildRECORD || BuildRECORDlib
+ RECORDDIR = record
+#endif
+#ifdef SiteExtensionLibs
+ SITEEXTS = SiteExtensionLibs
+#endif
+#ifdef SiteExtensionDirs
+ SITEEXTDIRS = SiteExtensionDirs
+#endif
+ LIBREGEX = RegexLibrary
+
+
+#if BuildRender
+ RENDERDIR = render
+ RENDERLIB = $(RENDERDIR)/librender.a
+#endif
+#if BuildRandR
+ RANDRDIR = randr
+ RANDRLIB = $(RANDRDIR)/librandr.a
+#endif
+#if BuildXfixes
+ FIXESDIR = xfixes
+ FIXESLIB = $(FIXESDIR)/libxfixes.a
+#endif
+#if BuildDamage
+ DAMAGEDIR = damageext
+ DAMAGELIB = $(DAMAGEDIR)/libdamage.a
+#endif
+#if BuildComposite
+ CWDIR = miext/cw
+ COMPOSITEDIR = composite
+ COMPOSITELIB = $(COMPOSITEDIR)/libcomposite.a
+ CW = miext/cw/LibraryTargetName(cw)
+#endif
+ EXTENSIONS = $(COMPOSITELIB) $(DAMAGELIB) $(DAMAGE) $(FIXESLIB) $(CW) \
+ $(OTHEREXTS) $(GLXEXT) $(RANDRLIB) $(RENDERLIB)
+ OTHEREXTS = Xext/LibraryTargetName(ext) $(XKBEXT) $(XINPUTEXT) \
+ $(DBEEXT) $(RECORDEXT) $(SITEEXTS)
+ EXTDIRS = Xext $(XKBDIR) $(XIDIR) $(GLXDIR) \
+ $(DBEDIR) $(RECORDDIR) $(SITEEXTDIRS) \
+ $(RANDRDIR) $(RENDERDIR) $(XPCONFIGDIR) \
+ $(FIXESDIR) $(DAMAGEDIR) $(CWDIR) $(COMPOSITEDIR)
+ OS = os/LibraryTargetName(os)
+ BSDEMUL = $(DEPXBSDLIB)
+ FB = fb/LibraryTargetName(fb)
+#if (!(defined(NXAgentServer) && NXAgentServer))
+ DAMAGE = miext/damage/LibraryTargetName(damage)
+#endif
+ SHADOW = miext/shadow/LibraryTargetName(shadow)
+ LAYER = miext/layer/LibraryTargetName(layer)
+#if !HasFfs && (defined(mingwArchitecture) || defined(cygwinArchitecture))
+ /* Order of libraries is important when linking in mingw or
+ * cygwin. libmi.a requires ffs from libdix.a. So it is added
+ * after libmi.a on the commandline */
+ MI = mi/LibraryTargetName(mi) $(DIX)
+#else
+ MI = mi/LibraryTargetName(mi)
+#endif
+ MIINITEXTOBJ = mi/miinitext.o
+ DIX = dix/LibraryTargetName(dix)
+#if UsbMouseSupport
+#if !HasLibUsb
+ USB = $(XF86OSSRC)/bsd/libusb/LibraryTargetName(usb)
+#else
+ USB = UsbHidLib
+#endif
+#endif
+#ifdef ServerExtraSysLibs
+ EXTRASYSLIBS = ServerExtraSysLibs
+#endif
+#if HasPam && HasPamMisc
+ PAMLIBS = PamLibraries PamMiscLibraries
+#endif
+ SYSLIBS = $(ZLIB) MathLibrary $(USB) \
+ $(PAMLIBS) $(EXTRASYSLIBS)
+#if !HasCbrt
+ CBRT = mi/LibraryTargetName(cbrt)
+#endif
+ STDDIRS = include dix os mi $(XPDDXDIR) $(EXTDIRS)
+ FBDIR = fb
+
+XCOMM
+XCOMM This turns off the default rule for compiling .c files because
+XCOMM this makefile does not really know how to build it. This is really
+XCOMM just a hack because of the Sun version of make and nfs.
+XCOMM
+.c.o:
+
+.s.o:
+
+#if HasParallelMake
+XCOMM
+XCOMM force non-parallel build of XF86 servers to prevent MUTEX overrides
+XCOMM
+#if defined(NXAgentServer) && NXAgentServer
+NXAGENT = nxagent
+#endif
+#if defined(NXWinServer) && NXWinServer
+NXWIN = NXWin
+#endif
+#if (defined(NXAgentServer) && NXAgentServer) || \
+ (defined(NXWinServer) && NXWinServer)
+MakeMutex($(NXAGENT) $(NXWIN))
+#endif
+MakeMutex($(STDDIRS) fb)
+#endif
+
+
+#if defined(NXAgentServer) && NXAgentServer
+XCOMM
+XCOMM Nested server with NXlib-based ddx and compressed transport.
+XCOMM
+FBSUBDIR = fb
+MIDAMAGEDIR = miext/damage
+FBDIR = fb
+#ifndef Win32Architecture
+NXAGENTDDXDIR = hw/nxagent
+#else
+NXAGENTDDXDIR = hw
+#endif
+
+NXAGENTDIRS = $(STDDIRS) $(FBDIR) $(MIDAMAGEDIR) $(NXAGENTDDXDIR) $(DEPDIRS)
+
+NX_XCOMP_HEADERS = \
+ ../../../nxcomp/MD5.h \
+ ../../../nxcomp/NXalert.h \
+ ../../../nxcomp/NX.h \
+ ../../../nxcomp/NXpack.h \
+ ../../../nxcomp/NXproto.h \
+ ../../../nxcomp/NXvars.h \
+ $(NULL)
+
+NX_XCOMPSHAD_HEADERS = \
+ ../../../nxcompshad/Shadow.h \
+ $(NULL)
+
+NX_HEADERS = \
+ $(NX_XCOMP_HEADERS) \
+ $(NX_XCOMPSHAD_HEADERS) \
+ $(NULL)
+
+BuildIncludes($(NX_HEADERS),nx,..)
+
+#if defined(SunArchitecture) || \
+ defined(SparcArchitecture)
+NXAGENTOBJS = hw/nxagent/miinitext.o \
+ hw/nxagent/NXwindow.o \
+ hw/nxagent/NXevents.o \
+ hw/nxagent/NXproperty.o \
+ hw/nxagent/NXdixfonts.o \
+ hw/nxagent/NXglyphcurs.o \
+ hw/nxagent/NXdispatch.o \
+ hw/nxagent/NXrender.o \
+ hw/nxagent/NXglyph.o \
+ hw/nxagent/NXpicture.o \
+ hw/nxagent/NXextension.o \
+ hw/nxagent/NXglxext.o \
+ hw/nxagent/NXmiexpose.o \
+ hw/nxagent/NXresource.o \
+ hw/nxagent/NXdamage.o \
+ $(NULL)
+#elif !defined(Win32Architecture)
+NXAGENTOBJS = hw/nxagent/miinitext.o \
+ hw/nxagent/NXwindow.o \
+ hw/nxagent/NXevents.o \
+ hw/nxagent/NXproperty.o \
+ hw/nxagent/NXdixfonts.o \
+ hw/nxagent/NXglyphcurs.o \
+ hw/nxagent/NXdispatch.o \
+ hw/nxagent/NXrender.o \
+ hw/nxagent/NXglyph.o \
+ hw/nxagent/NXpicture.o \
+ hw/nxagent/NXextension.o \
+ hw/nxagent/NXglxext.o \
+ hw/nxagent/NXxvdisp.o \
+ hw/nxagent/NXmiexpose.o \
+ hw/nxagent/NXresource.o \
+ hw/nxagent/NXdamage.o \
+ $(NULL)
+#else
+NXAGENTOBJS = hw/nxagent/miinitext.o \
+ hw/nxagent/NXwindow.o \
+ hw/nxagent/NXevents.o \
+ hw/nxagent/NXproperty.o \
+ hw/nxagent/NXdixfonts.o \
+ hw/nxagent/NXglyphcurs.o \
+ hw/nxagent/NXdispatch.o \
+ hw/nxagent/NXrender.o \
+ hw/nxagent/NXglyph.o \
+ hw/nxagent/NXpicture.o \
+ hw/nxagent/NXextension.o \
+ hw/nxagent/NXglxext.o \
+ hw/nxagent/NXxvdisp.o \
+ hw/nxagent/NXmiexpose.o \
+ hw/nxagent/NXresource.o \
+ hw/nxagent/NXdamage.o \
+ dix/main.o \
+ $(NULL)
+#endif
+
+XPMLIB = -lXpm
+XMLLIB = `pkg-config --libs libxml-2.0`
+PIXMANLIB = `pkg-config --libs pixman-1`
+ZLIB = `pkg-config --libs zlib`
+PNGLIB = `pkg-config --libs libpng`
+JPEGLIB = -ljpeg
+
+NXAGENT = hw/nxagent/LibraryTargetName(nxagent)
+NXCOMPEXT = hw/nxagent/compext/LibraryTargetName(compext)
+NXAGENTLIBS = PreFbLibs $(NXAGENT) FbPostFbLibs $(NXCOMPEXT) $(NXAGENT) $(MI)
+NXAGENTSYSLIBS = $(LDPRELIBS) $(XLIB) $(SYSLIBS) $(XPMLIB) $(XMLLIB)
+NXCOMPEXTSYSLIBS = $(PIXMANLIB) $(ZLIB) $(PNGLIB) $(JPEGLIB)
+#if HasParallelMake
+MakeMutex($(NXAGENTDIRS) $(NXCOMPEXT) $(NXAGENTOBJS) $(NXAGENTLIBS) $(NXCOMPEXTSYSLIBS) $(NXAGENTSYSLIBS))
+#endif
+#if ForceServerRemake
+$(NXAGENTOBJS) $(NXAGENTLIBS) $(NXAGENTSYSLIBS):: $(NXAGENTDIRS)
+ @if [ -f $@ ]; then touch $@ >/dev/null 2>&1 || exit 0; fi
+#endif
+#if NXLibraries
+/*
+ * We need this as the linker will try to locate dependencies of X11 and Xext.
+ */
+
+#if defined(SunArchitecture)
+NXAGENTNXLIBS = -L/usr/sfw/lib \
+ -L../../../nxcomp \
+ -L../../../nxcompshad \
+ -lrt \
+ -lXcomp \
+ -lXcompshad \
+ -lXrender \
+ -lXfixes \
+ $(XFONTLIB) \
+ -lXcomposite \
+ -lXinerama \
+ -lXdmcp \
+ -lNX_X11 \
+ -lXext \
+ $(NULL)
+#elif defined(cygwinArchitecture)
+NXAGENTNXLIBS = -L../../../nxcomp \
+ -L../../../nxcompshad \
+ -lXcomp \
+ -lXcompshad \
+ -lXrender \
+ -lXfixes \
+ $(XFONTLIB) \
+ -lXcomposite \
+ -lXdmcp \
+ -lNX_X11 \
+ -lXext \
+ $(NULL)
+#elif defined(OpenBSDArchitecture)
+NXAGENTNXLIBS = -L../../../nxcomp \
+ -L../../../nx-X11/exports/lib \
+ -L../../../nxcompshad \
+ -lkvm \
+ -lXcomp \
+ -lXcompshad \
+ -lXrender \
+ -lXfixes \
+ $(XFONTLIB) \
+ -lXcomposite \
+ -lXinerama \
+ -lXdmcp \
+ -lNX_X11 \
+ -lXext \
+ $(NULL)
+#else
+NXAGENTNXLIBS = -L../../../nxcomp \
+ -L../../../nxcompshad \
+ -lXcomp \
+ -lXcompshad \
+ -lXrender \
+ -lXfixes \
+ $(XFONTLIB) \
+ -lXcomposite \
+ -lXinerama \
+ -lXdmcp \
+ -lNX_X11 \
+ -lXext \
+ $(NULL)
+#endif
+#endif
+
+#ifdef cygwinArchitecture
+NX_XSHADOWLIBNAME = cygXcompshad.dll
+#else
+NX_XSHADOWLIBNAME = libXcompshad.so
+#endif
+
+ServerTarget(nxagent,$(NXAGENTDIRS),$(NXAGENTOBJS), \
+ $(LIBCWRAPPER) $(NXCOMPEXT) $(NXAGENTLIBS) $(LOADABLEEXTS),$(NXAGENTNXLIBS) $(NXAGENTSYSLIBS) $(NXCOMPEXTSYSLIBS))
+
+/*
+ * Hard coded target to build a static nxagent server.
+ */
+nxagent_static: nxagent
+ if [ -f nxagent_static ]; then set -x; \
+ $(MV) nxagent_static nxagent_static.bak; \
+ else exit 0; fi
+ $(CCLINK) -o nxagent_static -static $(LDOPTIONS) $(NXAGENTOBJS) \
+ $(LIBCWRAPPER) $(NXCOMPEXT) $(NXAGENTLIBS) $(LOADABLEEXTS) $(LDLIBS) \
+ $(NXCOMPEXTSYSLIBS) $(NXAGENTSYSLIBS) $(EXTRA_LOAD_FLAGS)
+
+/*
+ * Hard coded target to build a static nxagent server except for libX11 and libXext.
+ */
+nxagent_static_nolibs: nxagent
+ if [ -f nxagent_static_nolibs ]; then set -x; \
+ $(MV) nxagent__static_nolibs nxagent_static_nolibs.bak; \
+ else exit 0; fi
+ $(CCLINK) -o nxagent_static_nolibs -Wl,-Bstatic $(LDOPTIONS) $(NXAGENTOBJS) \
+ $(NXAGENTLIBS) $(LOADABLEEXTS) $(LIBCWRAPPER) $(LDLIBS) \
+ $(LDPRELIBS) $(SYSLIBS) -Wl,-Bdynamic -lNX_X11 -lXext $(EXTRA_LOAD_FLAGS)
+#endif /* NXAgentServer */
+
+#if defined(NXWinServer) && NXWinServer
+XCOMM
+XCOMM X Server for MS Windows
+XCOMM
+FBSUBDIR = fb
+MIDAMAGEDIR = miext/damage
+SHADOWDIR = miext/shadow
+#if BuildXWinLayer
+LAYERDIR = miext/layer
+XWINLAYERLIB = $(LAYER)
+#else
+LAYERDIR =
+XWINLAYERLIB =
+#endif
+#if BuildXWinMultiWindowExtWM
+ROOTLESSDIR = miext/rootless
+ROOTLESSLIB = $(ROOTLESSDIR)/LibraryTargetName(rootless) \
+ $(ROOTLESSDIR)/safeAlpha/LibraryTargetName(safeAlpha) \
+ $(ROOTLESSDIR)/accel/LibraryTargetName(rlAccel)
+#else
+ROOTLESSDIR =
+ROOTLESSLIB =
+#endif
+NXWINDDXDIR = hw/nxwin
+#if BuildXWinXF86Config
+XWINPARSERDIR = hw/xfree86/parser
+XWINPARSERLIB = $(XWINPARSERDIR)/LibraryTargetName(xf86config)
+#else
+XWINPARSERDIR =
+XWINPARSERLIB =
+#endif
+XWINOPENGLLIB =
+
+NXWINLIB = $(NXWINDDXDIR)/LibraryTargetName(NXWin)
+NXWINDIRS = $(STDDIRS) $(FBDIR) $(SHADOWDIR) $(LAYERDIR) $(NXWINDDXDIR) \
+ $(DEPDIRS) $(XWINPARSERDIR) $(ROOTLESSDIR) $(MIDAMAGEDIR)
+NXWINOBJS = $(NXWINDDXDIR)/stubs.o $(NXWINDDXDIR)/NXWin.res
+NXWINLIBS = PreFbLibs $(NXWINLIB) FbPostFbLibs $(NXWINLIB) $(XWINLAYERLIB) \
+ $(SHADOW) $(XWINPARSERLIB) $(ROOTLESSLIB) $(OS)
+#if BuildXWinMultiWindow || BuildXWinClipboard
+XWINX11 = $(XONLYLIB)
+# if defined(Win32Architecture)
+PTHREADLIB = -lpthreadGC
+# endif
+#endif
+#if defined(Win32Architecture)
+XWINW32 = -lgdi32 -lwsock32 $(PTHREADLIB)
+#else
+XWINW32 = -lgdi32
+#endif
+NXWINSYSLIBS = $(LDPRELIBS) $(XWINX11) $(SYSLIBS) $(XWINW32)
+
+NXWINNXLIBS = -L../../../nxcomp -lXcomp
+
+/*
+ * These flags cause NXWin.exe to be a Windows executable, which
+ * prevents NXWin.exe from opening a Command Prompt window when it is
+ * started. However, the flags also prevent NXWin.exe from outputting
+ * its status and error message to a Command Prompt; thus, one most
+ * implement a method to redirect status and error messages to a file
+ * before enabling these flags.
+ */
+EXTRA_LDOPTIONS = -e _mainCRTStartup
+
+#if HasParallelMake
+MakeMutex($(NXWINDIRS) $(NXWINOBJS) $(NXWINLIB) $(NXWINLIBS) $(NXWINSYSLIBS) $(NXWINNXLIBS))
+#endif
+
+#if ForceServerRemake
+$(NXWINOBJS) $(NXWINLIB) $(NXWINLIBS) $(NXWINSYSLIBS) $(NXWINNXLIBS):: $(NXWINDIRS)
+ @if [ -f $@ ]; then touch $@ >/dev/null 2>&1 || exit 0; fi
+#endif
+
+#ifdef mingwArchitecture
+NXWINSERVERNAME=NXming
+#else
+NXWINSERVERNAME=NXWin
+#endif
+ServerTarget($(NXWINSERVERNAME),$(NXWINDIRS),$(NXWINOBJS), \
+ $(LIBCWRAPPER) $(NXWINLIBS) $(LOADABLEEXTS),$(NXWINSYSLIBS) $(NXWINNXLIBS))
+
+#ifndef ServerToInstall
+# define ServerToInstall $(NXWINSERVERNAME)
+#endif
+
+#endif /* NXWinServer */
+
+#if 0
+#if defined(NXWinServer) && NXWinServer
+XCOMM
+XCOMM X Server for MS Windows
+XCOMM
+FBDIR = fb
+SHADOWDIR = miext/shadow
+LAYERDIR = miext/layer
+NXWINDDXDIR = hw/nxwin
+XWINPARSERDIR = hw/xfree86/parser
+XWINPARSERLIB = $(XWINPARSERDIR)/LibraryTargetName(xf86config)
+NXWINLIB = $(NXWINDDXDIR)/LibraryTargetName(nxwin)
+NXWINDIRS = $(STDDIRS) $(FBDIR) $(SHADOWDIR) $(LAYERDIR) $(NXWINDDXDIR) \
+ $(DEPDIRS) $(XWINPARSERDIR)
+#NXWINOBJS = $(NXWINDDXDIR)/stubs.o $(NXWINDDXDIR)/NX.res \
+ $(NXWINDDXDIR)/NXwindow.o \
+ $(NXWINDDXDIR)/NXdispatch.o $(NXWINDDXDIR)/NXproperty.o \
+ $(NXWINDDXDIR)/NXevents.o
+NXWINOBJS = $(NXWINDDXDIR)/stubs.o $(NXWINDDXDIR)/NX.res
+NXWINLIBS = PreFbLibs $(NXWINLIB) FbPostFbLibs $(LAYER) $(SHADOW) \
+ $(XWINPARSERLIB)
+NXWINSYSLIBS = $(LDPRELIBS) $(XLIB) $(SYSLIBS) -lgdi32 -lddraw
+NXWINNXLIBS = -L../../../nxcomp -lXcomp
+
+/*
+ * These flags cause NXWin.exe to be a Windows executable, which
+ * prevents NXWin.exe from opening a Command Prompt window when it is
+ * started. However, the flags also prevent NXWin.exe from outputting
+ * its status and error message to a Command Prompt; thus, one most
+ * implement a method to redirect status and error messages to a file
+ * before enabling these flags.
+ */
+EXTRA_LDOPTIONS = -mwindows -e _mainCRTStartup
+
+#if HasParallelMake
+MakeMutex($(NXWINDIRS) $(NXWINOBJS) $(NXWINLIB) $(NXWINLIBS) $(NXWINSYSLIBS) $(NXWINNXLIBS))
+#endif
+
+#if ForceServerRemake
+$(NXWINOBJS) $(NXWINLIB) $(NXWINLIBS) $(NXWINSYSLIBS) $(NXWINNXLIBS):: $(NXWINDIRS)
+ @if [ -f $@ ]; then touch $@ >/dev/null 2>&1 || exit 0; fi
+#endif
+
+ServerTarget(NXWin,$(NXWINDIRS),$(NXWINOBJS), \
+ $(NXWINLIBS) $(LOADABLEEXTS) $(LIBCWRAPPER),$(NXWINSYSLIBS) $(NXWINNXLIBS))
+
+#ifndef ServerToInstall
+#define ServerToInstall NXWin
+#endif
+
+#endif /* NXWinServer */
+#endif
+
+MIEXTDIRS = $(SHADOWDIR) $(LAYERDIR) $(ROOTLESSDIR) $(MIDAMAGEDIR)
+IPLANDIRS = $(IPLAN2P2DIR) $(IPLAN2P4DIR) $(IPLAN2P8DIR)
+DDXDIRS = $(DECWSDDXDIR) $(SUNDDXDIR) \
+ $(HPDDXDIR) $(XFREE86DDXDIR) \
+ $(NXAGENTDDXDIR) $(NXWINDDXDIR)
+SUBDIRS = $(STDDIRS) \
+ $(IPLANDIRS) $(ILBMDIR) \
+ $(DDXDIRS) $(FBSUBDIR) $(KDRIVEDIRS) $(MIEXTDIRS)
+
+#if defined(ServerToInstall)
+install::
+ -(cd $(DESTDIR)$(BINDIR); $(RM) X; $(LN) ServerToInstall X)
+#endif
+
+#define IHaveSubdirs
+
+DependSubdirs($(SUBDIRS))
+MakeLintLibSubdirs($(SUBDIRS))
+LintSubdirs($(SUBDIRS))
+
+ForceSubdirs($(DEPDIRS) $(SUBDIRS))
+
+DEFAULTFONTPATH = DefaultFontPath
+EXTRAMANDEFS = -D__default_font_path__="`echo $(DEFAULTFONTPATH) | sed -e 's/,/, /g'`"
diff --git a/nx-X11/programs/Xserver/Xext/Imakefile b/nx-X11/programs/Xserver/Xext/Imakefile
new file mode 100644
index 000000000..becc7b66e
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/Imakefile
@@ -0,0 +1,137 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <Server.tmpl>
+
+#if HasShm && (!(defined(NXAgentServer) && NXAgentServer))
+ SHMSRCS = shm.c
+ SHMOBJS = shm.o
+#endif
+
+#if BuildScreenSaverExt
+ SCRNSAVSRC = saver.c
+ SCRNSAVOBJ = saver.o
+#endif
+
+#if BuildXF86BigfontExt
+XF86BIGFSRCS = xf86bigfont.c
+XF86BIGFOBJS = xf86bigfont.o
+#if HasShm
+ SHM_DEFINES = -DHAS_SHM
+#endif
+#endif
+
+#if BuildXvExt && ( (defined(NXAgentServer) && NXAgentServer) && !defined(SunArchitecture) && !defined(cygwinArchitecture) )
+ XVSRCS = xvmain.c xvmc.c
+ XVOBJS = xvmain.o xvmc.o
+#elif BuildXvExt
+ XVSRCS = xvmain.c xvdisp.c xvmc.c
+ XVOBJS = xvmain.o xvdisp.o xvmc.o
+#endif
+
+#if BuildXResExt
+ XRESSRCS = xres.c
+ XRESOBJS = xres.o
+#endif
+
+#if BuildXCSecurity
+ SECURITYSRCS = security.c
+ SECURITYOBJS = security.o
+ SERVERCONFIGDIR = ServerConfigDir
+ POLICYFILEDEF = -DDEFAULTPOLICYFILE=\"$(SERVERCONFIGDIR)/SecurityPolicy\"
+#endif
+#if BuildXinerama
+ PNRXSRCS = panoramiX.c panoramiXSwap.c panoramiXprocs.c
+ PNRXOBJS = panoramiX.o panoramiXSwap.o panoramiXprocs.o
+ PNRXINCLUDES = -I../mi -I../render
+#endif
+#if BuildDPMS
+ DPMSSRCS = dpms.c
+ DPMSOBJS = dpms.o
+#endif
+
+ SRCS = shape.c $(SHMSRCS) xcmisc.c\
+ xtest.c xtest1di.c xtest1dd.c sleepuntil.c \
+ bigreq.c sync.c $(SCRNSAVSRC) \
+ $(XF86BIGFSRCS) $(SECURITYSRCS) \
+ $(PNRXSRCS) $(DPMSSRCS) \
+ $(XVSRCS) $(XRESSRCS) $(DMXSRCS)
+
+ OBJS = shape.o $(SHMOBJS) xcmisc.o \
+ xtest.o xtest1di.o xtest1dd.o sleepuntil.o \
+ bigreq.o sync.o $(SCRNSAVOBJ) \
+ $(XF86BIGFOBJS) $(SECURITYOBJS) \
+ $(PNRXOBJS) $(DPMSOBJS) \
+ $(XVOBJS) $(XRESOBJS) $(DMXOBJS)
+
+ SOBJS = $(SHMOBJS) $(SECURITYOBJS) \
+ shape.o xtest.o xtest1di.o xtest1dd.o sleepuntil.o $(PNRXOBJS) \
+ $(XF86BIGFOBJS)
+
+#if defined(NXAgentServer) && NXAgentServer
+NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+
+#if defined(XorgVersion)
+/* XXX Check if this can be eliminated */
+XF86INCLUDES = -I$(XF86COMSRC)
+#endif
+ INCLUDES = -I. -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) \
+ $(PNRXINCLUDES) \
+ $(XF86INCLUDES) \
+ $(DMXINCLUDES) \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ DEFINES = $(EXT_DEFINES) $(XVMCSHM_DEFINES) $(NX_DEFINES)
+#else
+ DEFINES = $(EXT_DEFINES) $(XVMCSHM_DEFINES)
+#endif
+
+NormalLibraryObjectRule()
+
+NormalLibraryTarget(ext,$(OBJS))
+LintLibraryTarget(ext,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#if BuildXF86BigfontExt
+SpecialCObjectRule(xf86bigfont,$(ICONFIGFILES),$(SHM_DEFINES))
+#endif
+#if BuildXCSecurity
+SpecialCObjectRule(security,$(ICONFIGFILES),$(POLICYFILEDEF))
+#endif
+
+LinkConfDirectory(xserver,.,xserver,.)
+
+#if BuildXCSecurity && InstallSecurityConfig
+InstallNonExecFile(SecurityPolicy,$(SERVERCONFIGDIR))
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(xvdix.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xvmcext.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/Xext/SecurityPolicy b/nx-X11/programs/Xserver/Xext/SecurityPolicy
new file mode 100644
index 000000000..cc521c263
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/SecurityPolicy
@@ -0,0 +1,88 @@
+version-1
+
+# $Xorg: SecurityPolicy,v 1.3 2000/08/17 19:47:56 cpqbld Exp $
+
+# The site policy fields are interpreted by the XC-QUERY-SECURITY-1
+# authorization protocol. The values are arbitrary and site-specific.
+# Refer to the Security Extension Specification for the usage of the policies.
+#sitepolicy A
+#sitepolicy B
+#sitepolicy C
+
+# Property access rules:
+# property <property> <window> <permissions>
+# <window> ::= any | root | <propertyselector>
+# <propertyselector> ::= <property> | <property>=<value>
+# <permissions> :== [ <operation> | <action> | <space> ]*
+# <operation> :== r | w | d
+# r read
+# w write
+# d delete
+# <action> :== a | i | e
+# a allow
+# i ignore
+# e error
+
+# Allow reading of application resources, but not writing.
+property RESOURCE_MANAGER root ar iw
+property SCREEN_RESOURCES root ar iw
+
+# Ignore attempts to use cut buffers. Giving errors causes apps to crash,
+# and allowing access may give away too much information.
+property CUT_BUFFER0 root irw
+property CUT_BUFFER1 root irw
+property CUT_BUFFER2 root irw
+property CUT_BUFFER3 root irw
+property CUT_BUFFER4 root irw
+property CUT_BUFFER5 root irw
+property CUT_BUFFER6 root irw
+property CUT_BUFFER7 root irw
+
+# If you are using Motif, you probably want these.
+property _MOTIF_DEFAULT_BINDINGS root ar iw
+property _MOTIF_DRAG_WINDOW root ar iw
+property _MOTIF_DRAG_TARGETS any ar iw
+property _MOTIF_DRAG_ATOMS any ar iw
+property _MOTIF_DRAG_ATOM_PAIRS any ar iw
+
+# If you are running CDE you also need these
+property _MOTIF_WM_INFO root arw
+property TT_SESSION root irw
+property WM_ICON_SIZE root irw
+property "SDT Pixel Set" any irw
+
+# The next two rules let xwininfo -tree work when untrusted.
+property WM_NAME any ar
+
+# Allow read of WM_CLASS, but only for windows with WM_NAME.
+# This might be more restrictive than necessary, but demonstrates
+# the <required property> facility, and is also an attempt to
+# say "top level windows only."
+property WM_CLASS WM_NAME ar
+
+# These next three let xlsclients work untrusted. Think carefully
+# before including these; giving away the client machine name and command
+# may be exposing too much.
+property WM_STATE WM_NAME ar
+property WM_CLIENT_MACHINE WM_NAME ar
+property WM_COMMAND WM_NAME ar
+
+# To let untrusted clients use the standard colormaps created by
+# xstdcmap, include these lines.
+property RGB_DEFAULT_MAP root ar
+property RGB_BEST_MAP root ar
+property RGB_RED_MAP root ar
+property RGB_GREEN_MAP root ar
+property RGB_BLUE_MAP root ar
+property RGB_GRAY_MAP root ar
+
+# To let untrusted clients use the color management database created
+# by xcmsdb, include these lines.
+property XDCCC_LINEAR_RGB_CORRECTION root ar
+property XDCCC_LINEAR_RGB_MATRICES root ar
+property XDCCC_GRAY_SCREENWHITEPOINT root ar
+property XDCCC_GRAY_CORRECTION root ar
+
+# To let untrusted clients use the overlay visuals that many vendors
+# support, include this line.
+property SERVER_OVERLAY_VISUALS root ar
diff --git a/nx-X11/programs/Xserver/Xext/bigreq.c b/nx-X11/programs/Xserver/Xext/bigreq.c
new file mode 100644
index 000000000..be5919328
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/bigreq.c
@@ -0,0 +1,103 @@
+/*
+
+Copyright 1992, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <nx-X11/extensions/bigreqstr.h>
+#include "opaque.h"
+
+#if 0
+static unsigned char XBigReqCode;
+#endif
+
+static void BigReqResetProc(
+ ExtensionEntry * /* extEntry */
+);
+
+static DISPATCH_PROC(ProcBigReqDispatch);
+
+void
+BigReqExtensionInit(void)
+{
+#if 0
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(XBigReqExtensionName, 0, 0,
+ ProcBigReqDispatch, ProcBigReqDispatch,
+ BigReqResetProc, StandardMinorOpcode)) != 0)
+ XBigReqCode = (unsigned char)extEntry->base;
+#else
+ (void) AddExtension(XBigReqExtensionName, 0, 0,
+ ProcBigReqDispatch, ProcBigReqDispatch,
+ BigReqResetProc, StandardMinorOpcode);
+#endif
+
+ DeclareExtensionSecurity(XBigReqExtensionName, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+BigReqResetProc (extEntry)
+ ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcBigReqDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xBigReqEnableReq);
+ xBigReqEnableReply rep;
+
+ if (client->swapped) {
+ swaps(&stuff->length);
+ }
+ if (stuff->brReqType != X_BigReqEnable)
+ return BadRequest;
+ REQUEST_SIZE_MATCH(xBigReqEnableReq);
+ client->big_requests = TRUE;
+ memset(&rep, 0, sizeof(xBigReqEnableReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.max_request_size = maxBigRequestSize;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.max_request_size);
+ }
+ WriteToClient(client, sizeof(xBigReqEnableReply), &rep);
+ return(client->noClientException);
+}
diff --git a/nx-X11/programs/Xserver/Xext/dpms.c b/nx-X11/programs/Xserver/Xext/dpms.c
new file mode 100644
index 000000000..ea9781353
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/dpms.c
@@ -0,0 +1,435 @@
+/*****************************************************************
+
+Copyright (c) 1996 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.
+
+******************************************************************/
+
+/*
+ * HISTORY
+ *
+ * @(#)RCSfile: dpms.c,v Revision: 1.1.4.5 (DEC) Date: 1996/03/04 15:27:00
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "opaque.h"
+#define DPMS_SERVER
+#include <nx-X11/extensions/dpms.h>
+#include <nx-X11/extensions/dpmsstr.h>
+#include "dpmsproc.h"
+
+#if 0
+static unsigned char DPMSCode;
+#endif
+static DISPATCH_PROC(ProcDPMSDispatch);
+static DISPATCH_PROC(SProcDPMSDispatch);
+static DISPATCH_PROC(ProcDPMSGetVersion);
+static DISPATCH_PROC(SProcDPMSGetVersion);
+static DISPATCH_PROC(ProcDPMSGetTimeouts);
+static DISPATCH_PROC(SProcDPMSGetTimeouts);
+static DISPATCH_PROC(ProcDPMSSetTimeouts);
+static DISPATCH_PROC(SProcDPMSSetTimeouts);
+static DISPATCH_PROC(ProcDPMSEnable);
+static DISPATCH_PROC(SProcDPMSEnable);
+static DISPATCH_PROC(ProcDPMSDisable);
+static DISPATCH_PROC(SProcDPMSDisable);
+static DISPATCH_PROC(ProcDPMSForceLevel);
+static DISPATCH_PROC(SProcDPMSForceLevel);
+static DISPATCH_PROC(ProcDPMSInfo);
+static DISPATCH_PROC(SProcDPMSInfo);
+static DISPATCH_PROC(ProcDPMSCapable);
+static DISPATCH_PROC(SProcDPMSCapable);
+static void DPMSResetProc(ExtensionEntry* extEntry);
+
+void
+DPMSExtensionInit(void)
+{
+#if 0
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(DPMSExtensionName, 0, 0,
+ ProcDPMSDispatch, SProcDPMSDispatch,
+ DPMSResetProc, StandardMinorOpcode)))
+ DPMSCode = (unsigned char)extEntry->base;
+#else
+ (void) AddExtension(DPMSExtensionName, 0, 0,
+ ProcDPMSDispatch, SProcDPMSDispatch,
+ DPMSResetProc, StandardMinorOpcode);
+#endif
+}
+
+/*ARGSUSED*/
+static void
+DPMSResetProc (extEntry)
+ ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcDPMSGetVersion(client)
+ register ClientPtr client;
+{
+ /* REQUEST(xDPMSGetVersionReq); */
+ xDPMSGetVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = DPMSMajorVersion;
+ rep.minorVersion = DPMSMinorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xDPMSGetVersionReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSCapable(register ClientPtr client)
+{
+ /* REQUEST(xDPMSCapableReq); */
+ xDPMSCapableReply rep;
+
+ REQUEST_SIZE_MATCH(xDPMSCapableReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.capable = DPMSCapableFlag;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ }
+ WriteToClient(client, sizeof(xDPMSCapableReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSGetTimeouts(client)
+ register ClientPtr client;
+{
+ /* REQUEST(xDPMSGetTimeoutsReq); */
+ xDPMSGetTimeoutsReply rep;
+
+ REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.standby = DPMSStandbyTime / MILLI_PER_SECOND;
+ rep.suspend = DPMSSuspendTime / MILLI_PER_SECOND;
+ rep.off = DPMSOffTime / MILLI_PER_SECOND;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.standby);
+ swaps(&rep.suspend);
+ swaps(&rep.off);
+ }
+ WriteToClient(client, sizeof(xDPMSGetTimeoutsReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSSetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSSetTimeoutsReq);
+
+ REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
+
+ if ((stuff->off != 0)&&(stuff->off < stuff->suspend))
+ {
+ client->errorValue = stuff->off;
+ return BadValue;
+ }
+ if ((stuff->suspend != 0)&&(stuff->suspend < stuff->standby))
+ {
+ client->errorValue = stuff->suspend;
+ return BadValue;
+ }
+
+ DPMSStandbyTime = stuff->standby * MILLI_PER_SECOND;
+ DPMSSuspendTime = stuff->suspend * MILLI_PER_SECOND;
+ DPMSOffTime = stuff->off * MILLI_PER_SECOND;
+ SetDPMSTimers();
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSEnable(client)
+ register ClientPtr client;
+{
+ /* REQUEST(xDPMSEnableReq); */
+
+ REQUEST_SIZE_MATCH(xDPMSEnableReq);
+
+ if (DPMSCapableFlag)
+ DPMSEnabled = TRUE;
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSDisable(client)
+ register ClientPtr client;
+{
+ /* REQUEST(xDPMSDisableReq); */
+
+ REQUEST_SIZE_MATCH(xDPMSDisableReq);
+
+ DPMSSet(DPMSModeOn);
+
+ DPMSEnabled = FALSE;
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSForceLevel(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSForceLevelReq);
+
+ REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
+
+ if (!DPMSEnabled)
+ return BadMatch;
+
+ if (stuff->level == DPMSModeOn) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis();
+ } else if (stuff->level == DPMSModeStandby) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSStandbyTime;
+ } else if (stuff->level == DPMSModeSuspend) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSSuspendTime;
+ } else if (stuff->level == DPMSModeOff) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSOffTime;
+ } else {
+ client->errorValue = stuff->level;
+ return BadValue;
+ }
+
+ DPMSSet(stuff->level);
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSInfo(register ClientPtr client)
+{
+ /* REQUEST(xDPMSInfoReq); */
+ xDPMSInfoReply rep;
+
+ REQUEST_SIZE_MATCH(xDPMSInfoReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.power_level = DPMSPowerLevel;
+ rep.state = DPMSEnabled;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.power_level);
+ }
+ WriteToClient(client, sizeof(xDPMSInfoReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_DPMSGetVersion:
+ return ProcDPMSGetVersion(client);
+ case X_DPMSCapable:
+ return ProcDPMSCapable(client);
+ case X_DPMSGetTimeouts:
+ return ProcDPMSGetTimeouts(client);
+ case X_DPMSSetTimeouts:
+ return ProcDPMSSetTimeouts(client);
+ case X_DPMSEnable:
+ return ProcDPMSEnable(client);
+ case X_DPMSDisable:
+ return ProcDPMSDisable(client);
+ case X_DPMSForceLevel:
+ return ProcDPMSForceLevel(client);
+ case X_DPMSInfo:
+ return ProcDPMSInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcDPMSGetVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSGetVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
+ swaps(&stuff->majorVersion);
+ swaps(&stuff->minorVersion);
+ return ProcDPMSGetVersion(client);
+}
+
+static int
+SProcDPMSCapable(register ClientPtr client)
+{
+ REQUEST(xDPMSCapableReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSCapableReq);
+
+ return ProcDPMSCapable(client);
+}
+
+static int
+SProcDPMSGetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSGetTimeoutsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
+
+ return ProcDPMSGetTimeouts(client);
+}
+
+static int
+SProcDPMSSetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSSetTimeoutsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
+
+ swaps(&stuff->standby);
+ swaps(&stuff->suspend);
+ swaps(&stuff->off);
+ return ProcDPMSSetTimeouts(client);
+}
+
+static int
+SProcDPMSEnable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSEnableReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSEnableReq);
+
+ return ProcDPMSEnable(client);
+}
+
+static int
+SProcDPMSDisable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSDisableReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSDisableReq);
+
+ return ProcDPMSDisable(client);
+}
+
+static int
+SProcDPMSForceLevel(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSForceLevelReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
+
+ swaps(&stuff->level);
+
+ return ProcDPMSForceLevel(client);
+}
+
+static int
+SProcDPMSInfo(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSInfoReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDPMSInfoReq);
+
+ return ProcDPMSInfo(client);
+}
+
+static int
+SProcDPMSDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_DPMSGetVersion:
+ return SProcDPMSGetVersion(client);
+ case X_DPMSCapable:
+ return SProcDPMSCapable(client);
+ case X_DPMSGetTimeouts:
+ return SProcDPMSGetTimeouts(client);
+ case X_DPMSSetTimeouts:
+ return SProcDPMSSetTimeouts(client);
+ case X_DPMSEnable:
+ return SProcDPMSEnable(client);
+ case X_DPMSDisable:
+ return SProcDPMSDisable(client);
+ case X_DPMSForceLevel:
+ return SProcDPMSForceLevel(client);
+ case X_DPMSInfo:
+ return SProcDPMSInfo(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/dpmsproc.h b/nx-X11/programs/Xserver/Xext/dpmsproc.h
new file mode 100644
index 000000000..f5485ea79
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/dpmsproc.h
@@ -0,0 +1,15 @@
+
+/* Prototypes for functions that the DDX must provide */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DPMSPROC_H_
+#define _DPMSPROC_H_
+
+void DPMSSet(int level);
+int DPMSGet(int *plevel);
+Bool DPMSSupported(void);
+
+#endif
diff --git a/nx-X11/programs/Xserver/Xext/dpmsstubs.c b/nx-X11/programs/Xserver/Xext/dpmsstubs.c
new file mode 100644
index 000000000..9f99a2d22
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/dpmsstubs.c
@@ -0,0 +1,52 @@
+/*****************************************************************
+
+Copyright (c) 1996 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.
+
+******************************************************************/
+
+typedef int Bool;
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dpmsproc.h"
+
+#define FALSE 0
+
+Bool DPMSSupported(void)
+{
+ return FALSE;
+}
+
+int DPMSGet(int *plevel)
+{
+ return -1;
+}
+
+void DPMSSet(int level)
+{
+
+}
diff --git a/nx-X11/programs/Xserver/Xext/panoramiX.c b/nx-X11/programs/Xserver/Xext/panoramiX.c
new file mode 100644
index 000000000..e720965d4
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiX.c
@@ -0,0 +1,1287 @@
+/*****************************************************************
+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.
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xarch.h>
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "gc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "panoramiX.h"
+#include <nx-X11/extensions/panoramiXproto.h>
+#include "panoramiXsrv.h"
+#include "globals.h"
+#include "servermd.h"
+#include "resource.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+#include "protocol-versions.h"
+
+#ifdef GLXPROXY
+extern VisualPtr glxMatchVisual(ScreenPtr pScreen,
+ VisualPtr pVisual,
+ ScreenPtr pMatchScreen);
+#endif
+
+#if 0
+static unsigned char PanoramiXReqCode = 0;
+#endif
+/*
+ * PanoramiX data declarations
+ */
+
+int PanoramiXPixWidth = 0;
+int PanoramiXPixHeight = 0;
+int PanoramiXNumScreens = 0;
+
+PanoramiXData *panoramiXdataPtr = NULL;
+RegionRec PanoramiXScreenRegion = {{0, 0, 0, 0}, NULL};
+
+static int PanoramiXNumDepths;
+static DepthPtr PanoramiXDepths;
+static int PanoramiXNumVisuals;
+static VisualPtr PanoramiXVisuals;
+
+/* We support at most 256 visuals */
+XID *PanoramiXVisualTable = NULL;
+
+unsigned long XRC_DRAWABLE;
+unsigned long XRT_WINDOW;
+unsigned long XRT_PIXMAP;
+unsigned long XRT_GC;
+unsigned long XRT_COLORMAP;
+
+/*
+ * Function prototypes
+ */
+
+static int panoramiXGeneration;
+static int ProcPanoramiXDispatch(ClientPtr client);
+
+static void PanoramiXResetProc(ExtensionEntry*);
+
+/*
+ * External references for functions and data variables
+ */
+
+#include "panoramiXh.h"
+
+int (* SavedProcVector[256]) (ClientPtr client) = { NULL, };
+ScreenInfo *GlobalScrInfo = NULL;
+
+static int PanoramiXGCIndex = -1;
+static int PanoramiXScreenIndex = -1;
+
+typedef struct {
+ DDXPointRec clipOrg;
+ DDXPointRec patOrg;
+ GCFuncs *wrapFuncs;
+} PanoramiXGCRec, *PanoramiXGCPtr;
+
+typedef struct {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+} PanoramiXScreenRec, *PanoramiXScreenPtr;
+
+RegionRec XineramaScreenRegions[MAXSCREENS];
+
+static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void XineramaChangeGC(GCPtr, unsigned long);
+static void XineramaCopyGC(GCPtr, unsigned long, GCPtr);
+static void XineramaDestroyGC(GCPtr);
+static void XineramaChangeClip(GCPtr, int, void *, int);
+static void XineramaDestroyClip(GCPtr);
+static void XineramaCopyClip(GCPtr, GCPtr);
+
+GCFuncs XineramaGCFuncs = {
+ XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC,
+ XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip
+};
+
+#define Xinerama_GC_FUNC_PROLOGUE(pGC)\
+ PanoramiXGCPtr pGCPriv = \
+ (PanoramiXGCPtr) (pGC)->devPrivates[PanoramiXGCIndex].ptr;\
+ (pGC)->funcs = pGCPriv->wrapFuncs;
+
+#define Xinerama_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->funcs = &XineramaGCFuncs;
+
+
+static Bool
+XineramaCloseScreen (ScreenPtr pScreen)
+{
+ PanoramiXScreenPtr pScreenPriv =
+ (PanoramiXScreenPtr) pScreen->devPrivates[PanoramiXScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+
+ RegionUninit(&XineramaScreenRegions[pScreen->myNum]);
+ if (pScreen->myNum == 0)
+ RegionUninit(&PanoramiXScreenRegion);
+
+ free ((void *) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+Bool
+XineramaCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ PanoramiXScreenPtr pScreenPriv =
+ (PanoramiXScreenPtr) pScreen->devPrivates[PanoramiXScreenIndex].ptr;
+ Bool ret;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ if((ret = (*pScreen->CreateGC)(pGC))) {
+ PanoramiXGCPtr pGCPriv =
+ (PanoramiXGCPtr) pGC->devPrivates[PanoramiXGCIndex].ptr;
+
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &XineramaGCFuncs;
+
+ pGCPriv->clipOrg.x = pGC->clipOrg.x;
+ pGCPriv->clipOrg.y = pGC->clipOrg.y;
+ pGCPriv->patOrg.x = pGC->patOrg.x;
+ pGCPriv->patOrg.y = pGC->patOrg.y;
+ }
+ pScreen->CreateGC = XineramaCreateGC;
+
+ return ret;
+}
+
+static void
+XineramaValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+
+ if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) {
+ /* the root window */
+ int x_off = panoramiXdataPtr[pGC->pScreen->myNum].x;
+ int y_off = panoramiXdataPtr[pGC->pScreen->myNum].y;
+ int new_val;
+
+ new_val = pGCPriv->clipOrg.x - x_off;
+ if(pGC->clipOrg.x != new_val) {
+ pGC->clipOrg.x = new_val;
+ changes |= GCClipXOrigin;
+ }
+ new_val = pGCPriv->clipOrg.y - y_off;
+ if(pGC->clipOrg.y != new_val) {
+ pGC->clipOrg.y = new_val;
+ changes |= GCClipYOrigin;
+ }
+ new_val = pGCPriv->patOrg.x - x_off;
+ if(pGC->patOrg.x != new_val) {
+ pGC->patOrg.x = new_val;
+ changes |= GCTileStipXOrigin;
+ }
+ new_val = pGCPriv->patOrg.y - y_off;
+ if(pGC->patOrg.y != new_val) {
+ pGC->patOrg.y = new_val;
+ changes |= GCTileStipYOrigin;
+ }
+ } else {
+ if(pGC->clipOrg.x != pGCPriv->clipOrg.x) {
+ pGC->clipOrg.x = pGCPriv->clipOrg.x;
+ changes |= GCClipXOrigin;
+ }
+ if(pGC->clipOrg.y != pGCPriv->clipOrg.y) {
+ pGC->clipOrg.y = pGCPriv->clipOrg.y;
+ changes |= GCClipYOrigin;
+ }
+ if(pGC->patOrg.x != pGCPriv->patOrg.x) {
+ pGC->patOrg.x = pGCPriv->patOrg.x;
+ changes |= GCTileStipXOrigin;
+ }
+ if(pGC->patOrg.y != pGCPriv->patOrg.y) {
+ pGC->patOrg.y = pGCPriv->patOrg.y;
+ changes |= GCTileStipYOrigin;
+ }
+ }
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaDestroyGC(GCPtr pGC)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+
+ if(mask & GCTileStipXOrigin)
+ pGCPriv->patOrg.x = pGC->patOrg.x;
+ if(mask & GCTileStipYOrigin)
+ pGCPriv->patOrg.y = pGC->patOrg.y;
+ if(mask & GCClipXOrigin)
+ pGCPriv->clipOrg.x = pGC->clipOrg.x;
+ if(mask & GCClipYOrigin)
+ pGCPriv->clipOrg.y = pGC->clipOrg.y;
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ PanoramiXGCPtr pSrcPriv =
+ (PanoramiXGCPtr) pGCSrc->devPrivates[PanoramiXGCIndex].ptr;
+ Xinerama_GC_FUNC_PROLOGUE (pGCDst);
+
+ if(mask & GCTileStipXOrigin)
+ pGCPriv->patOrg.x = pSrcPriv->patOrg.x;
+ if(mask & GCTileStipYOrigin)
+ pGCPriv->patOrg.y = pSrcPriv->patOrg.y;
+ if(mask & GCClipXOrigin)
+ pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x;
+ if(mask & GCClipYOrigin)
+ pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y;
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ Xinerama_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+XineramaChangeClip (
+ GCPtr pGC,
+ int type,
+ void *pvalue,
+ int nrects
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ Xinerama_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+XineramaDestroyClip(GCPtr pGC)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+
+int
+XineramaDeleteResource(void * data, XID id)
+{
+ free(data);
+ return 1;
+}
+
+
+static Bool
+XineramaFindIDOnAnyScreen(void * resource, XID id, void * privdata)
+{
+ PanoramiXRes *res = (PanoramiXRes*)resource;
+ int j;
+
+ FOR_NSCREENS(j)
+ if(res->info[j].id == *((XID*)privdata)) return TRUE;
+
+ return FALSE;
+}
+
+PanoramiXRes *
+PanoramiXFindIDOnAnyScreen(RESTYPE type, XID id)
+{
+ return LookupClientResourceComplex(clients[CLIENT_ID(id)], type,
+ XineramaFindIDOnAnyScreen, &id);
+}
+
+typedef struct {
+ int screen;
+ int id;
+} PanoramiXSearchData;
+
+
+static Bool
+XineramaFindIDByScrnum(void * resource, XID id, void * privdata)
+{
+ PanoramiXRes *res = (PanoramiXRes*)resource;
+ PanoramiXSearchData *data = (PanoramiXSearchData*)privdata;
+
+ return (res->info[data->screen].id == data->id);
+}
+
+PanoramiXRes *
+PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen)
+{
+ PanoramiXSearchData data;
+
+ if(!screen)
+ return LookupIDByType(id, type);
+
+ data.screen = screen;
+ data.id = id;
+
+ return LookupClientResourceComplex(clients[CLIENT_ID(id)], type,
+ XineramaFindIDByScrnum, &data);
+}
+
+WindowPtr
+PanoramiXChangeWindow(int ScrnNum, WindowPtr pWin)
+{
+ int num = pWin->drawable.pScreen->myNum;
+
+ if(num != ScrnNum) {
+ PanoramiXRes *win;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, num);
+
+ if (win)
+ pWin = (WindowPtr) LookupIDByType(win->info[ScrnNum].id, RT_WINDOW);
+ }
+
+ return pWin;
+}
+
+typedef struct _connect_callback_list {
+ void (*func)(void);
+ struct _connect_callback_list *next;
+} XineramaConnectionCallbackList;
+
+static XineramaConnectionCallbackList *ConnectionCallbackList = NULL;
+
+Bool
+XineramaRegisterConnectionBlockCallback(void (*func)(void))
+{
+ XineramaConnectionCallbackList *newlist;
+
+ if(!(newlist = malloc(sizeof(XineramaConnectionCallbackList))))
+ return FALSE;
+
+ newlist->next = ConnectionCallbackList;
+ newlist->func = func;
+ ConnectionCallbackList = newlist;
+
+ return TRUE;
+}
+
+static void XineramaInitData(ScreenPtr pScreen)
+{
+ int i, w, h;
+
+ RegionNull(&PanoramiXScreenRegion);
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ BoxRec TheBox;
+
+ pScreen = screenInfo.screens[i];
+
+ panoramiXdataPtr[i].x = dixScreenOrigins[i].x;
+ panoramiXdataPtr[i].y = dixScreenOrigins[i].y;
+ panoramiXdataPtr[i].width = pScreen->width;
+ panoramiXdataPtr[i].height = pScreen->height;
+
+ TheBox.x1 = panoramiXdataPtr[i].x;
+ TheBox.x2 = TheBox.x1 + panoramiXdataPtr[i].width;
+ TheBox.y1 = panoramiXdataPtr[i].y;
+ TheBox.y2 = TheBox.y1 + panoramiXdataPtr[i].height;
+
+ RegionInit(&XineramaScreenRegions[i], &TheBox, 1);
+ RegionUnion(&PanoramiXScreenRegion, &PanoramiXScreenRegion,
+ &XineramaScreenRegions[i]);
+ }
+
+ PanoramiXPixWidth = panoramiXdataPtr[0].x + panoramiXdataPtr[0].width;
+ PanoramiXPixHeight = panoramiXdataPtr[0].y + panoramiXdataPtr[0].height;
+
+ for (i = 1; i < PanoramiXNumScreens; i++) {
+ w = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
+ h = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
+
+ if (PanoramiXPixWidth < w)
+ PanoramiXPixWidth = w;
+ if (PanoramiXPixHeight < h)
+ PanoramiXPixHeight = h;
+ }
+}
+
+void XineramaReinitData(ScreenPtr pScreen)
+{
+ int i;
+
+ RegionUninit(&PanoramiXScreenRegion);
+ for (i = 0; i < PanoramiXNumScreens; i++)
+ RegionUninit(&XineramaScreenRegions[i]);
+
+ XineramaInitData(pScreen);
+}
+
+/*
+ * PanoramiXExtensionInit():
+ * Called from InitExtensions in main().
+ * Register PanoramiXeen Extension
+ * Initialize global variables.
+ */
+
+void PanoramiXExtensionInit(int argc, char *argv[])
+{
+ int i;
+ Bool success = FALSE;
+ ExtensionEntry *extEntry;
+ ScreenPtr pScreen = screenInfo.screens[0];
+ PanoramiXScreenPtr pScreenPriv;
+
+ if (noPanoramiXExtension)
+ return;
+
+ GlobalScrInfo = &screenInfo; /* For debug visibility */
+ PanoramiXNumScreens = screenInfo.numScreens;
+ if (PanoramiXNumScreens == 1) { /* Only 1 screen */
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ while (panoramiXGeneration != serverGeneration) {
+ extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
+ ProcPanoramiXDispatch,
+ SProcPanoramiXDispatch, PanoramiXResetProc,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ ErrorF("PanoramiXExtensionInit(): failed to AddExtension\n");
+ break;
+ }
+
+#if 0
+ PanoramiXReqCode = (unsigned char)extEntry->base;
+#endif
+
+ /*
+ * First make sure all the basic allocations succeed. If not,
+ * run in non-PanoramiXeen mode.
+ */
+
+ panoramiXdataPtr = (PanoramiXData *)
+ calloc(PanoramiXNumScreens, sizeof(PanoramiXData));
+
+ BREAK_IF(!panoramiXdataPtr);
+ BREAK_IF((PanoramiXGCIndex = AllocateGCPrivateIndex()) < 0);
+ BREAK_IF((PanoramiXScreenIndex = AllocateScreenPrivateIndex()) < 0);
+
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(!AllocateGCPrivate(pScreen, PanoramiXGCIndex,
+ sizeof(PanoramiXGCRec))) {
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ pScreenPriv = malloc(sizeof(PanoramiXScreenRec));
+ pScreen->devPrivates[PanoramiXScreenIndex].ptr =
+ (void *)pScreenPriv;
+ if(!pScreenPriv) {
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+
+ pScreen->CreateGC = XineramaCreateGC;
+ pScreen->CloseScreen = XineramaCloseScreen;
+ }
+
+ XRC_DRAWABLE = CreateNewResourceClass();
+ XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource) |
+ XRC_DRAWABLE;
+ XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource) |
+ XRC_DRAWABLE;
+ XRT_GC = CreateNewResourceType(XineramaDeleteResource);
+ XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource);
+
+ panoramiXGeneration = serverGeneration;
+ success = TRUE;
+ }
+
+ if (!success) {
+ noPanoramiXExtension = TRUE;
+ ErrorF("%s Extension failed to initialize\n", PANORAMIX_PROTOCOL_NAME);
+ return;
+ }
+
+ XineramaInitData(pScreen);
+
+ /*
+ * Put our processes into the ProcVector
+ */
+
+ for (i = 256; i--; )
+ SavedProcVector[i] = ProcVector[i];
+
+ ProcVector[X_CreateWindow] = PanoramiXCreateWindow;
+ ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes;
+ ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow;
+ ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows;
+ ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet;
+ ProcVector[X_ReparentWindow] = PanoramiXReparentWindow;
+ ProcVector[X_MapWindow] = PanoramiXMapWindow;
+ ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows;
+ ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow;
+ ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows;
+ ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow;
+ ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow;
+ ProcVector[X_GetGeometry] = PanoramiXGetGeometry;
+ ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords;
+ ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap;
+ ProcVector[X_FreePixmap] = PanoramiXFreePixmap;
+ ProcVector[X_CreateGC] = PanoramiXCreateGC;
+ ProcVector[X_ChangeGC] = PanoramiXChangeGC;
+ ProcVector[X_CopyGC] = PanoramiXCopyGC;
+ ProcVector[X_SetDashes] = PanoramiXSetDashes;
+ ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles;
+ ProcVector[X_FreeGC] = PanoramiXFreeGC;
+ ProcVector[X_ClearArea] = PanoramiXClearToBackground;
+ ProcVector[X_CopyArea] = PanoramiXCopyArea;;
+ ProcVector[X_CopyPlane] = PanoramiXCopyPlane;;
+ ProcVector[X_PolyPoint] = PanoramiXPolyPoint;
+ ProcVector[X_PolyLine] = PanoramiXPolyLine;
+ ProcVector[X_PolySegment] = PanoramiXPolySegment;
+ ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle;
+ ProcVector[X_PolyArc] = PanoramiXPolyArc;
+ ProcVector[X_FillPoly] = PanoramiXFillPoly;
+ ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle;
+ ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc;
+ ProcVector[X_PutImage] = PanoramiXPutImage;
+ ProcVector[X_GetImage] = PanoramiXGetImage;
+ ProcVector[X_PolyText8] = PanoramiXPolyText8;
+ ProcVector[X_PolyText16] = PanoramiXPolyText16;
+ ProcVector[X_ImageText8] = PanoramiXImageText8;
+ ProcVector[X_ImageText16] = PanoramiXImageText16;
+ ProcVector[X_CreateColormap] = PanoramiXCreateColormap;
+ ProcVector[X_FreeColormap] = PanoramiXFreeColormap;
+ ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree;
+ ProcVector[X_InstallColormap] = PanoramiXInstallColormap;
+ ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap;
+ ProcVector[X_AllocColor] = PanoramiXAllocColor;
+ ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor;
+ ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells;
+ ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes;
+ ProcVector[X_FreeColors] = PanoramiXFreeColors;
+ ProcVector[X_StoreColors] = PanoramiXStoreColors;
+ ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor;
+
+#ifdef RENDER
+ PanoramiXRenderInit ();
+#endif
+}
+
+extern Bool CreateConnectionBlock(void);
+
+Bool PanoramiXCreateConnectionBlock(void)
+{
+ int i, j, length;
+ Bool disableBackingStore = FALSE;
+ Bool disableSaveUnders = FALSE;
+ int old_width, old_height;
+ float width_mult, height_mult;
+ xWindowRoot *root;
+ xVisualType *visual;
+ xDepth *depth;
+ VisualPtr pVisual;
+ ScreenPtr pScreen;
+
+ /*
+ * Do normal CreateConnectionBlock but faking it for only one screen
+ */
+
+ if(!PanoramiXNumDepths) {
+ ErrorF("PanoramiX error: Incompatible screens. No common visuals\n");
+ return FALSE;
+ }
+
+ for(i = 1; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) {
+ ErrorF("PanoramiX error: Incompatible screens. Root window depths differ\n");
+ return FALSE;
+ }
+ if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport)
+ disableBackingStore = TRUE;
+ if(pScreen->saveUnderSupport != screenInfo.screens[0]->saveUnderSupport)
+ disableSaveUnders = TRUE;
+ }
+
+ if(disableBackingStore || disableSaveUnders) {
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(disableBackingStore)
+ pScreen->backingStoreSupport = NotUseful;
+ if(disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+ }
+ }
+
+ i = screenInfo.numScreens;
+ screenInfo.numScreens = 1;
+ if (!CreateConnectionBlock()) {
+ screenInfo.numScreens = i;
+ return FALSE;
+ }
+
+ screenInfo.numScreens = i;
+
+ root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart);
+ length = connBlockScreenStart + sizeof(xWindowRoot);
+
+ /* overwrite the connection block */
+ root->nDepths = PanoramiXNumDepths;
+
+ for (i = 0; i < PanoramiXNumDepths; i++) {
+ depth = (xDepth *) (ConnectionInfo + length);
+ depth->depth = PanoramiXDepths[i].depth;
+ depth->nVisuals = PanoramiXDepths[i].numVids;
+ length += sizeof(xDepth);
+ visual = (xVisualType *)(ConnectionInfo + length);
+
+ for (j = 0; j < depth->nVisuals; j++, visual++) {
+ visual->visualID = PanoramiXDepths[i].vids[j];
+
+ for (pVisual = PanoramiXVisuals;
+ pVisual->vid != visual->visualID;
+ pVisual++)
+ ;
+
+ visual->class = pVisual->class;
+ visual->bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual->colormapEntries = pVisual->ColormapEntries;
+ visual->redMask = pVisual->redMask;
+ visual->greenMask = pVisual->greenMask;
+ visual->blueMask = pVisual->blueMask;
+ }
+
+ length += (depth->nVisuals * sizeof(xVisualType));
+ }
+
+ connSetupPrefix.length = length >> 2;
+
+ free(PanoramiXVisuals);
+ for (i = 0; i < PanoramiXNumDepths; i++)
+ free(PanoramiXDepths[i].vids);
+ free(PanoramiXDepths);
+
+ /*
+ * OK, change some dimensions so it looks as if it were one big screen
+ */
+
+ old_width = root->pixWidth;
+ old_height = root->pixHeight;
+
+ root->pixWidth = PanoramiXPixWidth;
+ root->pixHeight = PanoramiXPixHeight;
+ width_mult = (1.0 * root->pixWidth) / old_width;
+ height_mult = (1.0 * root->pixHeight) / old_height;
+ root->mmWidth *= width_mult;
+ root->mmHeight *= height_mult;
+
+ while(ConnectionCallbackList) {
+ void *tmp;
+
+ tmp = (void *)ConnectionCallbackList;
+ (*ConnectionCallbackList->func)();
+ ConnectionCallbackList = ConnectionCallbackList->next;
+ free(tmp);
+ }
+
+ return TRUE;
+}
+
+extern
+void PanoramiXConsolidate(void)
+{
+ int i, j, k;
+ VisualPtr pVisual, pVisual2;
+ ScreenPtr pScreen, pScreen2;
+ DepthPtr pDepth, pDepth2;
+ PanoramiXRes *root, *defmap, *saver;
+ Bool foundDepth, missingDepth;
+
+ if(!PanoramiXVisualTable)
+ PanoramiXVisualTable = calloc(256 * MAXSCREENS, sizeof(XID));
+
+ pScreen = screenInfo.screens[0];
+ pVisual = pScreen->visuals;
+ pDepth = pScreen->allowedDepths;
+
+ PanoramiXNumDepths = 0;
+ PanoramiXDepths = calloc(pScreen->numDepths,sizeof(DepthRec));
+ PanoramiXNumVisuals = 0;
+ PanoramiXVisuals = calloc(pScreen->numVisuals,sizeof(VisualRec));
+
+ for (i = 0; i < pScreen->numDepths; i++, pDepth++) {
+ missingDepth = FALSE;
+ for (j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen2 = screenInfo.screens[j];
+ pDepth2 = pScreen2->allowedDepths;
+
+ foundDepth = FALSE;
+ for (k = 0; k < pScreen2->numDepths; k++, pDepth2++) {
+ if(pDepth2->depth == pDepth->depth) {
+ foundDepth = TRUE;
+ break;
+ }
+ }
+
+ if(!foundDepth) {
+ missingDepth = TRUE;
+ break;
+ }
+ }
+
+ if(!missingDepth) {
+ PanoramiXDepths[PanoramiXNumDepths].depth = pDepth->depth;
+ PanoramiXDepths[PanoramiXNumDepths].numVids = 0;
+ if(pDepth->numVids)
+ PanoramiXDepths[PanoramiXNumDepths].vids =
+ malloc(sizeof(VisualID) * pDepth->numVids);
+ else
+ PanoramiXDepths[PanoramiXNumDepths].vids = NULL;
+ PanoramiXNumDepths++;
+ }
+ }
+
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = pVisual->vid;
+
+ /* check if the visual exists on all screens */
+ for (j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen2 = screenInfo.screens[j];
+
+#ifdef GLXPROXY
+ pVisual2 = glxMatchVisual(pScreen, pVisual, pScreen2);
+ if (pVisual2) {
+ PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] =
+ pVisual2->vid;
+ continue;
+ } else if (glxMatchVisual(pScreen, pVisual, pScreen)) {
+ PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] = 0;
+ break;
+ }
+#endif
+ pVisual2 = pScreen2->visuals;
+
+ for (k = 0; k < pScreen2->numVisuals; k++, pVisual2++) {
+ if ((pVisual->class == pVisual2->class) &&
+ (pVisual->ColormapEntries == pVisual2->ColormapEntries) &&
+ (pVisual->nplanes == pVisual2->nplanes) &&
+ (pVisual->redMask == pVisual2->redMask) &&
+ (pVisual->greenMask == pVisual2->greenMask) &&
+ (pVisual->blueMask == pVisual2->blueMask) &&
+ (pVisual->offsetRed == pVisual2->offsetRed) &&
+ (pVisual->offsetGreen == pVisual2->offsetGreen) &&
+ (pVisual->offsetBlue == pVisual2->offsetBlue))
+ {
+ /* We merely assign the first visual that matches. OpenGL
+ will need to get involved at some point if you want
+ match GLX visuals */
+ PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] =
+ pVisual2->vid;
+ break;
+ }
+ }
+ }
+
+ /* if it doesn't exist on all screens we can't use it */
+ for (j = 0; j < PanoramiXNumScreens; j++) {
+ if (!PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j]) {
+ PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = 0;
+ break;
+ }
+ }
+
+ /* if it does, make sure it's in the list of supported depths and visuals */
+ if(PanoramiXVisualTable[pVisual->vid * MAXSCREENS]) {
+ PanoramiXVisuals[PanoramiXNumVisuals].vid = pVisual->vid;
+ PanoramiXVisuals[PanoramiXNumVisuals].class = pVisual->class;
+ PanoramiXVisuals[PanoramiXNumVisuals].bitsPerRGBValue = pVisual->bitsPerRGBValue;
+ PanoramiXVisuals[PanoramiXNumVisuals].ColormapEntries = pVisual->ColormapEntries;
+ PanoramiXVisuals[PanoramiXNumVisuals].nplanes = pVisual->nplanes;
+ PanoramiXVisuals[PanoramiXNumVisuals].redMask = pVisual->redMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].greenMask = pVisual->greenMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].blueMask = pVisual->blueMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetRed = pVisual->offsetRed;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetGreen = pVisual->offsetGreen;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetBlue = pVisual->offsetBlue;
+ PanoramiXNumVisuals++;
+
+ for (j = 0; j < PanoramiXNumDepths; j++) {
+ if (PanoramiXDepths[j].depth == pVisual->nplanes) {
+ PanoramiXDepths[j].vids[PanoramiXDepths[j].numVids] = pVisual->vid;
+ PanoramiXDepths[j].numVids++;
+ break;
+ }
+ }
+ }
+ }
+
+
+ root = (PanoramiXRes *) malloc(sizeof(PanoramiXRes));
+ root->type = XRT_WINDOW;
+ defmap = (PanoramiXRes *) malloc(sizeof(PanoramiXRes));
+ defmap->type = XRT_COLORMAP;
+ saver = (PanoramiXRes *) malloc(sizeof(PanoramiXRes));
+ saver->type = XRT_WINDOW;
+
+
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ root->info[i].id = screenInfo.screens[i]->root->drawable.id;
+ root->u.win.class = InputOutput;
+ root->u.win.root = TRUE;
+ saver->info[i].id = savedScreenInfo[i].wid;
+ saver->u.win.class = InputOutput;
+ saver->u.win.root = TRUE;
+ defmap->info[i].id = (screenInfo.screens[i])->defColormap;
+ }
+
+ AddResource(root->info[0].id, XRT_WINDOW, root);
+ AddResource(saver->info[0].id, XRT_WINDOW, saver);
+ AddResource(defmap->info[0].id, XRT_COLORMAP, defmap);
+}
+
+
+/*
+ * PanoramiXResetProc()
+ * Exit, deallocating as needed.
+ */
+
+static void PanoramiXResetProc(ExtensionEntry* extEntry)
+{
+ int i;
+
+#ifdef RENDER
+ PanoramiXRenderReset ();
+#endif
+ screenInfo.numScreens = PanoramiXNumScreens;
+ for (i = 256; i--; )
+ ProcVector[i] = SavedProcVector[i];
+
+ free(panoramiXdataPtr);
+}
+
+
+int
+ProcPanoramiXQueryVersion (ClientPtr client)
+{
+ /* REQUEST(xPanoramiXQueryVersionReq); */
+ xPanoramiXQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION;
+ rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcPanoramiXGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPanoramiXExtension;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl ((int* )&rep.state);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetStateReply), &rep);
+ return client->noClientException;
+
+}
+
+int
+ProcPanoramiXGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = PanoramiXNumScreens;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl ((int* )&rep.ScreenCount);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), &rep);
+ return client->noClientException;
+}
+
+int
+ProcPanoramiXGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ /* screen dimensions */
+ rep.width = panoramiXdataPtr[stuff->screen].width;
+ rep.height = panoramiXdataPtr[stuff->screen].height;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.width);
+ swapl (&rep.height);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), &rep);
+ return client->noClientException;
+}
+
+
+int
+ProcXineramaIsActive(ClientPtr client)
+{
+ /* REQUEST(xXineramaIsActiveReq); */
+ xXineramaIsActiveReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPanoramiXExtension;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.state);
+ }
+ WriteToClient (client, sizeof (xXineramaIsActiveReply), &rep);
+ return client->noClientException;
+}
+
+
+int
+ProcXineramaQueryScreens(ClientPtr client)
+{
+ /* REQUEST(xXineramaQueryScreensReq); */
+ xXineramaQueryScreensReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
+ rep.length = rep.number * sz_XineramaScreenInfo >> 2;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.number);
+ }
+ WriteToClient (client, sizeof (xXineramaQueryScreensReply), &rep);
+
+ if(!noPanoramiXExtension) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ scratch.x_org = panoramiXdataPtr[i].x;
+ scratch.y_org = panoramiXdataPtr[i].y;
+ scratch.width = panoramiXdataPtr[i].width;
+ scratch.height = panoramiXdataPtr[i].height;
+
+ if(client->swapped) {
+ swaps (&scratch.x_org);
+ swaps (&scratch.y_org);
+ swaps (&scratch.width);
+ swaps (&scratch.height);
+ }
+ WriteToClient (client, sz_XineramaScreenInfo, &scratch);
+ }
+ }
+
+ return client->noClientException;
+}
+
+
+static int
+ProcPanoramiXDispatch (ClientPtr client)
+{ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return ProcPanoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return ProcPanoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return ProcPanoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return ProcPanoramiXGetScreenSize(client);
+ case X_XineramaIsActive:
+ return ProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return ProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define SHIFT_L(v,s) (v) << (s)
+#define SHIFT_R(v,s) (v) >> (s)
+#else
+#define SHIFT_L(v,s) (v) >> (s)
+#define SHIFT_R(v,s) (v) << (s)
+#endif
+
+static void
+CopyBits(char *dst, int shiftL, char *src, int bytes)
+{
+ /* Just get it to work. Worry about speed later */
+ int shiftR = 8 - shiftL;
+
+ while(bytes--) {
+ *dst |= SHIFT_L(*src, shiftL);
+ *(dst + 1) |= SHIFT_R(*src, shiftR);
+ dst++; src++;
+ }
+}
+
+
+/* Caution. This doesn't support 2 and 4 bpp formats. We expect
+ 1 bpp and planar data to be already cleared when presented
+ to this function */
+
+void
+XineramaGetImageData(
+ DrawablePtr *pDrawables,
+ int left,
+ int top,
+ int width,
+ int height,
+ unsigned int format,
+ unsigned long planemask,
+ char *data,
+ int pitch,
+ Bool isRoot
+){
+ RegionRec SrcRegion, GrabRegion;
+ BoxRec SrcBox, *pbox;
+ int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth;
+ DrawablePtr pDraw = pDrawables[0];
+ char *ScratchMem = NULL;
+
+ size = 0;
+
+ /* find box in logical screen space */
+ SrcBox.x1 = left;
+ SrcBox.y1 = top;
+ if(!isRoot) {
+ SrcBox.x1 += pDraw->x + panoramiXdataPtr[0].x;
+ SrcBox.y1 += pDraw->y + panoramiXdataPtr[0].y;
+ }
+ SrcBox.x2 = SrcBox.x1 + width;
+ SrcBox.y2 = SrcBox.y1 + height;
+
+ RegionInit(&SrcRegion, &SrcBox, 1);
+ RegionNull(&GrabRegion);
+
+ depth = (format == XYPixmap) ? 1 : pDraw->depth;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ pDraw = pDrawables[i];
+
+ inOut = RegionContainsRect(&XineramaScreenRegions[i],&SrcBox);
+
+ if(inOut == rgnIN) {
+ (*pDraw->pScreen->GetImage)(pDraw,
+ SrcBox.x1 - pDraw->x - panoramiXdataPtr[i].x,
+ SrcBox.y1 - pDraw->y - panoramiXdataPtr[i].y,
+ width, height, format, planemask, data);
+ break;
+ } else if (inOut == rgnOUT)
+ continue;
+
+ RegionIntersect(&GrabRegion, &SrcRegion,
+ &XineramaScreenRegions[i]);
+
+ nbox = RegionNumRects(&GrabRegion);
+
+ if(nbox) {
+ pbox = RegionRects(&GrabRegion);
+
+ while(nbox--) {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ ScratchPitch = PixmapBytePad(w, depth);
+ sizeNeeded = ScratchPitch * h;
+
+ if(sizeNeeded > size) {
+ char *tmpdata = ScratchMem;
+ ScratchMem = realloc(ScratchMem, sizeNeeded);
+ if(ScratchMem)
+ size = sizeNeeded;
+ else {
+ ScratchMem = tmpdata;
+ break;
+ }
+ }
+
+ x = pbox->x1 - pDraw->x - panoramiXdataPtr[i].x;
+ y = pbox->y1 - pDraw->y - panoramiXdataPtr[i].y;
+
+ (*pDraw->pScreen->GetImage)(pDraw, x, y, w, h,
+ format, planemask, ScratchMem);
+
+ /* copy the memory over */
+
+ if(depth == 1) {
+ int k, shift, leftover, index, index2;
+
+ x = pbox->x1 - SrcBox.x1;
+ y = pbox->y1 - SrcBox.y1;
+ shift = x & 7;
+ x >>= 3;
+ leftover = w & 7;
+ w >>= 3;
+
+ /* clean up the edge */
+ if(leftover) {
+ int mask = (1 << leftover) - 1;
+ for(j = h, k = w; j--; k += ScratchPitch)
+ ScratchMem[k] &= mask;
+ }
+
+ for(j = 0, index = (pitch * y) + x, index2 = 0; j < h;
+ j++, index += pitch, index2 += ScratchPitch)
+ {
+ if(w) {
+ if(!shift)
+ memcpy(data + index, ScratchMem + index2, w);
+ else
+ CopyBits(data + index, shift,
+ ScratchMem + index2, w);
+ }
+
+ if(leftover) {
+ data[index + w] |=
+ SHIFT_L(ScratchMem[index2 + w], shift);
+ if((shift + leftover) > 8)
+ data[index + w + 1] |=
+ SHIFT_R(ScratchMem[index2 + w],(8 - shift));
+ }
+ }
+ } else {
+ j = BitsPerPixel(depth) >> 3;
+ x = (pbox->x1 - SrcBox.x1) * j;
+ y = pbox->y1 - SrcBox.y1;
+ w *= j;
+
+ for(j = 0; j < h; j++) {
+ memcpy(data + (pitch * (y + j)) + x,
+ ScratchMem + (ScratchPitch * j), w);
+ }
+ }
+ pbox++;
+ }
+
+ RegionSubtract(&SrcRegion, &SrcRegion, &GrabRegion);
+ if(!RegionNotEmpty(&SrcRegion))
+ break;
+ }
+
+ }
+
+ if(ScratchMem)
+ free(ScratchMem);
+
+ RegionUninit(&SrcRegion);
+ RegionUninit(&GrabRegion);
+}
diff --git a/nx-X11/programs/Xserver/Xext/panoramiX.h b/nx-X11/programs/Xserver/Xext/panoramiX.h
new file mode 100644
index 000000000..210ba2751
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiX.h
@@ -0,0 +1,113 @@
+/* $TOG: panoramiX.h /main/4 1998/03/17 06:51:02 kaleb $ */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
+
+/*
+ * PanoramiX definitions
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PANORAMIX_H_
+#define _PANORAMIX_H_
+
+#include <nx-X11/extensions/panoramiXext.h>
+/*#include "gcstruct.h"*/
+
+
+typedef struct _PanoramiXData {
+ int x;
+ int y;
+ int width;
+ int height;
+} PanoramiXData;
+
+typedef struct _PanoramiXInfo {
+ XID id ;
+} PanoramiXInfo;
+
+typedef struct {
+ PanoramiXInfo info[MAXSCREENS];
+ RESTYPE type;
+ union {
+ struct {
+ char visibility;
+ char class;
+ char root;
+ } win;
+ struct {
+ Bool shared;
+ } pix;
+#ifdef RENDER
+ struct {
+ Bool root;
+ } pict;
+#endif
+ char raw_data[4];
+ } u;
+} PanoramiXRes;
+
+#define FOR_NSCREENS_FORWARD(j) for(j = 0; j < PanoramiXNumScreens; j++)
+#define FOR_NSCREENS_BACKWARD(j) for(j = PanoramiXNumScreens - 1; j >= 0; j--)
+#define FOR_NSCREENS(j) FOR_NSCREENS_FORWARD(j)
+
+#define BREAK_IF(a) if ((a)) break
+#define IF_RETURN(a,b) if ((a)) return (b)
+
+#define FORCE_ROOT(a) { \
+ int _j; \
+ for (_j = PanoramiXNumScreens - 1; _j; _j--) \
+ if ((a).root == screenInfo.screens[_j]->root->drawable.id) \
+ break; \
+ (a).rootX += panoramiXdataPtr[_j].x; \
+ (a).rootY += panoramiXdataPtr[_j].y; \
+ (a).root = screenInfo.screens[0]->root->drawable.id; \
+}
+
+#define FORCE_WIN(a) { \
+ if ((win = PanoramiXFindIDOnAnyScreen(XRT_WINDOW, a))) { \
+ (a) = win->info[0].id; /* Real ID */ \
+ } \
+}
+
+#define FORCE_CMAP(a) { \
+ if ((win = PanoramiXFindIDOnAnyScreen(XRT_COLORMAP, a))) { \
+ (a) = win->info[0].id; /* Real ID */ \
+ } \
+}
+
+#define IS_SHARED_PIXMAP(r) (((r)->type == XRT_PIXMAP) && (r)->u.pix.shared)
+
+#define SKIP_FAKE_WINDOW(a) if(!LookupIDByType(a, XRT_WINDOW)) return
+
+#endif /* _PANORAMIX_H_ */
diff --git a/nx-X11/programs/Xserver/Xext/panoramiXSwap.c b/nx-X11/programs/Xserver/Xext/panoramiXSwap.c
new file mode 100644
index 000000000..218d83d72
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiXSwap.c
@@ -0,0 +1,136 @@
+/*****************************************************************
+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.
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "gc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#if 0
+#include <sys/workstation.h>
+#include <nx-X11/Xserver/ws.h>
+#endif
+#include "panoramiX.h"
+#include <nx-X11/extensions/panoramiXproto.h>
+#include "panoramiXsrv.h"
+#include "globals.h"
+#include "panoramiXh.h"
+
+static int
+SProcPanoramiXQueryVersion (ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return ProcPanoramiXQueryVersion(client);
+}
+
+static int
+SProcPanoramiXGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ return ProcPanoramiXGetState(client);
+}
+
+static int
+SProcPanoramiXGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return ProcPanoramiXGetScreenCount(client);
+}
+
+static int
+SProcPanoramiXGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return ProcPanoramiXGetScreenSize(client);
+}
+
+
+static int
+SProcXineramaIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return ProcXineramaIsActive(client);
+}
+
+
+static int
+SProcXineramaQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return ProcXineramaQueryScreens(client);
+}
+
+
+int
+SProcPanoramiXDispatch (ClientPtr client)
+{ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return SProcPanoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SProcPanoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SProcPanoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SProcPanoramiXGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return SProcXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
diff --git a/nx-X11/programs/Xserver/Xext/panoramiXh.h b/nx-X11/programs/Xserver/Xext/panoramiXh.h
new file mode 100644
index 000000000..6cee650ac
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiXh.h
@@ -0,0 +1,77 @@
+
+/*
+ * Server dispatcher function replacements
+ */
+
+extern int PanoramiXCreateWindow(ClientPtr client);
+extern int PanoramiXChangeWindowAttributes(ClientPtr client);
+extern int PanoramiXDestroyWindow(ClientPtr client);
+extern int PanoramiXDestroySubwindows(ClientPtr client);
+extern int PanoramiXChangeSaveSet(ClientPtr client);
+extern int PanoramiXReparentWindow(ClientPtr client);
+extern int PanoramiXMapWindow(ClientPtr client);
+extern int PanoramiXMapSubwindows(ClientPtr client);
+extern int PanoramiXUnmapWindow(ClientPtr client);
+extern int PanoramiXUnmapSubwindows(ClientPtr client);
+extern int PanoramiXConfigureWindow(ClientPtr client);
+extern int PanoramiXCirculateWindow(ClientPtr client);
+extern int PanoramiXGetGeometry(ClientPtr client);
+extern int PanoramiXTranslateCoords(ClientPtr client);
+extern int PanoramiXCreatePixmap(ClientPtr client);
+extern int PanoramiXFreePixmap(ClientPtr client);
+extern int PanoramiXCreateGC(ClientPtr client);
+extern int PanoramiXChangeGC(ClientPtr client);
+extern int PanoramiXCopyGC(ClientPtr client);
+extern int PanoramiXCopyColormapAndFree(ClientPtr client);
+extern int PanoramiXSetDashes(ClientPtr client);
+extern int PanoramiXSetClipRectangles(ClientPtr client);
+extern int PanoramiXFreeGC(ClientPtr client);
+extern int PanoramiXClearToBackground(ClientPtr client);
+extern int PanoramiXCopyArea(ClientPtr client);
+extern int PanoramiXCopyPlane(ClientPtr client);
+extern int PanoramiXPolyPoint(ClientPtr client);
+extern int PanoramiXPolyLine(ClientPtr client);
+extern int PanoramiXPolySegment(ClientPtr client);
+extern int PanoramiXPolyRectangle(ClientPtr client);
+extern int PanoramiXPolyArc(ClientPtr client);
+extern int PanoramiXFillPoly(ClientPtr client);
+extern int PanoramiXPolyFillArc(ClientPtr client);
+extern int PanoramiXPolyFillRectangle(ClientPtr client);
+extern int PanoramiXPutImage(ClientPtr client);
+extern int PanoramiXGetImage(ClientPtr client);
+extern int PanoramiXPolyText8(ClientPtr client);
+extern int PanoramiXPolyText16(ClientPtr client);
+extern int PanoramiXImageText8(ClientPtr client);
+extern int PanoramiXImageText16(ClientPtr client);
+extern int PanoramiXCreateColormap(ClientPtr client);
+extern int PanoramiXFreeColormap(ClientPtr client);
+extern int PanoramiXInstallColormap(ClientPtr client);
+extern int PanoramiXUninstallColormap(ClientPtr client);
+extern int PanoramiXAllocColor(ClientPtr client);
+extern int PanoramiXAllocNamedColor(ClientPtr client);
+extern int PanoramiXAllocColorCells(ClientPtr client);
+extern int PanoramiXStoreNamedColor(ClientPtr client);
+extern int PanoramiXFreeColors(ClientPtr client);
+extern int PanoramiXStoreColors(ClientPtr client);
+extern int PanoramiXAllocColorPlanes(ClientPtr client);
+
+#define PROC_EXTERN(pfunc) extern int pfunc(ClientPtr)
+
+PROC_EXTERN(ProcPanoramiXQueryVersion);
+PROC_EXTERN(ProcPanoramiXGetState);
+PROC_EXTERN(ProcPanoramiXGetScreenCount);
+PROC_EXTERN(ProcPanoramiXGetScreenSize);
+
+PROC_EXTERN(ProcXineramaQueryScreens);
+PROC_EXTERN(ProcXineramaIsActive);
+extern Bool XineramaCreateGC(GCPtr pGC);
+
+extern int SProcPanoramiXDispatch(ClientPtr client);
+
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+extern xConnSetupPrefix connSetupPrefix;
+
+extern ScreenInfo *GlobalScrInfo;
+extern int (* SavedProcVector[256]) (ClientPtr client);
+
diff --git a/nx-X11/programs/Xserver/Xext/panoramiXprocs.c b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c
new file mode 100644
index 000000000..93626bbeb
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiXprocs.c
@@ -0,0 +1,2368 @@
+/*****************************************************************
+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.
+******************************************************************/
+
+/* Massively rewritten by Mark Vojkovich <markv@valinux.com> */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "inputstr.h"
+#include "migc.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#include "resource.h"
+#include "panoramiXh.h"
+
+#define XINERAMA_IMAGE_BUFSIZE (256*1024)
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#if 0
+extern void (* EventSwapVector[128]) (fsError *, fsError *);
+
+extern void Swap32Write();
+extern void SLHostsExtend();
+extern void SQColorsExtend();
+WriteSConnectionInfo();
+extern void WriteSConnSetupPrefix();
+#endif
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+extern XID clientErrorValue; /* XXX this is a kludge */
+
+int PanoramiXCreateWindow(ClientPtr client)
+{
+ PanoramiXRes *parent, *newWin;
+ PanoramiXRes *backPix = NULL;
+ PanoramiXRes *bordPix = NULL;
+ PanoramiXRes *cmap = NULL;
+ REQUEST(xCreateWindowReq);
+ int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
+ int result = 0, len, j;
+ int orig_x, orig_y;
+ XID orig_visual, tmp;
+ Bool parentIsRoot;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ if (!(parent = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->parent, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if(stuff->class == CopyFromParent)
+ stuff->class = parent->u.win.class;
+
+ if((stuff->class == InputOnly) && (stuff->mask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ if ((Mask)stuff->mask & CWBackPixmap) {
+ pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pback_offset);
+ if ((tmp != None) && (tmp != ParentRelative)) {
+ if(!(backPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & CWBorderPixmap) {
+ pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (tmp != CopyFromParent) {
+ if(!(bordPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & CWColormap) {
+ cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+ if ((tmp != CopyFromParent) && (tmp != None)) {
+ if(!(cmap = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_COLORMAP, DixReadAccess)))
+ return BadColor;
+ }
+ }
+
+ if(!(newWin = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newWin->type = XRT_WINDOW;
+ newWin->u.win.visibility = VisibilityNotViewable;
+ newWin->u.win.class = stuff->class;
+ newWin->u.win.root = FALSE;
+ newWin->info[0].id = stuff->wid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newWin->info[j].id = FakeClientID(client->index);
+
+ if (stuff->class == InputOnly)
+ stuff->visual = CopyFromParent;
+ orig_visual = stuff->visual;
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
+ (stuff->parent == savedScreenInfo[0].wid);
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->wid = newWin->info[j].id;
+ stuff->parent = parent->info[j].id;
+ if (parentIsRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ if (backPix)
+ *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
+ if (bordPix)
+ *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
+ if (cmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
+ if ( orig_visual != CopyFromParent )
+ stuff->visual = PanoramiXVisualTable[(orig_visual*MAXSCREENS) + j];
+ result = (*SavedProcVector[X_CreateWindow])(client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newWin->info[0].id, XRT_WINDOW, newWin);
+ else
+ free(newWin);
+
+ return (result);
+}
+
+
+int PanoramiXChangeWindowAttributes(ClientPtr client)
+{
+ PanoramiXRes *win;
+ PanoramiXRes *backPix = NULL;
+ PanoramiXRes *bordPix = NULL;
+ PanoramiXRes *cmap = NULL;
+ REQUEST(xChangeWindowAttributesReq);
+ int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
+ int result = 0, len, j;
+ XID tmp;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (Ones(stuff->valueMask) != len)
+ return BadLength;
+
+ if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if((win->u.win.class == InputOnly) &&
+ (stuff->valueMask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ if ((Mask)stuff->valueMask & CWBackPixmap) {
+ pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pback_offset);
+ if ((tmp != None) && (tmp != ParentRelative)) {
+ if(!(backPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->valueMask & CWBorderPixmap) {
+ pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (tmp != CopyFromParent) {
+ if(!(bordPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->valueMask & CWColormap) {
+ cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+ if ((tmp != CopyFromParent) && (tmp != None)) {
+ if(!(cmap = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_COLORMAP, DixReadAccess)))
+ return BadColor;
+ }
+ }
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->window = win->info[j].id;
+ if (backPix)
+ *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[j].id;
+ if (bordPix)
+ *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[j].id;
+ if (cmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[j].id;
+ result = (*SavedProcVector[X_ChangeWindowAttributes])(client);
+ }
+
+ return (result);
+}
+
+
+int PanoramiXDestroyWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixDestroyAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_DestroyWindow])(client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcDestroyWindow is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+
+int PanoramiXDestroySubwindows(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixDestroyAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_DestroySubwindows])(client);
+ if(result != Success) break;
+ }
+
+ /* DestroySubwindows is using FreeResource which will free
+ our resources for us on the last pass through the loop above */
+
+ return (result);
+}
+
+
+int PanoramiXChangeSaveSet(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xChangeSaveSetReq);
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->window = win->info[j].id;
+ result = (*SavedProcVector[X_ChangeSaveSet])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXReparentWindow(ClientPtr client)
+{
+ PanoramiXRes *win, *parent;
+ int result = 0, j;
+ int x, y;
+ Bool parentIsRoot;
+ REQUEST(xReparentWindowReq);
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if(!(parent = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->parent, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ x = stuff->x;
+ y = stuff->y;
+ parentIsRoot = (stuff->parent == screenInfo.screens[0]->root->drawable.id) ||
+ (stuff->parent == savedScreenInfo[0].wid);
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->window = win->info[j].id;
+ stuff->parent = parent->info[j].id;
+ if(parentIsRoot) {
+ stuff->x = x - panoramiXdataPtr[j].x;
+ stuff->y = y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_ReparentWindow])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXMapWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_MapWindow])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXMapSubwindows(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_MapSubwindows])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXUnmapWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_UnmapWindow])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXUnmapSubwindows(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->id = win->info[j].id;
+ result = (*SavedProcVector[X_UnmapSubwindows])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXConfigureWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ PanoramiXRes *sib = NULL;
+ WindowPtr pWin;
+ int result = 0, j, len, sib_offset = 0, x = 0, y = 0;
+ int x_offset = -1;
+ int y_offset = -1;
+ REQUEST(xConfigureWindowReq);
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ /* because we need the parent */
+ if (!(pWin = (WindowPtr)SecurityLookupIDByType(
+ client, stuff->window, RT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if (!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if ((Mask)stuff->mask & CWSibling) {
+ XID tmp;
+ sib_offset = Ones((Mask)stuff->mask & (CWSibling - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + sib_offset))) {
+ if(!(sib = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+ }
+ }
+
+ if(pWin->parent && ((pWin->parent == screenInfo.screens[0]->root) ||
+ (pWin->parent->drawable.id == savedScreenInfo[0].wid)))
+ {
+ if ((Mask)stuff->mask & CWX) {
+ x_offset = 0;
+ x = *((CARD32 *)&stuff[1]);
+ }
+ if ((Mask)stuff->mask & CWY) {
+ y_offset = (x_offset == -1) ? 0 : 1;
+ y = *((CARD32 *) &stuff[1] + y_offset);
+ }
+ }
+
+ /* have to go forward or you get expose events before
+ ConfigureNotify events */
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ if(sib)
+ *((CARD32 *) &stuff[1] + sib_offset) = sib->info[j].id;
+ if(x_offset >= 0)
+ *((CARD32 *) &stuff[1] + x_offset) = x - panoramiXdataPtr[j].x;
+ if(y_offset >= 0)
+ *((CARD32 *) &stuff[1] + y_offset) = y - panoramiXdataPtr[j].y;
+ result = (*SavedProcVector[X_ConfigureWindow])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXCirculateWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ result = (*SavedProcVector[X_CirculateWindow])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXGetGeometry(ClientPtr client)
+{
+ xGetGeometryReply rep;
+ DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ VERIFY_GEOMETRABLE (pDraw, stuff->id, client);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.root = screenInfo.screens[0]->root->drawable.id;
+ rep.depth = pDraw->depth;
+ rep.width = pDraw->width;
+ rep.height = pDraw->height;
+ rep.x = rep.y = rep.borderWidth = 0;
+
+ if (stuff->id == rep.root) {
+ xWindowRoot *root = (xWindowRoot *)
+ (ConnectionInfo + connBlockScreenStart);
+
+ rep.width = root->pixWidth;
+ rep.height = root->pixHeight;
+ } else
+ if ((pDraw->type == UNDRAWABLE_WINDOW) || (pDraw->type == DRAWABLE_WINDOW))
+ {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ rep.x = pWin->origin.x - wBorderWidth (pWin);
+ rep.y = pWin->origin.y - wBorderWidth (pWin);
+ if((pWin->parent == screenInfo.screens[0]->root) ||
+ (pWin->parent->drawable.id == savedScreenInfo[0].wid))
+ {
+ rep.x += panoramiXdataPtr[0].x;
+ rep.y += panoramiXdataPtr[0].y;
+ }
+ rep.borderWidth = pWin->borderWidth;
+ }
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return (client->noClientException);
+}
+
+int PanoramiXTranslateCoords(ClientPtr client)
+{
+ INT16 x, y;
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ DixReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+
+ if((pWin == screenInfo.screens[0]->root) ||
+ (pWin->drawable.id == savedScreenInfo[0].wid))
+ {
+ x = stuff->srcX - panoramiXdataPtr[0].x;
+ y = stuff->srcY - panoramiXdataPtr[0].y;
+ } else {
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ }
+ pWin = pDst->firstChild;
+ while (pWin) {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ RegionContainsPoint(
+ wBoundingShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ if((pDst == screenInfo.screens[0]->root) ||
+ (pDst->drawable.id == savedScreenInfo[0].wid))
+ {
+ rep.dstX += panoramiXdataPtr[0].x;
+ rep.dstY += panoramiXdataPtr[0].y;
+ }
+
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int PanoramiXCreatePixmap(ClientPtr client)
+{
+ PanoramiXRes *refDraw, *newPix;
+ int result = 0, j;
+ REQUEST(xCreatePixmapReq);
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+
+ if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixReadAccess)))
+ return BadDrawable;
+
+ if(!(newPix = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newPix->type = XRT_PIXMAP;
+ newPix->u.pix.shared = FALSE;
+ newPix->info[0].id = stuff->pid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPix->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->pid = newPix->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ result = (*SavedProcVector[X_CreatePixmap])(client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newPix->info[0].id, XRT_PIXMAP, newPix);
+ else
+ free(newPix);
+
+ return (result);
+}
+
+
+int PanoramiXFreePixmap(ClientPtr client)
+{
+ PanoramiXRes *pix;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ client->errorValue = stuff->id;
+
+ if(!(pix = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_PIXMAP, DixDestroyAccess)))
+ return BadPixmap;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = pix->info[j].id;
+ result = (*SavedProcVector[X_FreePixmap])(client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcFreePixmap is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+
+int PanoramiXCreateGC(ClientPtr client)
+{
+ PanoramiXRes *refDraw;
+ PanoramiXRes *newGC;
+ PanoramiXRes *stip = NULL;
+ PanoramiXRes *tile = NULL;
+ PanoramiXRes *clip = NULL;
+ REQUEST(xCreateGCReq);
+ int tile_offset = 0, stip_offset = 0, clip_offset = 0;
+ int result = 0, len, j;
+ XID tmp;
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+
+ client->errorValue = stuff->gc;
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ if (!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixReadAccess)))
+ return BadDrawable;
+
+ if ((Mask)stuff->mask & GCTile) {
+ tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
+ if(!(tile = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & GCStipple) {
+ stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
+ if(!(stip = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & GCClipMask) {
+ clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
+ if(!(clip = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+
+ if(!(newGC = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newGC->type = XRT_GC;
+ newGC->info[0].id = stuff->gc;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newGC->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->gc = newGC->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ if (tile)
+ *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
+ if (stip)
+ *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
+ if (clip)
+ *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
+ result = (*SavedProcVector[X_CreateGC])(client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newGC->info[0].id, XRT_GC, newGC);
+ else
+ free(newGC);
+
+ return (result);
+}
+
+int PanoramiXChangeGC(ClientPtr client)
+{
+ PanoramiXRes *gc;
+ PanoramiXRes *stip = NULL;
+ PanoramiXRes *tile = NULL;
+ PanoramiXRes *clip = NULL;
+ REQUEST(xChangeGCReq);
+ int tile_offset = 0, stip_offset = 0, clip_offset = 0;
+ int result = 0, len, j;
+ XID tmp;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ if (!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if ((Mask)stuff->mask & GCTile) {
+ tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + tile_offset))) {
+ if(!(tile = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & GCStipple) {
+ stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + stip_offset))) {
+ if(!(stip = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+ if ((Mask)stuff->mask & GCClipMask) {
+ clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
+ if ((tmp = *((CARD32 *) &stuff[1] + clip_offset))) {
+ if(!(clip = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->gc = gc->info[j].id;
+ if (tile)
+ *((CARD32 *) &stuff[1] + tile_offset) = tile->info[j].id;
+ if (stip)
+ *((CARD32 *) &stuff[1] + stip_offset) = stip->info[j].id;
+ if (clip)
+ *((CARD32 *) &stuff[1] + clip_offset) = clip->info[j].id;
+ result = (*SavedProcVector[X_ChangeGC])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXCopyGC(ClientPtr client)
+{
+ PanoramiXRes *srcGC, *dstGC;
+ int result = 0, j;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+
+ if(!(srcGC = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->srcGC, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if(!(dstGC = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->dstGC, XRT_GC, DixWriteAccess)))
+ return BadGC;
+
+ FOR_NSCREENS(j) {
+ stuff->srcGC = srcGC->info[j].id;
+ stuff->dstGC = dstGC->info[j].id;
+ result = (*SavedProcVector[X_CopyGC])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXSetDashes(ClientPtr client)
+{
+ PanoramiXRes *gc;
+ int result = 0, j;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixWriteAccess)))
+ return BadGC;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->gc = gc->info[j].id;
+ result = (*SavedProcVector[X_SetDashes])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXSetClipRectangles(ClientPtr client)
+{
+ PanoramiXRes *gc;
+ int result = 0, j;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixWriteAccess)))
+ return BadGC;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->gc = gc->info[j].id;
+ result = (*SavedProcVector[X_SetClipRectangles])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXFreeGC(ClientPtr client)
+{
+ PanoramiXRes *gc;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_GC, DixDestroyAccess)))
+ return BadGC;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = gc->info[j].id;
+ result = (*SavedProcVector[X_FreeGC])(client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcFreeGC is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+
+int PanoramiXClearToBackground(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int result = 0, j, x, y;
+ Bool isRoot;
+ REQUEST(xClearAreaReq);
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ x = stuff->x;
+ y = stuff->y;
+ isRoot = win->u.win.root;
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->window = win->info[j].id;
+ if(isRoot) {
+ stuff->x = x - panoramiXdataPtr[j].x;
+ stuff->y = y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_ClearArea])(client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+
+/*
+ For Window to Pixmap copies you're screwed since each screen's
+ pixmap will look like what it sees on its screen. Unless the
+ screens overlap and the window lies on each, the two copies
+ will be out of sync. To remedy this we do a GetImage and PutImage
+ in place of the copy. Doing this as a single Image isn't quite
+ correct since it will include the obscured areas but we will
+ have to fix this later. (MArk).
+*/
+
+int PanoramiXCopyArea(ClientPtr client)
+{
+ int j, result = 0, srcx, srcy, dstx, dsty;
+ PanoramiXRes *gc, *src, *dst;
+ Bool srcIsRoot = FALSE;
+ Bool dstIsRoot = FALSE;
+ Bool srcShared, dstShared;
+ REQUEST(xCopyAreaReq);
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ if(!(src = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->srcDrawable, XRC_DRAWABLE, DixReadAccess)))
+ return BadDrawable;
+
+ srcShared = IS_SHARED_PIXMAP(src);
+
+ if(!(dst = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->dstDrawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ dstShared = IS_SHARED_PIXMAP(dst);
+
+ if(dstShared && srcShared)
+ return (* SavedProcVector[X_CopyArea])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if((dst->type == XRT_WINDOW) && dst->u.win.root)
+ dstIsRoot = TRUE;
+ if((src->type == XRT_WINDOW) && src->u.win.root)
+ srcIsRoot = TRUE;
+
+ srcx = stuff->srcX; srcy = stuff->srcY;
+ dstx = stuff->dstX; dsty = stuff->dstY;
+ if((dst->type == XRT_PIXMAP) && (src->type == XRT_WINDOW)) {
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDst;
+ GCPtr pGC;
+ char *data;
+ int pitch;
+
+ FOR_NSCREENS(j)
+ VERIFY_DRAWABLE(drawables[j], src->info[j].id, client);
+
+ pitch = PixmapBytePad(stuff->width, drawables[0]->depth);
+ if(!(data = calloc(1, stuff->height * pitch)))
+ return BadAlloc;
+
+ XineramaGetImageData(drawables, srcx, srcy,
+ stuff->width, stuff->height, ZPixmap, ~0, data, pitch,
+ srcIsRoot);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->gc = gc->info[j].id;
+ VALIDATE_DRAWABLE_AND_GC(dst->info[j].id, pDst, pGC, client);
+
+ if(drawables[0]->depth != pDst->depth) {
+ client->errorValue = stuff->dstDrawable;
+ free(data);
+ return (BadMatch);
+ }
+
+ (*pGC->ops->PutImage) (pDst, pGC, pDst->depth, dstx, dsty,
+ stuff->width, stuff->height,
+ 0, ZPixmap, data);
+
+ if(dstShared) break;
+ }
+
+ free(data);
+
+ result = Success;
+ } else {
+ DrawablePtr pDst = NULL, pSrc = NULL;
+ GCPtr pGC = NULL;
+ RegionPtr pRgn[MAXSCREENS];
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->dstDrawable = dst->info[j].id;
+ stuff->srcDrawable = src->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (srcIsRoot) {
+ stuff->srcX = srcx - panoramiXdataPtr[j].x;
+ stuff->srcY = srcy - panoramiXdataPtr[j].y;
+ }
+ if (dstIsRoot) {
+ stuff->dstX = dstx - panoramiXdataPtr[j].x;
+ stuff->dstY = dsty - panoramiXdataPtr[j].y;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable) {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ DixReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) ||
+ (pDst->depth != pSrc->depth)) {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ } else
+ pSrc = pDst;
+
+ pRgn[j] = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
+ stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+
+ if(dstShared) {
+ while(j--) pRgn[j] = NULL;
+ break;
+ }
+ }
+
+ if(pGC->graphicsExposures) {
+ ScreenPtr pScreen = pDst->pScreen;
+ RegionRec totalReg;
+ Bool overlap;
+
+ RegionNull(&totalReg);
+ FOR_NSCREENS_BACKWARD(j) {
+ if(pRgn[j]) {
+ if(srcIsRoot) {
+ RegionTranslate(pRgn[j],
+ panoramiXdataPtr[j].x, panoramiXdataPtr[j].y);
+ }
+ RegionAppend(&totalReg, pRgn[j]);
+ RegionDestroy(pRgn[j]);
+ }
+ }
+ RegionValidate(&totalReg, &overlap);
+ (*pScreen->SendGraphicsExpose)(
+ client, &totalReg, stuff->dstDrawable, X_CopyArea, 0);
+ RegionUninit(&totalReg);
+ }
+
+ result = client->noClientException;
+ }
+
+ return (result);
+}
+
+
+int PanoramiXCopyPlane(ClientPtr client)
+{
+ int j, srcx, srcy, dstx, dsty;
+ PanoramiXRes *gc, *src, *dst;
+ Bool srcIsRoot = FALSE;
+ Bool dstIsRoot = FALSE;
+ Bool srcShared, dstShared;
+ DrawablePtr psrcDraw, pdstDraw = NULL;
+ GCPtr pGC = NULL;
+ RegionPtr pRgn[MAXSCREENS];
+ REQUEST(xCopyPlaneReq);
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ if(!(src = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->srcDrawable, XRC_DRAWABLE, DixReadAccess)))
+ return BadDrawable;
+
+ srcShared = IS_SHARED_PIXMAP(src);
+
+ if(!(dst = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->dstDrawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ dstShared = IS_SHARED_PIXMAP(dst);
+
+ if(dstShared && srcShared)
+ return (* SavedProcVector[X_CopyPlane])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if((dst->type == XRT_WINDOW) && dst->u.win.root)
+ dstIsRoot = TRUE;
+ if((src->type == XRT_WINDOW) && src->u.win.root)
+ srcIsRoot = TRUE;
+
+ srcx = stuff->srcX; srcy = stuff->srcY;
+ dstx = stuff->dstX; dsty = stuff->dstY;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->dstDrawable = dst->info[j].id;
+ stuff->srcDrawable = src->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (srcIsRoot) {
+ stuff->srcX = srcx - panoramiXdataPtr[j].x;
+ stuff->srcY = srcy - panoramiXdataPtr[j].y;
+ }
+ if (dstIsRoot) {
+ stuff->dstX = dstx - panoramiXdataPtr[j].x;
+ stuff->dstY = dsty - panoramiXdataPtr[j].y;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable) {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ DixReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen) {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ } else
+ psrcDraw = pdstDraw;
+
+ if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+ (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
+ client->errorValue = stuff->bitPlane;
+ return(BadValue);
+ }
+
+ pRgn[j] = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC,
+ stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY, stuff->bitPlane);
+
+ if(dstShared) {
+ while(j--) pRgn[j] = NULL;
+ break;
+ }
+ }
+
+ if(pGC->graphicsExposures) {
+ ScreenPtr pScreen = pdstDraw->pScreen;
+ RegionRec totalReg;
+ Bool overlap;
+
+ RegionNull(&totalReg);
+ FOR_NSCREENS_BACKWARD(j) {
+ if(pRgn[j]) {
+ RegionAppend(&totalReg, pRgn[j]);
+ RegionDestroy(pRgn[j]);
+ }
+ }
+ RegionValidate(&totalReg, &overlap);
+ (*pScreen->SendGraphicsExpose)(
+ client, &totalReg, stuff->dstDrawable, X_CopyPlane, 0);
+ RegionUninit(&totalReg);
+ }
+
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyPoint(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ int result = 0, npoint, j;
+ xPoint *origPts;
+ Bool isRoot;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyPoint])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint > 0) {
+ origPts = (xPoint *) malloc(npoint * sizeof(xPoint));
+ memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPoint *pnts = (xPoint*)&stuff[1];
+ int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
+
+ while(i--) {
+ pnts->x -= x_off;
+ pnts->y -= y_off;
+ pnts++;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyPoint])(client);
+ if(result != Success) break;
+ }
+ free(origPts);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyLine(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ int result = 0, npoint, j;
+ xPoint *origPts;
+ Bool isRoot;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyLine])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 0){
+ origPts = (xPoint *) malloc(npoint * sizeof(xPoint));
+ memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origPts, npoint * sizeof(xPoint));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPoint *pnts = (xPoint*)&stuff[1];
+ int i = (stuff->coordMode==CoordModePrevious) ? 1 : npoint;
+
+ while(i--) {
+ pnts->x -= x_off;
+ pnts->y -= y_off;
+ pnts++;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyLine])(client);
+ if(result != Success) break;
+ }
+ free(origPts);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolySegment(ClientPtr client)
+{
+ int result = 0, nsegs, i, j;
+ PanoramiXRes *gc, *draw;
+ xSegment *origSegs;
+ Bool isRoot;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolySegment])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if(nsegs & 4) return BadLength;
+ nsegs >>= 3;
+ if (nsegs > 0) {
+ origSegs = (xSegment *) malloc(nsegs * sizeof(xSegment));
+ memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origSegs, nsegs * sizeof(xSegment));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xSegment *segs = (xSegment*)&stuff[1];
+
+ for (i = nsegs; i--; segs++) {
+ segs->x1 -= x_off;
+ segs->x2 -= x_off;
+ segs->y1 -= y_off;
+ segs->y2 -= y_off;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolySegment])(client);
+ if(result != Success) break;
+ }
+ free(origSegs);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyRectangle(ClientPtr client)
+{
+ int result = 0, nrects, i, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ xRectangle *origRecs;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyRectangle])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if(nrects & 4) return BadLength;
+ nrects >>= 3;
+ if (nrects > 0){
+ origRecs = (xRectangle *) malloc(nrects * sizeof(xRectangle));
+ memcpy((char *)origRecs,(char *)&stuff[1],nrects * sizeof(xRectangle));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origRecs, nrects * sizeof(xRectangle));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) &stuff[1];
+
+ for (i = nrects; i--; rects++) {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyRectangle])(client);
+ if(result != Success) break;
+ }
+ free(origRecs);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyArc(ClientPtr client)
+{
+ int result = 0, narcs, i, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ xArc *origArcs;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyArc])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if(narcs % sizeof(xArc)) return BadLength;
+ narcs /= sizeof(xArc);
+ if (narcs > 0){
+ origArcs = (xArc *) malloc(narcs * sizeof(xArc));
+ memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xArc *arcs = (xArc *) &stuff[1];
+
+ for (i = narcs; i--; arcs++) {
+ arcs->x -= x_off;
+ arcs->y -= y_off;
+ }
+ }
+ }
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyArc])(client);
+ if(result != Success) break;
+ }
+ free(origArcs);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXFillPoly(ClientPtr client)
+{
+ int result = 0, count, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ DDXPointPtr locPts;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_FillPoly])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ count = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (count > 0){
+ locPts = (DDXPointPtr) malloc(count * sizeof(DDXPointRec));
+ memcpy((char *)locPts, (char *)&stuff[1], count * sizeof(DDXPointRec));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], locPts, count * sizeof(DDXPointRec));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ DDXPointPtr pnts = (DDXPointPtr)&stuff[1];
+ int i = (stuff->coordMode==CoordModePrevious) ? 1 : count;
+
+ while(i--) {
+ pnts->x -= x_off;
+ pnts->y -= y_off;
+ pnts++;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_FillPoly])(client);
+ if(result != Success) break;
+ }
+ free(locPts);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyFillRectangle(ClientPtr client)
+{
+ int result = 0, things, i, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ xRectangle *origRects;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyFillRectangle])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if(things & 4) return BadLength;
+ things >>= 3;
+ if (things > 0){
+ origRects = (xRectangle *) malloc(things * sizeof(xRectangle));
+ memcpy((char*)origRects,(char*)&stuff[1], things * sizeof(xRectangle));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origRects, things * sizeof(xRectangle));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) &stuff[1];
+
+ for (i = things; i--; rects++) {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyFillRectangle])(client);
+ if(result != Success) break;
+ }
+ free(origRects);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyFillArc(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int result = 0, narcs, i, j;
+ xArc *origArcs;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyFillArc])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ IF_RETURN((narcs % sizeof(xArc)), BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs > 0) {
+ origArcs = (xArc *) malloc(narcs * sizeof(xArc));
+ memcpy((char *) origArcs, (char *)&stuff[1], narcs * sizeof(xArc));
+ FOR_NSCREENS_FORWARD(j){
+
+ if(j) memcpy(&stuff[1], origArcs, narcs * sizeof(xArc));
+
+ if (isRoot) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xArc *arcs = (xArc *) &stuff[1];
+
+ for (i = narcs; i--; arcs++) {
+ arcs->x -= x_off;
+ arcs->y -= y_off;
+ }
+ }
+ }
+
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PolyFillArc])(client);
+ if(result != Success) break;
+ }
+ free(origArcs);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPutImage(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int j, result = 0, orig_x, orig_y;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PutImage])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->dstX;
+ orig_y = stuff->dstY;
+ FOR_NSCREENS_BACKWARD(j){
+ if (isRoot) {
+ stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ result = (* SavedProcVector[X_PutImage])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXGetImage(ClientPtr client)
+{
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDraw;
+ PanoramiXRes *draw;
+ xGetImageReply xgi;
+ Bool isRoot;
+ char *pBuf;
+ int i, x, y, w, h, format;
+ Mask plane = 0, planemask;
+ int linesDone, nlines, linesPerBuf;
+ long widthBytesLine, length;
+
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(draw->type == XRT_PIXMAP)
+ return (*SavedProcVector[X_GetImage])(client);
+
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+ if(!((WindowPtr)pDraw)->realized)
+ return(BadMatch);
+
+ x = stuff->x;
+ y = stuff->y;
+ w = stuff->width;
+ h = stuff->height;
+ format = stuff->format;
+ planemask = stuff->planeMask;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ if(isRoot) {
+ if( /* check for being onscreen */
+ x < 0 || x + w > PanoramiXPixWidth ||
+ y < 0 || y + h > PanoramiXPixHeight )
+ return(BadMatch);
+ } else {
+ if( /* check for being onscreen */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+ return(BadMatch);
+ }
+
+ drawables[0] = pDraw;
+ for(i = 1; i < PanoramiXNumScreens; i++)
+ VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap) {
+ widthBytesLine = PixmapBytePad(w, pDraw->depth);
+ length = widthBytesLine * h;
+
+
+ } else {
+ widthBytesLine = BitmapBytePad(w);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * h *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = (length + 3) >> 2;
+
+ if (widthBytesLine == 0 || h == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= XINERAMA_IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else {
+ linesPerBuf = XINERAMA_IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > h)
+ linesPerBuf = h;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if(!(pBuf = malloc(length)))
+ return (BadAlloc);
+
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+
+ if (linesPerBuf == 0) {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap) {
+ linesDone = 0;
+ while (h - linesDone > 0) {
+ nlines = min(linesPerBuf, h - linesDone);
+
+ if(pDraw->depth == 1)
+ bzero(pBuf, nlines * widthBytesLine);
+
+ XineramaGetImageData(drawables, x, y + linesDone, w, nlines,
+ format, planemask, pBuf, widthBytesLine, isRoot);
+
+ WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ linesDone += nlines;
+ }
+ } else { /* XYPixmap */
+ for (; plane; plane >>= 1) {
+ if (planemask & plane) {
+ linesDone = 0;
+ while (h - linesDone > 0) {
+ nlines = min(linesPerBuf, h - linesDone);
+
+ bzero(pBuf, nlines * widthBytesLine);
+
+ XineramaGetImageData(drawables, x, y + linesDone, w,
+ nlines, format, plane, pBuf,
+ widthBytesLine, isRoot);
+
+ WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+ free(pBuf);
+ return (client->noClientException);
+}
+
+
+/* The text stuff should be rewritten so that duplication happens
+ at the GlyphBlt level. That is, loading the font and getting
+ the glyphs should only happen once */
+
+int
+PanoramiXPolyText8(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int result = 0, j;
+ int orig_x, orig_y;
+ REQUEST(xPolyTextReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyText8])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_PolyText8])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+int
+PanoramiXPolyText16(ClientPtr client)
+{
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int result = 0, j;
+ int orig_x, orig_y;
+ REQUEST(xPolyTextReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_PolyText16])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_PolyText16])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXImageText8(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int orig_x, orig_y;
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_ImageText8])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_ImageText8])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXImageText16(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *gc, *draw;
+ Bool isRoot;
+ int orig_x, orig_y;
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(IS_SHARED_PIXMAP(draw))
+ return (*SavedProcVector[X_ImageText16])(client);
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_ImageText16])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+
+int PanoramiXCreateColormap(ClientPtr client)
+{
+ PanoramiXRes *win, *newCmap;
+ int result = 0, j, orig_visual;
+ REQUEST(xCreateColormapReq);
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->window, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ if(!stuff->visual || (stuff->visual > 255))
+ return BadValue;
+
+ if(!(newCmap = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newCmap->type = XRT_COLORMAP;
+ newCmap->info[0].id = stuff->mid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newCmap->info[j].id = FakeClientID(client->index);
+
+ orig_visual = stuff->visual;
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->mid = newCmap->info[j].id;
+ stuff->window = win->info[j].id;
+ stuff->visual = PanoramiXVisualTable[(orig_visual * MAXSCREENS) + j];
+ result = (* SavedProcVector[X_CreateColormap])(client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
+ else
+ free(newCmap);
+
+ return (result);
+}
+
+
+int PanoramiXFreeColormap(ClientPtr client)
+{
+ PanoramiXRes *cmap;
+ int result = 0, j;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ client->errorValue = stuff->id;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_COLORMAP, DixDestroyAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = cmap->info[j].id;
+ result = (* SavedProcVector[X_FreeColormap])(client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcFreeColormap is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+
+int
+PanoramiXCopyColormapAndFree(ClientPtr client)
+{
+ PanoramiXRes *cmap, *newCmap;
+ int result = 0, j;
+ REQUEST(xCopyColormapAndFreeReq);
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+
+ client->errorValue = stuff->srcCmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->srcCmap, XRT_COLORMAP,
+ DixReadAccess | DixWriteAccess)))
+ return BadColor;
+
+ if(!(newCmap = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newCmap->type = XRT_COLORMAP;
+ newCmap->info[0].id = stuff->mid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newCmap->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->srcCmap = cmap->info[j].id;
+ stuff->mid = newCmap->info[j].id;
+ result = (* SavedProcVector[X_CopyColormapAndFree])(client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newCmap->info[0].id, XRT_COLORMAP, newCmap);
+ else
+ free(newCmap);
+
+ return (result);
+}
+
+
+int PanoramiXInstallColormap(ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int result = 0, j;
+ PanoramiXRes *cmap;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ client->errorValue = stuff->id;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_COLORMAP, DixReadAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->id = cmap->info[j].id;
+ result = (* SavedProcVector[X_InstallColormap])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXUninstallColormap(ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int result = 0, j;
+ PanoramiXRes *cmap;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ client->errorValue = stuff->id;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->id, XRT_COLORMAP, DixReadAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->id = cmap->info[j].id;
+ result = (* SavedProcVector[X_UninstallColormap])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocColor(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_AllocColor])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocNamedColor(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_AllocNamedColor])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocColorCells(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_AllocColorCells])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocColorPlanes(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_AllocColorPlanes])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+
+int PanoramiXFreeColors(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_FreeColors])(client);
+ }
+ return (result);
+}
+
+
+int PanoramiXStoreColors(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_StoreColors])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+
+
+int PanoramiXStoreNamedColor(ClientPtr client)
+{
+ int result = 0, j;
+ PanoramiXRes *cmap;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+
+ client->errorValue = stuff->cmap;
+
+ if(!(cmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->cmap, XRT_COLORMAP, DixWriteAccess)))
+ return BadColor;
+
+ FOR_NSCREENS_BACKWARD(j){
+ stuff->cmap = cmap->info[j].id;
+ result = (* SavedProcVector[X_StoreNamedColor])(client);
+ if(result != Success) break;
+ }
+ return (result);
+}
diff --git a/nx-X11/programs/Xserver/Xext/panoramiXsrv.h b/nx-X11/programs/Xserver/Xext/panoramiXsrv.h
new file mode 100644
index 000000000..91c41b4e3
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/panoramiXsrv.h
@@ -0,0 +1,49 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PANORAMIXSRV_H_
+#define _PANORAMIXSRV_H_
+
+#include "panoramiX.h"
+
+extern int PanoramiXNumScreens;
+extern PanoramiXData *panoramiXdataPtr;
+extern int PanoramiXPixWidth;
+extern int PanoramiXPixHeight;
+extern RegionRec PanoramiXScreenRegion;
+extern XID *PanoramiXVisualTable;
+
+extern void PanoramiXConsolidate(void);
+extern Bool PanoramiXCreateConnectionBlock(void);
+extern PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int);
+extern PanoramiXRes * PanoramiXFindIDOnAnyScreen(RESTYPE, XID);
+extern WindowPtr PanoramiXChangeWindow(int, WindowPtr);
+extern Bool XineramaRegisterConnectionBlockCallback(void (*func)(void));
+extern int XineramaDeleteResource(void *, XID);
+
+extern void XineramaReinitData(ScreenPtr);
+
+extern RegionRec XineramaScreenRegions[MAXSCREENS];
+
+extern unsigned long XRC_DRAWABLE;
+extern unsigned long XRT_WINDOW;
+extern unsigned long XRT_PIXMAP;
+extern unsigned long XRT_GC;
+extern unsigned long XRT_COLORMAP;
+
+extern void XineramaGetImageData(
+ DrawablePtr *pDrawables,
+ int left,
+ int top,
+ int width,
+ int height,
+ unsigned int format,
+ unsigned long planemask,
+ char *data,
+ int pitch,
+ Bool isRoot
+);
+
+#endif /* _PANORAMIXSRV_H_ */
diff --git a/nx-X11/programs/Xserver/Xext/saver.c b/nx-X11/programs/Xserver/Xext/saver.c
new file mode 100644
index 000000000..066dffed0
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/saver.c
@@ -0,0 +1,1395 @@
+/*
+ * $XConsortium: saver.c,v 1.12 94/04/17 20:59:36 dpw Exp $
+ *
+Copyright (c) 1992 X Consortium
+
+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 THE
+X CONSORTIUM 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 X Consortium 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 X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include <nx-X11/extensions/saverproto.h>
+#include "gcstruct.h"
+#include "cursorstr.h"
+#include "colormapst.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+
+#include <stdio.h>
+
+#include "protocol-versions.h"
+
+#if 0
+static unsigned char ScreenSaverReqCode = 0;
+#endif
+static int ScreenSaverEventBase = 0;
+
+extern DISPATCH_PROC(ProcScreenSaverQueryInfo);
+static DISPATCH_PROC(ProcScreenSaverDispatch);
+static DISPATCH_PROC(ProcScreenSaverQueryVersion);
+static DISPATCH_PROC(ProcScreenSaverSelectInput);
+static DISPATCH_PROC(ProcScreenSaverSetAttributes);
+static DISPATCH_PROC(ProcScreenSaverUnsetAttributes);
+static DISPATCH_PROC(SProcScreenSaverDispatch);
+static DISPATCH_PROC(SProcScreenSaverQueryInfo);
+static DISPATCH_PROC(SProcScreenSaverQueryVersion);
+static DISPATCH_PROC(SProcScreenSaverSelectInput);
+static DISPATCH_PROC(SProcScreenSaverSetAttributes);
+static DISPATCH_PROC(SProcScreenSaverUnsetAttributes);
+
+static Bool ScreenSaverHandle (
+ ScreenPtr /* pScreen */,
+ int /* xstate */,
+ Bool /* force */
+ );
+
+static Bool
+CreateSaverWindow (
+ ScreenPtr /* pScreen */
+ );
+
+static Bool
+DestroySaverWindow (
+ ScreenPtr /* pScreen */
+ );
+
+static void
+UninstallSaverColormap (
+ ScreenPtr /* pScreen */
+ );
+
+static void
+CheckScreenPrivate (
+ ScreenPtr /* pScreen */
+ );
+
+static void SScreenSaverNotifyEvent (
+ xScreenSaverNotifyEvent * /* from */,
+ xScreenSaverNotifyEvent * /* to */
+ );
+
+static void ScreenSaverResetProc (
+ ExtensionEntry * /* extEntry */
+ );
+
+/*
+ * each screen has a list of clients requesting
+ * ScreenSaverNotify events. Each client has a resource
+ * for each screen it selects ScreenSaverNotify input for,
+ * this resource is used to delete the ScreenSaverNotifyRec
+ * entry from the per-screen queue.
+ */
+
+static RESTYPE EventType; /* resource type for event masks */
+
+typedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
+
+typedef struct _ScreenSaverEvent {
+ ScreenSaverEventPtr next;
+ ClientPtr client;
+ ScreenPtr screen;
+ XID resource;
+ CARD32 mask;
+} ScreenSaverEventRec;
+
+static int ScreenSaverFreeEvents(
+ void * /* value */,
+ XID /* id */
+);
+
+static Bool setEventMask (
+ ScreenPtr /* pScreen */,
+ ClientPtr /* client */,
+ unsigned long /* mask */
+);
+
+static unsigned long getEventMask (
+ ScreenPtr /* pScreen */,
+ ClientPtr /* client */
+);
+
+/*
+ * when a client sets the screen saver attributes, a resource is
+ * kept to be freed when the client exits
+ */
+
+static RESTYPE AttrType; /* resource type for attributes */
+
+typedef struct _ScreenSaverAttr {
+ ScreenPtr screen;
+ ClientPtr client;
+ XID resource;
+ short x, y;
+ unsigned short width, height, borderWidth;
+ unsigned char class;
+ unsigned char depth;
+ VisualID visual;
+ CursorPtr pCursor;
+ PixmapPtr pBackgroundPixmap;
+ PixmapPtr pBorderPixmap;
+ Colormap colormap;
+ unsigned long mask; /* no pixmaps or cursors */
+ unsigned long *values;
+} ScreenSaverAttrRec, *ScreenSaverAttrPtr;
+
+static int ScreenSaverFreeAttr (
+ void * /* value */,
+ XID /* id */
+);
+
+static void FreeAttrs (
+ ScreenSaverAttrPtr /* pAttr */
+);
+
+static void FreeScreenAttr (
+ ScreenSaverAttrPtr /* pAttr */
+);
+
+static void
+SendScreenSaverNotify (
+ ScreenPtr /* pScreen */,
+ int /* state */,
+ Bool /* forced */
+);
+
+typedef struct _ScreenSaverScreenPrivate {
+ ScreenSaverEventPtr events;
+ ScreenSaverAttrPtr attr;
+ Bool hasWindow;
+ Colormap installedMap;
+} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
+
+static ScreenSaverScreenPrivatePtr
+MakeScreenPrivate (
+ ScreenPtr /* pScreen */
+ );
+
+static int ScreenPrivateIndex;
+
+#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr)(s)->devPrivates[ScreenPrivateIndex].ptr)
+#define SetScreenPrivate(s,v) ((s)->devPrivates[ScreenPrivateIndex].ptr = (void *) v);
+#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
+
+#define New(t) ((t *) malloc (sizeof (t)))
+
+/****************
+ * ScreenSaverExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+
+void
+ScreenSaverExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+ ScreenPtr pScreen;
+
+ AttrType = CreateNewResourceType(ScreenSaverFreeAttr);
+ EventType = CreateNewResourceType(ScreenSaverFreeEvents);
+ ScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ SetScreenPrivate (pScreen, NULL);
+ }
+ if (AttrType && EventType && ScreenPrivateIndex != -1 &&
+ (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
+ ProcScreenSaverDispatch, SProcScreenSaverDispatch,
+ ScreenSaverResetProc, StandardMinorOpcode)))
+ {
+#if 0
+ ScreenSaverReqCode = (unsigned char)extEntry->base;
+#endif
+ ScreenSaverEventBase = extEntry->eventBase;
+ EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ScreenSaverResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+}
+
+static void
+CheckScreenPrivate (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen (pScreen);
+
+ if (!pPriv)
+ return;
+ if (!pPriv->attr && !pPriv->events &&
+ !pPriv->hasWindow && pPriv->installedMap == None)
+ {
+ free (pPriv);
+ SetScreenPrivate (pScreen, NULL);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ }
+}
+
+static ScreenSaverScreenPrivatePtr
+MakeScreenPrivate (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen (pScreen);
+
+ if (pPriv)
+ return pPriv;
+ pPriv = New (ScreenSaverScreenPrivateRec);
+ if (!pPriv)
+ return 0;
+ pPriv->events = 0;
+ pPriv->attr = 0;
+ pPriv->hasWindow = FALSE;
+ pPriv->installedMap = None;
+ SetScreenPrivate (pScreen, pPriv);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = ScreenSaverHandle;
+ return pPriv;
+}
+
+static unsigned long
+getEventMask (pScreen, client)
+ ScreenPtr pScreen;
+ ClientPtr client;
+{
+ SetupScreen(pScreen);
+ ScreenSaverEventPtr pEv;
+
+ if (!pPriv)
+ return 0;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ if (pEv->client == client)
+ return pEv->mask;
+ return 0;
+}
+
+static Bool
+setEventMask (pScreen, client, mask)
+ ScreenPtr pScreen;
+ ClientPtr client;
+ unsigned long mask;
+{
+ SetupScreen(pScreen);
+ ScreenSaverEventPtr pEv, *pPrev;
+
+ if (getEventMask (pScreen, client) == mask)
+ return TRUE;
+ if (!pPriv)
+ {
+ pPriv = MakeScreenPrivate (pScreen);
+ if (!pPriv)
+ return FALSE;
+ }
+ for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
+ if (pEv->client == client)
+ break;
+ if (mask == 0)
+ {
+ FreeResource (pEv->resource, EventType);
+ *pPrev = pEv->next;
+ free (pEv);
+ CheckScreenPrivate (pScreen);
+ }
+ else
+ {
+ if (!pEv)
+ {
+ pEv = New (ScreenSaverEventRec);
+ if (!pEv)
+ {
+ CheckScreenPrivate (pScreen);
+ return FALSE;
+ }
+ *pPrev = pEv;
+ pEv->next = NULL;
+ pEv->client = client;
+ pEv->screen = pScreen;
+ pEv->resource = FakeClientID (client->index);
+ if (!AddResource (pEv->resource, EventType, (void *) pEv))
+ return FALSE;
+ }
+ pEv->mask = mask;
+ }
+ return TRUE;
+}
+
+static void
+FreeAttrs (pAttr)
+ ScreenSaverAttrPtr pAttr;
+{
+ PixmapPtr pPixmap;
+ CursorPtr pCursor;
+
+ if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
+ (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+ if ((pPixmap = pAttr->pBorderPixmap) != 0)
+ (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+ if ((pCursor = pAttr->pCursor) != 0)
+ FreeCursor (pCursor, (Cursor) 0);
+}
+
+static void
+FreeScreenAttr (pAttr)
+ ScreenSaverAttrPtr pAttr;
+{
+ FreeAttrs (pAttr);
+ free (pAttr->values);
+ free (pAttr);
+}
+
+static int
+ScreenSaverFreeEvents (value, id)
+ void * value;
+ XID id;
+{
+ ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value;
+ ScreenPtr pScreen = pOld->screen;
+ SetupScreen (pScreen);
+ ScreenSaverEventPtr pEv, *pPrev;
+
+ if (!pPriv)
+ return TRUE;
+ for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
+ if (pEv == pOld)
+ break;
+ if (!pEv)
+ return TRUE;
+ *pPrev = pEv->next;
+ free (pEv);
+ CheckScreenPrivate (pScreen);
+ return TRUE;
+}
+
+static int
+ScreenSaverFreeAttr (value, id)
+ void * value;
+ XID id;
+{
+ ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value;
+ ScreenPtr pScreen = pOldAttr->screen;
+ SetupScreen (pScreen);
+
+ if (!pPriv)
+ return TRUE;
+ if (pPriv->attr != pOldAttr)
+ return TRUE;
+ FreeScreenAttr (pOldAttr);
+ pPriv->attr = NULL;
+ if (pPriv->hasWindow)
+ {
+ SaveScreens (SCREEN_SAVER_FORCER, ScreenSaverReset);
+ SaveScreens (SCREEN_SAVER_FORCER, ScreenSaverActive);
+ }
+ CheckScreenPrivate (pScreen);
+ return TRUE;
+}
+
+static void
+SendScreenSaverNotify (pScreen, state, forced)
+ ScreenPtr pScreen;
+ int state;
+ Bool forced;
+{
+ ScreenSaverScreenPrivatePtr pPriv;
+ ScreenSaverEventPtr pEv;
+ unsigned long mask;
+ xScreenSaverNotifyEvent ev;
+ int kind;
+
+ UpdateCurrentTimeIf ();
+ mask = ScreenSaverNotifyMask;
+ if (state == ScreenSaverCycle)
+ mask = ScreenSaverCycleMask;
+ pScreen = screenInfo.screens[pScreen->myNum];
+ pPriv = GetScreenPrivate(pScreen);
+ if (!pPriv)
+ return;
+ if (pPriv->attr)
+ kind = ScreenSaverExternal;
+ else if (ScreenSaverBlanking != DontPreferBlanking)
+ kind = ScreenSaverBlanked;
+ else
+ kind = ScreenSaverInternal;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ {
+ if (!(pEv->mask & mask))
+ continue;
+ ev.type = ScreenSaverNotify + ScreenSaverEventBase;
+ ev.state = state;
+ ev.timestamp = currentTime.milliseconds;
+ ev.root = pScreen->root->drawable.id;
+ ev.window = savedScreenInfo[pScreen->myNum].wid;
+ ev.kind = kind;
+ ev.forced = forced;
+ WriteEventsToClient (pEv->client, 1, (xEvent *) &ev);
+ }
+}
+
+static void
+SScreenSaverNotifyEvent (from, to)
+ xScreenSaverNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ to->state = from->state;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->root, to->root);
+ cpswapl (from->window, to->window);
+ to->kind = from->kind;
+ to->forced = from->forced;
+}
+
+static void
+UninstallSaverColormap (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen(pScreen);
+ ColormapPtr pCmap;
+
+ if (pPriv && pPriv->installedMap != None)
+ {
+ pCmap = (ColormapPtr) LookupIDByType (pPriv->installedMap, RT_COLORMAP);
+ if (pCmap)
+ (*pCmap->pScreen->UninstallColormap) (pCmap);
+ pPriv->installedMap = None;
+ CheckScreenPrivate (pScreen);
+ }
+}
+
+static Bool
+CreateSaverWindow (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen (pScreen);
+ ScreenSaverStuffPtr pSaver;
+ ScreenSaverAttrPtr pAttr;
+ WindowPtr pWin;
+ int result;
+ unsigned long mask;
+ Colormap *installedMaps;
+ int numInstalled;
+ int i;
+ Colormap wantMap;
+ ColormapPtr pCmap;
+
+ pSaver = &savedScreenInfo[pScreen->myNum];
+ if (pSaver->pWindow)
+ {
+ pSaver->pWindow = NullWindow;
+ FreeResource (pSaver->wid, RT_NONE);
+ if (pPriv)
+ {
+ UninstallSaverColormap (pScreen);
+ pPriv->hasWindow = FALSE;
+ CheckScreenPrivate (pScreen);
+ }
+ }
+
+ if (!pPriv || !(pAttr = pPriv->attr))
+ return FALSE;
+
+ pPriv->installedMap = None;
+
+ if (GrabInProgress && GrabInProgress != pAttr->client->index)
+ return FALSE;
+
+ pWin = CreateWindow (pSaver->wid, pScreen->root,
+ pAttr->x, pAttr->y, pAttr->width, pAttr->height,
+ pAttr->borderWidth, pAttr->class,
+ pAttr->mask, (XID *)pAttr->values,
+ pAttr->depth, serverClient, pAttr->visual,
+ &result);
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
+ return FALSE;
+
+ mask = 0;
+ if (pAttr->pBackgroundPixmap)
+ {
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pAttr->pBackgroundPixmap;
+ pAttr->pBackgroundPixmap->refcnt++;
+ mask |= CWBackPixmap;
+ }
+ if (pAttr->pBorderPixmap)
+ {
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pAttr->pBorderPixmap;
+ pAttr->pBorderPixmap->refcnt++;
+ mask |= CWBorderPixmap;
+ }
+ if (pAttr->pCursor)
+ {
+ if (!pWin->optional)
+ if (!MakeWindowOptional (pWin))
+ {
+ FreeResource (pWin->drawable.id, RT_NONE);
+ return FALSE;
+ }
+ if (pWin->optional->cursor)
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->optional->cursor = pAttr->pCursor;
+ pAttr->pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ CheckWindowOptionalNeed (pWin);
+ mask |= CWCursor;
+ }
+ if (mask)
+ (*pScreen->ChangeWindowAttributes) (pWin, mask);
+
+ if (pAttr->colormap != None)
+ (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap,
+ serverClient);
+
+ MapWindow (pWin, serverClient);
+
+ pPriv->hasWindow = TRUE;
+ pSaver->pWindow = pWin;
+
+ /* check and install our own colormap if it isn't installed now */
+ wantMap = wColormap (pWin);
+ if (wantMap == None)
+ return TRUE;
+ installedMaps = (Colormap *) malloc (pScreen->maxInstalledCmaps *
+ sizeof (Colormap));
+ numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pScreen, installedMaps);
+ for (i = 0; i < numInstalled; i++)
+ if (installedMaps[i] == wantMap)
+ break;
+
+ free ((char *) installedMaps);
+
+ if (i < numInstalled)
+ return TRUE;
+
+ pCmap = (ColormapPtr) LookupIDByType (wantMap, RT_COLORMAP);
+ if (!pCmap)
+ return TRUE;
+
+ pPriv->installedMap = wantMap;
+
+ (*pCmap->pScreen->InstallColormap) (pCmap);
+
+ return TRUE;
+}
+
+static Bool
+DestroySaverWindow (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen(pScreen);
+ ScreenSaverStuffPtr pSaver;
+
+ if (!pPriv || !pPriv->hasWindow)
+ return FALSE;
+
+ pSaver = &savedScreenInfo[pScreen->myNum];
+ if (pSaver->pWindow)
+ {
+ pSaver->pWindow = NullWindow;
+ FreeResource (pSaver->wid, RT_NONE);
+ }
+ pPriv->hasWindow = FALSE;
+ CheckScreenPrivate (pScreen);
+ UninstallSaverColormap (pScreen);
+ return TRUE;
+}
+
+static Bool
+ScreenSaverHandle (pScreen, xstate, force)
+ ScreenPtr pScreen;
+ int xstate;
+ Bool force;
+{
+ int state = 0;
+ Bool ret = FALSE;
+ ScreenSaverScreenPrivatePtr pPriv;
+
+ switch (xstate)
+ {
+ case SCREEN_SAVER_ON:
+ state = ScreenSaverOn;
+ ret = CreateSaverWindow (pScreen);
+ break;
+ case SCREEN_SAVER_OFF:
+ state = ScreenSaverOff;
+ ret = DestroySaverWindow (pScreen);
+ break;
+ case SCREEN_SAVER_CYCLE:
+ state = ScreenSaverCycle;
+ pPriv = GetScreenPrivate (pScreen);
+ if (pPriv && pPriv->hasWindow)
+ ret = TRUE;
+
+ }
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pScreen->myNum)
+#endif
+ SendScreenSaverNotify (pScreen, state, force);
+ return ret;
+}
+
+static int
+ProcScreenSaverQueryVersion (client)
+ register ClientPtr client;
+{
+ xScreenSaverQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_SAVER_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SAVER_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+ WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcScreenSaverQueryInfo (client)
+ register ClientPtr client;
+{
+ REQUEST(xScreenSaverQueryInfoReq);
+ xScreenSaverQueryInfoReply rep;
+ ScreenSaverStuffPtr pSaver;
+ DrawablePtr pDraw;
+ CARD32 lastInput;
+ ScreenSaverScreenPrivatePtr pPriv;
+
+ REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq);
+ pDraw = (DrawablePtr) LookupDrawable (stuff->drawable, client);
+ if (!pDraw)
+ return BadDrawable;
+
+ pSaver = &savedScreenInfo[pDraw->pScreen->myNum];
+ pPriv = GetScreenPrivate (pDraw->pScreen);
+
+ UpdateCurrentTime ();
+ lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.window = pSaver->wid;
+ if (screenIsSaved != SCREEN_SAVER_OFF)
+ {
+ rep.state = ScreenSaverOn;
+ if (ScreenSaverTime)
+ rep.tilOrSince = lastInput - ScreenSaverTime;
+ else
+ rep.tilOrSince = 0;
+ }
+ else
+ {
+ if (ScreenSaverTime)
+ {
+ rep.state = ScreenSaverOff;
+ if (ScreenSaverTime < lastInput)
+ rep.tilOrSince = 0;
+ else
+ rep.tilOrSince = ScreenSaverTime - lastInput;
+ }
+ else
+ {
+ rep.state = ScreenSaverDisabled;
+ rep.tilOrSince = 0;
+ }
+ }
+ rep.idle = lastInput;
+ rep.eventMask = getEventMask (pDraw->pScreen, client);
+ if (pPriv && pPriv->attr)
+ rep.kind = ScreenSaverExternal;
+ else if (ScreenSaverBlanking != DontPreferBlanking)
+ rep.kind = ScreenSaverBlanked;
+ else
+ rep.kind = ScreenSaverInternal;
+ if (client->swapped)
+ {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.window);
+ swapl (&rep.tilOrSince);
+ swapl (&rep.idle);
+ swapl (&rep.eventMask);
+ }
+ WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcScreenSaverSelectInput (client)
+ register ClientPtr client;
+{
+ REQUEST(xScreenSaverSelectInputReq);
+ DrawablePtr pDraw;
+
+ REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq);
+ pDraw = (DrawablePtr) LookupDrawable (stuff->drawable, client);
+ if (!pDraw)
+ return BadDrawable;
+ if (!setEventMask (pDraw->pScreen, client, stuff->eventMask))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ScreenSaverSetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+ DrawablePtr pDraw;
+ WindowPtr pParent;
+ ScreenPtr pScreen;
+ ScreenSaverScreenPrivatePtr pPriv = 0;
+ ScreenSaverAttrPtr pAttr = 0;
+ int ret;
+ int len;
+ int class, bw, depth;
+ unsigned long visual;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ WindowOptPtr ancwopt;
+ unsigned int *pVlist;
+ unsigned long *values = 0;
+ unsigned long tmask, imask;
+ unsigned long val;
+ Pixmap pixID;
+ PixmapPtr pPixmap;
+ Cursor cursorID;
+ CursorPtr pCursor;
+ Colormap cmap;
+ ColormapPtr pCmap;
+
+ REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
+ pDraw = (DrawablePtr) LookupDrawable (stuff->drawable, client);
+ if (!pDraw)
+ return BadDrawable;
+ pScreen = pDraw->pScreen;
+ pParent = pScreen->root;
+
+ len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ switch (class = stuff->c_class)
+ {
+ case CopyFromParent:
+ case InputOnly:
+ case InputOutput:
+ break;
+ default:
+ client->errorValue = class;
+ return BadValue;
+ }
+ bw = stuff->borderWidth;
+ depth = stuff->depth;
+ visual = stuff->visualID;
+
+ /* copied directly from CreateWindow */
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ client->errorValue = class;
+ return BadValue;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ return BadMatch;
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ return BadMatch;
+
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent)
+ visual = ancwopt->visual;
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ return BadMatch;
+ }
+
+ if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ return BadMatch;
+ }
+
+ if (((stuff->mask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ return BadMatch;
+ }
+
+ /* end of errors from CreateWindow */
+
+ pPriv = GetScreenPrivate (pScreen);
+ if (pPriv && pPriv->attr)
+ {
+ if (pPriv->attr->client != client)
+ return BadAccess;
+ }
+ if (!pPriv)
+ {
+ pPriv = MakeScreenPrivate (pScreen);
+ if (!pPriv)
+ return FALSE;
+ }
+ pAttr = New (ScreenSaverAttrRec);
+ if (!pAttr)
+ {
+ ret = BadAlloc;
+ goto bail;
+ }
+ /* over allocate for override redirect */
+ values = (unsigned long *) malloc ((len + 1) * sizeof (unsigned long));
+ if (!values)
+ {
+ ret = BadAlloc;
+ goto bail;
+ }
+ pAttr->screen = pScreen;
+ pAttr->client = client;
+ pAttr->x = stuff->x;
+ pAttr->y = stuff->y;
+ pAttr->width = stuff->width;
+ pAttr->height = stuff->height;
+ pAttr->borderWidth = stuff->borderWidth;
+ pAttr->class = stuff->c_class;
+ pAttr->depth = depth;
+ pAttr->visual = visual;
+ pAttr->colormap = None;
+ pAttr->pCursor = NullCursor;
+ pAttr->pBackgroundPixmap = NullPixmap;
+ pAttr->pBorderPixmap = NullPixmap;
+ pAttr->values = values;
+ /*
+ * go through the mask, checking the values,
+ * looking up pixmaps and cursors and hold a reference
+ * to them.
+ */
+ pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
+ pVlist = (unsigned int *) (stuff + 1);
+ while (tmask) {
+ imask = lowbit (tmask);
+ tmask &= ~imask;
+ switch (imask)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ if (pixID == None)
+ {
+ *values++ = None;
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (depth != pParent->drawable.depth)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ *values++ = ParentRelative;
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)LookupIDByType(pixID, RT_PIXMAP);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->pBackgroundPixmap = pPixmap;
+ pPixmap->refcnt++;
+ pAttr->mask &= ~CWBackPixmap;
+ }
+ else
+ {
+ ret = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ if (pixID == CopyFromParent)
+ {
+ if (depth != pParent->drawable.depth)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ *values++ = CopyFromParent;
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)LookupIDByType(pixID, RT_PIXMAP);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->pBorderPixmap = pPixmap;
+ pPixmap->refcnt++;
+ pAttr->mask &= ~CWBorderPixmap;
+ }
+ else
+ {
+ ret = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ if (val > StaticGravity)
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ if (val > StaticGravity)
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWBackingPlanes:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBackingPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWEventMask:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWDontPropagate:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWOverrideRedirect:
+ if (!(stuff->mask & CWOverrideRedirect))
+ pVlist--;
+ else
+ {
+ val = (BOOL ) *pVlist;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ }
+ *values++ = xTrue;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pCmap = (ColormapPtr)LookupIDByType(cmap, RT_COLORMAP);
+ if (!pCmap)
+ {
+ ret = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->colormap = cmap;
+ pAttr->mask &= ~CWColormap;
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ if ( cursorID == None)
+ {
+ *values++ = None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)LookupIDByType(cursorID, RT_CURSOR);
+ if (!pCursor)
+ {
+ ret = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ pCursor->refcnt++;
+ pAttr->pCursor = pCursor;
+ pAttr->mask &= ~CWCursor;
+ }
+ break;
+ default:
+ ret = BadValue;
+ client->errorValue = stuff->mask;
+ goto PatchUp;
+ }
+ pVlist++;
+ }
+ if (pPriv->attr)
+ FreeScreenAttr (pPriv->attr);
+ pPriv->attr = pAttr;
+ pAttr->resource = FakeClientID (client->index);
+ if (!AddResource (pAttr->resource, AttrType, (void *) pAttr))
+ return BadAlloc;
+ return Success;
+PatchUp:
+ FreeAttrs (pAttr);
+bail:
+ CheckScreenPrivate (pScreen);
+ if (pAttr) free (pAttr->values);
+ free (pAttr);
+ return ret;
+}
+
+static int
+ScreenSaverUnsetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+ DrawablePtr pDraw;
+ ScreenSaverScreenPrivatePtr pPriv;
+
+ REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq);
+ pDraw = (DrawablePtr) LookupDrawable (stuff->drawable, client);
+ if (!pDraw)
+ return BadDrawable;
+ pPriv = GetScreenPrivate (pDraw->pScreen);
+ if (pPriv && pPriv->attr && pPriv->attr->client == client)
+ {
+ FreeResource (pPriv->attr->resource, AttrType);
+ FreeScreenAttr (pPriv->attr);
+ pPriv->attr = NULL;
+ CheckScreenPrivate (pDraw->pScreen);
+ }
+ return Success;
+}
+
+static int
+ProcScreenSaverSetAttributes (ClientPtr client)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ REQUEST(xScreenSaverSetAttributesReq);
+ PanoramiXRes *draw;
+ PanoramiXRes *backPix = NULL;
+ PanoramiXRes *bordPix = NULL;
+ PanoramiXRes *cmap = NULL;
+ int i, status = 0, len;
+ int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
+ XID orig_visual, tmp;
+
+ REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ len = stuff->length - (sizeof(xScreenSaverSetAttributesReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ if((Mask)stuff->mask & CWBackPixmap) {
+ pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pback_offset);
+ if ((tmp != None) && (tmp != ParentRelative)) {
+ if(!(backPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+
+ if ((Mask)stuff->mask & CWBorderPixmap) {
+ pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (tmp != CopyFromParent) {
+ if(!(bordPix = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ }
+ }
+
+ if ((Mask)stuff->mask & CWColormap) {
+ cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+ if ((tmp != CopyFromParent) && (tmp != None)) {
+ if(!(cmap = (PanoramiXRes*) SecurityLookupIDByType(
+ client, tmp, XRT_COLORMAP, DixReadAccess)))
+ return BadColor;
+ }
+ }
+
+ orig_visual = stuff->visualID;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ stuff->drawable = draw->info[i].id;
+ if (backPix)
+ *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
+ if (bordPix)
+ *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
+ if (cmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
+
+ if (orig_visual != CopyFromParent)
+ stuff->visualID =
+ PanoramiXVisualTable[(orig_visual*MAXSCREENS) + i];
+
+ status = ScreenSaverSetAttributes(client);
+ }
+
+ return status;
+ }
+#endif
+
+ return ScreenSaverSetAttributes(client);
+}
+
+static int
+ProcScreenSaverUnsetAttributes (ClientPtr client)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ REQUEST(xScreenSaverUnsetAttributesReq);
+ PanoramiXRes *draw;
+ int i;
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ for(i = PanoramiXNumScreens - 1; i > 0; i--) {
+ stuff->drawable = draw->info[i].id;
+ ScreenSaverUnsetAttributes(client);
+ }
+
+ stuff->drawable = draw->info[0].id;
+ }
+#endif
+
+ return ScreenSaverUnsetAttributes(client);
+}
+
+static DISPATCH_PROC((*NormalVector[])) = {
+ ProcScreenSaverQueryVersion,
+ ProcScreenSaverQueryInfo,
+ ProcScreenSaverSelectInput,
+ ProcScreenSaverSetAttributes,
+ ProcScreenSaverUnsetAttributes,
+};
+
+#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0]))
+
+static int
+ProcScreenSaverDispatch (client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ if (stuff->data < NUM_REQUESTS)
+ return (*NormalVector[stuff->data])(client);
+ return BadRequest;
+}
+
+static int
+SProcScreenSaverQueryVersion (client)
+ ClientPtr client;
+{
+ REQUEST(xScreenSaverQueryVersionReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
+ return ProcScreenSaverQueryVersion (client);
+}
+
+static int
+SProcScreenSaverQueryInfo (client)
+ ClientPtr client;
+{
+ REQUEST(xScreenSaverQueryInfoReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
+ swapl (&stuff->drawable);
+ return ProcScreenSaverQueryInfo (client);
+}
+
+static int
+SProcScreenSaverSelectInput (client)
+ ClientPtr client;
+{
+ REQUEST(xScreenSaverSelectInputReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
+ swapl (&stuff->drawable);
+ swapl (&stuff->eventMask);
+ return ProcScreenSaverSelectInput (client);
+}
+
+static int
+SProcScreenSaverSetAttributes (client)
+ ClientPtr client;
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+
+ swaps (&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
+ swapl (&stuff->drawable);
+ swaps (&stuff->x);
+ swaps (&stuff->y);
+ swaps (&stuff->width);
+ swaps (&stuff->height);
+ swaps (&stuff->borderWidth);
+ swapl (&stuff->visualID);
+ swapl (&stuff->mask);
+ SwapRestL(stuff);
+ return ProcScreenSaverSetAttributes (client);
+}
+
+static int
+SProcScreenSaverUnsetAttributes (client)
+ ClientPtr client;
+{
+ REQUEST(xScreenSaverUnsetAttributesReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
+ swapl (&stuff->drawable);
+ return ProcScreenSaverUnsetAttributes (client);
+}
+
+static DISPATCH_PROC((*SwappedVector[])) = {
+ SProcScreenSaverQueryVersion,
+ SProcScreenSaverQueryInfo,
+ SProcScreenSaverSelectInput,
+ SProcScreenSaverSetAttributes,
+ SProcScreenSaverUnsetAttributes,
+};
+
+static int
+SProcScreenSaverDispatch (client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ if (stuff->data < NUM_REQUESTS)
+ return (*SwappedVector[stuff->data])(client);
+ return BadRequest;
+}
diff --git a/nx-X11/programs/Xserver/Xext/security.c b/nx-X11/programs/Xserver/Xext/security.c
new file mode 100644
index 000000000..2a7d5628f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/security.c
@@ -0,0 +1,2177 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1996, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "propertyst.h"
+#include "protocol-versions.h"
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/securstr.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h> /* for file reading operations */
+#include <nx-X11/Xatom.h> /* for XA_STRING */
+
+#ifdef NXAGENT_SERVER
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#endif
+
+#ifndef DEFAULTPOLICYFILE
+# define DEFAULTPOLICYFILE NULL
+#endif
+
+#ifdef NXAGENT_SERVER
+
+#define NX_ALTERNATIVEPOLICYFILE "/usr/local/share/nx/SecurityPolicy"
+
+#endif
+
+#if defined(WIN32) || defined(__CYGWIN__)
+#include <nx-X11/Xos.h>
+#undef index
+#endif
+
+/*
+ * Set here the required NX log level.
+ */
+
+#ifdef NXAGENT_SERVER
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#endif
+
+#ifdef NXAGENT_SERVER
+
+static char _NXPolicyFilePath[1024];
+
+#endif
+
+static int SecurityErrorBase; /* first Security error number */
+static int SecurityEventBase; /* first Security event number */
+
+CallbackListPtr SecurityValidateGroupCallback = NULL; /* see security.h */
+
+RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */
+
+static RESTYPE RTEventClient;
+
+/* Proc vectors for untrusted clients, swapped and unswapped versions.
+ * These are the same as the normal proc vectors except that extensions
+ * that haven't declared themselves secure will have ProcBadRequest plugged
+ * in for their major opcode dispatcher. This prevents untrusted clients
+ * from guessing extension major opcodes and using the extension even though
+ * the extension can't be listed or queried.
+ */
+int (*UntrustedProcVector[256])(
+ ClientPtr /*client*/
+);
+int (*SwappedUntrustedProcVector[256])(
+ ClientPtr /*client*/
+);
+
+#ifdef NXAGENT_SERVER
+
+/*
+ * This function returns the SecurityPolicy
+ * file full path. This path is referred by
+ * SecurityPolicyFile variable (generally it
+ * contains the hardcoded path at compile time).
+ * If the path does not exist, the function will
+ * try a set of well known paths.
+ */
+
+char *_NXGetPolicyFilePath(const char *path)
+{
+
+ struct stat SecurityPolicyStat;
+
+ /*
+ * Check the policy file path only once.
+ */
+
+ if (*_NXPolicyFilePath != '\0')
+ {
+ return _NXPolicyFilePath;
+ }
+
+ if (stat(path, &SecurityPolicyStat) == 0)
+ {
+ if (strlen(path) + 1 > 1024)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
+ #endif
+
+ goto _NXGetPolicyFilePathError;
+ }
+
+ strcpy(_NXPolicyFilePath, path);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
+ _NXPolicyFilePath);
+ #endif
+
+ return _NXPolicyFilePath;
+ }
+
+ if (stat(DEFAULTPOLICYFILE, &SecurityPolicyStat) == 0)
+ {
+ if (strlen(DEFAULTPOLICYFILE) + 1 > 1024)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
+ #endif
+
+ goto _NXGetPolicyFilePathError;
+ }
+
+ strcpy(_NXPolicyFilePath, DEFAULTPOLICYFILE);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
+ _NXPolicyFilePath);
+ #endif
+
+ return _NXPolicyFilePath;
+ }
+
+ if (stat(NX_ALTERNATIVEPOLICYFILE, &SecurityPolicyStat) == 0)
+ {
+ if (strlen(NX_ALTERNATIVEPOLICYFILE) + 1 > 1024)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
+ #endif
+
+ goto _NXGetPolicyFilePathError;
+ }
+
+ strcpy(_NXPolicyFilePath, NX_ALTERNATIVEPOLICYFILE);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
+ _NXPolicyFilePath);
+ #endif
+
+ return _NXPolicyFilePath;
+ }
+
+_NXGetPolicyFilePathError:
+
+ if (strlen(path) + 1 > 1024)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file exceeded.\n");
+ #endif
+ }
+
+ strcpy(_NXPolicyFilePath, path);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetPolicyFilePath: Using default SecurityPolicy file path [%s].\n",
+ _NXPolicyFilePath);
+ #endif
+
+ return _NXPolicyFilePath;
+}
+
+#endif
+
+/* SecurityAudit
+ *
+ * Arguments:
+ * format is the formatting string to be used to interpret the
+ * remaining arguments.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Writes the message to the log file if security logging is on.
+ */
+
+void
+SecurityAudit(char *format, ...)
+{
+ va_list args;
+
+ if (auditTrailLevel < SECURITY_AUDIT_LEVEL)
+ return;
+ va_start(args, format);
+ VAuditF(format, args);
+ va_end(args);
+} /* SecurityAudit */
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+/* SecurityDeleteAuthorization
+ *
+ * Arguments:
+ * value is the authorization to delete.
+ * id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ * Frees everything associated with the authorization.
+ */
+
+static int
+SecurityDeleteAuthorization(
+ void * value,
+ XID id)
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+ unsigned short name_len, data_len;
+ char *name, *data;
+ int status;
+ int i;
+ OtherClientsPtr pEventClient;
+
+ /* Remove the auth using the os layer auth manager */
+
+ status = AuthorizationFromID(pAuth->id, &name_len, &name,
+ &data_len, &data);
+ assert(status);
+ status = RemoveAuthorization(name_len, name, data_len, data);
+ assert(status);
+ (void)status;
+
+ /* free the auth timer if there is one */
+
+ if (pAuth->timer) TimerFree(pAuth->timer);
+
+ /* send revoke events */
+
+ while ((pEventClient = pAuth->eventClients))
+ {
+ /* send revocation event event */
+ xSecurityAuthorizationRevokedEvent are;
+ are.type = SecurityEventBase + XSecurityAuthorizationRevoked;
+ are.authId = pAuth->id;
+ WriteEventsToClient(rClient(pEventClient), 1, (xEvent *)&are);
+ FreeResource(pEventClient->resource, RT_NONE);
+ }
+
+ /* kill all clients using this auth */
+
+ for (i = 1; i<currentMaxClients; i++)
+ {
+ if (clients[i] && (clients[i]->authId == pAuth->id))
+ CloseDownClient(clients[i]);
+ }
+
+ SecurityAudit("revoked authorization ID %d\n", pAuth->id);
+ free(pAuth);
+ return Success;
+
+} /* SecurityDeleteAuthorization */
+
+
+/* resource delete function for RTEventClient */
+static int
+SecurityDeleteAuthorizationEventClient(
+ void * value,
+ XID id)
+{
+ OtherClientsPtr pEventClient, prev = NULL;
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (pEventClient->resource == id)
+ {
+ if (prev)
+ prev->next = pEventClient->next;
+ else
+ pAuth->eventClients = pEventClient->next;
+ free(pEventClient);
+ return(Success);
+ }
+ prev = pEventClient;
+ }
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+} /* SecurityDeleteAuthorizationEventClient */
+
+
+/* SecurityComputeAuthorizationTimeout
+ *
+ * Arguments:
+ * pAuth is the authorization for which we are computing the timeout
+ * seconds is the number of seconds we want to wait
+ *
+ * Returns:
+ * the number of milliseconds that the auth timer should be set to
+ *
+ * Side Effects:
+ * Sets pAuth->secondsRemaining to any "overflow" amount of time
+ * that didn't fit in 32 bits worth of milliseconds
+ */
+
+static CARD32
+SecurityComputeAuthorizationTimeout(
+ SecurityAuthorizationPtr pAuth,
+ unsigned int seconds)
+{
+ /* maxSecs is the number of full seconds that can be expressed in
+ * 32 bits worth of milliseconds
+ */
+ CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND;
+
+ if (seconds > maxSecs)
+ { /* only come here if we want to wait more than 49 days */
+ pAuth->secondsRemaining = seconds - maxSecs;
+ return maxSecs * MILLI_PER_SECOND;
+ }
+ else
+ { /* by far the common case */
+ pAuth->secondsRemaining = 0;
+ return seconds * MILLI_PER_SECOND;
+ }
+} /* SecurityStartAuthorizationTimer */
+
+/* SecurityAuthorizationExpired
+ *
+ * This function is passed as an argument to TimerSet and gets called from
+ * the timer manager in the os layer when its time is up.
+ *
+ * Arguments:
+ * timer is the timer for this authorization.
+ * time is the current time.
+ * pval is the authorization whose time is up.
+ *
+ * Returns:
+ * A new time delay in milliseconds if the timer should wait some
+ * more, else zero.
+ *
+ * Side Effects:
+ * Frees the authorization resource if the timeout period is really
+ * over, otherwise recomputes pAuth->secondsRemaining.
+ */
+
+static CARD32
+SecurityAuthorizationExpired(
+ OsTimerPtr timer,
+ CARD32 time,
+ void * pval)
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval;
+
+ assert(pAuth->timer == timer);
+
+ if (pAuth->secondsRemaining)
+ {
+ return SecurityComputeAuthorizationTimeout(pAuth,
+ pAuth->secondsRemaining);
+ }
+ else
+ {
+ FreeResource(pAuth->id, RT_NONE);
+ return 0;
+ }
+} /* SecurityAuthorizationExpired */
+
+/* SecurityStartAuthorizationTimer
+ *
+ * Arguments:
+ * pAuth is the authorization whose timer should be started.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * A timer is started, set to expire after the timeout period for
+ * this authorization. When it expires, the function
+ * SecurityAuthorizationExpired will be called.
+ */
+
+static void
+SecurityStartAuthorizationTimer(
+ SecurityAuthorizationPtr pAuth)
+{
+ pAuth->timer = TimerSet(pAuth->timer, 0,
+ SecurityComputeAuthorizationTimeout(pAuth, pAuth->timeout),
+ SecurityAuthorizationExpired, pAuth);
+} /* SecurityStartAuthorizationTimer */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcSecurityQueryVersion(
+ ClientPtr client)
+{
+ /* REQUEST(xSecurityQueryVersionReq); */
+ xSecurityQueryVersionReply rep;
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = SERVER_SECURITY_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SECURITY_MINOR_VERSION;
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, SIZEOF(xSecurityQueryVersionReply),
+ &rep);
+ return (client->noClientException);
+} /* ProcSecurityQueryVersion */
+
+
+static int
+SecurityEventSelectForAuthorization(
+ SecurityAuthorizationPtr pAuth,
+ ClientPtr client,
+ Mask mask)
+{
+ OtherClients *pEventClient;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (SameClient(pEventClient, client))
+ {
+ if (mask == 0)
+ FreeResource(pEventClient->resource, RT_NONE);
+ else
+ pEventClient->mask = mask;
+ return Success;
+ }
+ }
+
+ pEventClient = (OtherClients *) malloc(sizeof(OtherClients));
+ if (!pEventClient)
+ return BadAlloc;
+ pEventClient->mask = mask;
+ pEventClient->resource = FakeClientID(client->index);
+ pEventClient->next = pAuth->eventClients;
+ if (!AddResource(pEventClient->resource, RTEventClient,
+ (void *)pAuth))
+ {
+ free(pEventClient);
+ return BadAlloc;
+ }
+ pAuth->eventClients = pEventClient;
+
+ return Success;
+} /* SecurityEventSelectForAuthorization */
+
+
+static int
+ProcSecurityGenerateAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ int len; /* request length in CARD32s*/
+ Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */
+ SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */
+ int err; /* error to return from this function */
+ XID authId; /* authorization ID assigned by os layer */
+ xSecurityGenerateAuthorizationReply rep; /* reply struct */
+ unsigned int trustLevel; /* trust level of new auth */
+ XID group; /* group of new auth */
+ CARD32 timeout; /* timeout of new auth */
+ CARD32 *values; /* list of supplied attributes */
+ char *protoname; /* auth proto name sent in request */
+ char *protodata; /* auth proto data sent in request */
+ unsigned int authdata_len; /* # bytes of generated auth data */
+ char *pAuthdata; /* generated auth data */
+ Mask eventMask; /* what events on this auth does client want */
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ /* check request length */
+
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ len = SIZEOF(xSecurityGenerateAuthorizationReq) >> 2;
+ len += (stuff->nbytesAuthProto + (unsigned)3) >> 2;
+ len += (stuff->nbytesAuthData + (unsigned)3) >> 2;
+ values = ((CARD32 *)stuff) + len;
+ len += Ones(stuff->valueMask);
+ if (client->req_len != len)
+ return BadLength;
+
+ /* check valuemask */
+ if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes)
+ {
+ client->errorValue = stuff->valueMask;
+ return BadValue;
+ }
+
+ /* check timeout */
+ timeout = 60;
+ if (stuff->valueMask & XSecurityTimeout)
+ {
+ timeout = *values++;
+ }
+
+ /* check trustLevel */
+ trustLevel = XSecurityClientUntrusted;
+ if (stuff->valueMask & XSecurityTrustLevel)
+ {
+ trustLevel = *values++;
+ if (trustLevel != XSecurityClientTrusted &&
+ trustLevel != XSecurityClientUntrusted)
+ {
+ client->errorValue = trustLevel;
+ return BadValue;
+ }
+ }
+
+ /* check group */
+ group = None;
+ if (stuff->valueMask & XSecurityGroup)
+ {
+ group = *values++;
+ if (SecurityValidateGroupCallback)
+ {
+ SecurityValidateGroupInfoRec vgi;
+ vgi.group = group;
+ vgi.valid = FALSE;
+ CallCallbacks(&SecurityValidateGroupCallback, (void *)&vgi);
+
+ /* if nobody said they recognized it, it's an error */
+
+ if (!vgi.valid)
+ {
+ client->errorValue = group;
+ return BadValue;
+ }
+ }
+ }
+
+ /* check event mask */
+ eventMask = 0;
+ if (stuff->valueMask & XSecurityEventMask)
+ {
+ eventMask = *values++;
+ if (eventMask & ~XSecurityAllEventMasks)
+ {
+ client->errorValue = eventMask;
+ return BadValue;
+ }
+ }
+
+ protoname = (char *)&stuff[1];
+ protodata = protoname + ((stuff->nbytesAuthProto + (unsigned)3) >> 2);
+
+ /* call os layer to generate the authorization */
+
+ authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname,
+ stuff->nbytesAuthData, protodata,
+ &authdata_len, &pAuthdata);
+ if ((XID) ~0L == authId)
+ {
+ err = SecurityErrorBase + XSecurityBadAuthorizationProtocol;
+ goto bailout;
+ }
+
+ /* now that we've added the auth, remember to remove it if we have to
+ * abort the request for some reason (like allocation failure)
+ */
+ removeAuth = TRUE;
+
+ /* associate additional information with this auth ID */
+
+ pAuth = (SecurityAuthorizationPtr)malloc(sizeof(SecurityAuthorizationRec));
+ if (!pAuth)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* fill in the auth fields */
+
+ pAuth->id = authId;
+ pAuth->timeout = timeout;
+ pAuth->group = group;
+ pAuth->trustLevel = trustLevel;
+ pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */
+ pAuth->secondsRemaining = 0;
+ pAuth->timer = NULL;
+ pAuth->eventClients = NULL;
+
+ /* handle event selection */
+ if (eventMask)
+ {
+ err = SecurityEventSelectForAuthorization(pAuth, client, eventMask);
+ if (err != Success)
+ goto bailout;
+ }
+
+ if (!AddResource(authId, SecurityAuthorizationResType, pAuth))
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* start the timer ticking */
+
+ if (pAuth->timeout != 0)
+ SecurityStartAuthorizationTimer(pAuth);
+
+ /* tell client the auth id and data */
+
+ rep.type = X_Reply;
+ rep.length = (authdata_len + 3) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.authId = authId;
+ rep.dataLength = authdata_len;
+
+ if (client->swapped)
+ {
+ swapl(&rep.length);
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.authId);
+ swaps(&rep.dataLength);
+ }
+
+ WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply),
+ &rep);
+ WriteToClient(client, authdata_len, pAuthdata);
+
+ SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n",
+ client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout,
+ pAuth->group, eventMask);
+
+ /* the request succeeded; don't call RemoveAuthorization or free pAuth */
+
+ removeAuth = FALSE;
+ pAuth = NULL;
+ err = client->noClientException;
+
+bailout:
+ if (removeAuth)
+ RemoveAuthorization(stuff->nbytesAuthProto, protoname,
+ authdata_len, pAuthdata);
+ if (pAuth) free(pAuth);
+ return err;
+
+} /* ProcSecurityGenerateAuthorization */
+
+static int
+ProcSecurityRevokeAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+ SecurityAuthorizationPtr pAuth;
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+
+ pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(client,
+ stuff->authId, SecurityAuthorizationResType, DixDestroyAccess);
+ if (!pAuth)
+ return SecurityErrorBase + XSecurityBadAuthorization;
+
+ FreeResource(stuff->authId, RT_NONE);
+ return Success;
+} /* ProcSecurityRevokeAuthorization */
+
+
+static int
+ProcSecurityDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return ProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return ProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return ProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* ProcSecurityDispatch */
+
+static int
+SProcSecurityQueryVersion(
+ ClientPtr client)
+{
+ REQUEST(xSecurityQueryVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ swaps(&stuff->majorVersion);
+ swaps(&stuff->minorVersion);
+ return ProcSecurityQueryVersion(client);
+} /* SProcSecurityQueryVersion */
+
+
+static int
+SProcSecurityGenerateAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ CARD32 *values;
+ unsigned long nvalues;
+ int values_offset;
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ swaps(&stuff->nbytesAuthProto);
+ swaps(&stuff->nbytesAuthData);
+ swapl(&stuff->valueMask);
+ values_offset = ((stuff->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((stuff->nbytesAuthData + (unsigned)3) >> 2);
+ if (values_offset >
+ stuff->length - (sz_xSecurityGenerateAuthorizationReq >> 2))
+ return BadLength;
+ values = (CARD32 *)(&stuff[1]) + values_offset;
+ nvalues = (((CARD32 *)stuff) + stuff->length) - values;
+ SwapLongs(values, nvalues);
+ return ProcSecurityGenerateAuthorization(client);
+} /* SProcSecurityGenerateAuthorization */
+
+
+static int
+SProcSecurityRevokeAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+ swapl(&stuff->authId);
+ return ProcSecurityRevokeAuthorization(client);
+} /* SProcSecurityRevokeAuthorization */
+
+
+static int
+SProcSecurityDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return SProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return SProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return SProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* SProcSecurityDispatch */
+
+static void
+SwapSecurityAuthorizationRevokedEvent(
+ xSecurityAuthorizationRevokedEvent *from,
+ xSecurityAuthorizationRevokedEvent *to)
+{
+ to->type = from->type;
+ to->detail = from->detail;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->authId, to->authId);
+}
+
+/* SecurityDetermineEventPropogationLimits
+ *
+ * This is a helper function for SecurityCheckDeviceAccess.
+ *
+ * Arguments:
+ * dev is the device for which the starting and stopping windows for
+ * event propogation should be determined.
+ * The values pointed to by ppWin and ppStopWin are not used.
+ *
+ * Returns:
+ * ppWin is filled in with a pointer to the window at which event
+ * propogation for the given device should start given the current
+ * state of the server (pointer position, window layout, etc.)
+ * ppStopWin is filled in with the window at which event propogation
+ * should stop; events should not go to ppStopWin.
+ *
+ * Side Effects: none.
+ */
+
+static void
+SecurityDetermineEventPropogationLimits(
+ DeviceIntPtr dev,
+ WindowPtr *ppWin,
+ WindowPtr *ppStopWin)
+{
+ WindowPtr pFocusWin = dev->focus ? dev->focus->win : NoneWin;
+
+ if (pFocusWin == NoneWin)
+ { /* no focus -- events don't go anywhere */
+ *ppWin = *ppStopWin = NULL;
+ return;
+ }
+
+ if (pFocusWin == PointerRootWin)
+ { /* focus follows the pointer */
+ *ppWin = GetSpriteWindow();
+ *ppStopWin = NULL; /* propogate all the way to the root */
+ }
+ else
+ { /* a real window is set for the focus */
+ WindowPtr pSpriteWin = GetSpriteWindow();
+ *ppStopWin = pFocusWin->parent; /* don't go past the focus window */
+
+ /* if the pointer is in a subwindow of the focus window, start
+ * at that subwindow, else start at the focus window itself
+ */
+ if (IsParent(pFocusWin, pSpriteWin))
+ *ppWin = pSpriteWin;
+ else *ppWin = pFocusWin;
+ }
+} /* SecurityDetermineEventPropogationLimits */
+
+
+/* SecurityCheckDeviceAccess
+ *
+ * Arguments:
+ * client is the client attempting to access a device.
+ * dev is the device being accessed.
+ * fromRequest is TRUE if the device access is a direct result of
+ * the client executing some request and FALSE if it is a
+ * result of the server trying to send an event (e.g. KeymapNotify)
+ * to the client.
+ * Returns:
+ * TRUE if the device access should be allowed, else FALSE.
+ *
+ * Side Effects:
+ * An audit message is generated if access is denied.
+ */
+
+Bool
+SecurityCheckDeviceAccess(client, dev, fromRequest)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ Bool fromRequest;
+{
+ WindowPtr pWin, pStopWin;
+ Bool untrusted_got_event;
+ Bool found_event_window;
+ Mask eventmask;
+ int reqtype = 0;
+
+ /* trusted clients always allowed to do anything */
+ if (client->trustLevel == XSecurityClientTrusted)
+ return TRUE;
+
+ /* device security other than keyboard is not implemented yet */
+ if (dev != inputInfo.keyboard)
+ return TRUE;
+
+ /* some untrusted client wants access */
+
+ if (fromRequest)
+ {
+ reqtype = ((xReq *)client->requestBuffer)->reqType;
+ switch (reqtype)
+ {
+ /* never allow these */
+ case X_ChangeKeyboardMapping:
+ case X_ChangeKeyboardControl:
+ case X_SetModifierMapping:
+ SecurityAudit("client %d attempted request %d\n",
+ client->index, reqtype);
+ return FALSE;
+ default:
+ break;
+ }
+ }
+
+ untrusted_got_event = FALSE;
+ found_event_window = FALSE;
+
+ if (dev->grab)
+ {
+ untrusted_got_event =
+ ((rClient(dev->grab))->trustLevel != XSecurityClientTrusted);
+ }
+ else
+ {
+ SecurityDetermineEventPropogationLimits(dev, &pWin, &pStopWin);
+
+ eventmask = KeyPressMask | KeyReleaseMask;
+ while ( (pWin != pStopWin) && !found_event_window)
+ {
+ OtherClients *other;
+
+ if (pWin->eventMask & eventmask)
+ {
+ found_event_window = TRUE;
+ client = wClient(pWin);
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ untrusted_got_event = TRUE;
+ }
+ }
+ if (wOtherEventMasks(pWin) & eventmask)
+ {
+ found_event_window = TRUE;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & eventmask)
+ {
+ client = rClient(other);
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ untrusted_got_event = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (wDontPropagateMask(pWin) & eventmask)
+ break;
+ pWin = pWin->parent;
+ } /* while propogating the event */
+ }
+
+ /* allow access by untrusted clients only if an event would have gone
+ * to an untrusted client
+ */
+
+ if (!untrusted_got_event)
+ {
+ char *devname = dev->name;
+ if (!devname) devname = "unnamed";
+ if (fromRequest)
+ SecurityAudit("client %d attempted request %d device %d (%s)\n",
+ client->index, reqtype, dev->id, devname);
+ else
+ SecurityAudit("client %d attempted to access device %d (%s)\n",
+ client->index, dev->id, devname);
+ }
+ return untrusted_got_event;
+} /* SecurityCheckDeviceAccess */
+
+
+
+/* SecurityAuditResourceIDAccess
+ *
+ * Arguments:
+ * client is the client doing the resource access.
+ * id is the resource id.
+ *
+ * Returns: NULL
+ *
+ * Side Effects:
+ * An audit message is generated with details of the denied
+ * resource access.
+ */
+
+static void *
+SecurityAuditResourceIDAccess(
+ ClientPtr client,
+ XID id)
+{
+ int cid = CLIENT_ID(id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+ switch (reqtype)
+ {
+ case X_ChangeProperty:
+ case X_DeleteProperty:
+ case X_GetProperty:
+ {
+ xChangePropertyReq *req =
+ (xChangePropertyReq *)client->requestBuffer;
+ int propertyatom = req->property;
+ const char *propertyname = NameForAtom(propertyatom);
+
+ SecurityAudit("client %d attempted request %d with window 0x%x property %s of client %d\n",
+ client->index, reqtype, id, propertyname, cid);
+ break;
+ }
+ default:
+ {
+ SecurityAudit("client %d attempted request %d with resource 0x%x of client %d\n",
+ client->index, reqtype, id, cid);
+ break;
+ }
+ }
+ return NULL;
+} /* SecurityAuditResourceIDAccess */
+
+
+/* SecurityCheckResourceIDAccess
+ *
+ * This function gets plugged into client->CheckAccess and is called from
+ * SecurityLookupIDByType/Class to determine if the client can access the
+ * resource.
+ *
+ * Arguments:
+ * client is the client doing the resource access.
+ * id is the resource id.
+ * rtype is its type or class.
+ * access_mode represents the intended use of the resource; see
+ * resource.h.
+ * rval is a pointer to the resource structure for this resource.
+ *
+ * Returns:
+ * If access is granted, the value of rval that was passed in, else NULL.
+ *
+ * Side Effects:
+ * Disallowed resource accesses are audited.
+ */
+
+static void *
+SecurityCheckResourceIDAccess(
+ ClientPtr client,
+ XID id,
+ RESTYPE rtype,
+ Mask access_mode,
+ void * rval)
+{
+ int cid = CLIENT_ID(id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+
+ if (DixUnknownAccess == access_mode)
+ return rval; /* for compatibility, we have to allow access */
+
+ switch (reqtype)
+ { /* these are always allowed */
+ case X_QueryTree:
+ case X_TranslateCoords:
+ case X_GetGeometry:
+ /* property access is controlled in SecurityCheckPropertyAccess */
+ case X_GetProperty:
+ case X_ChangeProperty:
+ case X_DeleteProperty:
+ case X_RotateProperties:
+ case X_ListProperties:
+ return rval;
+ default:
+ break;
+ }
+
+ if (cid != 0)
+ { /* not a server-owned resource */
+ /*
+ * The following 'if' restricts clients to only access resources at
+ * the same trustLevel. Since there are currently only two trust levels,
+ * and trusted clients never call this function, this degenerates into
+ * saying that untrusted clients can only access resources of other
+ * untrusted clients. One way to add the notion of groups would be to
+ * allow values other than Trusted (0) and Untrusted (1) for this field.
+ * Clients at the same trust level would be able to use each other's
+ * resources, but not those of clients at other trust levels. I haven't
+ * tried it, but this probably mostly works already. The obvious
+ * competing alternative for grouping clients for security purposes is to
+ * use app groups. dpw
+ */
+ if (client->trustLevel == clients[cid]->trustLevel
+ )
+ return rval;
+ else
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ else /* server-owned resource - probably a default colormap or root window */
+ {
+ if (RT_WINDOW == rtype || RC_DRAWABLE == rtype)
+ {
+ switch (reqtype)
+ { /* the following operations are allowed on root windows */
+ case X_CreatePixmap:
+ case X_CreateGC:
+ case X_CreateWindow:
+ case X_CreateColormap:
+ case X_ListProperties:
+ case X_GrabPointer:
+ case X_UngrabButton:
+ case X_QueryBestSize:
+ case X_GetWindowAttributes:
+ break;
+ case X_SendEvent:
+ { /* see if it is an event specified by the ICCCM */
+ xSendEventReq *req = (xSendEventReq *)
+ (client->requestBuffer);
+ if (req->propagate == xTrue
+ ||
+ (req->eventMask != ColormapChangeMask &&
+ req->eventMask != StructureNotifyMask &&
+ req->eventMask !=
+ (SubstructureRedirectMask|SubstructureNotifyMask)
+ )
+ ||
+ (req->event.u.u.type != UnmapNotify &&
+ req->event.u.u.type != ConfigureRequest &&
+ req->event.u.u.type != ClientMessage
+ )
+ )
+ { /* not an ICCCM event */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ break;
+ } /* case X_SendEvent on root */
+
+ case X_ChangeWindowAttributes:
+ { /* Allow selection of PropertyNotify and StructureNotify
+ * events on the root.
+ */
+ xChangeWindowAttributesReq *req =
+ (xChangeWindowAttributesReq *)(client->requestBuffer);
+ if (req->valueMask == CWEventMask)
+ {
+ CARD32 value = *((CARD32 *)(req + 1));
+ if ( (value &
+ ~(PropertyChangeMask|StructureNotifyMask)) == 0)
+ break;
+ }
+ return SecurityAuditResourceIDAccess(client, id);
+ } /* case X_ChangeWindowAttributes on root */
+
+ default:
+ {
+ /* others not allowed */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ }
+ } /* end server-owned window or drawable */
+ else if (SecurityAuthorizationResType == rtype)
+ {
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)rval;
+ if (pAuth->trustLevel != client->trustLevel)
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ else if (RT_COLORMAP != rtype)
+ { /* don't allow anything else besides colormaps */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ }
+ return rval;
+} /* SecurityCheckResourceIDAccess */
+
+
+/* SecurityClientStateCallback
+ *
+ * Arguments:
+ * pcbl is &ClientStateCallback.
+ * nullata is NULL.
+ * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ * which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *
+ * If a new client is connecting, its authorization ID is copied to
+ * client->authID. If this is a generated authorization, its reference
+ * count is bumped, its timer is cancelled if it was running, and its
+ * trustlevel is copied to client->trustLevel.
+ *
+ * If a client is disconnecting and the client was using a generated
+ * authorization, the authorization's reference count is decremented, and
+ * if it is now zero, the timer for this authorization is started.
+ */
+
+static void
+SecurityClientStateCallback(
+ CallbackListPtr *pcbl,
+ void * nulldata,
+ void * calldata)
+{
+ NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+ ClientPtr client = pci->client;
+
+ switch (client->clientState)
+ {
+ case ClientStateRunning:
+ {
+ XID authId = AuthorizationIDOfClient(client);
+ SecurityAuthorizationPtr pAuth;
+
+ client->authId = authId;
+ pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
+ SecurityAuthorizationResType);
+ if (pAuth)
+ { /* it is a generated authorization */
+ pAuth->refcnt++;
+ if (pAuth->refcnt == 1)
+ {
+ if (pAuth->timer) TimerCancel(pAuth->timer);
+ }
+ client->trustLevel = pAuth->trustLevel;
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ client->CheckAccess = SecurityCheckResourceIDAccess;
+ client->requestVector = client->swapped ?
+ SwappedUntrustedProcVector : UntrustedProcVector;
+ }
+ }
+ break;
+ }
+ case ClientStateGone:
+ case ClientStateRetained: /* client disconnected */
+ {
+ XID authId = client->authId;
+ SecurityAuthorizationPtr pAuth;
+
+ pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
+ SecurityAuthorizationResType);
+ if (pAuth)
+ { /* it is a generated authorization */
+ pAuth->refcnt--;
+ if (pAuth->refcnt == 0)
+ {
+ SecurityStartAuthorizationTimer(pAuth);
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+} /* SecurityClientStateCallback */
+
+/* SecurityCensorImage
+ *
+ * Called after pScreen->GetImage to prevent pieces or trusted windows from
+ * being returned in image data from an untrusted window.
+ *
+ * Arguments:
+ * client is the client doing the GetImage.
+ * pVisibleRegion is the visible region of the window.
+ * widthBytesLine is the width in bytes of one horizontal line in pBuf.
+ * pDraw is the source window.
+ * x, y, w, h is the rectangle of image data from pDraw in pBuf.
+ * format is the format of the image data in pBuf: ZPixmap or XYPixmap.
+ * pBuf is the image data.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Any part of the rectangle (x, y, w, h) that is outside the visible
+ * region of the window will be destroyed (overwritten) in pBuf.
+ */
+void
+SecurityCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h,
+ format, pBuf)
+ ClientPtr client;
+ RegionPtr pVisibleRegion;
+ long widthBytesLine;
+ DrawablePtr pDraw;
+ int x, y, w, h;
+ unsigned int format;
+ char * pBuf;
+{
+ RegionRec imageRegion; /* region representing x,y,w,h */
+ RegionRec censorRegion; /* region to obliterate */
+ BoxRec imageBox;
+ int nRects;
+
+ imageBox.x1 = x;
+ imageBox.y1 = y;
+ imageBox.x2 = x + w;
+ imageBox.y2 = y + h;
+ RegionInit(&imageRegion, &imageBox, 1);
+ RegionNull(&censorRegion);
+
+ /* censorRegion = imageRegion - visibleRegion */
+ RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion);
+ nRects = RegionNumRects(&censorRegion);
+ if (nRects > 0)
+ { /* we have something to censor */
+ GCPtr pScratchGC = NULL;
+ PixmapPtr pPix = NULL;
+ xRectangle *pRects = NULL;
+ Bool failed = FALSE;
+ int depth = 1;
+ int bitsPerPixel = 1;
+ int i;
+ BoxPtr pBox;
+
+ /* convert region to list-of-rectangles for PolyFillRect */
+
+ pRects = (xRectangle *)malloc(nRects * sizeof(xRectangle *));
+ if (!pRects)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+ for (pBox = RegionRects(&censorRegion), i = 0;
+ i < nRects;
+ i++, pBox++)
+ {
+ pRects[i].x = pBox->x1;
+ pRects[i].y = pBox->y1 - imageBox.y1;
+ pRects[i].width = pBox->x2 - pBox->x1;
+ pRects[i].height = pBox->y2 - pBox->y1;
+ }
+
+ /* use pBuf as a fake pixmap */
+
+ if (format == ZPixmap)
+ {
+ depth = pDraw->depth;
+ bitsPerPixel = pDraw->bitsPerPixel;
+ }
+
+ pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
+ depth, bitsPerPixel,
+ widthBytesLine, (void *)pBuf);
+ if (!pPix)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+
+ pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
+ if (!pScratchGC)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+
+ ValidateGC(&pPix->drawable, pScratchGC);
+ (* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
+ pScratchGC, nRects, pRects);
+
+ failSafe:
+ if (failed)
+ {
+ /* Censoring was not completed above. To be safe, wipe out
+ * all the image data so that nothing trusted gets out.
+ */
+ bzero(pBuf, (int)(widthBytesLine * h));
+ }
+ if (pRects) free(pRects);
+ if (pScratchGC) FreeScratchGC(pScratchGC);
+ if (pPix) FreeScratchPixmapHeader(pPix);
+ }
+ RegionUninit(&imageRegion);
+ RegionUninit(&censorRegion);
+} /* SecurityCensorImage */
+
+/**********************************************************************/
+
+typedef struct _PropertyAccessRec {
+ ATOM name;
+ ATOM mustHaveProperty;
+ char *mustHaveValue;
+ char windowRestriction;
+#define SecurityAnyWindow 0
+#define SecurityRootWindow 1
+#define SecurityWindowWithProperty 2
+ char readAction;
+ char writeAction;
+ char destroyAction;
+ struct _PropertyAccessRec *next;
+} PropertyAccessRec, *PropertyAccessPtr;
+
+static PropertyAccessPtr PropertyAccessList = NULL;
+static char SecurityDefaultAction = SecurityErrorOperation;
+static char *SecurityPolicyFile = DEFAULTPOLICYFILE;
+static ATOM SecurityMaxPropertyName = 0;
+
+static char *SecurityKeywords[] = {
+#define SecurityKeywordComment 0
+ "#",
+#define SecurityKeywordProperty 1
+ "property",
+#define SecurityKeywordSitePolicy 2
+ "sitepolicy",
+#define SecurityKeywordRoot 3
+ "root",
+#define SecurityKeywordAny 4
+ "any"
+};
+
+#define NUMKEYWORDS (sizeof(SecurityKeywords) / sizeof(char *))
+
+#undef PROPDEBUG
+/*#define PROPDEBUG 1*/
+
+static void
+SecurityFreePropertyAccessList(void)
+{
+ while (PropertyAccessList)
+ {
+ PropertyAccessPtr freeit = PropertyAccessList;
+ PropertyAccessList = PropertyAccessList->next;
+ free(freeit);
+ }
+} /* SecurityFreePropertyAccessList */
+
+#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') )
+
+static char *
+SecuritySkipWhitespace(
+ char *p)
+{
+ while (SecurityIsWhitespace(*p))
+ p++;
+ return p;
+} /* SecuritySkipWhitespace */
+
+
+static char *
+SecurityParseString(
+ char **rest)
+{
+ char *startOfString;
+ char *s = *rest;
+ char endChar = 0;
+
+ s = SecuritySkipWhitespace(s);
+
+ if (*s == '"' || *s == '\'')
+ {
+ endChar = *s++;
+ startOfString = s;
+ while (*s && (*s != endChar))
+ s++;
+ }
+ else
+ {
+ startOfString = s;
+ while (*s && !SecurityIsWhitespace(*s))
+ s++;
+ }
+ if (*s)
+ {
+ *s = '\0';
+ *rest = s + 1;
+ return startOfString;
+ }
+ else
+ {
+ *rest = s;
+ return (endChar) ? NULL : startOfString;
+ }
+} /* SecurityParseString */
+
+
+static int
+SecurityParseKeyword(
+ char **p)
+{
+ int i;
+ char *s = *p;
+ s = SecuritySkipWhitespace(s);
+ for (i = 0; i < NUMKEYWORDS; i++)
+ {
+ int len = strlen(SecurityKeywords[i]);
+ if (strncmp(s, SecurityKeywords[i], len) == 0)
+ {
+ *p = s + len;
+ return (i);
+ }
+ }
+ *p = s;
+ return -1;
+} /* SecurityParseKeyword */
+
+
+static Bool
+SecurityParsePropertyAccessRule(
+ char *p)
+{
+ char *propname;
+ char c;
+ char action = SecurityDefaultAction;
+ char readAction, writeAction, destroyAction;
+ PropertyAccessPtr pacl, prev, cur;
+ char *mustHaveProperty = NULL;
+ char *mustHaveValue = NULL;
+ Bool invalid;
+ char windowRestriction;
+ int size;
+ int keyword;
+
+ /* get property name */
+ propname = SecurityParseString(&p);
+ if (!propname || (strlen(propname) == 0))
+ return FALSE;
+
+ /* get window on which property must reside for rule to apply */
+
+ keyword = SecurityParseKeyword(&p);
+ if (keyword == SecurityKeywordRoot)
+ windowRestriction = SecurityRootWindow;
+ else if (keyword == SecurityKeywordAny)
+ windowRestriction = SecurityAnyWindow;
+ else /* not root or any, must be a property name */
+ {
+ mustHaveProperty = SecurityParseString(&p);
+ if (!mustHaveProperty || (strlen(mustHaveProperty) == 0))
+ return FALSE;
+ windowRestriction = SecurityWindowWithProperty;
+ p = SecuritySkipWhitespace(p);
+ if (*p == '=')
+ { /* property value is specified too */
+ p++; /* skip over '=' */
+ mustHaveValue = SecurityParseString(&p);
+ if (!mustHaveValue)
+ return FALSE;
+ }
+ }
+
+ /* get operations and actions */
+
+ invalid = FALSE;
+ readAction = writeAction = destroyAction = SecurityDefaultAction;
+ while ( (c = *p++) && !invalid)
+ {
+ switch (c)
+ {
+ case 'i': action = SecurityIgnoreOperation; break;
+ case 'a': action = SecurityAllowOperation; break;
+ case 'e': action = SecurityErrorOperation; break;
+
+ case 'r': readAction = action; break;
+ case 'w': writeAction = action; break;
+ case 'd': destroyAction = action; break;
+
+ default :
+ if (!SecurityIsWhitespace(c))
+ invalid = TRUE;
+ break;
+ }
+ }
+ if (invalid)
+ return FALSE;
+
+ /* We've successfully collected all the information needed for this
+ * property access rule. Now record it in a PropertyAccessRec.
+ */
+ size = sizeof(PropertyAccessRec);
+
+ /* If there is a property value string, allocate space for it
+ * right after the PropertyAccessRec.
+ */
+ if (mustHaveValue)
+ size += strlen(mustHaveValue) + 1;
+ pacl = (PropertyAccessPtr)malloc(size);
+ if (!pacl)
+ return FALSE;
+
+ pacl->name = MakeAtom(propname, strlen(propname), TRUE);
+ if (pacl->name == BAD_RESOURCE)
+ {
+ free(pacl);
+ return FALSE;
+ }
+ if (mustHaveProperty)
+ {
+ pacl->mustHaveProperty = MakeAtom(mustHaveProperty,
+ strlen(mustHaveProperty), TRUE);
+ if (pacl->mustHaveProperty == BAD_RESOURCE)
+ {
+ free(pacl);
+ return FALSE;
+ }
+ }
+ else
+ pacl->mustHaveProperty = 0;
+
+ if (mustHaveValue)
+ {
+ pacl->mustHaveValue = (char *)(pacl + 1);
+ strcpy(pacl->mustHaveValue, mustHaveValue);
+ }
+ else
+ pacl->mustHaveValue = NULL;
+
+ SecurityMaxPropertyName = max(SecurityMaxPropertyName, pacl->name);
+
+ pacl->windowRestriction = windowRestriction;
+ pacl->readAction = readAction;
+ pacl->writeAction = writeAction;
+ pacl->destroyAction = destroyAction;
+
+ /* link the new rule into the list of rules in order of increasing
+ * property name (atom) value to make searching easier
+ */
+
+ for (prev = NULL, cur = PropertyAccessList;
+ cur && cur->name <= pacl->name;
+ prev = cur, cur = cur->next)
+ ;
+ if (!prev)
+ {
+ pacl->next = cur;
+ PropertyAccessList = pacl;
+ }
+ else
+ {
+ prev->next = pacl;
+ pacl->next = cur;
+ }
+ return TRUE;
+} /* SecurityParsePropertyAccessRule */
+
+static char **SecurityPolicyStrings = NULL;
+static int nSecurityPolicyStrings = 0;
+
+static Bool
+SecurityParseSitePolicy(
+ char *p)
+{
+ char *policyStr = SecurityParseString(&p);
+ char *copyPolicyStr;
+ char **newStrings;
+
+ if (!policyStr)
+ return FALSE;
+
+ copyPolicyStr = (char *)malloc(strlen(policyStr) + 1);
+ if (!copyPolicyStr)
+ return TRUE;
+ strcpy(copyPolicyStr, policyStr);
+ newStrings = (char **)realloc(SecurityPolicyStrings,
+ sizeof (char *) * (nSecurityPolicyStrings + 1));
+ if (!newStrings)
+ {
+ free(copyPolicyStr);
+ return TRUE;
+ }
+
+ SecurityPolicyStrings = newStrings;
+ SecurityPolicyStrings[nSecurityPolicyStrings++] = copyPolicyStr;
+
+ return TRUE;
+
+} /* SecurityParseSitePolicy */
+
+
+char **
+SecurityGetSitePolicyStrings(n)
+ int *n;
+{
+ *n = nSecurityPolicyStrings;
+ return SecurityPolicyStrings;
+} /* SecurityGetSitePolicyStrings */
+
+static void
+SecurityFreeSitePolicyStrings(void)
+{
+ if (SecurityPolicyStrings)
+ {
+ assert(nSecurityPolicyStrings);
+ while (nSecurityPolicyStrings--)
+ {
+ free(SecurityPolicyStrings[nSecurityPolicyStrings]);
+ }
+ free(SecurityPolicyStrings);
+ SecurityPolicyStrings = NULL;
+ nSecurityPolicyStrings = 0;
+ }
+} /* SecurityFreeSitePolicyStrings */
+
+
+static void
+SecurityLoadPropertyAccessList(void)
+{
+ FILE *f;
+ int lineNumber = 0;
+
+ SecurityMaxPropertyName = 0;
+
+#ifdef NXAGENT_SERVER
+
+ if (!_NXGetPolicyFilePath(SecurityPolicyFile))
+ {
+ return;
+ }
+
+#else
+
+ if (!SecurityPolicyFile)
+ return;
+
+#endif
+
+#ifdef NXAGENT_SERVER
+
+ f = Fopen(_NXGetPolicyFilePath(SecurityPolicyFile), "r");
+
+#else
+
+ f = Fopen(SecurityPolicyFile, "r");
+
+#endif
+
+ if (!f)
+ {
+#ifdef NXAGENT_SERVER
+
+ ErrorF("error opening security policy file %s\n",
+ _NXGetPolicyFilePath(SecurityPolicyFile));
+
+#else
+
+ ErrorF("error opening security policy file %s\n",
+ SecurityPolicyFile);
+
+#endif
+
+ return;
+ }
+
+ while (!feof(f))
+ {
+ char buf[200];
+ Bool validLine;
+ char *p;
+
+ if (!(p = fgets(buf, sizeof(buf), f)))
+ break;
+ lineNumber++;
+
+ /* if first line, check version number */
+ if (lineNumber == 1)
+ {
+ char *v = SecurityParseString(&p);
+ if (strcmp(v, SECURITY_POLICY_FILE_VERSION) != 0)
+ {
+
+#ifdef NXAGENT_SERVER
+
+ ErrorF("%s: invalid security policy file version, ignoring file\n",
+ _NXGetPolicyFilePath(SecurityPolicyFile));
+
+#else
+
+ ErrorF("%s: invalid security policy file version, ignoring file\n",
+ SecurityPolicyFile);
+
+#endif
+
+ break;
+ }
+ validLine = TRUE;
+ }
+ else
+ {
+ switch (SecurityParseKeyword(&p))
+ {
+ case SecurityKeywordComment:
+ validLine = TRUE;
+ break;
+
+ case SecurityKeywordProperty:
+ validLine = SecurityParsePropertyAccessRule(p);
+ break;
+
+ case SecurityKeywordSitePolicy:
+ validLine = SecurityParseSitePolicy(p);
+ break;
+
+ default:
+ validLine = (*p == '\0'); /* blank lines OK, others not */
+ break;
+ }
+ }
+
+#ifdef NXAGENT_SERVER
+
+ if (!validLine)
+ {
+ ErrorF("Line %d of %s invalid, ignoring\n",
+ lineNumber, _NXGetPolicyFilePath(SecurityPolicyFile));
+ }
+
+#else
+
+ if (!validLine)
+ ErrorF("Line %d of %s invalid, ignoring\n",
+ lineNumber, SecurityPolicyFile);
+
+#endif
+
+ } /* end while more input */
+
+#ifdef PROPDEBUG
+ {
+ PropertyAccessPtr pacl;
+ char *op = "aie";
+ for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
+ {
+ ErrorF("property %s ", NameForAtom(pacl->name));
+ switch (pacl->windowRestriction)
+ {
+ case SecurityAnyWindow: ErrorF("any "); break;
+ case SecurityRootWindow: ErrorF("root "); break;
+ case SecurityWindowWithProperty:
+ {
+ ErrorF("%s ", NameForAtom(pacl->mustHaveProperty));
+ if (pacl->mustHaveValue)
+ ErrorF(" = \"%s\" ", pacl->mustHaveValue);
+
+ }
+ break;
+ }
+ ErrorF("%cr %cw %cd\n", op[pacl->readAction],
+ op[pacl->writeAction], op[pacl->destroyAction]);
+ }
+ }
+#endif /* PROPDEBUG */
+
+ Fclose(f);
+} /* SecurityLoadPropertyAccessList */
+
+
+static Bool
+SecurityMatchString(
+ char *ws,
+ char *cs)
+{
+ while (*ws && *cs)
+ {
+ if (*ws == '*')
+ {
+ Bool match = FALSE;
+ ws++;
+ while (!(match = SecurityMatchString(ws, cs)) && *cs)
+ {
+ cs++;
+ }
+ return match;
+ }
+ else if (*ws == *cs)
+ {
+ ws++;
+ cs++;
+ }
+ else break;
+ }
+ return ( ( (*ws == '\0') || ((*ws == '*') && *(ws+1) == '\0') )
+ && (*cs == '\0') );
+} /* SecurityMatchString */
+
+#ifdef PROPDEBUG
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+
+char
+SecurityCheckPropertyAccess(client, pWin, propertyName, access_mode)
+ ClientPtr client;
+ WindowPtr pWin;
+ ATOM propertyName;
+ Mask access_mode;
+{
+ PropertyAccessPtr pacl;
+ char action = SecurityDefaultAction;
+
+ /* if client trusted or window untrusted, allow operation */
+
+ if ( (client->trustLevel == XSecurityClientTrusted) ||
+ (wClient(pWin)->trustLevel != XSecurityClientTrusted) )
+ return SecurityAllowOperation;
+
+#ifdef PROPDEBUG
+ /* For testing, it's more convenient if the property rules file gets
+ * reloaded whenever it changes, so we can rapidly try things without
+ * having to reset the server.
+ */
+ {
+ struct stat buf;
+ static time_t lastmod = 0;
+
+#ifdef NXAGENT_SERVER
+
+ int ret = stat(_NXGetPolicyFilePath(SecurityPolicyFile), &buf);
+
+#else
+
+ int ret = stat(SecurityPolicyFile , &buf);
+
+#endif
+
+ if ( (ret == 0) && (buf.st_mtime > lastmod) )
+ {
+ ErrorF("reloading property rules\n");
+ SecurityFreePropertyAccessList();
+ SecurityLoadPropertyAccessList();
+ lastmod = buf.st_mtime;
+ }
+ }
+#endif
+
+ /* If the property atom is bigger than any atoms on the list,
+ * we know we won't find it, so don't even bother looking.
+ */
+ if (propertyName <= SecurityMaxPropertyName)
+ {
+ /* untrusted client operating on trusted window; see if it's allowed */
+
+ for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
+ {
+ if (pacl->name < propertyName)
+ continue;
+ if (pacl->name > propertyName)
+ break;
+
+ /* pacl->name == propertyName, so see if it applies to this window */
+
+ switch (pacl->windowRestriction)
+ {
+ case SecurityAnyWindow: /* always applies */
+ break;
+
+ case SecurityRootWindow:
+ {
+ /* if not a root window, this rule doesn't apply */
+ if (pWin->parent)
+ continue;
+ }
+ break;
+
+ case SecurityWindowWithProperty:
+ {
+ PropertyPtr pProp = wUserProps (pWin);
+ Bool match = FALSE;
+ char *p;
+ char *pEndData;
+
+ while (pProp)
+ {
+ if (pProp->propertyName == pacl->mustHaveProperty)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp)
+ continue;
+ if (!pacl->mustHaveValue)
+ break;
+ if (pProp->type != XA_STRING || pProp->format != 8)
+ continue;
+
+ p = pProp->data;
+ pEndData = ((char *)pProp->data) + pProp->size;
+ while (!match && p < pEndData)
+ {
+ if (SecurityMatchString(pacl->mustHaveValue, p))
+ match = TRUE;
+ else
+ { /* skip to the next string */
+ while (*p++ && p < pEndData)
+ ;
+ }
+ }
+ if (!match)
+ continue;
+ }
+ break; /* end case SecurityWindowWithProperty */
+ } /* end switch on windowRestriction */
+
+ /* If we get here, the property access rule pacl applies.
+ * If pacl doesn't apply, something above should have
+ * executed a continue, which will skip the follwing code.
+ */
+ action = SecurityAllowOperation;
+ if (access_mode & DixReadAccess)
+ action = max(action, pacl->readAction);
+ if (access_mode & DixWriteAccess)
+ action = max(action, pacl->writeAction);
+ if (access_mode & DixDestroyAccess)
+ action = max(action, pacl->destroyAction);
+ break;
+ } /* end for each pacl */
+ } /* end if propertyName <= SecurityMaxPropertyName */
+
+ if (SecurityAllowOperation != action)
+ { /* audit the access violation */
+ int cid = CLIENT_ID(pWin->drawable.id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+ char *actionstr = (SecurityIgnoreOperation == action) ?
+ "ignored" : "error";
+ SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n",
+ client->index, reqtype, pWin->drawable.id,
+ NameForAtom(propertyName), propertyName, cid, actionstr);
+ }
+ return action;
+} /* SecurityCheckPropertyAccess */
+
+
+/* SecurityResetProc
+ *
+ * Arguments:
+ * extEntry is the extension information for the security extension.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by Security at server shutdown time.
+ */
+
+static void
+SecurityResetProc(
+ ExtensionEntry *extEntry)
+{
+ SecurityFreePropertyAccessList();
+ SecurityFreeSitePolicyStrings();
+} /* SecurityResetProc */
+
+
+int
+XSecurityOptions(argc, argv, i)
+ int argc;
+ char **argv;
+ int i;
+{
+ if (strcmp(argv[i], "-sp") == 0)
+ {
+ if (i < argc)
+ SecurityPolicyFile = argv[++i];
+ return (i + 1);
+ }
+ return (i);
+} /* XSecurityOptions */
+
+
+
+/* SecurityExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Enables the Security extension if possible.
+ */
+
+void
+SecurityExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ SecurityAuthorizationResType =
+ CreateNewResourceType(SecurityDeleteAuthorization);
+
+ RTEventClient = CreateNewResourceType(
+ SecurityDeleteAuthorizationEventClient);
+
+ if (!SecurityAuthorizationResType || !RTEventClient)
+ return;
+
+ RTEventClient |= RC_NEVERRETAIN;
+
+ if (!AddCallback(&ClientStateCallback, SecurityClientStateCallback, NULL))
+ return;
+
+ extEntry = AddExtension(SECURITY_EXTENSION_NAME,
+ XSecurityNumberEvents, XSecurityNumberErrors,
+ ProcSecurityDispatch, SProcSecurityDispatch,
+ SecurityResetProc, StandardMinorOpcode);
+
+ SecurityErrorBase = extEntry->errorBase;
+ SecurityEventBase = extEntry->eventBase;
+
+ EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] =
+ (EventSwapPtr)SwapSecurityAuthorizationRevokedEvent;
+
+ /* initialize untrusted proc vectors */
+
+ for (i = 0; i < 128; i++)
+ {
+ UntrustedProcVector[i] = ProcVector[i];
+ SwappedUntrustedProcVector[i] = SwappedProcVector[i];
+ }
+
+ /* make sure insecure extensions are not allowed */
+
+ for (i = 128; i < 256; i++)
+ {
+ if (!UntrustedProcVector[i])
+ {
+ UntrustedProcVector[i] = ProcBadRequest;
+ SwappedUntrustedProcVector[i] = ProcBadRequest;
+ }
+ }
+
+ SecurityLoadPropertyAccessList();
+
+} /* SecurityExtensionInit */
diff --git a/nx-X11/programs/Xserver/Xext/shape.c b/nx-X11/programs/Xserver/Xext/shape.c
new file mode 100644
index 000000000..fa7f9e2e9
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/shape.c
@@ -0,0 +1,1310 @@
+/************************************************************
+
+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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include <X11/extensions/shapeproto.h>
+#include "protocol-versions.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+
+typedef RegionPtr (*CreateDftPtr)(
+ WindowPtr /* pWin */
+ );
+
+static int ShapeFreeClient(
+ void * /* data */,
+ XID /* id */
+ );
+static int ShapeFreeEvents(
+ void * /* data */,
+ XID /* id */
+ );
+static void ShapeResetProc(
+ ExtensionEntry * /* extEntry */
+ );
+static void SShapeNotifyEvent(
+ xShapeNotifyEvent * /* from */,
+ xShapeNotifyEvent * /* to */
+ );
+static int
+RegionOperate (
+ ClientPtr /* client */,
+ WindowPtr /* pWin */,
+ int /* kind */,
+ RegionPtr * /* destRgnp */,
+ RegionPtr /* srcRgn */,
+ int /* op */,
+ int /* xoff */,
+ int /* yoff */,
+ CreateDftPtr /* create */
+ );
+
+/* SendShapeNotify, CreateBoundingShape and CreateClipShape are used
+ * externally by the Xfixes extension and are now defined in window.h
+ */
+
+static DISPATCH_PROC(ProcShapeCombine);
+static DISPATCH_PROC(ProcShapeDispatch);
+static DISPATCH_PROC(ProcShapeGetRectangles);
+static DISPATCH_PROC(ProcShapeInputSelected);
+static DISPATCH_PROC(ProcShapeMask);
+static DISPATCH_PROC(ProcShapeOffset);
+static DISPATCH_PROC(ProcShapeQueryExtents);
+static DISPATCH_PROC(ProcShapeQueryVersion);
+static DISPATCH_PROC(ProcShapeRectangles);
+static DISPATCH_PROC(ProcShapeSelectInput);
+static DISPATCH_PROC(SProcShapeCombine);
+static DISPATCH_PROC(SProcShapeDispatch);
+static DISPATCH_PROC(SProcShapeGetRectangles);
+static DISPATCH_PROC(SProcShapeInputSelected);
+static DISPATCH_PROC(SProcShapeMask);
+static DISPATCH_PROC(SProcShapeOffset);
+static DISPATCH_PROC(SProcShapeQueryExtents);
+static DISPATCH_PROC(SProcShapeQueryVersion);
+static DISPATCH_PROC(SProcShapeRectangles);
+static DISPATCH_PROC(SProcShapeSelectInput);
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#if 0
+static unsigned char ShapeReqCode = 0;
+#endif
+static int ShapeEventBase = 0;
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+
+/*
+ * each window has a list of clients requesting
+ * ShapeNotify events. Each client has a resource
+ * for each window it selects ShapeNotify input for,
+ * this resource is used to delete the ShapeNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _ShapeEvent *ShapeEventPtr;
+
+typedef struct _ShapeEvent {
+ ShapeEventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+} ShapeEventRec;
+
+/****************
+ * ShapeExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+
+void
+ShapeExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ ClientType = CreateNewResourceType(ShapeFreeClient);
+ EventType = CreateNewResourceType(ShapeFreeEvents);
+ if (ClientType && EventType &&
+ (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
+ ProcShapeDispatch, SProcShapeDispatch,
+ ShapeResetProc, StandardMinorOpcode)))
+ {
+#if 0
+ ShapeReqCode = (unsigned char)extEntry->base;
+#endif
+ ShapeEventBase = extEntry->eventBase;
+ EventSwapVector[ShapeEventBase] = (EventSwapPtr) SShapeNotifyEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShapeResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+}
+
+static int
+RegionOperate (client, pWin, kind, destRgnp, srcRgn, op, xoff, yoff, create)
+ ClientPtr client;
+ WindowPtr pWin;
+ int kind;
+ RegionPtr *destRgnp, srcRgn;
+ int op;
+ int xoff, yoff;
+ CreateDftPtr create; /* creates a reasonable *destRgnp */
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (srcRgn && (xoff || yoff))
+ RegionTranslate(srcRgn, xoff, yoff);
+ if (!pWin->parent)
+ {
+ if (srcRgn)
+ RegionDestroy(srcRgn);
+ return Success;
+ }
+
+ /* May/30/2001:
+ * The shape.PS specs say if src is None, existing shape is to be
+ * removed (and so the op-code has no meaning in such removal);
+ * see shape.PS, page 3, ShapeMask.
+ */
+ if (srcRgn == NULL) {
+ if (*destRgnp != NULL) {
+ RegionDestroy(*destRgnp);
+ *destRgnp = 0;
+ /* go on to remove shape and generate ShapeNotify */
+ }
+ else {
+ /* May/30/2001:
+ * The target currently has no shape in effect, so nothing to
+ * do here. The specs say that ShapeNotify is generated whenever
+ * the client region is "modified"; since no modification is done
+ * here, we do not generate that event. The specs does not say
+ * "it is an error to request removal when there is no shape in
+ * effect", so we return good status.
+ */
+ return Success;
+ }
+ }
+ else switch (op) {
+ case ShapeSet:
+ if (*destRgnp)
+ RegionDestroy(*destRgnp);
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ break;
+ case ShapeUnion:
+ if (*destRgnp)
+ RegionUnion(*destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeIntersect:
+ if (*destRgnp)
+ RegionIntersect(*destRgnp, *destRgnp, srcRgn);
+ else {
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ }
+ break;
+ case ShapeSubtract:
+ if (!*destRgnp)
+ *destRgnp = (*create)(pWin);
+ RegionSubtract(*destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeInvert:
+ if (!*destRgnp)
+ *destRgnp = RegionCreate((BoxPtr) 0, 0);
+ else
+ RegionSubtract(*destRgnp, srcRgn, *destRgnp);
+ break;
+ default:
+ client->errorValue = op;
+ return BadValue;
+ }
+ if (srcRgn)
+ RegionDestroy(srcRgn);
+ (*pScreen->SetShape) (pWin);
+ SendShapeNotify (pWin, kind);
+ return Success;
+}
+
+RegionPtr
+CreateBoundingShape (pWin)
+ WindowPtr pWin;
+{
+ BoxRec extents;
+
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ return RegionCreate(&extents, 1);
+}
+
+RegionPtr
+CreateClipShape (pWin)
+ WindowPtr pWin;
+{
+ BoxRec extents;
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ return RegionCreate(&extents, 1);
+}
+
+static int
+ProcShapeQueryVersion (client)
+ register ClientPtr client;
+{
+ xShapeQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH (xShapeQueryVersionReq);
+ memset(&rep, 0, sizeof(xShapeQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_SHAPE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SHAPE_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof (xShapeQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+/*****************
+ * ProcShapeRectangles
+ *
+ *****************/
+
+static int
+ProcShapeRectangles (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ REQUEST(xShapeRectanglesReq);
+ xRectangle *prects;
+ int nrects, ctype;
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ CreateDftPtr createDefault;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ UpdateCurrentTime();
+ pWin = LookupWindow (stuff->dest, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq));
+ if (nrects & 4)
+ return BadLength;
+ nrects >>= 3;
+ prects = (xRectangle *) &stuff[1];
+ ctype = VerifyRectOrder(nrects, prects, (int)stuff->ordering);
+ if (ctype < 0)
+ return BadMatch;
+ srcRgn = RegionFromRects(nrects, prects, ctype);
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeRectangles(
+ register ClientPtr client)
+{
+ REQUEST(xShapeRectanglesReq);
+ PanoramiXRes *win;
+ int j, result = 0;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->dest, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ result = ProcShapeRectangles (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+
+/**************
+ * ProcShapeMask
+ **************/
+
+
+static int
+ProcShapeMask (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeMaskReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ PixmapPtr pPixmap;
+ CreateDftPtr createDefault;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ UpdateCurrentTime();
+ pWin = SecurityLookupWindow (stuff->dest, client, DixWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (stuff->src == None)
+ srcRgn = 0;
+ else {
+ pPixmap = (PixmapPtr) SecurityLookupIDByType(client, stuff->src,
+ RT_PIXMAP, DixReadAccess);
+ if (!pPixmap)
+ return BadPixmap;
+ if (pPixmap->drawable.pScreen != pScreen ||
+ pPixmap->drawable.depth != 1)
+ return BadMatch;
+ srcRgn = BitmapToRegion(pScreen, pPixmap);
+ if (!srcRgn)
+ return BadAlloc;
+ }
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeMask(
+ register ClientPtr client)
+{
+ REQUEST(xShapeMaskReq);
+ PanoramiXRes *win, *pmap;
+ int j, result = 0;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->dest, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if(stuff->src != None) {
+ if(!(pmap = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->src, XRT_PIXMAP, DixReadAccess)))
+ return BadPixmap;
+ } else
+ pmap = NULL;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ if(pmap)
+ stuff->src = pmap->info[j].id;
+ result = ProcShapeMask (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+
+/************
+ * ProcShapeCombine
+ ************/
+
+static int
+ProcShapeCombine (client)
+ register ClientPtr client;
+{
+ WindowPtr pSrcWin, pDestWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeCombineReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ CreateDftPtr createDefault;
+ CreateDftPtr createSrc;
+ RegionPtr tmp;
+
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ UpdateCurrentTime();
+ pDestWin = LookupWindow (stuff->dest, client);
+ if (!pDestWin)
+ return BadWindow;
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pDestWin->drawable.pScreen;
+
+ pSrcWin = LookupWindow (stuff->src, client);
+ if (!pSrcWin)
+ return BadWindow;
+ switch (stuff->srcKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape (pSrcWin);
+ createSrc = CreateClipShape;
+ break;
+ case ShapeInput:
+ srcRgn = wInputShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->srcKind;
+ return BadValue;
+ }
+ if (pSrcWin->drawable.pScreen != pScreen)
+ {
+ return BadMatch;
+ }
+
+ if (srcRgn) {
+ tmp = RegionCreate((BoxPtr) 0, 0);
+ RegionCopy(tmp, srcRgn);
+ srcRgn = tmp;
+ } else
+ srcRgn = (*createSrc) (pSrcWin);
+
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pDestWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pDestWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pDestWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pDestWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeCombine(
+ register ClientPtr client)
+{
+ REQUEST(xShapeCombineReq);
+ PanoramiXRes *win, *win2;
+ int j, result = 0;
+
+ REQUEST_AT_LEAST_SIZE (xShapeCombineReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->dest, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ if(!(win2 = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->src, XRT_WINDOW, DixReadAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ stuff->src = win2->info[j].id;
+ result = ProcShapeCombine (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+/*************
+ * ProcShapeOffset
+ *************/
+
+static int
+ProcShapeOffset (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeOffsetReq);
+ RegionPtr srcRgn;
+
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ UpdateCurrentTime();
+ pWin = LookupWindow (stuff->dest, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pWin);
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape(pWin);
+ break;
+ case ShapeInput:
+ srcRgn = wInputShape (pWin);
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (srcRgn)
+ {
+ RegionTranslate(srcRgn, stuff->xOff, stuff->yOff);
+ (*pScreen->SetShape) (pWin);
+ }
+ SendShapeNotify (pWin, (int)stuff->destKind);
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeOffset(
+ register ClientPtr client)
+{
+ REQUEST(xShapeOffsetReq);
+ PanoramiXRes *win;
+ int j, result = 0;
+
+ REQUEST_AT_LEAST_SIZE (xShapeOffsetReq);
+
+ if(!(win = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->dest, XRT_WINDOW, DixWriteAccess)))
+ return BadWindow;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ result = ProcShapeOffset (client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+#endif
+
+
+static int
+ProcShapeQueryExtents (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeQueryExtentsReq);
+ WindowPtr pWin;
+ xShapeQueryExtentsReply rep;
+ BoxRec extents, *pExtents;
+ RegionPtr region;
+
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ memset(&rep, 0, sizeof(xShapeQueryExtentsReply));
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.boundingShaped = (wBoundingShape(pWin) != 0);
+ rep.clipShaped = (wClipShape(pWin) != 0);
+ if ((region = wBoundingShape(pWin))) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = RegionExtents(region);
+ extents = *pExtents;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ }
+ rep.xBoundingShape = extents.x1;
+ rep.yBoundingShape = extents.y1;
+ rep.widthBoundingShape = extents.x2 - extents.x1;
+ rep.heightBoundingShape = extents.y2 - extents.y1;
+ if ((region = wClipShape(pWin))) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = RegionExtents(region);
+ extents = *pExtents;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ }
+ rep.xClipShape = extents.x1;
+ rep.yClipShape = extents.y1;
+ rep.widthClipShape = extents.x2 - extents.x1;
+ rep.heightClipShape = extents.y2 - extents.y1;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.xBoundingShape);
+ swaps(&rep.yBoundingShape);
+ swaps(&rep.widthBoundingShape);
+ swaps(&rep.heightBoundingShape);
+ swaps(&rep.xClipShape);
+ swaps(&rep.yClipShape);
+ swaps(&rep.widthClipShape);
+ swaps(&rep.heightClipShape);
+ }
+ WriteToClient(client, sizeof (xShapeQueryExtentsReply), &rep);
+ return (client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeClient (data, id)
+ void *data;
+ XID id;
+{
+ ShapeEventPtr pShapeEvent;
+ WindowPtr pWin;
+ ShapeEventPtr *pHead, pCur, pPrev;
+
+ pShapeEvent = (ShapeEventPtr) data;
+ pWin = pShapeEvent->window;
+ pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ }
+ }
+ free ((void *) pShapeEvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeEvents (data, id)
+ void *data;
+ XID id;
+{
+ ShapeEventPtr *pHead, pCur, pNext;
+
+ pHead = (ShapeEventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ free ((void *) pCur);
+ }
+ free ((void *) pHead);
+ return 1;
+}
+
+static int
+ProcShapeSelectInput (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeSelectInputReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ pWin = SecurityLookupWindow (stuff->window, client, DixWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ pHead = (ShapeEventPtr *)SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType, DixWriteAccess);
+ switch (stuff->enable) {
+ case xTrue:
+ if (pHead) {
+
+ /* check for existing entry. */
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client)
+ return Success;
+ }
+ }
+
+ /* build the entry */
+ pNewShapeEvent = (ShapeEventPtr)
+ malloc (sizeof (ShapeEventRec));
+ if (!pNewShapeEvent)
+ return BadAlloc;
+ pNewShapeEvent->next = 0;
+ pNewShapeEvent->client = client;
+ pNewShapeEvent->window = pWin;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewShapeEvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (void *)pNewShapeEvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (ShapeEventPtr *) malloc (sizeof (ShapeEventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, EventType, (void *)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewShapeEvent->next = *pHead;
+ *pHead = pNewShapeEvent;
+ break;
+ case xFalse:
+ /* delete the interest */
+ if (pHead) {
+ pNewShapeEvent = 0;
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ if (pShapeEvent->client == client)
+ break;
+ pNewShapeEvent = pShapeEvent;
+ }
+ if (pShapeEvent) {
+ FreeResource (pShapeEvent->clientResource, ClientType);
+ if (pNewShapeEvent)
+ pNewShapeEvent->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ free (pShapeEvent);
+ }
+ }
+ break;
+ default:
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+/*
+ * deliver the event
+ */
+
+void
+SendShapeNotify (pWin, which)
+ WindowPtr pWin;
+ int which;
+{
+ ShapeEventPtr *pHead, pShapeEvent;
+ xShapeNotifyEvent se;
+ BoxRec extents;
+ RegionPtr region;
+ BYTE shaped;
+
+ pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (!pHead)
+ return;
+ switch (which) {
+ case ShapeBounding:
+ region = wBoundingShape(pWin);
+ if (region) {
+ extents = *RegionExtents(region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ break;
+ case ShapeClip:
+ region = wClipShape(pWin);
+ if (region) {
+ extents = *RegionExtents(region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ shaped = xFalse;
+ }
+ break;
+ case ShapeInput:
+ region = wInputShape(pWin);
+ if (region) {
+ extents = *RegionExtents(region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ break;
+ default:
+ return;
+ }
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ se.type = ShapeNotify + ShapeEventBase;
+ se.kind = which;
+ se.window = pWin->drawable.id;
+ se.x = extents.x1;
+ se.y = extents.y1;
+ se.width = extents.x2 - extents.x1;
+ se.height = extents.y2 - extents.y1;
+ se.time = currentTime.milliseconds;
+ se.shaped = shaped;
+ WriteEventsToClient (pShapeEvent->client, 1, (xEvent *) &se);
+ }
+}
+
+static int
+ProcShapeInputSelected (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeInputSelectedReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, *pHead;
+ int enabled;
+ xShapeInputSelectedReply rep;
+
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ pHead = (ShapeEventPtr *) SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType, DixReadAccess);
+ enabled = xFalse;
+ if (pHead) {
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client) {
+ enabled = xTrue;
+ break;
+ }
+ }
+ }
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.enabled = enabled;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ }
+ WriteToClient (client, sizeof (xShapeInputSelectedReply), &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcShapeGetRectangles (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeGetRectanglesReq);
+ WindowPtr pWin;
+ xShapeGetRectanglesReply rep;
+ xRectangle *rects;
+ int nrects, i;
+ RegionPtr region;
+
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ region = wBoundingShape(pWin);
+ break;
+ case ShapeClip:
+ region = wClipShape(pWin);
+ break;
+ case ShapeInput:
+ region = wInputShape (pWin);
+ break;
+ default:
+ client->errorValue = stuff->kind;
+ return BadValue;
+ }
+ if (!region) {
+ nrects = 1;
+ rects = (xRectangle *) malloc (sizeof (xRectangle));
+ if (!rects)
+ return BadAlloc;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
+ case ShapeClip:
+ rects->x = 0;
+ rects->y = 0;
+ rects->width = pWin->drawable.width;
+ rects->height = pWin->drawable.height;
+ break;
+ case ShapeInput:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
+ }
+ } else {
+ BoxPtr box;
+ nrects = RegionNumRects(region);
+ box = RegionRects(region);
+ rects = (xRectangle *) malloc (nrects * sizeof (xRectangle));
+ if (!rects && nrects)
+ return BadAlloc;
+ for (i = 0; i < nrects; i++, box++) {
+ rects[i].x = box->x1;
+ rects[i].y = box->y1;
+ rects[i].width = box->x2 - box->x1;
+ rects[i].height = box->y2 - box->y1;
+ }
+ }
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (nrects * sizeof (xRectangle)) >> 2;
+ rep.ordering = YXBanded;
+ rep.nrects = nrects;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.nrects);
+ SwapShorts ((short *)rects, (unsigned long)nrects * 4);
+ }
+ WriteToClient (client, sizeof (rep), &rep);
+ WriteToClient (client, nrects * sizeof (xRectangle), rects);
+ free (rects);
+ return client->noClientException;
+}
+
+static int
+ProcShapeDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return ProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeRectangles (client);
+ else
+#endif
+ return ProcShapeRectangles (client);
+ case X_ShapeMask:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeMask (client);
+ else
+#endif
+ return ProcShapeMask (client);
+ case X_ShapeCombine:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeCombine (client);
+ else
+#endif
+ return ProcShapeCombine (client);
+ case X_ShapeOffset:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeOffset (client);
+ else
+#endif
+ return ProcShapeOffset (client);
+ case X_ShapeQueryExtents:
+ return ProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return ProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return ProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return ProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SShapeNotifyEvent(from, to)
+ xShapeNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswapl (from->window, to->window);
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswaps (from->x, to->x);
+ cpswaps (from->y, to->y);
+ cpswaps (from->width, to->width);
+ cpswaps (from->height, to->height);
+ cpswapl (from->time, to->time);
+ to->shaped = from->shaped;
+}
+
+static int
+SProcShapeQueryVersion (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeQueryVersionReq);
+
+ swaps (&stuff->length);
+ return ProcShapeQueryVersion (client);
+}
+
+static int
+SProcShapeRectangles (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeRectanglesReq);
+
+ swaps (&stuff->length);
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ swapl (&stuff->dest);
+ swaps (&stuff->xOff);
+ swaps (&stuff->yOff);
+ SwapRestS(stuff);
+ return ProcShapeRectangles (client);
+}
+
+static int
+SProcShapeMask (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeMaskReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ swapl (&stuff->dest);
+ swaps (&stuff->xOff);
+ swaps (&stuff->yOff);
+ swapl (&stuff->src);
+ return ProcShapeMask (client);
+}
+
+static int
+SProcShapeCombine (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeCombineReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ swapl (&stuff->dest);
+ swaps (&stuff->xOff);
+ swaps (&stuff->yOff);
+ swapl (&stuff->src);
+ return ProcShapeCombine (client);
+}
+
+static int
+SProcShapeOffset (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeOffsetReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ swapl (&stuff->dest);
+ swaps (&stuff->xOff);
+ swaps (&stuff->yOff);
+ return ProcShapeOffset (client);
+}
+
+static int
+SProcShapeQueryExtents (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeQueryExtentsReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ swapl (&stuff->window);
+ return ProcShapeQueryExtents (client);
+}
+
+static int
+SProcShapeSelectInput (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeSelectInputReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ swapl (&stuff->window);
+ return ProcShapeSelectInput (client);
+}
+
+static int
+SProcShapeInputSelected (client)
+ register ClientPtr client;
+{
+ REQUEST (xShapeInputSelectedReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ swapl (&stuff->window);
+ return ProcShapeInputSelected (client);
+}
+
+static int
+SProcShapeGetRectangles (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeGetRectanglesReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ swapl (&stuff->window);
+ return ProcShapeGetRectangles (client);
+}
+
+static int
+SProcShapeDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return SProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+ return SProcShapeRectangles (client);
+ case X_ShapeMask:
+ return SProcShapeMask (client);
+ case X_ShapeCombine:
+ return SProcShapeCombine (client);
+ case X_ShapeOffset:
+ return SProcShapeOffset (client);
+ case X_ShapeQueryExtents:
+ return SProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return SProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return SProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return SProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/shm.c b/nx-X11/programs/Xserver/Xext/shm.c
new file mode 100644
index 000000000..ca1ff9a7f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/shm.c
@@ -0,0 +1,1305 @@
+/************************************************************
+
+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.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <nx-X11/Xfuncproto.h>
+
+#include "protocol-versions.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+ void * /* value */,
+ XID /* shmseg */
+ );
+static void ShmResetProc(
+ ExtensionEntry * /* extEntry */
+ );
+static void SShmCompletionEvent(
+ xShmCompletionEvent * /* from */,
+ xShmCompletionEvent * /* to */
+ );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+ if (!shmdesc) \
+ { \
+ client->errorValue = shmseg; \
+ return BadShmSegCode; \
+ } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+ VERIFY_SHMSEG(shmseg, shmdesc, client); \
+ if ((offset & 3) || (offset > shmdesc->size)) \
+ { \
+ client->errorValue = offset; \
+ return BadValue; \
+ } \
+ if (needwrite && !shmdesc->writable) \
+ return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+ if ((offset + len) > shmdesc->size) \
+ { \
+ return BadAccess; \
+ } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+ badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+ void (*oldHandler)();
+ int shmid = -1;
+
+ /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+ oldHandler = OsSignal(SIGSYS, SigSysHandler);
+
+ badSysCall = FALSE;
+ shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+
+ if (shmid != -1)
+ {
+ /* Successful allocation - clean up */
+ shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ OsSignal(SIGSYS, oldHandler);
+ return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+#ifndef NXAGENT_SERVER
+void
+ShmExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+ if (!CheckForShmSyscall())
+ {
+ ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+ return;
+ }
+#endif
+
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ {
+ sharedPixmaps = xTrue;
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ shmFuncs[i] = &miFuncs;
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+ if (sharedPixmaps)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+#ifdef PIXPRIV
+ shmPixmapPrivate = AllocatePixmapPrivateIndex();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!AllocatePixmapPrivate(screenInfo.screens[i],
+ shmPixmapPrivate, 0))
+ return;
+ }
+#endif
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ shmFuncs[i] = (ShmFuncsPtr)NULL;
+ shmPixFormat[i] = 0;
+ }
+}
+
+void
+ShmRegisterFuncs(
+ ScreenPtr pScreen,
+ ShmFuncsPtr funcs)
+{
+ shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+ ScreenPtr pScreen,
+ int format)
+{
+ shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ Bool ret;
+ if (pPixmap->refcnt == 1)
+ {
+ ShmDescPtr shmdesc;
+#ifdef PIXPRIV
+ shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+ char *base = (char *) pPixmap->devPrivate.ptr;
+
+ if (base != (void *) (pPixmap + 1))
+ {
+ for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+ {
+ if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+ break;
+ }
+ }
+ else
+ shmdesc = 0;
+#endif
+ if (shmdesc)
+ ShmDetachSegment ((void *) shmdesc, pPixmap->drawable.id);
+ }
+
+ pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = ShmDestroyPixmap;
+ return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ xShmQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ memset(&rep, 0, sizeof(xShmQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = pixmapFormat;
+ rep.majorVersion = SERVER_SHM_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SHM_MINOR_VERSION;
+ rep.uid = geteuid();
+ rep.gid = getegid();
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ swaps(&rep.uid);
+ swaps(&rep.gid);
+ }
+ WriteToClient(client, sizeof(xShmQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+ int uid, gid;
+ mode_t mask;
+
+ if (LocalClientCred(client, &uid, &gid) != -1) {
+
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ /* Check the owner */
+ if (perm->uid == uid || perm->cuid == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ /* Check the group */
+ if (perm->gid == gid || perm->cgid == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+ }
+ }
+ /* Otherwise, check everyone else */
+ mask = S_IROTH;
+ if (!readonly) {
+ mask |= S_IWOTH;
+ }
+ return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+ register ClientPtr client;
+{
+ struct shmid_ds buf;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmAttachReq);
+
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+ if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+ {
+ client->errorValue = stuff->readOnly;
+ return(BadValue);
+ }
+ for (shmdesc = Shmsegs;
+ shmdesc && (shmdesc->shmid != stuff->shmid);
+ shmdesc = shmdesc->next)
+ ;
+ if (shmdesc)
+ {
+ if (!stuff->readOnly && !shmdesc->writable)
+ return BadAccess;
+ shmdesc->refcnt++;
+ }
+ else
+ {
+ shmdesc = (ShmDescPtr) malloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ shmctl(stuff->shmid, IPC_STAT, &buf))
+ {
+ free(shmdesc);
+ return BadAccess;
+ }
+
+ /* The attach was performed with root privs. We must
+ * do manual checking of access rights for the credentials
+ * of the client */
+
+ if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+ shmdt(shmdesc->addr);
+ free(shmdesc);
+ return BadAccess;
+ }
+
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = buf.shm_segsz;
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (void *)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+ void * value; /* must conform to DeleteType */
+ XID shmseg;
+{
+ ShmDescPtr shmdesc = (ShmDescPtr)value;
+ ShmDescPtr *prev;
+
+ if (--shmdesc->refcnt)
+ return TRUE;
+ shmdt(shmdesc->addr);
+ for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+ ;
+ *prev = shmdesc->next;
+ free(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(client)
+ register ClientPtr client;
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ return;
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pmap)
+ {
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (void *)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+}
+#endif /* NXAGENT_SERVER */
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+ int j, result = 0, orig_x, orig_y;
+ PanoramiXRes *draw, *gc;
+ Bool sendEvent, isRoot;
+
+ REQUEST(xShmPutImageReq);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->dstX;
+ orig_y = stuff->dstY;
+ sendEvent = stuff->sendEvent;
+ stuff->sendEvent = 0;
+ FOR_NSCREENS(j) {
+ if(!j) stuff->sendEvent = sendEvent;
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = ProcShmPutImage(client);
+ if(result != client->noClientException) break;
+ }
+ return(result);
+}
+
+static int
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+ PanoramiXRes *draw;
+ DrawablePtr drawables[MAXSCREENS];
+ DrawablePtr pDraw;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int i, x, y, w, h, format;
+ Mask plane = 0, planemask;
+ long lenPer = 0, length, widthBytesLine;
+ Bool isRoot;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if (draw->type == XRT_PIXMAP)
+ return ProcShmGetImage(client);
+
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ x = stuff->x;
+ y = stuff->y;
+ w = stuff->width;
+ h = stuff->height;
+ format = stuff->format;
+ planemask = stuff->planeMask;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ if(isRoot) {
+ if( /* check for being onscreen */
+ x < 0 || x + w > PanoramiXPixWidth ||
+ y < 0 || y + h > PanoramiXPixHeight )
+ return(BadMatch);
+ } else {
+ if( /* check for being onscreen */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+ return(BadMatch);
+ }
+
+ drawables[0] = pDraw;
+ for(i = 1; i < PanoramiXNumScreens; i++)
+ VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+ memset(&xgi, 0, sizeof(xShmGetImageReply));
+ xgi.visual = wVisual(((WindowPtr)pDraw));
+ xgi.type = X_Reply;
+ xgi.length = 0;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+
+ if(format == ZPixmap) {
+ widthBytesLine = PixmapBytePad(w, pDraw->depth);
+ length = widthBytesLine * h;
+ } else {
+ widthBytesLine = PixmapBytePad(w, 1);
+ lenPer = widthBytesLine * h;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ length = lenPer * Ones(planemask & (plane | (plane - 1)));
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+ xgi.size = length;
+
+ if (length == 0) {/* nothing to do */ }
+ else if (format == ZPixmap) {
+ XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+ shmdesc->addr + stuff->offset,
+ widthBytesLine, isRoot);
+ } else {
+
+ length = stuff->offset;
+ for (; plane; plane >>= 1) {
+ if (planemask & plane) {
+ XineramaGetImageData(drawables, x, y, w, h,
+ format, plane, shmdesc->addr + length,
+ widthBytesLine, isRoot);
+ length += lenPer;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ swaps(&xgi.sequenceNumber);
+ swapl(&xgi.length);
+ swapl(&xgi.visual);
+ swapl(&xgi.size);
+ }
+ WriteToClient(client, sizeof(xShmGetImageReply), &xgi);
+
+ return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+ register ClientPtr client)
+{
+ ScreenPtr pScreen = NULL;
+ PixmapPtr pMap = NULL;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, j, result;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ unsigned int width, height, depth;
+ unsigned long size;
+ PanoramiXRes *newPix;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ width = stuff->width;
+ height = stuff->height;
+ depth = stuff->depth;
+ if (!width || !height || !depth)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (width > 32767 || height > 32767)
+ return BadAlloc;
+
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+
+CreatePmap:
+ size = PixmapBytePad(width, depth) * height;
+ if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+ if (size < width * height)
+ return BadAlloc;
+ /* thankfully, offset is unsigned */
+ if (stuff->offset + size < size)
+ return BadAlloc;
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
+
+ if(!(newPix = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newPix->type = XRT_PIXMAP;
+ newPix->u.pix.shared = TRUE;
+ newPix->info[0].id = stuff->pid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPix->info[j].id = FakeClientID(client->index);
+
+ result = (client->noClientException);
+
+ FOR_NSCREENS(j) {
+ pScreen = screenInfo.screens[j];
+
+ pMap = (*shmFuncs[j]->CreatePixmap)(pScreen,
+ stuff->width, stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+
+ if (pMap) {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (void *) shmdesc;
+#endif
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = newPix->info[j].id;
+ if (!AddResource(newPix->info[j].id, RT_PIXMAP, (void *)pMap)) {
+ (*pScreen->DestroyPixmap)(pMap);
+ result = BadAlloc;
+ break;
+ }
+ } else {
+ result = BadAlloc;
+ break;
+ }
+ }
+
+ if(result == BadAlloc) {
+ while(j--) {
+ (*pScreen->DestroyPixmap)(pMap);
+ FreeResource(newPix->info[j].id, RT_NONE);
+ }
+ free(newPix);
+ } else
+ AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+ return result;
+}
+
+#endif
+
+#ifndef NXAGENT_SERVER
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+ if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+ return BadValue;
+ if (stuff->format == XYBitmap)
+ {
+ if (stuff->depth != 1)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ /*
+ * There's a potential integer overflow in this check:
+ * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ * client);
+ * the version below ought to avoid it
+ */
+ if (stuff->totalHeight != 0 &&
+ length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+ client->errorValue = stuff->totalWidth;
+ return BadValue;
+ }
+ if (stuff->srcX > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcX;
+ return BadValue;
+ }
+ if (stuff->srcY > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcY;
+ return BadValue;
+ }
+ if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcWidth;
+ return BadValue;
+ }
+ if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcHeight;
+ return BadValue;
+ }
+
+ if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+ ((stuff->format != ZPixmap) &&
+ (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+ ((stuff->format == XYBitmap) ||
+ ((stuff->srcY == 0) &&
+ (stuff->srcHeight == stuff->totalHeight))))) &&
+ ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+ stuff->dstX, stuff->dstY,
+ stuff->totalWidth, stuff->srcHeight,
+ stuff->srcX, stuff->format,
+ shmdesc->addr + stuff->offset +
+ (stuff->srcY * length));
+ else
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ pDraw, pGC, stuff->depth, stuff->format,
+ stuff->totalWidth, stuff->totalHeight,
+ stuff->srcX, stuff->srcY,
+ stuff->srcWidth, stuff->srcHeight,
+ stuff->dstX, stuff->dstY,
+ shmdesc->addr + stuff->offset);
+
+ if (stuff->sendEvent)
+ {
+ xShmCompletionEvent ev;
+
+ memset(&ev, 0, sizeof(xShmCompletionEvent));
+ ev.type = ShmCompletionCode;
+ ev.drawable = stuff->drawable;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+#endif /* NXAGENT_SERVER */
+
+
+static int
+ProcShmGetImage(client)
+ register ClientPtr client;
+{
+ register DrawablePtr pDraw;
+ long lenPer = 0, length;
+ Mask plane = 0;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ memset(&xgi, 0, sizeof(xShmGetImageReply));
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + stuff->x < 0 ||
+ pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+ pDraw->y + stuff->y < 0 ||
+ pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+ stuff->x + (int)stuff->width >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+ stuff->y + (int)stuff->height >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual(((WindowPtr)pDraw));
+ }
+ else
+ {
+ if (stuff->x < 0 ||
+ stuff->x+(int)stuff->width > pDraw->width ||
+ stuff->y < 0 ||
+ stuff->y+(int)stuff->height > pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+ xgi.type = X_Reply;
+ xgi.length = 0;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(stuff->format == ZPixmap)
+ {
+ length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+ }
+ else
+ {
+ lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+ xgi.size = length;
+
+ if (length == 0)
+ {
+ /* nothing to do */
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, stuff->planeMask,
+ shmdesc->addr + stuff->offset);
+ }
+ else
+ {
+
+ length = stuff->offset;
+ for (; plane; plane >>= 1)
+ {
+ if (stuff->planeMask & plane)
+ {
+ (*pDraw->pScreen->GetImage)(pDraw,
+ stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, plane,
+ shmdesc->addr + length);
+ length += lenPer;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ swaps(&xgi.sequenceNumber);
+ swapl(&xgi.length);
+ swapl(&xgi.visual);
+ swapl(&xgi.size);
+ }
+ WriteToClient(client, sizeof(xShmGetImageReply), &xgi);
+
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
+ if (!pPixmap)
+ return NullPixmap;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ BitsPerPixel(depth), PixmapBytePad(width, depth), (void *)addr)) {
+ (*pScreen->DestroyPixmap)(pPixmap);
+ return NullPixmap;
+ }
+ return pPixmap;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcShmCreatePixmap(client)
+ register ClientPtr client;
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ DepthPtr pDepth;
+ register int i;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ unsigned int width, height, depth;
+ unsigned long size;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ width = stuff->width;
+ height = stuff->height;
+ depth = stuff->depth;
+ if (!width || !height || !depth)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (width > 32767 || height > 32767)
+ return BadAlloc;
+
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+
+CreatePmap:
+ size = PixmapBytePad(width, depth) * height;
+ if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+ if (size < width * height)
+ return BadAlloc;
+ /* thankfully, offset is unsigned */
+ if (stuff->offset + size < size)
+ return BadAlloc;
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
+ pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+#ifdef PIXPRIV
+ pMap->devPrivates[shmPixmapPrivate].ptr = (void *) shmdesc;
+#endif
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (void *)pMap))
+ {
+ return(client->noClientException);
+ }
+ }
+ return (BadAlloc);
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmPutImage(client);
+#endif
+ return ProcShmPutImage(client);
+ case X_ShmGetImage:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmGetImage(client);
+#endif
+ return ProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmCreatePixmap(client);
+#endif
+ return ProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+static void
+SShmCompletionEvent(from, to)
+ xShmCompletionEvent *from, *to;
+{
+ to->type = from->type;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->drawable, to->drawable);
+ cpswaps(from->minorEvent, to->minorEvent);
+ to->majorEvent = from->majorEvent;
+ cpswapl(from->shmseg, to->shmseg);
+ cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+ ClientPtr client;
+{
+ REQUEST(xShmAttachReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ swapl(&stuff->shmseg);
+ swapl(&stuff->shmid);
+ return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+ ClientPtr client;
+{
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+ ClientPtr client;
+{
+ REQUEST(xShmPutImageReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->totalWidth);
+ swaps(&stuff->totalHeight);
+ swaps(&stuff->srcX);
+ swaps(&stuff->srcY);
+ swaps(&stuff->srcWidth);
+ swaps(&stuff->srcHeight);
+ swaps(&stuff->dstX);
+ swaps(&stuff->dstY);
+ swapl(&stuff->shmseg);
+ swapl(&stuff->offset);
+ return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+ ClientPtr client;
+{
+ REQUEST(xShmGetImageReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ swapl(&stuff->drawable);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->planeMask);
+ swapl(&stuff->shmseg);
+ swapl(&stuff->offset);
+ return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+ ClientPtr client;
+{
+ REQUEST(xShmCreatePixmapReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ swapl(&stuff->pid);
+ swapl(&stuff->drawable);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->shmseg);
+ swapl(&stuff->offset);
+ return ProcShmCreatePixmap(client);
+}
+
+#ifndef NXAGENT_SERVER
+static int
+SProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ return SProcShmPutImage(client);
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+#endif /* NXAGENT_SERVER */
diff --git a/nx-X11/programs/Xserver/Xext/shmint.h b/nx-X11/programs/Xserver/Xext/shmint.h
new file mode 100644
index 000000000..5135d1729
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/shmint.h
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _SHMINT_H_
+#define _SHMINT_H_
+
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+
+#include "screenint.h"
+#include "pixmap.h"
+#include "gc.h"
+
+void
+ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs);
+
+void
+ShmSetPixmapFormat(ScreenPtr pScreen, int format);
+
+void
+ShmRegisterFbFuncs(ScreenPtr pScreen);
+
+#endif /* _SHMINT_H_ */
diff --git a/nx-X11/programs/Xserver/Xext/sleepuntil.c b/nx-X11/programs/Xserver/Xext/sleepuntil.c
new file mode 100644
index 000000000..1934828d4
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/sleepuntil.c
@@ -0,0 +1,238 @@
+/*
+ * $Xorg: sleepuntil.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $
+ *
+Copyright 1992, 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: Keith Packard, MIT X Consortium
+ */
+
+/* dixsleep.c - implement millisecond timeouts for X clients */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "sleepuntil.h"
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+typedef struct _Sertafied {
+ struct _Sertafied *next;
+ TimeStamp revive;
+ ClientPtr pClient;
+ XID id;
+ void (*notifyFunc)(
+ ClientPtr /* client */,
+ void * /* closure */
+ );
+
+ void *closure;
+} SertafiedRec, *SertafiedPtr;
+
+static SertafiedPtr pPending;
+static RESTYPE SertafiedResType;
+static Bool BlockHandlerRegistered;
+static int SertafiedGeneration;
+
+static void ClientAwaken(
+ ClientPtr /* client */,
+ void * /* closure */
+);
+static int SertafiedDelete(
+ void * /* value */,
+ XID /* id */
+);
+static void SertafiedBlockHandler(
+ void * /* data */,
+ OSTimePtr /* wt */,
+ void * /* LastSelectMask */
+);
+static void SertafiedWakeupHandler(
+ void * /* data */,
+ int /* i */,
+ void * /* LastSelectMask */
+);
+
+int
+ClientSleepUntil (client, revive, notifyFunc, closure)
+ ClientPtr client;
+ TimeStamp *revive;
+ void (*notifyFunc)(
+ ClientPtr /* client */,
+ void * /* closure */);
+ void *closure;
+{
+ SertafiedPtr pRequest, pReq, pPrev;
+
+ if (SertafiedGeneration != serverGeneration)
+ {
+ SertafiedResType = CreateNewResourceType (SertafiedDelete);
+ if (!SertafiedResType)
+ return FALSE;
+ SertafiedGeneration = serverGeneration;
+ BlockHandlerRegistered = FALSE;
+ }
+ pRequest = (SertafiedPtr) malloc (sizeof (SertafiedRec));
+ if (!pRequest)
+ return FALSE;
+ pRequest->pClient = client;
+ pRequest->revive = *revive;
+ pRequest->id = FakeClientID (client->index);
+ pRequest->closure = closure;
+ if (!BlockHandlerRegistered)
+ {
+ if (!RegisterBlockAndWakeupHandlers (SertafiedBlockHandler,
+ SertafiedWakeupHandler,
+ (void *) 0))
+ {
+ free (pRequest);
+ return FALSE;
+ }
+ BlockHandlerRegistered = TRUE;
+ }
+ pRequest->notifyFunc = 0;
+ if (!AddResource (pRequest->id, SertafiedResType, (void *) pRequest))
+ return FALSE;
+ if (!notifyFunc)
+ notifyFunc = ClientAwaken;
+ pRequest->notifyFunc = notifyFunc;
+ /* Insert into time-ordered queue, with earliest activation time coming first. */
+ pPrev = 0;
+ for (pReq = pPending; pReq; pReq = pReq->next)
+ {
+ if (CompareTimeStamps (pReq->revive, *revive) == LATER)
+ break;
+ pPrev = pReq;
+ }
+ if (pPrev)
+ pPrev->next = pRequest;
+ else
+ pPending = pRequest;
+ pRequest->next = pReq;
+ IgnoreClient (client);
+ return TRUE;
+}
+
+static void
+ClientAwaken (client, closure)
+ ClientPtr client;
+ void *closure;
+{
+ if (!client->clientGone)
+ AttendClient (client);
+}
+
+
+static int
+SertafiedDelete (value, id)
+ void * value;
+ XID id;
+{
+ SertafiedPtr pRequest = (SertafiedPtr)value;
+ SertafiedPtr pReq, pPrev;
+
+ pPrev = 0;
+ for (pReq = pPending; pReq; pPrev = pReq, pReq = pReq->next)
+ if (pReq == pRequest)
+ {
+ if (pPrev)
+ pPrev->next = pReq->next;
+ else
+ pPending = pReq->next;
+ break;
+ }
+ if (pRequest->notifyFunc)
+ (*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
+ free (pRequest);
+ return TRUE;
+}
+
+static void
+SertafiedBlockHandler (data, wt, LastSelectMask)
+ void *data; /* unused */
+ OSTimePtr wt; /* wait time */
+ void *LastSelectMask;
+{
+ SertafiedPtr pReq, pNext;
+ unsigned long delay;
+ TimeStamp now;
+
+ if (!pPending)
+ return;
+ now.milliseconds = GetTimeInMillis ();
+ now.months = currentTime.months;
+ if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
+ now.months++;
+ for (pReq = pPending; pReq; pReq = pNext)
+ {
+ pNext = pReq->next;
+ if (CompareTimeStamps (pReq->revive, now) == LATER)
+ break;
+ FreeResource (pReq->id, RT_NONE);
+
+ /* AttendClient() may have been called via the resource delete
+ * function so a client may have input to be processed and so
+ * set delay to 0 to prevent blocking in WaitForSomething().
+ */
+ AdjustWaitForDelay (wt, 0);
+ }
+ pReq = pPending;
+ if (!pReq)
+ return;
+ delay = pReq->revive.milliseconds - now.milliseconds;
+ AdjustWaitForDelay (wt, delay);
+}
+
+static void
+SertafiedWakeupHandler (data, i, LastSelectMask)
+ void * data;
+ int i;
+ void * LastSelectMask;
+{
+ SertafiedPtr pReq, pNext;
+ TimeStamp now;
+
+ now.milliseconds = GetTimeInMillis ();
+ now.months = currentTime.months;
+ if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
+ now.months++;
+ for (pReq = pPending; pReq; pReq = pNext)
+ {
+ pNext = pReq->next;
+ if (CompareTimeStamps (pReq->revive, now) == LATER)
+ break;
+ FreeResource (pReq->id, RT_NONE);
+ }
+ if (!pPending)
+ {
+ RemoveBlockAndWakeupHandlers (SertafiedBlockHandler,
+ SertafiedWakeupHandler,
+ (void *) 0);
+ BlockHandlerRegistered = FALSE;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/sleepuntil.h b/nx-X11/programs/Xserver/Xext/sleepuntil.h
new file mode 100644
index 000000000..c9c0f1478
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/sleepuntil.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * 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 THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _SLEEPUNTIL_H_
+#define _SLEEPUNTIL_H_ 1
+
+#include "dix.h"
+
+extern int ClientSleepUntil(
+ ClientPtr client,
+ TimeStamp *revive,
+ void (*notifyFunc)(
+ ClientPtr /* client */,
+ void * /* closure */
+ ),
+ void * Closure
+);
+
+#endif
diff --git a/nx-X11/programs/Xserver/Xext/sync.c b/nx-X11/programs/Xserver/Xext/sync.c
new file mode 100644
index 000000000..7fa6145a6
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/sync.c
@@ -0,0 +1,2479 @@
+/*
+
+Copyright 1991, 1993, 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.
+
+
+Copyright 1991, 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
+and Olivetti Research Limited, Cambridge, England.
+
+ 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 Olivetti
+not be used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Digital and Olivetti
+make no representations about the suitability of this software
+for any purpose. It is provided "as is" without express or implied warranty.
+
+DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THEY 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xmd.h>
+#include "misc.h"
+#include "os.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#define _SYNC_SERVER
+#include <nx-X11/extensions/sync.h>
+#include <nx-X11/extensions/syncstr.h>
+#include "protocol-versions.h"
+
+#include <stdio.h>
+#if !defined(WIN32)
+#include <sys/time.h>
+#endif
+
+/*
+ * Local Global Variables
+ */
+static int SyncEventBase;
+static int SyncErrorBase;
+static RESTYPE RTCounter = 0;
+static RESTYPE RTAwait;
+static RESTYPE RTAlarm;
+static RESTYPE RTAlarmClient;
+static int SyncNumSystemCounters = 0;
+static SyncCounter **SysCounterList = NULL;
+
+#define IsSystemCounter(pCounter) \
+ (pCounter && (pCounter->client == NULL))
+
+/* these are all the alarm attributes that pertain to the alarm's trigger */
+#define XSyncCAAllTrigger \
+ (XSyncCACounter | XSyncCAValueType | XSyncCAValue | XSyncCATestType)
+
+static int
+FreeAlarm(
+ void * /* addr */,
+ XID /* id */
+);
+
+static int
+FreeAlarmClient(
+ void * /* value */,
+ XID /* id */
+);
+
+static int
+FreeAwait(
+ void * /* addr */,
+ XID /* id */
+);
+
+static void
+ServertimeBracketValues(
+ void * /* pCounter */,
+ CARD64 * /* pbracket_less */,
+ CARD64 * /* pbracket_greater */
+);
+
+static void
+ServertimeQueryValue(
+ void * /* pCounter */,
+ CARD64 * /* pValue_return */
+);
+
+static void
+ServertimeWakeupHandler(
+ void * /* env */,
+ int /* rc */,
+ void * /* LastSelectMask */
+);
+
+static int
+SyncInitTrigger(
+ ClientPtr /* client */,
+ SyncTrigger * /* pTrigger */,
+ XSyncCounter /* counter */,
+ Mask /* changes */
+);
+
+static void
+SAlarmNotifyEvent(
+ xSyncAlarmNotifyEvent * /* from */,
+ xSyncAlarmNotifyEvent * /* to */
+);
+
+static void
+SCounterNotifyEvent(
+ xSyncCounterNotifyEvent * /* from */,
+ xSyncCounterNotifyEvent * /* to */
+);
+
+static void
+ServertimeBlockHandler(
+ void * /* env */,
+ struct timeval ** /* wt */,
+ void * /* LastSelectMask */
+);
+
+static int
+SyncAddTriggerToCounter(
+ SyncTrigger * /* pTrigger */
+);
+
+extern void
+SyncAlarmCounterDestroyed(
+ SyncTrigger * /* pTrigger */
+);
+
+static void
+SyncAlarmTriggerFired(
+ SyncTrigger * /* pTrigger */
+);
+
+static void
+SyncAwaitTriggerFired(
+ SyncTrigger * /* pTrigger */
+);
+
+static int
+SyncChangeAlarmAttributes(
+ ClientPtr /* client */,
+ SyncAlarm * /* pAlarm */,
+ Mask /* mask */,
+ CARD32 * /* values */
+);
+
+static Bool
+SyncCheckTriggerNegativeComparison(
+ SyncTrigger * /* pTrigger */,
+ CARD64 /* oldval */
+);
+
+static Bool
+SyncCheckTriggerNegativeTransition(
+ SyncTrigger * /* pTrigger */,
+ CARD64 /* oldval */
+);
+
+static Bool
+SyncCheckTriggerPositiveComparison(
+ SyncTrigger * /* pTrigger */,
+ CARD64 /* oldval */
+);
+
+static Bool
+SyncCheckTriggerPositiveTransition(
+ SyncTrigger * /* pTrigger */,
+ CARD64 /* oldval */
+);
+
+static SyncCounter *
+SyncCreateCounter(
+ ClientPtr /* client */,
+ XSyncCounter /* id */,
+ CARD64 /* initialvalue */
+);
+
+static void SyncComputeBracketValues(
+ SyncCounter * /* pCounter */,
+ Bool /* startOver */
+);
+
+static void
+SyncDeleteTriggerFromCounter(
+ SyncTrigger * /* pTrigger */
+);
+
+static Bool
+SyncEventSelectForAlarm(
+ SyncAlarm * /* pAlarm */,
+ ClientPtr /* client */,
+ Bool /* wantevents */
+);
+
+static void
+SyncInitServerTime(
+ void
+);
+
+static void
+SyncResetProc(
+ ExtensionEntry * /* extEntry */
+);
+
+static void
+SyncSendAlarmNotifyEvents(
+ SyncAlarm * /* pAlarm */
+);
+
+static void
+SyncSendCounterNotifyEvents(
+ ClientPtr /* client */,
+ SyncAwait ** /* ppAwait */,
+ int /* num_events */
+);
+
+static DISPATCH_PROC(ProcSyncAwait);
+static DISPATCH_PROC(ProcSyncChangeAlarm);
+static DISPATCH_PROC(ProcSyncChangeCounter);
+static DISPATCH_PROC(ProcSyncCreateAlarm);
+static DISPATCH_PROC(ProcSyncCreateCounter);
+static DISPATCH_PROC(ProcSyncDestroyAlarm);
+static DISPATCH_PROC(ProcSyncDestroyCounter);
+static DISPATCH_PROC(ProcSyncDispatch);
+static DISPATCH_PROC(ProcSyncGetPriority);
+static DISPATCH_PROC(ProcSyncInitialize);
+static DISPATCH_PROC(ProcSyncListSystemCounters);
+static DISPATCH_PROC(ProcSyncQueryAlarm);
+static DISPATCH_PROC(ProcSyncQueryCounter);
+static DISPATCH_PROC(ProcSyncSetCounter);
+static DISPATCH_PROC(ProcSyncSetPriority);
+static DISPATCH_PROC(SProcSyncAwait);
+static DISPATCH_PROC(SProcSyncChangeAlarm);
+static DISPATCH_PROC(SProcSyncChangeCounter);
+static DISPATCH_PROC(SProcSyncCreateAlarm);
+static DISPATCH_PROC(SProcSyncCreateCounter);
+static DISPATCH_PROC(SProcSyncDestroyAlarm);
+static DISPATCH_PROC(SProcSyncDestroyCounter);
+static DISPATCH_PROC(SProcSyncDispatch);
+static DISPATCH_PROC(SProcSyncGetPriority);
+static DISPATCH_PROC(SProcSyncInitialize);
+static DISPATCH_PROC(SProcSyncListSystemCounters);
+static DISPATCH_PROC(SProcSyncQueryAlarm);
+static DISPATCH_PROC(SProcSyncQueryCounter);
+static DISPATCH_PROC(SProcSyncSetCounter);
+static DISPATCH_PROC(SProcSyncSetPriority);
+
+/* Each counter maintains a simple linked list of triggers that are
+ * interested in the counter. The two functions below are used to
+ * delete and add triggers on this list.
+ */
+static void
+SyncDeleteTriggerFromCounter(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncTriggerList *pCur, *pPrev = NULL;
+
+ /* pCounter needs to be stored in pTrigger before calling here. */
+
+ if (!pTrigger->pCounter)
+ return;
+
+ for (pCur = pTrigger->pCounter->pTriglist; pCur; pCur = pCur->next)
+ {
+ if (pCur->pTrigger == pTrigger)
+ {
+ if (pPrev)
+ pPrev->next = pCur->next;
+ else
+ pTrigger->pCounter->pTriglist = pCur->next;
+ free(pCur);
+ break;
+ }
+ }
+
+ if (IsSystemCounter(pTrigger->pCounter))
+ SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+}
+
+
+static int
+SyncAddTriggerToCounter(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncTriggerList *pCur;
+
+ if (!pTrigger->pCounter)
+ return Success;
+
+ /* don't do anything if it's already there */
+ for (pCur = pTrigger->pCounter->pTriglist; pCur; pCur = pCur->next)
+ {
+ if (pCur->pTrigger == pTrigger)
+ return Success;
+ }
+
+ if (!(pCur = (SyncTriggerList *)malloc(sizeof(SyncTriggerList))))
+ return BadAlloc;
+
+ pCur->pTrigger = pTrigger;
+ pCur->next = pTrigger->pCounter->pTriglist;
+ pTrigger->pCounter->pTriglist = pCur;
+
+ if (IsSystemCounter(pTrigger->pCounter))
+ SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+
+ return Success;
+}
+
+
+/* Below are four possible functions that can be plugged into
+ * pTrigger->CheckTrigger, corresponding to the four possible
+ * test-types. These functions are called after the counter's
+ * value changes but are also passed the old counter value
+ * so they can inspect both the old and new values.
+ * (PositiveTransition and NegativeTransition need to see both
+ * pieces of information.) These functions return the truth value
+ * of the trigger.
+ *
+ * All of them include the condition pTrigger->pCounter == NULL.
+ * This is because the spec says that a trigger with a counter value
+ * of None is always TRUE.
+ */
+
+static Bool
+SyncCheckTriggerPositiveComparison(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ XSyncValueGreaterOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value));
+}
+
+static Bool
+SyncCheckTriggerNegativeComparison(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ XSyncValueLessOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value));
+}
+
+static Bool
+SyncCheckTriggerPositiveTransition(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ (XSyncValueLessThan(oldval, pTrigger->test_value) &&
+ XSyncValueGreaterOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value)));
+}
+
+static Bool
+SyncCheckTriggerNegativeTransition(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ (XSyncValueGreaterThan(oldval, pTrigger->test_value) &&
+ XSyncValueLessOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value)));
+}
+
+
+
+static int
+SyncInitTrigger(client, pTrigger, counter, changes)
+ ClientPtr client; /* so we can set errorValue */
+ SyncTrigger *pTrigger;
+ XSyncCounter counter;
+ Mask changes;
+{
+ SyncCounter *pCounter = pTrigger->pCounter;
+ int status;
+ Bool newcounter = FALSE;
+
+ if (changes & XSyncCACounter)
+ {
+ if (counter == None)
+ pCounter = NULL;
+ else if (!(pCounter = (SyncCounter *)SecurityLookupIDByType(
+ client, counter, RTCounter, DixReadAccess)))
+ {
+ client->errorValue = counter;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+ if (pCounter != pTrigger->pCounter)
+ { /* new counter for trigger */
+ SyncDeleteTriggerFromCounter(pTrigger);
+ pTrigger->pCounter = pCounter;
+ newcounter = TRUE;
+ }
+ }
+
+ /* if system counter, ask it what the current value is */
+
+ if (IsSystemCounter(pCounter))
+ {
+ (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
+ &pCounter->value);
+ }
+
+ if (changes & XSyncCAValueType)
+ {
+ if (pTrigger->value_type != XSyncRelative &&
+ pTrigger->value_type != XSyncAbsolute)
+ {
+ client->errorValue = pTrigger->value_type;
+ return BadValue;
+ }
+ }
+
+ if (changes & XSyncCATestType)
+ {
+ if (pTrigger->test_type != XSyncPositiveTransition &&
+ pTrigger->test_type != XSyncNegativeTransition &&
+ pTrigger->test_type != XSyncPositiveComparison &&
+ pTrigger->test_type != XSyncNegativeComparison)
+ {
+ client->errorValue = pTrigger->test_type;
+ return BadValue;
+ }
+ /* select appropriate CheckTrigger function */
+
+ switch (pTrigger->test_type)
+ {
+ case XSyncPositiveTransition:
+ pTrigger->CheckTrigger = SyncCheckTriggerPositiveTransition;
+ break;
+ case XSyncNegativeTransition:
+ pTrigger->CheckTrigger = SyncCheckTriggerNegativeTransition;
+ break;
+ case XSyncPositiveComparison:
+ pTrigger->CheckTrigger = SyncCheckTriggerPositiveComparison;
+ break;
+ case XSyncNegativeComparison:
+ pTrigger->CheckTrigger = SyncCheckTriggerNegativeComparison;
+ break;
+ }
+ }
+
+ if (changes & (XSyncCAValueType | XSyncCAValue))
+ {
+ if (pTrigger->value_type == XSyncAbsolute)
+ pTrigger->test_value = pTrigger->wait_value;
+ else /* relative */
+ {
+ Bool overflow;
+ if (pCounter == NULL)
+ return BadMatch;
+
+ XSyncValueAdd(&pTrigger->test_value, pCounter->value,
+ pTrigger->wait_value, &overflow);
+ if (overflow)
+ {
+ client->errorValue = XSyncValueHigh32(pTrigger->wait_value);
+ return BadValue;
+ }
+ }
+ }
+
+ /* we wait until we're sure there are no errors before registering
+ * a new counter on a trigger
+ */
+ if (newcounter)
+ {
+ if ((status = SyncAddTriggerToCounter(pTrigger)) != Success)
+ return status;
+ }
+ else if (IsSystemCounter(pCounter))
+ {
+ SyncComputeBracketValues(pCounter, /*startOver*/ TRUE);
+ }
+
+ return Success;
+}
+
+/* AlarmNotify events happen in response to actions taken on an Alarm or
+ * the counter used by the alarm. AlarmNotify may be sent to multiple
+ * clients. The alarm maintains a list of clients interested in events.
+ */
+static void
+SyncSendAlarmNotifyEvents(pAlarm)
+ SyncAlarm *pAlarm;
+{
+ SyncAlarmClientList *pcl;
+ xSyncAlarmNotifyEvent ane;
+ SyncTrigger *pTrigger = &pAlarm->trigger;
+
+ UpdateCurrentTime();
+
+ ane.type = SyncEventBase + XSyncAlarmNotify;
+ ane.kind = XSyncAlarmNotify;
+ ane.alarm = pAlarm->alarm_id;
+ if (pTrigger->pCounter)
+ {
+ ane.counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value);
+ ane.counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value);
+ }
+ else
+ { /* XXX what else can we do if there's no counter? */
+ ane.counter_value_hi = ane.counter_value_lo = 0;
+ }
+
+ ane.alarm_value_hi = XSyncValueHigh32(pTrigger->test_value);
+ ane.alarm_value_lo = XSyncValueLow32(pTrigger->test_value);
+ ane.time = currentTime.milliseconds;
+ ane.state = pAlarm->state;
+
+ /* send to owner */
+ if (pAlarm->events)
+ WriteEventsToClient(pAlarm->client, 1, (xEvent *) &ane);
+
+ /* send to other interested clients */
+ for (pcl = pAlarm->pEventClients; pcl; pcl = pcl->next)
+ WriteEventsToClient(pcl->client, 1, (xEvent *) &ane);
+}
+
+
+/* CounterNotify events only occur in response to an Await. The events
+ * go only to the Awaiting client.
+ */
+static void
+SyncSendCounterNotifyEvents(client, ppAwait, num_events)
+ ClientPtr client;
+ SyncAwait **ppAwait;
+ int num_events;
+{
+ xSyncCounterNotifyEvent *pEvents, *pev;
+ int i;
+
+ if (client->clientGone)
+ return;
+ pev = pEvents = (xSyncCounterNotifyEvent *)
+ malloc(num_events * sizeof(xSyncCounterNotifyEvent));
+ if (!pEvents)
+ return;
+ UpdateCurrentTime();
+ for (i = 0; i < num_events; i++, ppAwait++, pev++)
+ {
+ SyncTrigger *pTrigger = &(*ppAwait)->trigger;
+ pev->type = SyncEventBase + XSyncCounterNotify;
+ pev->kind = XSyncCounterNotify;
+ pev->counter = pTrigger->pCounter->id;
+ pev->wait_value_lo = XSyncValueLow32(pTrigger->test_value);
+ pev->wait_value_hi = XSyncValueHigh32(pTrigger->test_value);
+ pev->counter_value_lo = XSyncValueLow32(pTrigger->pCounter->value);
+ pev->counter_value_hi = XSyncValueHigh32(pTrigger->pCounter->value);
+ pev->time = currentTime.milliseconds;
+ pev->count = num_events - i - 1; /* events remaining */
+ pev->destroyed = pTrigger->pCounter->beingDestroyed;
+ }
+ /* swapping will be taken care of by this */
+ WriteEventsToClient(client, num_events, (xEvent *)pEvents);
+ free(pEvents);
+}
+
+
+/* This function is called when an alarm's counter is destroyed.
+ * It is plugged into pTrigger->CounterDestroyed (for alarm triggers).
+ */
+void
+SyncAlarmCounterDestroyed(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncAlarm *pAlarm = (SyncAlarm *)pTrigger;
+
+ pAlarm->state = XSyncAlarmInactive;
+ SyncSendAlarmNotifyEvents(pAlarm);
+ pTrigger->pCounter = NULL;
+}
+
+
+/* This function is called when an alarm "goes off."
+ * It is plugged into pTrigger->TriggerFired (for alarm triggers).
+ */
+static void
+SyncAlarmTriggerFired(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncAlarm *pAlarm = (SyncAlarm *)pTrigger;
+ CARD64 new_test_value;
+
+ /* no need to check alarm unless it's active */
+ if (pAlarm->state != XSyncAlarmActive)
+ return;
+
+ /* " if the counter value is None, or if the delta is 0 and
+ * the test-type is PositiveComparison or NegativeComparison,
+ * no change is made to value (test-value) and the alarm
+ * state is changed to Inactive before the event is generated."
+ */
+ if (pAlarm->trigger.pCounter == NULL
+ || (XSyncValueIsZero(pAlarm->delta)
+ && (pAlarm->trigger.test_type == XSyncPositiveComparison
+ || pAlarm->trigger.test_type == XSyncNegativeComparison)))
+ pAlarm->state = XSyncAlarmInactive;
+
+ new_test_value = pAlarm->trigger.test_value;
+
+ if (pAlarm->state == XSyncAlarmActive)
+ {
+ Bool overflow;
+ CARD64 oldvalue;
+ SyncTrigger *paTrigger = &pAlarm->trigger;
+
+ /* "The alarm is updated by repeatedly adding delta to the
+ * value of the trigger and re-initializing it until it
+ * becomes FALSE."
+ */
+ oldvalue = paTrigger->test_value;
+
+ /* XXX really should do something smarter here */
+
+ do
+ {
+ XSyncValueAdd(&paTrigger->test_value, paTrigger->test_value,
+ pAlarm->delta, &overflow);
+ } while (!overflow &&
+ (*paTrigger->CheckTrigger)(paTrigger,
+ paTrigger->pCounter->value));
+
+ new_test_value = paTrigger->test_value;
+ paTrigger->test_value = oldvalue;
+
+ /* "If this update would cause value to fall outside the range
+ * for an INT64...no change is made to value (test-value) and
+ * the alarm state is changed to Inactive before the event is
+ * generated."
+ */
+ if (overflow)
+ {
+ new_test_value = oldvalue;
+ pAlarm->state = XSyncAlarmInactive;
+ }
+ }
+ /* The AlarmNotify event has to have the "new state of the alarm"
+ * which we can't be sure of until this point. However, it has
+ * to have the "old" trigger test value. That's the reason for
+ * all the newvalue/oldvalue shuffling above. After we send the
+ * events, give the trigger its new test value.
+ */
+ SyncSendAlarmNotifyEvents(pAlarm);
+ pTrigger->test_value = new_test_value;
+}
+
+
+/* This function is called when an Await unblocks, either as a result
+ * of the trigger firing OR the counter being destroyed.
+ * It goes into pTrigger->TriggerFired AND pTrigger->CounterDestroyed
+ * (for Await triggers).
+ */
+static void
+SyncAwaitTriggerFired(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncAwait *pAwait = (SyncAwait *)pTrigger;
+ int numwaits;
+ SyncAwaitUnion *pAwaitUnion;
+ SyncAwait **ppAwait;
+ int num_events = 0;
+
+ pAwaitUnion = (SyncAwaitUnion *)pAwait->pHeader;
+ numwaits = pAwaitUnion->header.num_waitconditions;
+ ppAwait = (SyncAwait **)malloc(numwaits * sizeof(SyncAwait *));
+ if (!ppAwait)
+ goto bail;
+
+ pAwait = &(pAwaitUnion+1)->await;
+
+ /* "When a client is unblocked, all the CounterNotify events for
+ * the Await request are generated contiguously. If count is 0
+ * there are no more events to follow for this request. If
+ * count is n, there are at least n more events to follow."
+ *
+ * Thus, it is best to find all the counters for which events
+ * need to be sent first, so that an accurate count field can
+ * be stored in the events.
+ */
+ for ( ; numwaits; numwaits--, pAwait++)
+ {
+ CARD64 diff;
+ Bool overflow, diffgreater, diffequal;
+
+ /* "A CounterNotify event with the destroyed flag set to TRUE is
+ * always generated if the counter for one of the triggers is
+ * destroyed."
+ */
+ if (pAwait->trigger.pCounter->beingDestroyed)
+ {
+ ppAwait[num_events++] = pAwait;
+ continue;
+ }
+
+ /* "The difference between the counter and the test value is
+ * calculated by subtracting the test value from the value of
+ * the counter."
+ */
+ XSyncValueSubtract(&diff, pAwait->trigger.pCounter->value,
+ pAwait->trigger.test_value, &overflow);
+
+ /* "If the difference lies outside the range for an INT64, an
+ * event is not generated."
+ */
+ if (overflow)
+ continue;
+ diffgreater = XSyncValueGreaterThan(diff, pAwait->event_threshold);
+ diffequal = XSyncValueEqual(diff, pAwait->event_threshold);
+
+ /* "If the test-type is PositiveTransition or
+ * PositiveComparison, a CounterNotify event is generated if
+ * the difference is at least event-threshold. If the test-type
+ * is NegativeTransition or NegativeComparison, a CounterNotify
+ * event is generated if the difference is at most
+ * event-threshold."
+ */
+
+ if ( ((pAwait->trigger.test_type == XSyncPositiveComparison ||
+ pAwait->trigger.test_type == XSyncPositiveTransition)
+ && (diffgreater || diffequal))
+ ||
+ ((pAwait->trigger.test_type == XSyncNegativeComparison ||
+ pAwait->trigger.test_type == XSyncNegativeTransition)
+ && (!diffgreater) /* less or equal */
+ )
+ )
+ {
+ ppAwait[num_events++] = pAwait;
+ }
+ }
+ if (num_events)
+ SyncSendCounterNotifyEvents(pAwaitUnion->header.client, ppAwait,
+ num_events);
+ free(ppAwait);
+
+bail:
+ /* unblock the client */
+ AttendClient(pAwaitUnion->header.client);
+ /* delete the await */
+ FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
+}
+
+
+/* This function should always be used to change a counter's value so that
+ * any triggers depending on the counter will be checked.
+ */
+void
+SyncChangeCounter(pCounter, newval)
+ SyncCounter *pCounter;
+ CARD64 newval;
+{
+ SyncTriggerList *ptl, *pnext;
+ CARD64 oldval;
+
+ oldval = pCounter->value;
+ pCounter->value = newval;
+
+ /* run through triggers to see if any become true */
+ for (ptl = pCounter->pTriglist; ptl; ptl = pnext)
+ {
+ pnext = ptl->next;
+ if ((*ptl->pTrigger->CheckTrigger)(ptl->pTrigger, oldval))
+ (*ptl->pTrigger->TriggerFired)(ptl->pTrigger);
+ }
+
+ if (IsSystemCounter(pCounter))
+ {
+ SyncComputeBracketValues(pCounter, /* startOver */ FALSE);
+ }
+}
+
+
+/* loosely based on dix/events.c/EventSelectForWindow */
+static Bool
+SyncEventSelectForAlarm(pAlarm, client, wantevents)
+ SyncAlarm *pAlarm;
+ ClientPtr client;
+ Bool wantevents;
+{
+ SyncAlarmClientList *pClients;
+
+ if (client == pAlarm->client) /* alarm owner */
+ {
+ pAlarm->events = wantevents;
+ return Success;
+ }
+
+ /* see if the client is already on the list (has events selected) */
+
+ for (pClients = pAlarm->pEventClients; pClients;
+ pClients = pClients->next)
+ {
+ if (pClients->client == client)
+ {
+ /* client's presence on the list indicates desire for
+ * events. If the client doesn't want events, remove it
+ * from the list. If the client does want events, do
+ * nothing, since it's already got them.
+ */
+ if (!wantevents)
+ {
+ FreeResource(pClients->delete_id, RT_NONE);
+ }
+ return Success;
+ }
+ }
+
+ /* if we get here, this client does not currently have
+ * events selected on the alarm
+ */
+
+ if (!wantevents)
+ /* client doesn't want events, and we just discovered that it
+ * doesn't have them, so there's nothing to do.
+ */
+ return Success;
+
+ /* add new client to pAlarm->pEventClients */
+
+ pClients = (SyncAlarmClientList *) malloc(sizeof(SyncAlarmClientList));
+ if (!pClients)
+ return BadAlloc;
+
+ /* register it as a resource so it will be cleaned up
+ * if the client dies
+ */
+
+ pClients->delete_id = FakeClientID(client->index);
+ if (!AddResource(pClients->delete_id, RTAlarmClient, pAlarm))
+ {
+ free(pClients);
+ return BadAlloc;
+ }
+
+ /* link it into list after we know all the allocations succeed */
+
+ pClients->next = pAlarm->pEventClients;
+ pAlarm->pEventClients = pClients;
+ pClients->client = client;
+ return Success;
+}
+
+/*
+ * ** SyncChangeAlarmAttributes ** This is used by CreateAlarm and ChangeAlarm
+ */
+static int
+SyncChangeAlarmAttributes(client, pAlarm, mask, values)
+ ClientPtr client;
+ SyncAlarm *pAlarm;
+ Mask mask;
+ CARD32 *values;
+{
+ int status;
+ XSyncCounter counter;
+ Mask origmask = mask;
+
+ counter = pAlarm->trigger.pCounter ? pAlarm->trigger.pCounter->id : None;
+
+ while (mask)
+ {
+ int index2 = lowbit(mask);
+ mask &= ~index2;
+ switch (index2)
+ {
+ case XSyncCACounter:
+ mask &= ~XSyncCACounter;
+ /* sanity check in SyncInitTrigger */
+ counter = *values++;
+ break;
+
+ case XSyncCAValueType:
+ mask &= ~XSyncCAValueType;
+ /* sanity check in SyncInitTrigger */
+ pAlarm->trigger.value_type = *values++;
+ break;
+
+ case XSyncCAValue:
+ mask &= ~XSyncCAValue;
+ XSyncIntsToValue(&pAlarm->trigger.wait_value, values[1], values[0]);
+ values += 2;
+ break;
+
+ case XSyncCATestType:
+ mask &= ~XSyncCATestType;
+ /* sanity check in SyncInitTrigger */
+ pAlarm->trigger.test_type = *values++;
+ break;
+
+ case XSyncCADelta:
+ mask &= ~XSyncCADelta;
+ XSyncIntsToValue(&pAlarm->delta, values[1], values[0]);
+ values += 2;
+ break;
+
+ case XSyncCAEvents:
+ mask &= ~XSyncCAEvents;
+ if ((*values != xTrue) && (*values != xFalse))
+ {
+ client->errorValue = *values;
+ return BadValue;
+ }
+ status = SyncEventSelectForAlarm(pAlarm, client,
+ (Bool)(*values++));
+ if (status != Success)
+ return status;
+ break;
+
+ default:
+ client->errorValue = mask;
+ return BadValue;
+ }
+ }
+
+ /* "If the test-type is PositiveComparison or PositiveTransition
+ * and delta is less than zero, or if the test-type is
+ * NegativeComparison or NegativeTransition and delta is
+ * greater than zero, a Match error is generated."
+ */
+ if (origmask & (XSyncCADelta|XSyncCATestType))
+ {
+ CARD64 zero;
+ XSyncIntToValue(&zero, 0);
+ if ((((pAlarm->trigger.test_type == XSyncPositiveComparison) ||
+ (pAlarm->trigger.test_type == XSyncPositiveTransition))
+ && XSyncValueLessThan(pAlarm->delta, zero))
+ ||
+ (((pAlarm->trigger.test_type == XSyncNegativeComparison) ||
+ (pAlarm->trigger.test_type == XSyncNegativeTransition))
+ && XSyncValueGreaterThan(pAlarm->delta, zero))
+ )
+ {
+ return BadMatch;
+ }
+ }
+
+ /* postpone this until now, when we're sure nothing else can go wrong */
+ if ((status = SyncInitTrigger(client, &pAlarm->trigger, counter,
+ origmask & XSyncCAAllTrigger)) != Success)
+ return status;
+
+ /* XXX spec does not really say to do this - needs clarification */
+ pAlarm->state = XSyncAlarmActive;
+ return Success;
+}
+
+
+static SyncCounter *
+SyncCreateCounter(client, id, initialvalue)
+ ClientPtr client;
+ XSyncCounter id;
+ CARD64 initialvalue;
+{
+ SyncCounter *pCounter;
+
+ if (!(pCounter = (SyncCounter *) malloc(sizeof(SyncCounter))))
+ return (SyncCounter *)NULL;
+
+ if (!AddResource(id, RTCounter, (void *) pCounter))
+ {
+ free((void *) pCounter);
+ return (SyncCounter *)NULL;
+ }
+
+ pCounter->client = client;
+ pCounter->id = id;
+ pCounter->value = initialvalue;
+ pCounter->pTriglist = NULL;
+ pCounter->beingDestroyed = FALSE;
+ pCounter->pSysCounterInfo = NULL;
+ return pCounter;
+}
+
+static int FreeCounter(
+ void * /*env*/,
+ XID /*id*/
+);
+
+/*
+ * ***** System Counter utilities
+ */
+
+void *
+SyncCreateSystemCounter(name, initial, resolution, counterType,
+ QueryValue, BracketValues)
+ char *name;
+ CARD64 initial;
+ CARD64 resolution;
+ SyncCounterType counterType;
+ void (*QueryValue) (
+ void * /* pCounter */,
+ CARD64 * /* pValue_return */);
+ void (*BracketValues) (
+ void * /* pCounter */,
+ CARD64 * /* pbracket_less */,
+ CARD64 * /* pbracket_greater */);
+{
+ SyncCounter *pCounter;
+
+ SysCounterList = (SyncCounter **)realloc(SysCounterList,
+ (SyncNumSystemCounters+1)*sizeof(SyncCounter *));
+ if (!SysCounterList)
+ return (void *)NULL;
+
+ /* this function may be called before SYNC has been initialized, so we
+ * have to make sure RTCounter is created.
+ */
+ if (RTCounter == 0)
+ {
+ RTCounter = CreateNewResourceType(FreeCounter);
+ if (RTCounter == 0)
+ {
+ return (void *)NULL;
+ }
+ }
+
+ pCounter = SyncCreateCounter((ClientPtr)NULL, FakeClientID(0), initial);
+
+ if (pCounter)
+ {
+ SysCounterInfo *psci;
+
+ psci = (SysCounterInfo *)malloc(sizeof(SysCounterInfo));
+ if (!psci)
+ {
+ FreeResource(pCounter->id, RT_NONE);
+ return (void *) pCounter;
+ }
+ pCounter->pSysCounterInfo = psci;
+ psci->name = name;
+ psci->resolution = resolution;
+ psci->counterType = counterType;
+ psci->QueryValue = QueryValue;
+ psci->BracketValues = BracketValues;
+ XSyncMaxValue(&psci->bracket_greater);
+ XSyncMinValue(&psci->bracket_less);
+ SysCounterList[SyncNumSystemCounters++] = pCounter;
+ }
+ return (void *) pCounter;
+}
+
+void
+SyncDestroySystemCounter(pSysCounter)
+ void * pSysCounter;
+{
+ SyncCounter *pCounter = (SyncCounter *)pSysCounter;
+ FreeResource(pCounter->id, RT_NONE);
+}
+
+static void
+SyncComputeBracketValues(pCounter, startOver)
+ SyncCounter *pCounter;
+ Bool startOver;
+{
+ SyncTriggerList *pCur;
+ SyncTrigger *pTrigger;
+ SysCounterInfo *psci = pCounter->pSysCounterInfo;
+ CARD64 *pnewgtval = NULL;
+ CARD64 *pnewltval = NULL;
+ SyncCounterType ct;
+
+ if (!pCounter)
+ return;
+
+ ct = pCounter->pSysCounterInfo->counterType;
+ if (ct == XSyncCounterNeverChanges)
+ return;
+
+ if (startOver)
+ {
+ XSyncMaxValue(&psci->bracket_greater);
+ XSyncMinValue(&psci->bracket_less);
+ }
+
+ for (pCur = pCounter->pTriglist; pCur; pCur = pCur->next)
+ {
+ pTrigger = pCur->pTrigger;
+
+ if (pTrigger->test_type == XSyncPositiveComparison &&
+ ct != XSyncCounterNeverIncreases)
+ {
+ if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
+ XSyncValueLessThan(pTrigger->test_value,
+ psci->bracket_greater))
+ {
+ psci->bracket_greater = pTrigger->test_value;
+ pnewgtval = &psci->bracket_greater;
+ }
+ }
+ else if (pTrigger->test_type == XSyncNegativeComparison &&
+ ct != XSyncCounterNeverDecreases)
+ {
+ if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
+ XSyncValueGreaterThan(pTrigger->test_value,
+ psci->bracket_less))
+ {
+ psci->bracket_less = pTrigger->test_value;
+ pnewltval = &psci->bracket_less;
+ }
+ }
+ else if ( (pTrigger->test_type == XSyncPositiveTransition &&
+ ct != XSyncCounterNeverIncreases)
+ ||
+ (pTrigger->test_type == XSyncNegativeTransition &&
+ ct != XSyncCounterNeverDecreases)
+ )
+ {
+ if (XSyncValueLessThan(pCounter->value, pTrigger->test_value))
+ {
+ if (XSyncValueLessThan(pTrigger->test_value,
+ psci->bracket_greater))
+ {
+ psci->bracket_greater = pTrigger->test_value;
+ pnewgtval = &psci->bracket_greater;
+ }
+ else
+ if (XSyncValueGreaterThan(pTrigger->test_value,
+ psci->bracket_less))
+ {
+ psci->bracket_less = pTrigger->test_value;
+ pnewltval = &psci->bracket_less;
+ }
+ }
+ }
+ } /* end for each trigger */
+
+ if (pnewgtval || pnewltval)
+ {
+ (*psci->BracketValues)((void *)pCounter, pnewltval, pnewgtval);
+ }
+}
+
+/*
+ * ***** Resource delete functions
+ */
+
+/* ARGSUSED */
+static int
+FreeAlarm(addr, id)
+ void *addr;
+ XID id;
+{
+ SyncAlarm *pAlarm = (SyncAlarm *) addr;
+
+ pAlarm->state = XSyncAlarmDestroyed;
+
+ SyncSendAlarmNotifyEvents(pAlarm);
+
+ /* delete event selections */
+
+ while (pAlarm->pEventClients)
+ FreeResource(pAlarm->pEventClients->delete_id, RT_NONE);
+
+ SyncDeleteTriggerFromCounter(&pAlarm->trigger);
+
+ free(pAlarm);
+ return Success;
+}
+
+
+/*
+ * ** Cleanup after the destruction of a Counter
+ */
+/* ARGSUSED */
+static int
+FreeCounter(env, id)
+ void *env;
+ XID id;
+{
+ SyncCounter *pCounter = (SyncCounter *) env;
+ SyncTriggerList *ptl, *pnext;
+
+ pCounter->beingDestroyed = TRUE;
+ /* tell all the counter's triggers that the counter has been destroyed */
+ for (ptl = pCounter->pTriglist; ptl; ptl = pnext)
+ {
+ (*ptl->pTrigger->CounterDestroyed)(ptl->pTrigger);
+ pnext = ptl->next;
+ free(ptl); /* destroy the trigger list as we go */
+ }
+ if (IsSystemCounter(pCounter))
+ {
+ int i, found = 0;
+
+ free(pCounter->pSysCounterInfo);
+
+ /* find the counter in the list of system counters and remove it */
+
+ if (SysCounterList)
+ {
+ for (i = 0; i < SyncNumSystemCounters; i++)
+ {
+ if (SysCounterList[i] == pCounter)
+ {
+ found = i;
+ break;
+ }
+ }
+ if (found < (SyncNumSystemCounters-1))
+ {
+ for (i = found; i < SyncNumSystemCounters-1; i++)
+ {
+ SysCounterList[i] = SysCounterList[i+1];
+ }
+ }
+ }
+ SyncNumSystemCounters--;
+ }
+ free(pCounter);
+ return Success;
+}
+
+/*
+ * ** Cleanup after Await
+ */
+/* ARGSUSED */
+static int
+FreeAwait(addr, id)
+ void *addr;
+ XID id;
+{
+ SyncAwaitUnion *pAwaitUnion = (SyncAwaitUnion *) addr;
+ SyncAwait *pAwait;
+ int numwaits;
+
+ pAwait = &(pAwaitUnion+1)->await; /* first await on list */
+
+ /* remove triggers from counters */
+
+ for (numwaits = pAwaitUnion->header.num_waitconditions; numwaits;
+ numwaits--, pAwait++)
+ {
+ /* If the counter is being destroyed, FreeCounter will delete
+ * the trigger list itself, so don't do it here.
+ */
+ SyncCounter *pCounter = pAwait->trigger.pCounter;
+ if (pCounter && !pCounter->beingDestroyed)
+ SyncDeleteTriggerFromCounter(&pAwait->trigger);
+ }
+ free(pAwaitUnion);
+ return Success;
+}
+
+/* loosely based on dix/events.c/OtherClientGone */
+static int
+FreeAlarmClient(value, id)
+ void * value; /* must conform to DeleteType */
+ XID id;
+{
+ SyncAlarm *pAlarm = (SyncAlarm *)value;
+ SyncAlarmClientList *pCur, *pPrev;
+
+ for (pPrev = NULL, pCur = pAlarm->pEventClients;
+ pCur;
+ pPrev = pCur, pCur = pCur->next)
+ {
+ if (pCur->delete_id == id)
+ {
+ if (pPrev)
+ pPrev->next = pCur->next;
+ else
+ pAlarm->pEventClients = pCur->next;
+ free(pCur);
+ return(Success);
+ }
+ }
+ FatalError("alarm client not on event list");
+ /*NOTREACHED*/
+}
+
+
+/*
+ * ***** Proc functions
+ */
+
+
+/*
+ * ** Initialize the extension
+ */
+static int
+ProcSyncInitialize(client)
+ ClientPtr client;
+{
+ xSyncInitializeReply rep;
+
+ REQUEST_SIZE_MATCH(xSyncInitializeReq);
+
+ memset(&rep, 0, sizeof(xSyncInitializeReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_SYNC_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SYNC_MINOR_VERSION;
+ rep.length = 0;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ }
+ WriteToClient(client, sizeof(rep), &rep);
+ return (client->noClientException);
+}
+
+/*
+ * ** Get list of system counters available through the extension
+ */
+static int
+ProcSyncListSystemCounters(client)
+ ClientPtr client;
+{
+ xSyncListSystemCountersReply rep;
+ int i, len;
+ xSyncSystemCounter *list = NULL, *walklist = NULL;
+
+ REQUEST_SIZE_MATCH(xSyncListSystemCountersReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.nCounters = SyncNumSystemCounters;
+
+ for (i = len = 0; i < SyncNumSystemCounters; i++)
+ {
+ char *name = SysCounterList[i]->pSysCounterInfo->name;
+ /* pad to 4 byte boundary */
+ len += (sz_xSyncSystemCounter + strlen(name) + 3) & ~3;
+ }
+
+ if (len)
+ {
+ walklist = list = (xSyncSystemCounter *) malloc(len);
+ if (!list)
+ return BadAlloc;
+ }
+
+ rep.length = len >> 2;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.nCounters);
+ }
+
+ for (i = 0; i < SyncNumSystemCounters; i++)
+ {
+ int namelen;
+ char *pname_in_reply;
+ SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo;
+
+ walklist->counter = SysCounterList[i]->id;
+ walklist->resolution_hi = XSyncValueHigh32(psci->resolution);
+ walklist->resolution_lo = XSyncValueLow32(psci->resolution);
+ namelen = strlen(psci->name);
+ walklist->name_length = namelen;
+
+ if (client->swapped)
+ {
+ swapl(&walklist->counter);
+ swapl(&walklist->resolution_hi);
+ swapl(&walklist->resolution_lo);
+ swaps(&walklist->name_length);
+ }
+
+ pname_in_reply = ((char *)walklist) + sz_xSyncSystemCounter;
+ strncpy(pname_in_reply, psci->name, namelen);
+ walklist = (xSyncSystemCounter *) (((char *)walklist) +
+ ((sz_xSyncSystemCounter + namelen + 3) & ~3));
+ }
+
+ WriteToClient(client, sizeof(rep), &rep);
+ if (len)
+ {
+ WriteToClient(client, len, list);
+ free(list);
+ }
+
+ return (client->noClientException);
+}
+
+/*
+ * ** Set client Priority
+ */
+static int
+ProcSyncSetPriority(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncSetPriorityReq);
+ ClientPtr priorityclient;
+
+ REQUEST_SIZE_MATCH(xSyncSetPriorityReq);
+
+ if (stuff->id == None)
+ priorityclient = client;
+ else if (!(priorityclient = LookupClient(stuff->id, client)))
+ {
+ client->errorValue = stuff->id;
+ return BadMatch;
+ }
+
+ if (priorityclient->priority != stuff->priority)
+ {
+ priorityclient->priority = stuff->priority;
+
+ /* The following will force the server back into WaitForSomething
+ * so that the change in this client's priority is immediately
+ * reflected.
+ */
+ isItTimeToYield = TRUE;
+ dispatchException |= DE_PRIORITYCHANGE;
+ }
+ return Success;
+}
+
+/*
+ * ** Get client Priority
+ */
+static int
+ProcSyncGetPriority(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncGetPriorityReq);
+ xSyncGetPriorityReply rep;
+ ClientPtr priorityclient;
+
+ REQUEST_SIZE_MATCH(xSyncGetPriorityReq);
+
+ if (stuff->id == None)
+ priorityclient = client;
+ else if (!(priorityclient = LookupClient(stuff->id, client)))
+ {
+ client->errorValue = stuff->id;
+ return BadMatch;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.priority = priorityclient->priority;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.priority);
+ }
+
+ WriteToClient(client, sizeof(xSyncGetPriorityReply), &rep);
+
+ return (client->noClientException);
+}
+
+/*
+ * ** Create a new counter
+ */
+static int
+ProcSyncCreateCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncCreateCounterReq);
+ CARD64 initial;
+
+ REQUEST_SIZE_MATCH(xSyncCreateCounterReq);
+
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ XSyncIntsToValue(&initial, stuff->initial_value_lo, stuff->initial_value_hi);
+ if (!SyncCreateCounter(client, stuff->cid, initial))
+ return BadAlloc;
+
+ return (client->noClientException);
+}
+
+/*
+ * ** Set Counter value
+ */
+static int
+ProcSyncSetCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncSetCounterReq);
+ SyncCounter *pCounter;
+ CARD64 newvalue;
+
+ REQUEST_SIZE_MATCH(xSyncSetCounterReq);
+
+ pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->cid,
+ RTCounter, DixWriteAccess);
+ if (pCounter == NULL)
+ {
+ client->errorValue = stuff->cid;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+
+ if (IsSystemCounter(pCounter))
+ {
+ client->errorValue = stuff->cid;
+ return BadAccess;
+ }
+
+ XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi);
+ SyncChangeCounter(pCounter, newvalue);
+ return Success;
+}
+
+/*
+ * ** Change Counter value
+ */
+static int
+ProcSyncChangeCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncChangeCounterReq);
+ SyncCounter *pCounter;
+ CARD64 newvalue;
+ Bool overflow;
+
+ REQUEST_SIZE_MATCH(xSyncChangeCounterReq);
+
+ pCounter = (SyncCounter *) SecurityLookupIDByType(client, stuff->cid,
+ RTCounter, DixWriteAccess);
+ if (pCounter == NULL)
+ {
+ client->errorValue = stuff->cid;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+
+ if (IsSystemCounter(pCounter))
+ {
+ client->errorValue = stuff->cid;
+ return BadAccess;
+ }
+
+ XSyncIntsToValue(&newvalue, stuff->value_lo, stuff->value_hi);
+ XSyncValueAdd(&newvalue, pCounter->value, newvalue, &overflow);
+ if (overflow)
+ {
+ /* XXX 64 bit value can't fit in 32 bits; do the best we can */
+ client->errorValue = stuff->value_hi;
+ return BadValue;
+ }
+ SyncChangeCounter(pCounter, newvalue);
+ return Success;
+}
+
+/*
+ * ** Destroy a counter
+ */
+static int
+ProcSyncDestroyCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncDestroyCounterReq);
+ SyncCounter *pCounter;
+
+ REQUEST_SIZE_MATCH(xSyncDestroyCounterReq);
+
+ pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->counter,
+ RTCounter, DixDestroyAccess);
+ if (pCounter == NULL)
+ {
+ client->errorValue = stuff->counter;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+ if (IsSystemCounter(pCounter))
+ {
+ client->errorValue = stuff->counter;
+ return BadAccess;
+ }
+ FreeResource(pCounter->id, RT_NONE);
+ return Success;
+}
+
+
+/*
+ * ** Await
+ */
+static int
+ProcSyncAwait(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncAwaitReq);
+ int len, items;
+ int i;
+ xSyncWaitCondition *pProtocolWaitConds;
+ SyncAwaitUnion *pAwaitUnion;
+ SyncAwait *pAwait;
+ int status;
+
+ REQUEST_AT_LEAST_SIZE(xSyncAwaitReq);
+
+ len = client->req_len << 2;
+ len -= sz_xSyncAwaitReq;
+ items = len / sz_xSyncWaitCondition;
+
+ if (items * sz_xSyncWaitCondition != len)
+ {
+ return BadLength;
+ }
+ if (items == 0)
+ {
+ client->errorValue = items; /* XXX protocol change */
+ return BadValue;
+ }
+
+ pProtocolWaitConds = (xSyncWaitCondition *) & stuff[1];
+
+ /* all the memory for the entire await list is allocated
+ * here in one chunk
+ */
+ pAwaitUnion = (SyncAwaitUnion *)malloc((items+1) * sizeof(SyncAwaitUnion));
+ if (!pAwaitUnion)
+ return BadAlloc;
+
+ /* first item is the header, remainder are real wait conditions */
+
+ pAwaitUnion->header.delete_id = FakeClientID(client->index);
+ if (!AddResource(pAwaitUnion->header.delete_id, RTAwait, pAwaitUnion))
+ {
+ free(pAwaitUnion);
+ return BadAlloc;
+ }
+
+ /* don't need to do any more memory allocation for this request! */
+
+ pAwaitUnion->header.client = client;
+ pAwaitUnion->header.num_waitconditions = 0;
+
+ pAwait = &(pAwaitUnion+1)->await; /* skip over header */
+ for (i = 0; i < items; i++, pProtocolWaitConds++, pAwait++)
+ {
+ if (pProtocolWaitConds->counter == None) /* XXX protocol change */
+ {
+ /* this should take care of removing any triggers created by
+ * this request that have already been registered on counters
+ */
+ FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
+ client->errorValue = pProtocolWaitConds->counter;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+
+ /* sanity checks are in SyncInitTrigger */
+ pAwait->trigger.pCounter = NULL;
+ pAwait->trigger.value_type = pProtocolWaitConds->value_type;
+ XSyncIntsToValue(&pAwait->trigger.wait_value,
+ pProtocolWaitConds->wait_value_lo,
+ pProtocolWaitConds->wait_value_hi);
+ pAwait->trigger.test_type = pProtocolWaitConds->test_type;
+
+ status = SyncInitTrigger(client, &pAwait->trigger,
+ pProtocolWaitConds->counter, XSyncCAAllTrigger);
+ if (status != Success)
+ {
+ /* this should take care of removing any triggers created by
+ * this request that have already been registered on counters
+ */
+ FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
+ return status;
+ }
+ /* this is not a mistake -- same function works for both cases */
+ pAwait->trigger.TriggerFired = SyncAwaitTriggerFired;
+ pAwait->trigger.CounterDestroyed = SyncAwaitTriggerFired;
+ XSyncIntsToValue(&pAwait->event_threshold,
+ pProtocolWaitConds->event_threshold_lo,
+ pProtocolWaitConds->event_threshold_hi);
+ pAwait->pHeader = &pAwaitUnion->header;
+ pAwaitUnion->header.num_waitconditions++;
+ }
+
+ IgnoreClient(client);
+
+ /* see if any of the triggers are already true */
+
+ pAwait = &(pAwaitUnion+1)->await; /* skip over header */
+ for (i = 0; i < items; i++, pAwait++)
+ {
+ /* don't have to worry about NULL counters because the request
+ * errors before we get here out if they occur
+ */
+ if ((*pAwait->trigger.CheckTrigger)(&pAwait->trigger,
+ pAwait->trigger.pCounter->value))
+ {
+ (*pAwait->trigger.TriggerFired)(&pAwait->trigger);
+ break; /* once is enough */
+ }
+ }
+ return Success;
+}
+
+
+/*
+ * ** Query a counter
+ */
+static int
+ProcSyncQueryCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncQueryCounterReq);
+ xSyncQueryCounterReply rep;
+ SyncCounter *pCounter;
+
+ REQUEST_SIZE_MATCH(xSyncQueryCounterReq);
+
+ pCounter = (SyncCounter *)SecurityLookupIDByType(client, stuff->counter,
+ RTCounter, DixReadAccess);
+ if (pCounter == NULL)
+ {
+ client->errorValue = stuff->counter;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ /* if system counter, ask it what the current value is */
+
+ if (IsSystemCounter(pCounter))
+ {
+ (*pCounter->pSysCounterInfo->QueryValue) ((void *) pCounter,
+ &pCounter->value);
+ }
+
+ rep.value_hi = XSyncValueHigh32(pCounter->value);
+ rep.value_lo = XSyncValueLow32(pCounter->value);
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.value_hi);
+ swapl(&rep.value_lo);
+ }
+ WriteToClient(client, sizeof(xSyncQueryCounterReply), &rep);
+ return (client->noClientException);
+}
+
+
+/*
+ * ** Create Alarm
+ */
+static int
+ProcSyncCreateAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncCreateAlarmReq);
+ SyncAlarm *pAlarm;
+ int status;
+ unsigned long len, vmask;
+ SyncTrigger *pTrigger;
+
+ REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq);
+
+ LEGAL_NEW_RESOURCE(stuff->id, client);
+
+ vmask = stuff->valueMask;
+ len = client->req_len - (sizeof(xSyncCreateAlarmReq) >> 2);
+ /* the "extra" call to Ones accounts for the presence of 64 bit values */
+ if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue|XSyncCADelta))))
+ return BadLength;
+
+ if (!(pAlarm = (SyncAlarm *) malloc(sizeof(SyncAlarm))))
+ {
+ return BadAlloc;
+ }
+
+ /* set up defaults */
+
+ pTrigger = &pAlarm->trigger;
+ pTrigger->pCounter = NULL;
+ pTrigger->value_type = XSyncAbsolute;
+ XSyncIntToValue(&pTrigger->wait_value, 0L);
+ pTrigger->test_type = XSyncPositiveComparison;
+ pTrigger->TriggerFired = SyncAlarmTriggerFired;
+ pTrigger->CounterDestroyed = SyncAlarmCounterDestroyed;
+ status = SyncInitTrigger(client, pTrigger, None, XSyncCAAllTrigger);
+ if (status != Success)
+ {
+ free(pAlarm);
+ return status;
+ }
+
+ pAlarm->client = client;
+ pAlarm->alarm_id = stuff->id;
+ XSyncIntToValue(&pAlarm->delta, 1L);
+ pAlarm->events = TRUE;
+ pAlarm->state = XSyncAlarmInactive;
+ pAlarm->pEventClients = NULL;
+ status = SyncChangeAlarmAttributes(client, pAlarm, vmask,
+ (CARD32 *)&stuff[1]);
+ if (status != Success)
+ {
+ free(pAlarm);
+ return status;
+ }
+
+ if (!AddResource(stuff->id, RTAlarm, pAlarm))
+ {
+ free(pAlarm);
+ return BadAlloc;
+ }
+
+ /* see if alarm already triggered. NULL counter will not trigger
+ * in CreateAlarm and sets alarm state to Inactive.
+ */
+
+ if (!pTrigger->pCounter)
+ {
+ pAlarm->state = XSyncAlarmInactive; /* XXX protocol change */
+ }
+ else if ((*pTrigger->CheckTrigger)(pTrigger, pTrigger->pCounter->value))
+ {
+ (*pTrigger->TriggerFired)(pTrigger);
+ }
+
+ return Success;
+}
+
+/*
+ * ** Change Alarm
+ */
+static int
+ProcSyncChangeAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncChangeAlarmReq);
+ SyncAlarm *pAlarm;
+ long vmask;
+ int len, status;
+
+ REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq);
+
+ if (!(pAlarm = (SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm,
+ RTAlarm, DixWriteAccess)))
+ {
+ client->errorValue = stuff->alarm;
+ return SyncErrorBase + XSyncBadAlarm;
+ }
+
+ vmask = stuff->valueMask;
+ len = client->req_len - (sizeof(xSyncChangeAlarmReq) >> 2);
+ /* the "extra" call to Ones accounts for the presence of 64 bit values */
+ if (len != (Ones(vmask) + Ones(vmask & (XSyncCAValue|XSyncCADelta))))
+ return BadLength;
+
+ if ((status = SyncChangeAlarmAttributes(client, pAlarm, vmask,
+ (CARD32 *)&stuff[1])) != Success)
+ return status;
+
+ /* see if alarm already triggered. NULL counter WILL trigger
+ * in ChangeAlarm.
+ */
+
+ if (!pAlarm->trigger.pCounter ||
+ (*pAlarm->trigger.CheckTrigger)(&pAlarm->trigger,
+ pAlarm->trigger.pCounter->value))
+ {
+ (*pAlarm->trigger.TriggerFired)(&pAlarm->trigger);
+ }
+ return Success;
+}
+
+static int
+ProcSyncQueryAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncQueryAlarmReq);
+ SyncAlarm *pAlarm;
+ xSyncQueryAlarmReply rep;
+ SyncTrigger *pTrigger;
+
+ REQUEST_SIZE_MATCH(xSyncQueryAlarmReq);
+
+ pAlarm = (SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm,
+ RTAlarm, DixReadAccess);
+ if (!pAlarm)
+ {
+ client->errorValue = stuff->alarm;
+ return (SyncErrorBase + XSyncBadAlarm);
+ }
+
+ rep.type = X_Reply;
+ rep.length = (sizeof(xSyncQueryAlarmReply) - sizeof(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+
+ pTrigger = &pAlarm->trigger;
+ rep.counter = (pTrigger->pCounter) ? pTrigger->pCounter->id : None;
+
+#if 0 /* XXX unclear what to do, depends on whether relative value-types
+ * are "consumed" immediately and are considered absolute from then
+ * on.
+ */
+ rep.value_type = pTrigger->value_type;
+ rep.wait_value_hi = XSyncValueHigh32(pTrigger->wait_value);
+ rep.wait_value_lo = XSyncValueLow32(pTrigger->wait_value);
+#else
+ rep.value_type = XSyncAbsolute;
+ rep.wait_value_hi = XSyncValueHigh32(pTrigger->test_value);
+ rep.wait_value_lo = XSyncValueLow32(pTrigger->test_value);
+#endif
+
+ rep.test_type = pTrigger->test_type;
+ rep.delta_hi = XSyncValueHigh32(pAlarm->delta);
+ rep.delta_lo = XSyncValueLow32(pAlarm->delta);
+ rep.events = pAlarm->events;
+ rep.state = pAlarm->state;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.counter);
+ swapl(&rep.wait_value_hi);
+ swapl(&rep.wait_value_lo);
+ swapl(&rep.test_type);
+ swapl(&rep.delta_hi);
+ swapl(&rep.delta_lo);
+ }
+
+ WriteToClient(client, sizeof(xSyncQueryAlarmReply), &rep);
+ return (client->noClientException);
+}
+
+
+static int
+ProcSyncDestroyAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncDestroyAlarmReq);
+
+ REQUEST_SIZE_MATCH(xSyncDestroyAlarmReq);
+
+ if (!((SyncAlarm *)SecurityLookupIDByType(client, stuff->alarm,
+ RTAlarm, DixDestroyAccess)))
+ {
+ client->errorValue = stuff->alarm;
+ return SyncErrorBase + XSyncBadAlarm;
+ }
+
+ FreeResource(stuff->alarm, RT_NONE);
+ return (client->noClientException);
+}
+
+/*
+ * ** Given an extension request, call the appropriate request procedure
+ */
+static int
+ProcSyncDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+
+ case X_SyncInitialize:
+ return ProcSyncInitialize(client);
+ case X_SyncListSystemCounters:
+ return ProcSyncListSystemCounters(client);
+ case X_SyncCreateCounter:
+ return ProcSyncCreateCounter(client);
+ case X_SyncSetCounter:
+ return ProcSyncSetCounter(client);
+ case X_SyncChangeCounter:
+ return ProcSyncChangeCounter(client);
+ case X_SyncQueryCounter:
+ return ProcSyncQueryCounter(client);
+ case X_SyncDestroyCounter:
+ return ProcSyncDestroyCounter(client);
+ case X_SyncAwait:
+ return ProcSyncAwait(client);
+ case X_SyncCreateAlarm:
+ return ProcSyncCreateAlarm(client);
+ case X_SyncChangeAlarm:
+ return ProcSyncChangeAlarm(client);
+ case X_SyncQueryAlarm:
+ return ProcSyncQueryAlarm(client);
+ case X_SyncDestroyAlarm:
+ return ProcSyncDestroyAlarm(client);
+ case X_SyncSetPriority:
+ return ProcSyncSetPriority(client);
+ case X_SyncGetPriority:
+ return ProcSyncGetPriority(client);
+ default:
+ return BadRequest;
+ }
+}
+
+/*
+ * Boring Swapping stuff ...
+ */
+
+static int
+SProcSyncInitialize(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncInitializeReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncInitializeReq);
+
+ return ProcSyncInitialize(client);
+}
+
+static int
+SProcSyncListSystemCounters(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncListSystemCountersReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncListSystemCountersReq);
+
+ return ProcSyncListSystemCounters(client);
+}
+
+static int
+SProcSyncCreateCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncCreateCounterReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncCreateCounterReq);
+ swapl(&stuff->cid);
+ swapl(&stuff->initial_value_lo);
+ swapl(&stuff->initial_value_hi);
+
+ return ProcSyncCreateCounter(client);
+}
+
+static int
+SProcSyncSetCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncSetCounterReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncSetCounterReq);
+ swapl(&stuff->cid);
+ swapl(&stuff->value_lo);
+ swapl(&stuff->value_hi);
+
+ return ProcSyncSetCounter(client);
+}
+
+static int
+SProcSyncChangeCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncChangeCounterReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncChangeCounterReq);
+ swapl(&stuff->cid);
+ swapl(&stuff->value_lo);
+ swapl(&stuff->value_hi);
+
+ return ProcSyncChangeCounter(client);
+}
+
+static int
+SProcSyncQueryCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncQueryCounterReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncQueryCounterReq);
+ swapl(&stuff->counter);
+
+ return ProcSyncQueryCounter(client);
+}
+
+static int
+SProcSyncDestroyCounter(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncDestroyCounterReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncDestroyCounterReq);
+ swapl(&stuff->counter);
+
+ return ProcSyncDestroyCounter(client);
+}
+
+static int
+SProcSyncAwait(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncAwaitReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSyncAwaitReq);
+ SwapRestL(stuff);
+
+ return ProcSyncAwait(client);
+}
+
+
+static int
+SProcSyncCreateAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncCreateAlarmReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSyncCreateAlarmReq);
+ swapl(&stuff->id);
+ swapl(&stuff->valueMask);
+ SwapRestL(stuff);
+
+ return ProcSyncCreateAlarm(client);
+}
+
+static int
+SProcSyncChangeAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncChangeAlarmReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSyncChangeAlarmReq);
+ swapl(&stuff->alarm);
+ swapl(&stuff->valueMask);
+ SwapRestL(stuff);
+ return ProcSyncChangeAlarm(client);
+}
+
+static int
+SProcSyncQueryAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncQueryAlarmReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncQueryAlarmReq);
+ swapl(&stuff->alarm);
+
+ return ProcSyncQueryAlarm(client);
+}
+
+static int
+SProcSyncDestroyAlarm(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncDestroyAlarmReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncDestroyAlarmReq);
+ swapl(&stuff->alarm);
+
+ return ProcSyncDestroyAlarm(client);
+}
+
+static int
+SProcSyncSetPriority(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncSetPriorityReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncSetPriorityReq);
+ swapl(&stuff->id);
+ swapl(&stuff->priority);
+
+ return ProcSyncSetPriority(client);
+}
+
+static int
+SProcSyncGetPriority(client)
+ ClientPtr client;
+{
+ REQUEST(xSyncGetPriorityReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH (xSyncGetPriorityReq);
+ swapl(&stuff->id);
+
+ return ProcSyncGetPriority(client);
+}
+
+
+static int
+SProcSyncDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SyncInitialize:
+ return SProcSyncInitialize(client);
+ case X_SyncListSystemCounters:
+ return SProcSyncListSystemCounters(client);
+ case X_SyncCreateCounter:
+ return SProcSyncCreateCounter(client);
+ case X_SyncSetCounter:
+ return SProcSyncSetCounter(client);
+ case X_SyncChangeCounter:
+ return SProcSyncChangeCounter(client);
+ case X_SyncQueryCounter:
+ return SProcSyncQueryCounter(client);
+ case X_SyncDestroyCounter:
+ return SProcSyncDestroyCounter(client);
+ case X_SyncAwait:
+ return SProcSyncAwait(client);
+ case X_SyncCreateAlarm:
+ return SProcSyncCreateAlarm(client);
+ case X_SyncChangeAlarm:
+ return SProcSyncChangeAlarm(client);
+ case X_SyncQueryAlarm:
+ return SProcSyncQueryAlarm(client);
+ case X_SyncDestroyAlarm:
+ return SProcSyncDestroyAlarm(client);
+ case X_SyncSetPriority:
+ return SProcSyncSetPriority(client);
+ case X_SyncGetPriority:
+ return SProcSyncGetPriority(client);
+ default:
+ return BadRequest;
+ }
+}
+
+/*
+ * Event Swapping
+ */
+
+static void
+SCounterNotifyEvent(from, to)
+ xSyncCounterNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->counter, to->counter);
+ cpswapl(from->wait_value_lo, to->wait_value_lo);
+ cpswapl(from->wait_value_hi, to->wait_value_hi);
+ cpswapl(from->counter_value_lo, to->counter_value_lo);
+ cpswapl(from->counter_value_hi, to->counter_value_hi);
+ cpswapl(from->time, to->time);
+ cpswaps(from->count, to->count);
+ to->destroyed = from->destroyed;
+}
+
+
+static void
+SAlarmNotifyEvent(from, to)
+ xSyncAlarmNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->alarm, to->alarm);
+ cpswapl(from->counter_value_lo, to->counter_value_lo);
+ cpswapl(from->counter_value_hi, to->counter_value_hi);
+ cpswapl(from->alarm_value_lo, to->alarm_value_lo);
+ cpswapl(from->alarm_value_hi, to->alarm_value_hi);
+ cpswapl(from->time, to->time);
+ to->state = from->state;
+}
+
+/*
+ * ** Close everything down. ** This is fairly simple for now.
+ */
+/* ARGSUSED */
+static void
+SyncResetProc(extEntry)
+ ExtensionEntry *extEntry;
+{
+ free(SysCounterList);
+ SysCounterList = NULL;
+ RTCounter = 0;
+}
+
+
+/*
+ * ** Initialise the extension.
+ */
+void
+SyncExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ if (RTCounter == 0)
+ {
+ RTCounter = CreateNewResourceType(FreeCounter);
+ }
+ RTAlarm = CreateNewResourceType(FreeAlarm);
+ RTAwait = CreateNewResourceType(FreeAwait)|RC_NEVERRETAIN;
+ RTAlarmClient = CreateNewResourceType(FreeAlarmClient)|RC_NEVERRETAIN;
+
+ if (RTCounter == 0 || RTAwait == 0 || RTAlarm == 0 ||
+ RTAlarmClient == 0 ||
+ (extEntry = AddExtension(SYNC_NAME,
+ XSyncNumberEvents, XSyncNumberErrors,
+ ProcSyncDispatch, SProcSyncDispatch,
+ SyncResetProc,
+ StandardMinorOpcode)) == NULL)
+ {
+ ErrorF("Sync Extension %d.%d failed to Initialise\n",
+ SYNC_MAJOR_VERSION, SYNC_MINOR_VERSION);
+ return;
+ }
+
+ SyncEventBase = extEntry->eventBase;
+ SyncErrorBase = extEntry->errorBase;
+ EventSwapVector[SyncEventBase + XSyncCounterNotify] = (EventSwapPtr) SCounterNotifyEvent;
+ EventSwapVector[SyncEventBase + XSyncAlarmNotify] = (EventSwapPtr) SAlarmNotifyEvent;
+
+ /*
+ * Although SERVERTIME is implemented by the OS layer, we initialise it
+ * here because doing it in OsInit() is too early. The resource database
+ * is not initialised when OsInit() is called. This is just about OK
+ * because there is always a servertime counter.
+ */
+ SyncInitServerTime();
+
+#ifdef DEBUG
+ fprintf(stderr, "Sync Extension %d.%d\n",
+ SYNC_MAJOR_VERSION, SYNC_MINOR_VERSION);
+#endif
+}
+
+
+/*
+ * ***** SERVERTIME implementation - should go in its own file in OS directory?
+ */
+
+
+
+static void * ServertimeCounter;
+static XSyncValue Now;
+static XSyncValue *pnext_time;
+
+#define GetTime()\
+{\
+ unsigned long millis = GetTimeInMillis();\
+ unsigned long maxis = XSyncValueHigh32(Now);\
+ if (millis < XSyncValueLow32(Now)) maxis++;\
+ XSyncIntsToValue(&Now, millis, maxis);\
+}
+
+/*
+*** Server Block Handler
+*** code inspired by multibuffer extension
+ */
+/*ARGSUSED*/
+static void ServertimeBlockHandler(env, wt, LastSelectMask)
+void * env;
+struct timeval **wt;
+void * LastSelectMask;
+{
+ XSyncValue delay;
+ unsigned long timeout;
+
+ if (pnext_time)
+ {
+ GetTime();
+
+ if (XSyncValueGreaterOrEqual(Now, *pnext_time))
+ {
+ timeout = 0;
+ }
+ else
+ {
+ Bool overflow;
+ XSyncValueSubtract(&delay, *pnext_time, Now, &overflow);
+ (void)overflow;
+ timeout = XSyncValueLow32(delay);
+ }
+ AdjustWaitForDelay(wt, timeout); /* os/utils.c */
+ }
+}
+
+/*
+*** Wakeup Handler
+ */
+/*ARGSUSED*/
+static void ServertimeWakeupHandler(env, rc, LastSelectMask)
+void * env;
+int rc;
+void * LastSelectMask;
+{
+ if (pnext_time)
+ {
+ GetTime();
+
+ if (XSyncValueGreaterOrEqual(Now, *pnext_time))
+ {
+ SyncChangeCounter(ServertimeCounter, Now);
+ }
+ }
+}
+
+static void
+ServertimeQueryValue(pCounter, pValue_return)
+ void * pCounter;
+ CARD64 *pValue_return;
+{
+ GetTime();
+ *pValue_return = Now;
+}
+
+static void
+ServertimeBracketValues(pCounter, pbracket_less, pbracket_greater)
+ void * pCounter;
+ CARD64 *pbracket_less;
+ CARD64 *pbracket_greater;
+{
+ if (!pnext_time && pbracket_greater)
+ {
+ RegisterBlockAndWakeupHandlers(ServertimeBlockHandler,
+ ServertimeWakeupHandler,
+ NULL);
+ }
+ else if (pnext_time && !pbracket_greater)
+ {
+ RemoveBlockAndWakeupHandlers(ServertimeBlockHandler,
+ ServertimeWakeupHandler,
+ NULL);
+ }
+ pnext_time = pbracket_greater;
+}
+
+static void
+SyncInitServerTime()
+{
+ CARD64 resolution;
+
+ XSyncIntsToValue(&Now, GetTimeInMillis(), 0);
+ XSyncIntToValue(&resolution, 4);
+ ServertimeCounter = SyncCreateSystemCounter("SERVERTIME", Now, resolution,
+ XSyncCounterNeverDecreases,
+ ServertimeQueryValue, ServertimeBracketValues);
+ pnext_time = NULL;
+}
diff --git a/nx-X11/programs/Xserver/Xext/xcmisc.c b/nx-X11/programs/Xserver/Xext/xcmisc.c
new file mode 100644
index 000000000..bb47df979
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xcmisc.c
@@ -0,0 +1,239 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "swaprep.h"
+#include <nx-X11/extensions/xcmiscstr.h>
+
+#include <stdint.h>
+
+#if 0
+static unsigned char XCMiscCode;
+#endif
+
+static void XCMiscResetProc(
+ ExtensionEntry * /* extEntry */
+);
+
+static DISPATCH_PROC(ProcXCMiscDispatch);
+static DISPATCH_PROC(ProcXCMiscGetVersion);
+static DISPATCH_PROC(ProcXCMiscGetXIDList);
+static DISPATCH_PROC(ProcXCMiscGetXIDRange);
+static DISPATCH_PROC(SProcXCMiscDispatch);
+static DISPATCH_PROC(SProcXCMiscGetVersion);
+static DISPATCH_PROC(SProcXCMiscGetXIDList);
+static DISPATCH_PROC(SProcXCMiscGetXIDRange);
+
+void
+XCMiscExtensionInit(void)
+{
+#if 0
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(XCMiscExtensionName, 0, 0,
+ ProcXCMiscDispatch, SProcXCMiscDispatch,
+ XCMiscResetProc, StandardMinorOpcode)) != 0)
+ XCMiscCode = (unsigned char)extEntry->base;
+#else
+ (void) AddExtension(XCMiscExtensionName, 0, 0,
+ ProcXCMiscDispatch, SProcXCMiscDispatch,
+ XCMiscResetProc, StandardMinorOpcode);
+#endif
+
+ DeclareExtensionSecurity(XCMiscExtensionName, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+XCMiscResetProc (extEntry)
+ ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcXCMiscGetVersion(client)
+ register ClientPtr client;
+{
+ xXCMiscGetVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XCMiscMajorVersion;
+ rep.minorVersion = XCMiscMinorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xXCMiscGetVersionReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcXCMiscGetXIDRange(client)
+ register ClientPtr client;
+{
+ xXCMiscGetXIDRangeReply rep;
+ XID min_id, max_id;
+
+ REQUEST_SIZE_MATCH(xXCMiscGetXIDRangeReq);
+ GetXIDRange(client->index, FALSE, &min_id, &max_id);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.start_id = min_id;
+ rep.count = max_id - min_id + 1;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.start_id);
+ swapl(&rep.count);
+ }
+ WriteToClient(client, sizeof(xXCMiscGetXIDRangeReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcXCMiscGetXIDList(client)
+ register ClientPtr client;
+{
+ REQUEST(xXCMiscGetXIDListReq);
+ xXCMiscGetXIDListReply rep;
+ XID *pids;
+ unsigned int count;
+
+ REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
+
+ if (stuff->count > UINT32_MAX / sizeof(XID))
+ return BadAlloc;
+
+ pids = (XID *)malloc(stuff->count * sizeof(XID));
+ if (!pids)
+ {
+ return BadAlloc;
+ }
+ count = GetXIDList(client, stuff->count, pids);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = count;
+ rep.count = count;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.count);
+ }
+ WriteToClient(client, sizeof(xXCMiscGetXIDListReply), &rep);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, count * sizeof(XID), pids);
+ }
+ free(pids);
+ return(client->noClientException);
+}
+
+static int
+ProcXCMiscDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XCMiscGetVersion:
+ return ProcXCMiscGetVersion(client);
+ case X_XCMiscGetXIDRange:
+ return ProcXCMiscGetXIDRange(client);
+ case X_XCMiscGetXIDList:
+ return ProcXCMiscGetXIDList(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXCMiscGetVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xXCMiscGetVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
+ swaps(&stuff->majorVersion);
+ swaps(&stuff->minorVersion);
+ return ProcXCMiscGetVersion(client);
+}
+
+static int
+SProcXCMiscGetXIDRange(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ swaps(&stuff->length);
+ return ProcXCMiscGetXIDRange(client);
+}
+
+static int
+SProcXCMiscGetXIDList(client)
+ register ClientPtr client;
+{
+ REQUEST(xXCMiscGetXIDListReq);
+ REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->count);
+ return ProcXCMiscGetXIDList(client);
+}
+
+static int
+SProcXCMiscDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XCMiscGetVersion:
+ return SProcXCMiscGetVersion(client);
+ case X_XCMiscGetXIDRange:
+ return SProcXCMiscGetXIDRange(client);
+ case X_XCMiscGetXIDList:
+ return SProcXCMiscGetXIDList(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/xf86bigfont.c b/nx-X11/programs/Xserver/Xext/xf86bigfont.c
new file mode 100644
index 000000000..d8cae74ef
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xf86bigfont.c
@@ -0,0 +1,792 @@
+/*
+ * BIGFONT extension for sharing font metrics between clients (if possible)
+ * and for transmitting font metrics to clients in a compressed form.
+ *
+ * Copyright (c) 1999-2000 Bruno Haible
+ * Copyright (c) 1999-2000 The XFree86 Project, Inc.
+ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+/*
+ * Big fonts suffer from the following: All clients that have opened a
+ * font can access the complete glyph metrics array (the XFontStruct member
+ * `per_char') directly, without going through a macro. Moreover these
+ * glyph metrics are ink metrics, i.e. are not redundant even for a
+ * fixed-width font. For a Unicode font, the size of this array is 768 KB.
+ *
+ * Problems: 1. It eats a lot of memory in each client. 2. All this glyph
+ * metrics data is piped through the socket when the font is opened.
+ *
+ * This extension addresses these two problems for local clients, by using
+ * shared memory. It also addresses the second problem for non-local clients,
+ * by compressing the data before transmit by a factor of nearly 6.
+ *
+ * If you use this extension, your OS ought to nicely support shared memory.
+ * This means: Shared memory should be swappable to the swap, and the limits
+ * should be high enough (SHMMNI at least 64, SHMMAX at least 768 KB,
+ * SHMALL at least 48 MB). It is a plus if your OS allows shmat() calls
+ * on segments that have already been marked "removed", because it permits
+ * these segments to be cleaned up by the OS if the X server is killed with
+ * signal SIGKILL.
+ *
+ * This extension is transparently exploited by Xlib (functions XQueryFont,
+ * XLoadQueryFont).
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifdef HAS_SHM
+#if defined(linux) && (!defined(__GNU_LIBRARY__) || __GNU_LIBRARY__ < 2)
+/* libc4 does not define __GNU_LIBRARY__, libc5 defines __GNU_LIBRARY__ as 1 */
+/* Linux libc4 and libc5 only (because glibc doesn't include kernel headers):
+ Linux 2.0.x and 2.2.x define SHMLBA as PAGE_SIZE, but forget to define
+ PAGE_SIZE. It is defined in <asm/page.h>. */
+#include <asm/page.h>
+#endif
+#ifdef SVR4
+#include <sys/sysmacros.h>
+#endif
+#if defined(ISC) || defined(__CYGWIN__) || defined(__SCO__)
+#include <sys/param.h>
+#include <sys/sysmacros.h>
+#endif
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "dixfontstr.h"
+#include "extnsionst.h"
+#include "protocol-versions.h"
+
+#define _XF86BIGFONT_SERVER_
+#include <nx-X11/extensions/xf86bigfproto.h>
+
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#endif /* HAS_XFONT2 */
+
+static void XF86BigfontResetProc(
+ ExtensionEntry * /* extEntry */
+ );
+
+static DISPATCH_PROC(ProcXF86BigfontDispatch);
+static DISPATCH_PROC(ProcXF86BigfontQueryVersion);
+static DISPATCH_PROC(ProcXF86BigfontQueryFont);
+static DISPATCH_PROC(SProcXF86BigfontDispatch);
+static DISPATCH_PROC(SProcXF86BigfontQueryVersion);
+static DISPATCH_PROC(SProcXF86BigfontQueryFont);
+
+#if 0
+static unsigned char XF86BigfontReqCode;
+#endif
+
+#ifdef HAS_SHM
+
+/* A random signature, transmitted to the clients so they can verify that the
+ shared memory segment they are attaching to was really established by the
+ X server they are talking to. */
+static CARD32 signature;
+
+/* Index for additional information stored in a FontRec's devPrivates array. */
+static int FontShmdescIndex;
+
+static unsigned int pagesize;
+
+static Bool badSysCall = FALSE;
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+
+static void
+SigSysHandler(
+ int signo)
+{
+ badSysCall = TRUE;
+}
+
+static Bool
+CheckForShmSyscall(void)
+{
+ void (*oldHandler)(int);
+ int shmid = -1;
+
+ /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+ oldHandler = OsSignal(SIGSYS, SigSysHandler);
+
+ badSysCall = FALSE;
+ shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+ if (shmid != -1)
+ {
+ /* Successful allocation - clean up */
+ shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ OsSignal(SIGSYS, oldHandler);
+ return (!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+#endif
+
+void
+XFree86BigfontExtensionInit()
+{
+#if 0
+ ExtensionEntry* extEntry;
+
+ if ((extEntry = AddExtension(XF86BIGFONTNAME,
+ XF86BigfontNumberEvents,
+ XF86BigfontNumberErrors,
+ ProcXF86BigfontDispatch,
+ SProcXF86BigfontDispatch,
+ XF86BigfontResetProc,
+ StandardMinorOpcode))) {
+ XF86BigfontReqCode = (unsigned char) extEntry->base;
+#else
+ if (AddExtension(XF86BIGFONTNAME,
+ XF86BigfontNumberEvents,
+ XF86BigfontNumberErrors,
+ ProcXF86BigfontDispatch,
+ SProcXF86BigfontDispatch,
+ XF86BigfontResetProc,
+ StandardMinorOpcode)) {
+#endif
+#ifdef HAS_SHM
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+ /*
+ * Note: Local-clients will not be optimized without shared memory
+ * support. Remote-client optimization does not depend on shared
+ * memory support. Thus, the extension is still registered even
+ * when shared memory support is not functional.
+ */
+ if (!CheckForShmSyscall()) {
+ ErrorF(XF86BIGFONTNAME " extension local-client optimization disabled due to lack of shared memory support in the kernel\n");
+ return;
+ }
+#endif
+
+ srand((unsigned int) time(NULL));
+ signature = ((unsigned int) (65536.0/(RAND_MAX+1.0) * rand()) << 16)
+ + (unsigned int) (65536.0/(RAND_MAX+1.0) * rand());
+ /* fprintf(stderr, "signature = 0x%08X\n", signature); */
+
+#ifdef HAS_XFONT2
+ FontShmdescIndex = xfont2_allocate_font_private_index();
+#else
+ FontShmdescIndex = AllocateFontPrivateIndex();
+#endif /* HAS_XFONT2 */
+
+#if !defined(CSRG_BASED) && !defined(__CYGWIN__)
+ pagesize = SHMLBA;
+#else
+# ifdef _SC_PAGESIZE
+ pagesize = sysconf(_SC_PAGESIZE);
+# else
+ pagesize = getpagesize();
+# endif
+#endif
+#endif
+ }
+}
+
+
+/* ========== Management of shared memory segments ========== */
+
+#ifdef HAS_SHM
+
+#ifdef __linux__
+/* On Linux, shared memory marked as "removed" can still be attached.
+ Nice feature, because the kernel will automatically free the associated
+ storage when the server and all clients are gone. */
+#define EARLY_REMOVE
+#endif
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ struct _ShmDesc **prev;
+ int shmid;
+ char *attach_addr;
+} ShmDescRec, *ShmDescPtr;
+
+static ShmDescPtr ShmList = (ShmDescPtr) NULL;
+
+static ShmDescPtr
+shmalloc(
+ unsigned int size)
+{
+ ShmDescPtr pDesc;
+ int shmid;
+ char *addr;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+ if (pagesize == 0)
+ return (ShmDescPtr) NULL;
+#endif
+
+ /* On some older Linux systems, the number of shared memory segments
+ system-wide is 127. In Linux 2.4, it is 4095.
+ Therefore there is a tradeoff to be made between allocating a
+ shared memory segment on one hand, and allocating memory and piping
+ the glyph metrics on the other hand. If the glyph metrics size is
+ small, we prefer the traditional way. */
+ if (size < 3500)
+ return (ShmDescPtr) NULL;
+
+ pDesc = (ShmDescRec *) malloc(sizeof(ShmDescRec));
+ if (!pDesc)
+ return (ShmDescPtr) NULL;
+
+ size = (size + pagesize-1) & -pagesize;
+ shmid = shmget(IPC_PRIVATE, size, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
+ if (shmid == -1) {
+ ErrorF(XF86BIGFONTNAME " extension: shmget() failed, size = %u, errno = %d\n",
+ size, errno);
+ free(pDesc);
+ return (ShmDescPtr) NULL;
+ }
+
+ if ((addr = shmat(shmid, 0, 0)) == (char *)-1) {
+ ErrorF(XF86BIGFONTNAME " extension: shmat() failed, size = %u, errno = %d\n",
+ size, errno);
+ shmctl(shmid, IPC_RMID, (void *) 0);
+ free(pDesc);
+ return (ShmDescPtr) NULL;
+ }
+
+#ifdef EARLY_REMOVE
+ shmctl(shmid, IPC_RMID, (void *) 0);
+#endif
+
+ pDesc->shmid = shmid;
+ pDesc->attach_addr = addr;
+ if (ShmList) ShmList->prev = &pDesc->next;
+ pDesc->next = ShmList;
+ pDesc->prev = &ShmList;
+ ShmList = pDesc;
+
+ return pDesc;
+}
+
+static void
+shmdealloc(
+ ShmDescPtr pDesc)
+{
+#ifndef EARLY_REMOVE
+ shmctl(pDesc->shmid, IPC_RMID, (void *) 0);
+#endif
+ shmdt(pDesc->attach_addr);
+
+ if (pDesc->next) pDesc->next->prev = pDesc->prev;
+ *pDesc->prev = pDesc->next;
+ free(pDesc);
+}
+
+#endif
+
+/* Called when a font is closed. */
+void
+XF86BigfontFreeFontShm(
+ FontPtr pFont)
+{
+#ifdef HAS_SHM
+ ShmDescPtr pDesc;
+
+ /* If during shutdown of the server, XF86BigfontCleanup() has already
+ * called shmdealloc() for all segments, we don't need to do it here.
+ */
+ if (!ShmList)
+ return;
+
+ pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
+ if (pDesc)
+ shmdealloc(pDesc);
+#endif
+}
+
+/* Called upon fatal signal. */
+void
+XF86BigfontCleanup()
+{
+#ifdef HAS_SHM
+ while (ShmList)
+ shmdealloc(ShmList);
+#endif
+}
+
+/* Called when a server generation dies. */
+static void
+XF86BigfontResetProc(
+ ExtensionEntry* extEntry)
+{
+ /* This function is normally called from CloseDownExtensions(), called
+ * from main(). It will be followed by a call to FreeAllResources(),
+ * which will call XF86BigfontFreeFontShm() for each font. Thus it
+ * appears that we do not need to do anything in this function. --
+ * But I prefer to write robust code, and not keep shared memory lying
+ * around when it's not needed any more. (Someone might close down the
+ * extension without calling FreeAllResources()...)
+ */
+ XF86BigfontCleanup();
+}
+
+
+/* ========== Handling of extension specific requests ========== */
+
+static int
+ProcXF86BigfontQueryVersion(
+ ClientPtr client)
+{
+ xXF86BigfontQueryVersionReply reply;
+
+ REQUEST_SIZE_MATCH(xXF86BigfontQueryVersionReq);
+ memset(&reply, 0, sizeof(xXF86BigfontQueryVersionReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.majorVersion = SERVER_XF86BIGFONT_MAJOR_VERSION;
+ reply.minorVersion = SERVER_XF86BIGFONT_MINOR_VERSION;
+ reply.uid = geteuid();
+ reply.gid = getegid();
+#ifdef HAS_SHM
+ reply.signature = signature;
+#else
+ reply.signature = 0; /* This is redundant. Avoids uninitialized memory. */
+#endif
+ reply.capabilities =
+#ifdef HAS_SHM
+ (client->local && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0)
+#else
+ 0
+#endif
+ ; /* may add more bits here in future versions */
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swaps(&reply.majorVersion);
+ swaps(&reply.minorVersion);
+ swapl(&reply.uid);
+ swapl(&reply.gid);
+ swapl(&reply.signature);
+ }
+ WriteToClient(client,
+ sizeof(xXF86BigfontQueryVersionReply), &reply);
+ return client->noClientException;
+}
+
+static void
+swapCharInfo(
+ xCharInfo *pCI)
+{
+ swaps(&pCI->leftSideBearing);
+ swaps(&pCI->rightSideBearing);
+ swaps(&pCI->characterWidth);
+ swaps(&pCI->ascent);
+ swaps(&pCI->descent);
+ swaps(&pCI->attributes);
+}
+
+/* static CARD32 hashCI (xCharInfo *p); */
+#define hashCI(p) \
+ (CARD32)(((p->leftSideBearing << 27) + (p->leftSideBearing >> 5) + \
+ (p->rightSideBearing << 23) + (p->rightSideBearing >> 9) + \
+ (p->characterWidth << 16) + \
+ (p->ascent << 11) + (p->descent << 6)) ^ p->attributes)
+
+static int
+ProcXF86BigfontQueryFont(
+ ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xXF86BigfontQueryFontReq);
+ CARD32 stuff_flags;
+ xCharInfo* pmax;
+ xCharInfo* pmin;
+ int nCharInfos;
+ int shmid;
+#ifdef HAS_SHM
+ ShmDescPtr pDesc = NULL;
+#else
+#define pDesc 0
+#endif
+ xCharInfo* pCI;
+ CARD16* pIndex2UniqIndex;
+ CARD16* pUniqIndex2Index;
+ CARD32 nUniqCharInfos;
+
+#if 0
+ REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
+#else
+ switch (client->req_len) {
+ case 2: /* client with version 1.0 libX11 */
+ stuff_flags = (client->local && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0);
+ break;
+ case 3: /* client with version 1.1 libX11 */
+ stuff_flags = stuff->flags;
+ break;
+ default:
+ return BadLength;
+ }
+#endif
+ client->errorValue = stuff->id; /* EITHER font or gc */
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ DixReadAccess);
+ if (!pFont) {
+ /* can't use VERIFY_GC because it might return BadGC */
+ GC *pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ DixReadAccess);
+ if (!pGC) {
+ client->errorValue = stuff->id;
+ return BadFont; /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ pmax = FONTINKMAX(pFont);
+ pmin = FONTINKMIN(pFont);
+ nCharInfos =
+ (pmax->rightSideBearing == pmin->rightSideBearing
+ && pmax->leftSideBearing == pmin->leftSideBearing
+ && pmax->descent == pmin->descent
+ && pmax->ascent == pmin->ascent
+ && pmax->characterWidth == pmin->characterWidth)
+ ? 0 : N2dChars(pFont);
+ shmid = -1;
+ pCI = NULL;
+ pIndex2UniqIndex = NULL;
+ pUniqIndex2Index = NULL;
+ nUniqCharInfos = 0;
+
+ if (nCharInfos > 0) {
+#ifdef HAS_SHM
+ if (!badSysCall)
+ pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
+ else
+ pDesc = NULL;
+ if (pDesc) {
+ pCI = (xCharInfo *) pDesc->attach_addr;
+ if (stuff_flags & XF86Bigfont_FLAGS_Shm)
+ shmid = pDesc->shmid;
+ } else {
+ if (stuff_flags & XF86Bigfont_FLAGS_Shm && !badSysCall)
+ pDesc = shmalloc(nCharInfos * sizeof(xCharInfo)
+ + sizeof(CARD32));
+ if (pDesc) {
+ pCI = (xCharInfo *) pDesc->attach_addr;
+ shmid = pDesc->shmid;
+ } else {
+#endif
+ pCI = (xCharInfo *)
+ malloc(nCharInfos * sizeof(xCharInfo));
+ if (!pCI)
+ return BadAlloc;
+#ifdef HAS_SHM
+ }
+#endif
+ /* Fill nCharInfos starting at pCI. */
+ {
+ xCharInfo* prCI = pCI;
+ int ninfos = 0;
+ int ncols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ int row;
+ for (row = pFont->info.firstRow;
+ row <= pFont->info.lastRow && ninfos < nCharInfos;
+ row++) {
+ unsigned char chars[512];
+ xCharInfo* tmpCharInfos[256];
+ unsigned long count;
+ int col;
+ unsigned long i;
+ i = 0;
+ for (col = pFont->info.firstCol;
+ col <= pFont->info.lastCol;
+ col++) {
+ chars[i++] = row;
+ chars[i++] = col;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit,
+ &count, tmpCharInfos);
+ for (i = 0; i < count && ninfos < nCharInfos; i++) {
+ *prCI++ = *tmpCharInfos[i];
+ ninfos++;
+ }
+ }
+ }
+#ifdef HAS_SHM
+ if (pDesc && !badSysCall) {
+ *(CARD32 *)(pCI + nCharInfos) = signature;
+#ifdef HAS_XFONT2
+ if (!xfont2_font_set_private(pFont, FontShmdescIndex, pDesc)) {
+#else
+ if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) {
+#endif /* HAS_XFONT2 */
+ shmdealloc(pDesc);
+ return BadAlloc;
+ }
+ }
+ }
+#endif
+ if (shmid == -1) {
+ /* Cannot use shared memory, so remove-duplicates the xCharInfos
+ using a temporary hash table. */
+ /* Note that CARD16 is suitable as index type, because
+ nCharInfos <= 0x10000. */
+ CARD32 hashModulus;
+ CARD16* pHash2UniqIndex;
+ CARD16* pUniqIndex2NextUniqIndex;
+ CARD32 NextIndex;
+ CARD32 NextUniqIndex;
+ CARD16* tmp;
+ CARD32 i, j;
+
+ hashModulus = 67;
+ if (hashModulus > nCharInfos+1)
+ hashModulus = nCharInfos+1;
+
+ tmp = (CARD16*)
+ malloc((4*nCharInfos+1) * sizeof(CARD16));
+ if (!tmp) {
+ if (!pDesc) free(pCI);
+ return BadAlloc;
+ }
+ pIndex2UniqIndex = tmp;
+ /* nCharInfos elements */
+ pUniqIndex2Index = tmp + nCharInfos;
+ /* max. nCharInfos elements */
+ pUniqIndex2NextUniqIndex = tmp + 2*nCharInfos;
+ /* max. nCharInfos elements */
+ pHash2UniqIndex = tmp + 3*nCharInfos;
+ /* hashModulus (<= nCharInfos+1) elements */
+
+ /* Note that we can use 0xffff as end-of-list indicator, because
+ even if nCharInfos = 0x10000, 0xffff can not occur as valid
+ entry before the last element has been inserted. And once the
+ last element has been inserted, we don't need the hash table
+ any more. */
+ for (j = 0; j < hashModulus; j++)
+ pHash2UniqIndex[j] = (CARD16)(-1);
+
+ NextUniqIndex = 0;
+ for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) {
+ xCharInfo* p = &pCI[NextIndex];
+ CARD32 hashCode = hashCI(p) % hashModulus;
+ for (i = pHash2UniqIndex[hashCode];
+ i != (CARD16)(-1);
+ i = pUniqIndex2NextUniqIndex[i]) {
+ j = pUniqIndex2Index[i];
+ if (pCI[j].leftSideBearing == p->leftSideBearing
+ && pCI[j].rightSideBearing == p->rightSideBearing
+ && pCI[j].characterWidth == p->characterWidth
+ && pCI[j].ascent == p->ascent
+ && pCI[j].descent == p->descent
+ && pCI[j].attributes == p->attributes)
+ break;
+ }
+ if (i != (CARD16)(-1)) {
+ /* Found *p at Index j, UniqIndex i */
+ pIndex2UniqIndex[NextIndex] = i;
+ } else {
+ /* Allocate a new entry in the Uniq table */
+ if (hashModulus <= 2*NextUniqIndex
+ && hashModulus < nCharInfos+1) {
+ /* Time to increate hash table size */
+ hashModulus = 2*hashModulus+1;
+ if (hashModulus > nCharInfos+1)
+ hashModulus = nCharInfos+1;
+ for (j = 0; j < hashModulus; j++)
+ pHash2UniqIndex[j] = (CARD16)(-1);
+ for (i = 0; i < NextUniqIndex; i++)
+ pUniqIndex2NextUniqIndex[i] = (CARD16)(-1);
+ for (i = 0; i < NextUniqIndex; i++) {
+ j = pUniqIndex2Index[i];
+ p = &pCI[j];
+ hashCode = hashCI(p) % hashModulus;
+ pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
+ pHash2UniqIndex[hashCode] = i;
+ }
+ p = &pCI[NextIndex];
+ hashCode = hashCI(p) % hashModulus;
+ }
+ i = NextUniqIndex++;
+ pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
+ pHash2UniqIndex[hashCode] = i;
+ pUniqIndex2Index[i] = NextIndex;
+ pIndex2UniqIndex[NextIndex] = i;
+ }
+ }
+ nUniqCharInfos = NextUniqIndex;
+ /* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */
+ }
+ }
+
+ {
+ int nfontprops = pFont->info.nprops;
+ int rlength =
+ sizeof(xXF86BigfontQueryFontReply)
+ + nfontprops * sizeof(xFontProp)
+ + (nCharInfos > 0 && shmid == -1
+ ? nUniqCharInfos * sizeof(xCharInfo)
+ + (nCharInfos+1)/2 * 2 * sizeof(CARD16)
+ : 0);
+ xXF86BigfontQueryFontReply* reply =
+ (xXF86BigfontQueryFontReply *) calloc(1, rlength);
+ char* p;
+ if (!reply) {
+ if (nCharInfos > 0) {
+ if (shmid == -1) free(pIndex2UniqIndex);
+ if (!pDesc) free(pCI);
+ }
+ return BadAlloc;
+ }
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->minBounds = pFont->info.ink_minbounds;
+ reply->maxBounds = pFont->info.ink_maxbounds;
+ reply->minCharOrByte2 = pFont->info.firstCol;
+ reply->maxCharOrByte2 = pFont->info.lastCol;
+ reply->defaultChar = pFont->info.defaultCh;
+ reply->nFontProps = pFont->info.nprops;
+ reply->drawDirection = pFont->info.drawDirection;
+ reply->minByte1 = pFont->info.firstRow;
+ reply->maxByte1 = pFont->info.lastRow;
+ reply->allCharsExist = pFont->info.allExist;
+ reply->fontAscent = pFont->info.fontAscent;
+ reply->fontDescent = pFont->info.fontDescent;
+ reply->nCharInfos = nCharInfos;
+ reply->nUniqCharInfos = nUniqCharInfos;
+ reply->shmid = shmid;
+ reply->shmsegoffset = 0;
+ if (client->swapped) {
+ swaps(&reply->sequenceNumber);
+ swapl(&reply->length);
+ swapCharInfo(&reply->minBounds);
+ swapCharInfo(&reply->maxBounds);
+ swaps(&reply->minCharOrByte2);
+ swaps(&reply->maxCharOrByte2);
+ swaps(&reply->defaultChar);
+ swaps(&reply->nFontProps);
+ swaps(&reply->fontAscent);
+ swaps(&reply->fontDescent);
+ swapl(&reply->nCharInfos);
+ swapl(&reply->nUniqCharInfos);
+ swapl(&reply->shmid);
+ swapl(&reply->shmsegoffset);
+ }
+ p = (char*) &reply[1];
+ {
+ FontPropPtr pFP;
+ xFontProp* prFP;
+ int i;
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p;
+ i < nfontprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ if (client->swapped) {
+ swapl(&prFP->name);
+ swapl(&prFP->value);
+ }
+ }
+ p = (char*) prFP;
+ }
+ if (nCharInfos > 0 && shmid == -1) {
+ xCharInfo* pci;
+ CARD16* ps;
+ int i, j;
+ pci = (xCharInfo*) p;
+ for (i = 0; i < nUniqCharInfos; i++, pci++) {
+ *pci = pCI[pUniqIndex2Index[i]];
+ if (client->swapped)
+ swapCharInfo(pci);
+ }
+ ps = (CARD16*) pci;
+ for (j = 0; j < nCharInfos; j++, ps++) {
+ *ps = pIndex2UniqIndex[j];
+ if (client->swapped) {
+ swaps(ps);
+ }
+ }
+ }
+ WriteToClient(client, rlength, reply);
+ free(reply);
+ if (nCharInfos > 0) {
+ if (shmid == -1) free(pIndex2UniqIndex);
+ if (!pDesc) free(pCI);
+ }
+ return (client->noClientException);
+ }
+}
+
+static int
+ProcXF86BigfontDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_XF86BigfontQueryVersion:
+ return ProcXF86BigfontQueryVersion(client);
+ case X_XF86BigfontQueryFont:
+ return ProcXF86BigfontQueryFont(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXF86BigfontQueryVersion(
+ ClientPtr client)
+{
+ REQUEST(xXF86BigfontQueryVersionReq);
+
+ swaps(&stuff->length);
+ return ProcXF86BigfontQueryVersion(client);
+}
+
+static int
+SProcXF86BigfontQueryFont(
+ ClientPtr client)
+{
+ REQUEST(xXF86BigfontQueryFontReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
+ swapl(&stuff->id);
+ return ProcXF86BigfontQueryFont(client);
+}
+
+static int
+SProcXF86BigfontDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_XF86BigfontQueryVersion:
+ return SProcXF86BigfontQueryVersion(client);
+ case X_XF86BigfontQueryFont:
+ return SProcXF86BigfontQueryFont(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/xres.c b/nx-X11/programs/Xserver/Xext/xres.c
new file mode 100644
index 000000000..ceb9c65d4
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xres.c
@@ -0,0 +1,314 @@
+/*
+ Copyright (c) 2002 XFree86 Inc
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "swaprep.h"
+#include <nx-X11/extensions/XResproto.h>
+#include "pixmapstr.h"
+#include "protocol-versions.h"
+
+static int
+ProcXResQueryVersion (ClientPtr client)
+{
+ xXResQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH (xXResQueryVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.server_major = SERVER_XRES_MAJOR_VERSION;
+ rep.server_minor = SERVER_XRES_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.server_major);
+ swaps(&rep.server_minor);
+ }
+ WriteToClient(client, sizeof (xXResQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcXResQueryClients (ClientPtr client)
+{
+ /* REQUEST(xXResQueryClientsReq); */
+ xXResQueryClientsReply rep;
+ int *current_clients;
+ int i, num_clients;
+
+ REQUEST_SIZE_MATCH(xXResQueryClientsReq);
+
+ current_clients = malloc((currentMaxClients - 1) * sizeof(int));
+
+ num_clients = 0;
+ for(i = 1; i < currentMaxClients; i++) {
+ if(clients[i]) {
+ current_clients[num_clients] = i;
+ num_clients++;
+ }
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_clients = num_clients;
+ rep.length = rep.num_clients * sz_xXResClient >> 2;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.num_clients);
+ }
+ WriteToClient (client, sizeof (xXResQueryClientsReply), &rep);
+
+ if(num_clients) {
+ xXResClient scratch;
+
+ for(i = 0; i < num_clients; i++) {
+ scratch.resource_base = clients[current_clients[i]]->clientAsMask;
+ scratch.resource_mask = RESOURCE_ID_MASK;
+
+ if(client->swapped) {
+ swapl (&scratch.resource_base);
+ swapl (&scratch.resource_mask);
+ }
+ WriteToClient (client, sz_xXResClient, &scratch);
+ }
+ }
+
+ free(current_clients);
+
+ return (client->noClientException);
+}
+
+
+static void
+ResFindAllRes (void * value, XID id, RESTYPE type, void * cdata)
+{
+ int *counts = (int *)cdata;
+
+ counts[(type & TypeMask) - 1]++;
+}
+
+static int
+ProcXResQueryClientResources (ClientPtr client)
+{
+ REQUEST(xXResQueryClientResourcesReq);
+ xXResQueryClientResourcesReply rep;
+ int i, clientID, num_types;
+ int *counts;
+
+ REQUEST_SIZE_MATCH(xXResQueryClientResourcesReq);
+
+ clientID = CLIENT_ID(stuff->xid);
+
+ /* we could remove the (clientID == 0) check if we wanted to allow
+ probing the X-server's resource usage */
+ if(!clientID || (clientID >= currentMaxClients) || !clients[clientID]) {
+ client->errorValue = stuff->xid;
+ return BadValue;
+ }
+
+ counts = malloc((lastResourceType + 1) * sizeof(int));
+
+ memset(counts, 0, (lastResourceType + 1) * sizeof(int));
+
+ FindAllClientResources(clients[clientID], ResFindAllRes, counts);
+
+ num_types = 0;
+
+ for(i = 0; i <= lastResourceType; i++) {
+ if(counts[i]) num_types++;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_types = num_types;
+ rep.length = rep.num_types * sz_xXResType >> 2;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.num_types);
+ }
+ WriteToClient (client,sizeof(xXResQueryClientResourcesReply),&rep);
+
+ if(num_types) {
+ xXResType scratch;
+
+ for(i = 0; i < lastResourceType; i++) {
+ if(!counts[i]) continue;
+
+ if(!ResourceNames[i + 1]) {
+ char buf[40];
+ snprintf(buf, sizeof(buf), "Unregistered resource %i", i + 1);
+ RegisterResourceName(i + 1, buf);
+ }
+
+ scratch.resource_type = ResourceNames[i + 1];
+ scratch.count = counts[i];
+
+ if(client->swapped) {
+ swapl (&scratch.resource_type);
+ swapl (&scratch.count);
+ }
+ WriteToClient (client, sz_xXResType, &scratch);
+ }
+ }
+
+ free(counts);
+
+ return (client->noClientException);
+}
+
+static void
+ResFindPixmaps (void * value, XID id, void * cdata)
+{
+ unsigned long *bytes = (unsigned long *)cdata;
+ PixmapPtr pix = (PixmapPtr)value;
+
+ *bytes += (pix->devKind * pix->drawable.height);
+}
+
+static int
+ProcXResQueryClientPixmapBytes (ClientPtr client)
+{
+ REQUEST(xXResQueryClientPixmapBytesReq);
+ xXResQueryClientPixmapBytesReply rep;
+ int clientID;
+ unsigned long bytes;
+
+ REQUEST_SIZE_MATCH(xXResQueryClientPixmapBytesReq);
+
+ clientID = CLIENT_ID(stuff->xid);
+
+ /* we could remove the (clientID == 0) check if we wanted to allow
+ probing the X-server's resource usage */
+ if(!clientID || (clientID >= currentMaxClients) || !clients[clientID]) {
+ client->errorValue = stuff->xid;
+ return BadValue;
+ }
+
+ bytes = 0;
+
+ FindClientResourcesByType(clients[clientID], RT_PIXMAP, ResFindPixmaps,
+ (void *)(&bytes));
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.bytes = bytes;
+#ifdef XSERVER64
+ rep.bytes_overflow = bytes >> 32;
+#else
+ rep.bytes_overflow = 0;
+#endif
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber);
+ swapl (&rep.length);
+ swapl (&rep.bytes);
+ swapl (&rep.bytes_overflow);
+ }
+ WriteToClient (client,sizeof(xXResQueryClientPixmapBytesReply),&rep);
+
+ return (client->noClientException);
+}
+
+
+static void
+ResResetProc (ExtensionEntry *extEntry) { }
+
+static int
+ProcResDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_XResQueryVersion:
+ return ProcXResQueryVersion(client);
+ case X_XResQueryClients:
+ return ProcXResQueryClients(client);
+ case X_XResQueryClientResources:
+ return ProcXResQueryClientResources(client);
+ case X_XResQueryClientPixmapBytes:
+ return ProcXResQueryClientPixmapBytes(client);
+ default: break;
+ }
+
+ return BadRequest;
+}
+
+static int
+SProcXResQueryVersion (ClientPtr client)
+{
+ REQUEST_SIZE_MATCH (xXResQueryVersionReq);
+ return ProcXResQueryVersion(client);
+}
+
+static int
+SProcXResQueryClientResources (ClientPtr client)
+{
+ REQUEST(xXResQueryClientResourcesReq);
+
+ REQUEST_SIZE_MATCH (xXResQueryClientResourcesReq);
+ swapl(&stuff->xid);
+ return ProcXResQueryClientResources(client);
+}
+
+static int
+SProcXResQueryClientPixmapBytes (ClientPtr client)
+{
+ REQUEST(xXResQueryClientPixmapBytesReq);
+
+ REQUEST_SIZE_MATCH (xXResQueryClientPixmapBytesReq);
+ swapl(&stuff->xid);
+ return ProcXResQueryClientPixmapBytes(client);
+}
+
+static int
+SProcResDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ swaps(&stuff->length);
+
+ switch (stuff->data) {
+ case X_XResQueryVersion:
+ return SProcXResQueryVersion(client);
+ case X_XResQueryClients: /* nothing to swap */
+ return ProcXResQueryClients(client);
+ case X_XResQueryClientResources:
+ return SProcXResQueryClientResources(client);
+ case X_XResQueryClientPixmapBytes:
+ return SProcXResQueryClientPixmapBytes(client);
+ default: break;
+ }
+
+ return BadRequest;
+}
+
+void
+ResExtensionInit(void)
+{
+ (void) AddExtension(XRES_NAME, 0, 0,
+ ProcResDispatch, SProcResDispatch,
+ ResResetProc, StandardMinorOpcode);
+
+ RegisterResourceName(RT_NONE, "NONE");
+ RegisterResourceName(RT_WINDOW, "WINDOW");
+ RegisterResourceName(RT_PIXMAP, "PIXMAP");
+ RegisterResourceName(RT_GC, "GC");
+ RegisterResourceName(RT_FONT, "FONT");
+ RegisterResourceName(RT_CURSOR, "CURSOR");
+ RegisterResourceName(RT_COLORMAP, "COLORMAP");
+ RegisterResourceName(RT_CMAPENTRY, "COLORMAP ENTRY");
+ RegisterResourceName(RT_OTHERCLIENT, "OTHER CLIENT");
+ RegisterResourceName(RT_PASSIVEGRAB, "PASSIVE GRAB");
+}
diff --git a/nx-X11/programs/Xserver/Xext/xtest.c b/nx-X11/programs/Xserver/Xext/xtest.c
new file mode 100644
index 000000000..d78efd39b
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xtest.c
@@ -0,0 +1,594 @@
+/*
+
+Copyright 1992, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "dixevents.h"
+#include "sleepuntil.h"
+#define _XTEST_SERVER_
+#include <nx-X11/extensions/xtestconst.h>
+#include <nx-X11/extensions/xteststr.h>
+#ifdef XINPUT
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#define EXTENSION_EVENT_BASE 64
+#include "extinit.h" /* LookupDeviceIntRec */
+#endif /* XINPUT */
+
+#if 0
+static unsigned char XTestReqCode;
+#endif
+
+#ifdef XINPUT
+extern int DeviceValuator;
+#endif /* XINPUT */
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+static void XTestResetProc(
+ ExtensionEntry * /* extEntry */
+);
+static int XTestSwapFakeInput(
+ ClientPtr /* client */,
+ xReq * /* req */
+);
+
+static DISPATCH_PROC(ProcXTestCompareCursor);
+static DISPATCH_PROC(ProcXTestDispatch);
+static DISPATCH_PROC(ProcXTestFakeInput);
+static DISPATCH_PROC(ProcXTestGetVersion);
+static DISPATCH_PROC(ProcXTestGrabControl);
+static DISPATCH_PROC(SProcXTestCompareCursor);
+static DISPATCH_PROC(SProcXTestDispatch);
+static DISPATCH_PROC(SProcXTestFakeInput);
+static DISPATCH_PROC(SProcXTestGetVersion);
+static DISPATCH_PROC(SProcXTestGrabControl);
+
+void
+XTestExtensionInit(void)
+{
+#if 0
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(XTestExtensionName, 0, 0,
+ ProcXTestDispatch, SProcXTestDispatch,
+ XTestResetProc, StandardMinorOpcode)) != 0)
+ XTestReqCode = (unsigned char)extEntry->base;
+#else
+ (void) AddExtension(XTestExtensionName, 0, 0,
+ ProcXTestDispatch, SProcXTestDispatch,
+ XTestResetProc, StandardMinorOpcode);
+#endif
+}
+
+/*ARGSUSED*/
+static void
+XTestResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcXTestGetVersion(client)
+ register ClientPtr client;
+{
+ xXTestGetVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xXTestGetVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XTestMajorVersion;
+ rep.minorVersion = XTestMinorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xXTestGetVersionReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcXTestCompareCursor(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestCompareCursorReq);
+ xXTestCompareCursorReply rep;
+ WindowPtr pWin;
+ CursorPtr pCursor;
+
+ REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
+ pWin = (WindowPtr)LookupWindow(stuff->window, client);
+ if (!pWin)
+ return(BadWindow);
+ if (stuff->cursor == None)
+ pCursor = NullCursor;
+ else if (stuff->cursor == XTestCurrentCursor)
+ pCursor = GetSpriteCursor();
+ else {
+ pCursor = (CursorPtr)LookupIDByType(stuff->cursor, RT_CURSOR);
+ if (!pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+ }
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.same = (wCursor(pWin) == pCursor);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ }
+ WriteToClient(client, sizeof(xXTestCompareCursorReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcXTestFakeInput(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestFakeInputReq);
+ int nev;
+ int n;
+ xEvent *ev;
+ DeviceIntPtr dev = NULL;
+ WindowPtr root;
+ int type;
+#ifdef XINPUT
+ Bool extension = FALSE;
+ deviceValuator *dv = NULL;
+ int base;
+ int *values;
+#endif /* XINPUT */
+
+ nev = (stuff->length << 2) - sizeof(xReq);
+ if ((nev % sizeof(xEvent)) || !nev)
+ return BadLength;
+ nev /= sizeof(xEvent);
+ UpdateCurrentTime();
+ ev = (xEvent *)&((xReq *)stuff)[1];
+ type = ev->u.u.type & 0177;
+#ifdef XINPUT
+ if (type >= EXTENSION_EVENT_BASE)
+ {
+ type -= DeviceValuator;
+ switch (type) {
+ case XI_DeviceKeyPress:
+ case XI_DeviceKeyRelease:
+ case XI_DeviceButtonPress:
+ case XI_DeviceButtonRelease:
+ case XI_DeviceMotionNotify:
+ case XI_ProximityIn:
+ case XI_ProximityOut:
+ break;
+ default:
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ if (nev == 1 && type == XI_DeviceMotionNotify)
+ return BadLength;
+ if (type == XI_DeviceMotionNotify)
+ base = ((deviceValuator *)(ev+1))->first_valuator;
+ else
+ base = 0;
+ for (n = 1; n < nev; n++)
+ {
+ dv = (deviceValuator *)(ev + n);
+ if (dv->type != DeviceValuator)
+ {
+ client->errorValue = dv->type;
+ return BadValue;
+ }
+ if (dv->first_valuator != base)
+ {
+ client->errorValue = dv->first_valuator;
+ return BadValue;
+ }
+ if (!dv->num_valuators || dv->num_valuators > 6)
+ {
+ client->errorValue = dv->num_valuators;
+ return BadValue;
+ }
+ base += dv->num_valuators;
+ }
+ type = type - XI_DeviceKeyPress + KeyPress;
+ extension = TRUE;
+ }
+ else
+#endif /* XINPUT */
+ {
+ if (nev != 1)
+ return BadLength;
+ switch (type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ break;
+ default:
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ }
+ if (ev->u.keyButtonPointer.time)
+ {
+ TimeStamp activateTime;
+ CARD32 ms;
+
+ activateTime = currentTime;
+ ms = activateTime.milliseconds + ev->u.keyButtonPointer.time;
+ if (ms < activateTime.milliseconds)
+ activateTime.months++;
+ activateTime.milliseconds = ms;
+ ev->u.keyButtonPointer.time = 0;
+
+ /* see mbuf.c:QueueDisplayRequest for code similar to this */
+
+ if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
+ {
+ return BadAlloc;
+ }
+ /* swap the request back so we can simply re-execute it */
+ if (client->swapped)
+ {
+ (void) XTestSwapFakeInput(client, (xReq *)stuff);
+ swaps(&stuff->length);
+ }
+ ResetCurrentRequest (client);
+ client->sequence--;
+ return Success;
+ }
+#ifdef XINPUT
+ if (extension)
+ {
+ dev = LookupDeviceIntRec(stuff->deviceid & 0177);
+ if (!dev)
+ {
+ client->errorValue = stuff->deviceid & 0177;
+ return BadValue;
+ }
+ if (nev > 1)
+ {
+ dv = (deviceValuator *)(ev + 1);
+ if (!dev->valuator || dv->first_valuator >= dev->valuator->numAxes)
+ {
+ client->errorValue = dv->first_valuator;
+ return BadValue;
+ }
+ if (dv->first_valuator + dv->num_valuators >
+ dev->valuator->numAxes)
+ {
+ client->errorValue = dv->num_valuators;
+ return BadValue;
+ }
+ }
+ }
+#endif /* XINPUT */
+ switch (type)
+ {
+ case KeyPress:
+ case KeyRelease:
+#ifdef XINPUT
+ if (!extension)
+#endif /* XINPUT */
+ dev = (DeviceIntPtr)LookupKeyboardDevice();
+ if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode ||
+ ev->u.u.detail > dev->key->curKeySyms.maxKeyCode)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+ break;
+ case MotionNotify:
+#ifdef XINPUT
+ if (extension)
+ {
+ if (ev->u.u.detail != xFalse && ev->u.u.detail != xTrue)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+ if (ev->u.u.detail == xTrue && dev->valuator->mode == Absolute)
+ {
+ values = dev->valuator->axisVal + dv->first_valuator;
+ for (n = 1; n < nev; n++)
+ {
+ dv = (deviceValuator *)(ev + n);
+ switch (dv->num_valuators)
+ {
+ case 6:
+ dv->valuator5 += values[5];
+ case 5:
+ dv->valuator4 += values[4];
+ case 4:
+ dv->valuator3 += values[3];
+ case 3:
+ dv->valuator2 += values[2];
+ case 2:
+ dv->valuator1 += values[1];
+ case 1:
+ dv->valuator0 += values[0];
+ }
+ values += 6;
+ }
+ }
+ break;
+ }
+#endif /* XINPUT */
+ dev = (DeviceIntPtr)LookupPointerDevice();
+ if (ev->u.keyButtonPointer.root == None)
+ root = GetCurrentRootWindow();
+ else
+ {
+ root = LookupWindow(ev->u.keyButtonPointer.root, client);
+ if (!root)
+ return BadWindow;
+ if (root->parent)
+ {
+ client->errorValue = ev->u.keyButtonPointer.root;
+ return BadValue;
+ }
+ }
+ if (ev->u.u.detail == xTrue)
+ {
+ int x, y;
+ GetSpritePosition(&x, &y);
+ ev->u.keyButtonPointer.rootX += x;
+ ev->u.keyButtonPointer.rootY += y;
+ }
+ else if (ev->u.u.detail != xFalse)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ ScreenPtr pScreen = root->drawable.pScreen;
+ BoxRec box;
+ int i;
+ int x = ev->u.keyButtonPointer.rootX + panoramiXdataPtr[0].x;
+ int y = ev->u.keyButtonPointer.rootY + panoramiXdataPtr[0].y;
+ if (!RegionContainsPoint(&XineramaScreenRegions[pScreen->myNum],
+ x, y, &box)) {
+ FOR_NSCREENS(i) {
+ if (i == pScreen->myNum) continue;
+ if (RegionContainsPoint(
+ &XineramaScreenRegions[i],
+ x, y, &box)) {
+ root = screenInfo.screens[i]->root;
+ x -= panoramiXdataPtr[i].x;
+ y -= panoramiXdataPtr[i].y;
+ ev->u.keyButtonPointer.rootX = x;
+ ev->u.keyButtonPointer.rootY = y;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+ if (ev->u.keyButtonPointer.rootX < 0)
+ ev->u.keyButtonPointer.rootX = 0;
+ else if (ev->u.keyButtonPointer.rootX >= root->drawable.width)
+ ev->u.keyButtonPointer.rootX = root->drawable.width - 1;
+ if (ev->u.keyButtonPointer.rootY < 0)
+ ev->u.keyButtonPointer.rootY = 0;
+ else if (ev->u.keyButtonPointer.rootY >= root->drawable.height)
+ ev->u.keyButtonPointer.rootY = root->drawable.height - 1;
+
+#ifdef PANORAMIX
+ if ((!noPanoramiXExtension
+ && root->drawable.pScreen->myNum != XineramaGetCursorScreen())
+ || (noPanoramiXExtension && root != GetCurrentRootWindow()))
+
+#else
+ if (root != GetCurrentRootWindow())
+#endif
+ {
+ NewCurrentScreen(root->drawable.pScreen,
+ ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY);
+ return client->noClientException;
+ }
+ (*root->drawable.pScreen->SetCursorPosition)
+ (root->drawable.pScreen,
+ ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY, FALSE);
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+#ifdef XINPUT
+ if (!extension)
+#endif /* XINPUT */
+ dev = (DeviceIntPtr)LookupPointerDevice();
+ if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
+ {
+ client->errorValue = ev->u.u.detail;
+ return BadValue;
+ }
+ break;
+ }
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
+ ev->u.keyButtonPointer.time = currentTime.milliseconds;
+ (*dev->public.processInputProc)(ev, dev, nev);
+ return client->noClientException;
+}
+
+static int
+ProcXTestGrabControl(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestGrabControlReq);
+
+ REQUEST_SIZE_MATCH(xXTestGrabControlReq);
+ if ((stuff->impervious != xTrue) && (stuff->impervious != xFalse))
+ {
+ client->errorValue = stuff->impervious;
+ return(BadValue);
+ }
+ if (stuff->impervious)
+ MakeClientGrabImpervious(client);
+ else
+ MakeClientGrabPervious(client);
+ return(client->noClientException);
+}
+
+static int
+ProcXTestDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XTestGetVersion:
+ return ProcXTestGetVersion(client);
+ case X_XTestCompareCursor:
+ return ProcXTestCompareCursor(client);
+ case X_XTestFakeInput:
+ return ProcXTestFakeInput(client);
+ case X_XTestGrabControl:
+ return ProcXTestGrabControl(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXTestGetVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestGetVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXTestGetVersionReq);
+ swaps(&stuff->minorVersion);
+ return ProcXTestGetVersion(client);
+}
+
+static int
+SProcXTestCompareCursor(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestCompareCursorReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXTestCompareCursorReq);
+ swapl(&stuff->window);
+ swapl(&stuff->cursor);
+ return ProcXTestCompareCursor(client);
+}
+
+static int
+XTestSwapFakeInput(client, req)
+ register ClientPtr client;
+ xReq *req;
+{
+ register int nev;
+ register xEvent *ev;
+ xEvent sev;
+ EventSwapPtr proc;
+
+ nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
+ for (ev = (xEvent *)&req[1]; --nev >= 0; ev++)
+ {
+ /* Swap event */
+ proc = EventSwapVector[ev->u.u.type & 0177];
+ /* no swapping proc; invalid event type? */
+ if (!proc || proc == NotImplemented) {
+ client->errorValue = ev->u.u.type;
+ return BadValue;
+ }
+ (*proc)(ev, &sev);
+ *ev = sev;
+ }
+ return Success;
+}
+
+static int
+SProcXTestFakeInput(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xReq);
+
+ swaps(&stuff->length);
+ n = XTestSwapFakeInput(client, stuff);
+ if (n != Success)
+ return n;
+ return ProcXTestFakeInput(client);
+}
+
+static int
+SProcXTestGrabControl(client)
+ register ClientPtr client;
+{
+ REQUEST(xXTestGrabControlReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXTestGrabControlReq);
+ return ProcXTestGrabControl(client);
+}
+
+static int
+SProcXTestDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XTestGetVersion:
+ return SProcXTestGetVersion(client);
+ case X_XTestCompareCursor:
+ return SProcXTestCompareCursor(client);
+ case X_XTestFakeInput:
+ return SProcXTestFakeInput(client);
+ case X_XTestGrabControl:
+ return SProcXTestGrabControl(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/xtest1dd.c b/nx-X11/programs/Xserver/Xext/xtest1dd.c
new file mode 100644
index 000000000..e3a7aa07e
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xtest1dd.c
@@ -0,0 +1,1612 @@
+/*
+ * File: xtest1dd.c
+ *
+ * This file contains the device dependent parts of the input
+ * synthesis extension.
+ */
+
+/*
+
+
+Copyright 1986, 1987, 1988, 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.
+
+
+Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
+
+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 name of Hewlett-Packard not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Hewlett-Packard makes no representations about the
+suitability of this software for any purpose. It is provided
+"as is" without express or implied warranty.
+
+This software is not subject to any license of the American
+Telephone and Telegraph Company or of the Regents of the
+University of California.
+
+*/
+
+/***************************************************************
+ * include files
+ ***************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/Xos.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#define XTestSERVER_SIDE
+#include <nx-X11/extensions/xtestext1.h>
+
+#include "xtest1dd.h"
+
+/***************************************************************
+ * defines
+ ***************************************************************/
+
+/*
+ * the size of the fake input action array
+ */
+#define ACTION_ARRAY_SIZE 100
+
+/***************************************************************
+ * externals
+ ***************************************************************/
+
+/*
+ * Holds the xTestInputAction event type code.
+ * This is defined in xtestext1di.c.
+ */
+extern int XTestInputActionType;
+/*
+ * Holds the xTestFakeAck event type code.
+ * This is defined in xtestext1di.c.
+ */
+extern int XTestFakeAckType;
+/*
+ * used in the WriteReplyToClient macro
+ */
+extern int exclusive_steal;
+
+/***************************************************************
+ * variables
+ ***************************************************************/
+
+/*
+ * array to hold fake input actions
+ */
+struct {
+ /*
+ * holds the action type, one of: XTestDELAY_ACTION,
+ * XTestKEY_ACTION, XTestMOTION_ACTION, XTestJUMP_ACTION
+ */
+ CARD8 type;
+ /*
+ * holds the device type, in the range 0 to 15
+ */
+ CARD8 device;
+ /*
+ * for XTestKEY_ACTION type, holds the keycode
+ */
+ CARD8 keycode;
+ /*
+ * for XTestKEY_ACTION type, holds the key up/down state
+ */
+ CARD8 keystate;
+ /*
+ * for XTestMOTION_ACTION and XTestJUMP_ACTION types,
+ * holds the x and y coordinates to move the mouse to
+ */
+ int x;
+ int y;
+ /*
+ * holds the time to delay (in milliseconds) before performing
+ * the action
+ */
+ CARD32 delay_time;
+}action_array[ACTION_ARRAY_SIZE];
+
+/*
+ * write index for input action array
+ */
+static int write_index = 0;
+/*
+ * read index for input action array
+ */
+static int read_index = 0;
+/*
+ * this is where the input actions are accumulated until they are sent
+ * to a client (in a wire event)
+ */
+static xTestInputActionEvent input_action_packet;
+/*
+ * holds the index (in bytes) into the input actions buffer in the
+ * current input action event
+ */
+static int packet_index;
+/*
+ * logical x position of the mouse during input action gathering
+ */
+short xtest_mousex;
+/*
+ * logical y position of the mouse during input action gathering
+ */
+short xtest_mousey;
+/*
+ * logical x position of the mouse while we are reading fake input actions
+ * from the client and putting them into the fake input action array
+ */
+static short pmousex;
+/*
+ * logical y position of the mouse while we are reading fake input actions
+ * from the client and putting them into the fake input action array
+ */
+static short pmousey;
+/*
+ * The playback_on flag is set to 1 while there are input actions in the
+ * input action array. It is set to 0 when the server has received all of
+ * the user actions.
+ */
+int playback_on = 0;
+/*
+ * identity of the client using XTestGetInput to get user input actions
+ */
+ClientPtr current_xtest_client;
+/*
+ * if 1 send multiple input actions per XTestInputAction event;
+ * if 0 send one input action per XTestInputAction event
+ */
+static char packed_mode;
+/*
+ * identity of the client using the XTestFakeInput function to send some
+ * fake input actions to the server
+ */
+ClientPtr playback_client = NULL;
+/*
+ * Set to 1 when the XTestFAKE_ACK_REQUEST flag is set in a XTestFakeInput
+ * request. Set back to 0 when all of the input actions have been sent
+ * to the server.
+ */
+static int acknowledge = 0;
+/*
+ * The server's idea of the current time is saved in these variables when
+ * a XTestFakeInput request is received. It is restored when all fake input
+ * actions are sent to the server or when the playback client disconnects.
+ */
+static int saved_sec;
+static int saved_usec;
+/*
+ * Set to 1 when there is a valid time in saved_sec and saved_usec.
+ */
+static int time_saved = 0;
+/*
+ * holds the extension's notion of what the current time is while it is
+ * sending input actions to a client
+ */
+static struct timeval current_time;
+/*
+ * holds the time when the extension should place the next fake input action
+ * into the server's normal events queue
+ */
+static struct timeval play_time;
+/*
+ * set to 1 when play_time is first set, cleared to 0 when the
+ * client using the extension disconnects, or when XTestReset is called
+ */
+static char play_clock = 0;
+/*
+ * holds the amount of time left until the next input action from the
+ * input action array can be sent to the server
+ */
+static struct timeval rtime;
+/*
+ * Set to 1 after the extension is done waiting for the correct time delay
+ * for an input action to be sent to the server. Remains a 1 until the time
+ * delay for the next input action is computed. Then set to 0 if the
+ * extension has to wait for the correct time delay.
+ */
+static int go_for_next = 1;
+/*
+ * needed to restore waitime if playback is to be aborted
+ */
+static struct timeval *restorewait;
+/*
+ * tmon special command key
+ *
+ * To use the test monitor program (called tmon) efficiently, it is
+ * desirable to have the extension be able to recognize a special "trigger"
+ * key. If the extension did not do this, tmon would have to have the
+ * extension send all keyboard user input actions exclusively to tmon,
+ * only to have tmon send them right back if they were not the command key.
+ *
+ * If the extension can recognize the command key, then tmon can let the
+ * extension handle keyboard user input actions normally until the command
+ * key is pressed (and released), and only then have the extension start
+ * sending keyboard user input actions exclusively to tmon.
+ *
+ * Any key on the keyboard can be used for this command key. It is most
+ * convenient if it is a low-frequency key. If you want to generate a
+ * normal occurrance of this key to a client, just hit it twice. Tmon
+ * will recognize the first occurrance of the key, take control of the input
+ * actions, and wait for certain keys. If it sees another occurrance of the
+ * command key, it will send one occurrance of the command key to the
+ * extension, and go back to waiting.
+ *
+ * set and also referenced in device layer
+ * XXX there should be a way to set this through the protocol
+ */
+KeyCode xtest_command_key = 0;
+
+/***************************************************************
+ * function declarations
+ ***************************************************************/
+
+static void parse_key_fake(
+ XTestKeyInfo * /* fkey */
+ );
+static void parse_motion_fake(
+ XTestMotionInfo * /* fmotion */
+ );
+static void parse_jump_fake(
+ XTestJumpInfo * /* fjump */
+ );
+static void parse_delay_fake(
+ XTestDelayInfo * /* tevent */
+ );
+static void send_ack(
+ ClientPtr /* client */
+ );
+static void start_play_clock(
+ void
+ );
+static void compute_action_time(
+ struct timeval * /* rtime */
+ );
+static int find_residual_time(
+ struct timeval * /* rtime */
+ );
+
+static CARD16 check_time_event(
+ void
+ );
+static CARD32 current_ms(
+ struct timeval * /* otime */
+ );
+static int there_is_room(
+ int /* actsize */
+ );
+
+/******************************************************************************
+ *
+ * stop_stealing_input
+ *
+ * Stop stealing input actions.
+ */
+void
+stop_stealing_input()
+{
+/*
+ * put any code that you might need to stop stealing input actions here
+ */
+ if (packet_index != 0)
+ {
+ /*
+ * if there is a partially full input action event waiting
+ * when this function is called, send it to the client
+ */
+ flush_input_actions();
+ }
+}
+
+/******************************************************************************
+ *
+ * steal_input
+ *
+ * Start stealing input actions and sending them to the passed-in client.
+ */
+void
+steal_input(client, mode)
+/*
+ * which client is to receive the input action events
+ */
+ClientPtr client;
+/*
+ * what input action packing mode to use. one of 0, XTestPACKED_MOTION,
+ * or XTestPACKED_ACTIONS; optionally 'or'ed with XTestEXCLUSIVE,
+ */
+CARD32 mode;
+{
+ if (packet_index != 0)
+ {
+ /*
+ * if there is a partially full input action event waiting
+ * when this function is called, send it to the client
+ */
+ flush_input_actions();
+ }
+ else
+ {
+ /*
+ * otherwise, set up a new input action event
+ */
+ input_action_packet.type = XTestInputActionType;
+ packet_index = 0;
+ }
+ /*
+ * set up the new input action packing mode
+ */
+ packed_mode = mode & ~(XTestEXCLUSIVE);
+ /*
+ * keep track of where the mouse is
+ */
+ XTestGetPointerPos(&xtest_mousex, &xtest_mousey);
+ /*
+ * keep track of which client is getting input actions
+ */
+ current_xtest_client = client;
+ /*
+ * find out what time it is
+ */
+ X_GETTIMEOFDAY(&current_time);
+ /*
+ * jump to the initial position of the mouse, using a device type of 0.
+ */
+ XTestStealJumpData(xtest_mousex, xtest_mousey, 0);
+}
+
+/******************************************************************************
+ *
+ * flush_input_actions
+ *
+ * Write the input actions event to the current requesting client
+ * and re-initialize the input action event.
+ */
+void
+flush_input_actions()
+{
+ /*
+ * pointer to the input action event
+ */
+ char *rep;
+ /*
+ * loop index
+ */
+ int i;
+
+ if (packet_index == 0)
+ {
+ /*
+ * empty input actions event
+ */
+ return;
+ }
+ else if (packet_index < XTestACTIONS_SIZE)
+ {
+ /*
+ * fill to the end of the input actions event with 0's
+ */
+ for (i = packet_index; i <XTestACTIONS_SIZE; i++)
+ {
+ input_action_packet.actions[i] = 0;
+ }
+ }
+ rep = (char *) (&input_action_packet);
+
+ /*
+ * set the serial number of the input action event
+ */
+ input_action_packet.sequenceNumber = current_xtest_client->sequence;
+ /*
+ * send the input action event to the client
+ */
+ WriteEventsToClient(current_xtest_client, 1, (xEvent *) rep);
+ /*
+ * re-initialize the input action event
+ */
+ input_action_packet.type = XTestInputActionType;
+ packet_index = 0;
+}
+
+/******************************************************************************
+ *
+ * XTestStealJumpData
+ *
+ * Create one or more input actions and put them in the input action
+ * event. The input actions will be an (maybe) XTestDELAY_ACTION
+ * and an XTestJUMP_ACTION.
+ */
+void
+XTestStealJumpData(jx, jy, dev_type)
+/*
+ * the x and y coordinates to jump to
+ */
+int jx;
+int jy;
+/*
+ * which device caused the jump
+ */
+int dev_type;
+{
+ XTestJumpInfo *jmp_ptr;
+ /*
+ * time delta (in ms) from previous event
+ */
+ CARD16 tchar;
+
+ /*
+ * Get the time delta from the previous event. If needed,
+ * the check_time_event routine will put an XTestDELAY_ACTION
+ * type action in the input action event.
+ */
+ tchar = check_time_event();
+ if (!there_is_room(sizeof(XTestJumpInfo)))
+ {
+ /*
+ * If there isn't room in the input action event for
+ * an XTestJUMP_ACTION, then send that event to the
+ * client and start filling an empty one.
+ */
+ flush_input_actions();
+ }
+ /*
+ * update the logical mouse position
+ */
+ xtest_mousex = jx;
+ xtest_mousey = jy;
+ /*
+ * point jmp_ptr to the correct place in the input action event
+ */
+ jmp_ptr = (XTestJumpInfo *)
+ &(input_action_packet.actions[packet_index]);
+ /*
+ * compute the input action header
+ */
+ jmp_ptr->header = (XTestPackDeviceID(dev_type) | XTestJUMP_ACTION);
+ /*
+ * set the x and y coordinates to jump to in the input action
+ */
+ jmp_ptr->jumpx = jx;
+ jmp_ptr->jumpy = jy;
+ /*
+ * set the delay time in the input action
+ */
+ jmp_ptr->delay_time = tchar;
+ /*
+ * increment the packet index by the size of the input action
+ */
+ packet_index = packet_index + sizeof(XTestJumpInfo);
+ if (packed_mode == 0)
+ {
+ /*
+ * if input actions are not packed, send the input
+ * action event to the client
+ */
+ flush_input_actions();
+ }
+}
+
+/******************************************************************************
+ *
+ * current_ms
+ *
+ * Returns the number of milliseconds from the passed-in time to the
+ * current time, and then updates the passed-in time to the current time.
+ */
+static CARD32
+current_ms(otime)
+struct timeval *otime;
+{
+ struct timeval tval;
+ unsigned long the_ms;
+ unsigned long sec;
+ unsigned long usec;
+
+ /*
+ * get the current time
+ */
+ X_GETTIMEOFDAY(&tval);
+ if (tval.tv_usec < otime->tv_usec)
+ {
+ /*
+ * borrow a second's worth of microseconds if needed
+ */
+ usec = tval.tv_usec - otime->tv_usec + 1000000;
+ sec = tval.tv_sec - 1 - otime->tv_sec;
+ }
+ else
+ {
+ usec = tval.tv_usec - otime->tv_usec;
+ sec = tval.tv_sec - otime->tv_sec;
+ }
+ /*
+ * update the passed-in time to the new time
+ */
+ *otime = tval;
+ /*
+ * compute the number of milliseconds contained in
+ * 'sec' seconds and 'usec' microseconds
+ */
+ the_ms = (sec * 1000000L + usec) / 1000L;
+ return (the_ms);
+}
+
+/******************************************************************************
+ *
+ * check_time_event
+ *
+ * If time delta is > XTestSHORT_DELAY_TIME then insert a time event
+ * and return 0; else return the delay time.
+ */
+static CARD16
+check_time_event()
+{
+ CARD32 tstamp;
+ CARD16 tchar;
+ XTestDelayInfo *tptr;
+
+ /*
+ * get the number of milliseconds between input actions
+ */
+ tstamp = current_ms(&current_time);
+ /*
+ * if the number of milliseconds is too large to fit in a CARD16,
+ * then add a XTestDELAY_ACTION to the input action event.
+ */
+ if (tstamp > XTestSHORT_DELAY_TIME)
+ {
+ /*
+ * If there isn't room in the input action event for
+ * an XTestDELAY_ACTION, then send that event to the
+ * client and start filling an empty one.
+ */
+ if (!there_is_room(sizeof(XTestDelayInfo)))
+ {
+ flush_input_actions();
+ }
+ /*
+ * point tptr to the correct place in the input action event
+ */
+ tptr = (XTestDelayInfo *)
+ (&(input_action_packet.actions[packet_index]));
+ /*
+ * compute the input action header
+ */
+ tptr->header = XTestPackDeviceID(XTestDELAY_DEVICE_ID) |
+ XTestDELAY_ACTION;
+ /*
+ * set the delay time in the input action
+ */
+ tptr->delay_time = tstamp;
+ /*
+ * increment the packet index by the size of the input action
+ */
+ packet_index = packet_index + (sizeof(XTestDelayInfo));
+ if (packed_mode != XTestPACKED_ACTIONS)
+ {
+ /*
+ * if input actions are not packed, send the input
+ * action event to the client
+ */
+ flush_input_actions();
+ }
+ /*
+ * set the returned delay time to 0
+ */
+ tchar = 0;
+ }
+ else
+ {
+ /*
+ * set the returned delay time to the computed delay time
+ */
+ tchar = tstamp;
+ }
+ return(tchar);
+}
+
+/******************************************************************************
+ *
+ * there_is_room
+ *
+ * Checks if there is room in the input_action_packet for an input action
+ * of the size actsize bytes. Returns 1 if there is space, 0 otherwise.
+ *
+ */
+static int
+there_is_room(actsize)
+/*
+ * the number of bytes of space needed
+ */
+int actsize;
+{
+ if ((packet_index + actsize) > XTestACTIONS_SIZE)
+ {
+ return(0);
+ }
+ else
+ {
+ return(1);
+ }
+}
+
+/******************************************************************************
+ *
+ * XTestStealMotionData
+ *
+ * Put motion information from the locator into an input action.
+ *
+ * called from x_hil.c
+ */
+void
+XTestStealMotionData(dx, dy, dev_type, mx, my)
+/*
+ * the x and y delta motion of the locator
+ */
+int dx;
+int dy;
+/*
+ * which locator did the moving
+ */
+int dev_type;
+/*
+ * the x and y position of the locator before the delta motion
+ */
+int mx;
+int my;
+{
+ /*
+ * pointer to a XTestMOTION_ACTION input action
+ */
+ XTestMotionInfo *fm;
+ /*
+ * time delta from previous event
+ */
+ CARD16 tchar;
+
+ /*
+ * if the current position of the locator is not the same as
+ * the logical position, then update the logical position
+ */
+ if ((mx != xtest_mousex) || (my != xtest_mousey))
+ {
+ XTestStealJumpData(mx, my, dev_type);
+ }
+ /*
+ * if the delta motion is outside the range that can
+ * be held in a motion input action, use a jump input action
+ */
+ if ((dx > XTestMOTION_MAX) || (dx < XTestMOTION_MIN) ||
+ (dy > XTestMOTION_MAX) || (dy < XTestMOTION_MIN))
+ {
+ XTestStealJumpData((xtest_mousex + dx),
+ (xtest_mousey + dy), dev_type);
+ }
+ else
+ {
+ /*
+ * compute the new logical position of the mouse
+ */
+ xtest_mousex += dx;
+ xtest_mousey += dy;
+ /*
+ * Get the time delta from the previous event. If needed,
+ * the check_time_event routine will put an XTestDELAY_ACTION
+ * type action in the input action event.
+ */
+ tchar = check_time_event();
+ /*
+ * If there isn't room in the input action event for
+ * an XTestDELAY_ACTION, then send that event to the
+ * client and start filling an empty one.
+ */
+ if (!there_is_room(sizeof(XTestMotionInfo)))
+ {
+ flush_input_actions();
+ /*
+ * point fm to the correct place in the input action event
+ */
+ }
+ fm = (XTestMotionInfo *)
+ &(input_action_packet.actions[packet_index]);
+ /*
+ * compute the input action header
+ */
+ fm->header = XTestMOTION_ACTION;
+ if (dx < 0)
+ {
+ fm->header |= XTestX_NEGATIVE;
+ dx = abs(dx);
+ }
+ if (dy < 0)
+ {
+ fm->header |= XTestY_NEGATIVE;
+ dy = abs(dy);
+ }
+ fm->header |= XTestPackDeviceID(dev_type);
+ /*
+ * compute the motion data byte
+ */
+ fm->motion_data = XTestPackYMotionValue(dy);
+ fm->motion_data |= XTestPackXMotionValue(dx);
+ /*
+ * set the delay time in the input action
+ */
+ fm->delay_time = tchar;
+ /*
+ * increment the packet index by the size of the input action
+ */
+ packet_index = packet_index + sizeof(XTestMotionInfo);
+ if (packed_mode == 0)
+ {
+ /*
+ * if input actions are not packed, send the input
+ * action event to the client
+ */
+ flush_input_actions();
+ }
+
+ }
+}
+
+/******************************************************************************
+ *
+ * XTestStealKeyData
+ *
+ * Place this key data in the input_action_packet.
+ *
+ */
+Bool
+XTestStealKeyData(keycode, keystate, dev_type, locx, locy)
+/*
+ * which key/button moved
+ */
+unsigned keycode;
+/*
+ * whether the key/button was pressed or released
+ */
+int keystate;
+/*
+ * which device caused the input action
+ */
+int dev_type;
+/*
+ * the x and y coordinates of the locator when the action happenned
+ */
+int locx;
+int locy;
+{
+ /*
+ * pointer to key/button motion input action
+ */
+ XTestKeyInfo *kp;
+ /*
+ * time delta from previous event
+ */
+ CARD16 tchar;
+ char keytrans = 0;
+
+ /*
+ * update the logical position of the locator if the physical position
+ * of the locator is not the same as the logical position.
+ */
+ if ((locx != xtest_mousex) || (locy != xtest_mousey))
+ {
+ XTestStealJumpData(locx, locy, dev_type);
+ }
+ /*
+ * Get the time delta from the previous event. If needed,
+ * the check_time_event routine will put an XTestDELAY_ACTION
+ * type action in the input action event.
+ */
+ tchar = check_time_event();
+ if (!there_is_room(sizeof(XTestKeyInfo)))
+ {
+ /*
+ * If there isn't room in the input action event for
+ * an XTestDELAY_ACTION, then send that event to the
+ * client and start filling an empty one.
+ */
+ flush_input_actions();
+ }
+ /*
+ * point kp to the correct place in the input action event
+ */
+ kp = (XTestKeyInfo *)
+ (&(input_action_packet.actions[packet_index]));
+ /*
+ * compute the input action header
+ */
+ kp->header = XTestPackDeviceID(dev_type);
+ if ((keystate == KeyRelease) || (keystate == ButtonRelease))
+ {
+ keytrans = XTestKEY_UP;
+ }
+ else if ((keystate == KeyPress) || (keystate == ButtonPress))
+ {
+ keytrans = XTestKEY_DOWN;
+ }
+ else
+ {
+ printf("%s: invalid key/button state %d.\n",
+ XTestEXTENSION_NAME,
+ keystate);
+ }
+ kp->header = kp->header | keytrans | XTestKEY_ACTION;
+ /*
+ * set the keycode in the input action
+ */
+ kp->keycode = keycode;
+ /*
+ * set the delay time in the input action
+ */
+ kp->delay_time = tchar;
+ /*
+ * increment the packet index by the size of the input action
+ */
+ packet_index = packet_index + sizeof(XTestKeyInfo);
+ /*
+ * if the command key has been released or input actions are not
+ * packed, send the input action event to the client
+ */
+ if(((keycode == xtest_command_key) && (keystate == KeyRelease)) ||
+ (packed_mode != XTestPACKED_ACTIONS))
+ {
+ flush_input_actions();
+ }
+ /* return TRUE if the event should be passed on to DIX */
+ if (exclusive_steal)
+ return ((keystate == KeyRelease) &&
+ (keycode == xtest_command_key));
+ else
+ return ((keystate != KeyRelease) ||
+ (keycode != xtest_command_key));
+}
+
+/******************************************************************************
+ *
+ * parse_fake_input
+ *
+ * Parsing routine for a XTestFakeInput request. It will take a request
+ * and parse its contents into the input action array. Eventually the
+ * XTestProcessInputAction routine will be called to take input actions
+ * from the input action array and send them to the server to be handled.
+ */
+void
+parse_fake_input(client, req)
+/*
+ * which client did the XTestFakeInput request
+ */
+ClientPtr client;
+/*
+ * a pointer to the xTestFakeInputReq structure sent by the client
+ */
+char *req;
+{
+ /*
+ * if set to 1, done processing input actions from the request
+ */
+ int done = 0;
+ /*
+ * type of input action
+ */
+ CARD8 action_type;
+ /*
+ * device type
+ */
+ CARD8 dev_type;
+ /*
+ * pointer to an xTestFakeInputReq structure
+ */
+ xTestFakeInputReq *request;
+ /*
+ * holds the index into the action list in the request
+ */
+ int parse_index;
+
+ /*
+ * get a correct-type pointer to the client-supplied request data
+ */
+ request = (xTestFakeInputReq *) req;
+ /*
+ * save the acknowledge requested state for use in
+ * XTestProcessInputAction
+ */
+ acknowledge = request->ack;
+ /*
+ * set up an index into the action list in the request
+ */
+ parse_index = 0;
+ if (write_index >= ACTION_ARRAY_SIZE)
+ {
+ /*
+ * if the input action array is full, don't add any more
+ */
+ done = 1;
+ }
+ while (!done)
+ {
+ /*
+ * get the type of input action in the list
+ */
+ action_type = (request->action_list[parse_index])
+ & XTestACTION_TYPE_MASK;
+ /*
+ * get the type of device in the list
+ */
+ dev_type = XTestUnpackDeviceID(request->action_list[parse_index]);
+ /*
+ * process the input action appropriately
+ */
+ switch (action_type)
+ {
+ case XTestKEY_ACTION:
+ parse_key_fake((XTestKeyInfo *)
+ &(request->action_list[parse_index]));
+ parse_index = parse_index + sizeof(XTestKeyInfo);
+ break;
+ case XTestMOTION_ACTION:
+ parse_motion_fake((XTestMotionInfo *)
+ &(request->action_list[parse_index]));
+ parse_index = parse_index + sizeof(XTestMotionInfo);
+ break;
+ case XTestJUMP_ACTION:
+ parse_jump_fake((XTestJumpInfo *)
+ &(request->action_list[parse_index]));
+ parse_index = parse_index + sizeof(XTestJumpInfo);
+ break;
+ case XTestDELAY_ACTION:
+ if (dev_type == XTestDELAY_DEVICE_ID)
+ {
+ parse_delay_fake((XTestDelayInfo *)
+ &(request->action_list[parse_index]));
+ parse_index = parse_index +
+ sizeof(XTestDelayInfo);
+ }
+ else
+ {
+ /*
+ * An invalid input action header byte has
+ * been detected, so there are no more
+ * input actions in this request.
+ * The intended invalid action header byte
+ * for this case should have a value of 0.
+ */
+ done = 1;
+ }
+ break;
+ }
+ if (parse_index >= XTestMAX_ACTION_LIST_SIZE)
+ {
+ /*
+ * entire XTestFakeInput request has been processed
+ */
+ done = 1;
+ }
+ if (write_index >= ACTION_ARRAY_SIZE)
+ {
+ /*
+ * no room in the input actions array
+ */
+ done = 1;
+ }
+ }
+ if (write_index > read_index)
+ {
+ /*
+ * there are fake input actions in the input action array
+ * to be given to the server
+ */
+ playback_on = 1;
+ playback_client = client;
+ }
+}
+
+/******************************************************************************
+ *
+ * parse_key_fake
+ *
+ * Called from parse_fake_input.
+ *
+ * Copy the fake key input action from its packed form into the array of
+ * pending input events.
+ */
+static void
+parse_key_fake(fkey)
+XTestKeyInfo *fkey;
+{
+ action_array[write_index].type = XTestKEY_ACTION;
+ action_array[write_index].device = XTestUnpackDeviceID(fkey->header);
+ action_array[write_index].keycode = fkey->keycode;
+ action_array[write_index].keystate = fkey->header & XTestKEY_STATE_MASK;
+ action_array[write_index].delay_time = fkey->delay_time;
+ write_index++;
+}
+
+/******************************************************************************
+ *
+ * parse_motion_fake
+ *
+ * Called from parse_fake_input.
+ *
+ * Copy the fake motion input action from its packed form into the array of
+ * pending input events.
+ */
+static void
+parse_motion_fake(fmotion)
+XTestMotionInfo *fmotion;
+{
+ int dx;
+ int dy;
+
+ dx = (XTestUnpackXMotionValue(fmotion->motion_data));
+ dy = (XTestUnpackYMotionValue(fmotion->motion_data));
+ if (((fmotion->header) & XTestX_SIGN_BIT_MASK) == XTestX_NEGATIVE)
+ {
+ pmousex -= dx;
+ }
+ else
+ {
+ pmousex += dx;
+ }
+ if (((fmotion->header) & XTestY_SIGN_BIT_MASK) == XTestY_NEGATIVE)
+ {
+ pmousey -= dy;
+ }
+ else
+ {
+ pmousey += dy;
+ }
+ action_array[write_index].type = XTestJUMP_ACTION;
+ action_array[write_index].device = XTestUnpackDeviceID(fmotion->header);
+ action_array[write_index].x = pmousex;
+ action_array[write_index].y = pmousey;
+ action_array[write_index].delay_time = fmotion->delay_time;
+ write_index++;
+}
+
+/******************************************************************************
+ *
+ * parse_jump_fake
+ *
+ * Called from parse_fake_input.
+ *
+ * Copy the fake jump input action from its packed form into the array of
+ * pending input events.
+ */
+static void
+parse_jump_fake(fjump)
+XTestJumpInfo *fjump;
+{
+ pmousex = fjump->jumpx;
+ pmousey = fjump->jumpy;
+ action_array[write_index].type = XTestJUMP_ACTION;
+ action_array[write_index].device = XTestUnpackDeviceID(fjump->header);
+ action_array[write_index].x = pmousex;
+ action_array[write_index].y = pmousey;
+ action_array[write_index].delay_time = fjump->delay_time;
+ write_index++;
+}
+
+/******************************************************************************
+ *
+ * parse_delay_fake
+ *
+ * Called from parse_fake_input.
+ *
+ * Copy the fake delay input action from its packed form into the array of
+ * pending input events.
+ */
+static void
+parse_delay_fake(tevent)
+XTestDelayInfo *tevent;
+{
+ action_array[write_index].type = XTestDELAY_ACTION;
+ action_array[write_index].delay_time = tevent->delay_time;
+ write_index++;
+}
+
+/******************************************************************************
+ *
+ * XTestComputeWaitTime
+ *
+ * Compute the amount of time the server should wait before sending the
+ * next monitor event in playback mode.
+ */
+void
+XTestComputeWaitTime(waittime)
+struct timeval *waittime;
+{
+ /*
+ * The playback_on flag is set to 1 in parse_fake_input. It is set to
+ * 0 in XTestProcessInputAction if the server has replayed all input
+ * actions.
+ */
+ if (playback_on)
+ {
+ if (!play_clock)
+ {
+ /*
+ * if the playback clock has never been set,
+ * then do it now
+ */
+ start_play_clock();
+ }
+ /*
+ * We need to save the waittime the first time through. This
+ * is a value the server uses, and we have to restore it when
+ * all of the input actions are processed by the server.
+ */
+ if (!time_saved)
+ {
+ saved_sec = waittime->tv_sec;
+ saved_usec = waittime->tv_usec;
+ time_saved = 1;
+ }
+ if (go_for_next)
+ {
+ /*
+ * if we just processed an input action, figure out
+ * how long to wait for the next input action
+ */
+ compute_action_time(&rtime);
+ }
+ else
+ {
+ /*
+ * else just find out how much more time to wait
+ * on the current input action
+ */
+ (void)find_residual_time(&rtime);
+ }
+ waittime->tv_sec = rtime.tv_sec;
+ waittime->tv_usec = rtime.tv_usec;
+ }
+}
+
+/******************************************************************************
+ *
+ * XTestProcessInputAction
+ *
+ * If there are any input actions in the input action array,
+ * then take one out and process it.
+ *
+ */
+int
+XTestProcessInputAction(readable, waittime)
+/*
+ * This is the value that a 'select' function returned just before this
+ * routine was called. If the select timed out, this value will be 0.
+ *
+ * This extension modifies the select call's timeout value to cause the
+ * select to time out when the next input action is ready to given to
+ * the server. This routine is called immediately after the select, to
+ * give it a chance to process an input action. If we have an input action
+ * to process and the only reason that the select returned was because it
+ * timed out, then we change the select value to 1 and return 1 instead of 0.
+ */
+int readable;
+/*
+ * this is the timeout value that the select was called with
+ */
+struct timeval *waittime;
+{
+int mousex, mousey;
+ /*
+ * if playback_on is 0, then the input action array is empty
+ */
+ if (playback_on)
+ {
+ restorewait = waittime;
+ /*
+ * figure out if we need to wait for the next input action
+ */
+ if (find_residual_time(&rtime) > 0)
+ {
+ /*
+ * still have to wait before processing the current
+ * input action
+ */
+ go_for_next = 0;
+ }
+ else
+ {
+ /*
+ * don't have to wait any longer before processing
+ * the current input action
+ */
+ go_for_next = 1;
+ }
+ /*
+ * if we have an input action to process and the only reason
+ * that the select returned was because it timed out, then we
+ * change the select value to 1 and return 1 instead of 0
+ */
+ if (readable == 0)
+ {
+ readable++;
+ }
+ /*
+ * if we don't need to wait, then get an input action from
+ * the input action array and process it
+ */
+ if (go_for_next)
+ {
+ /*
+ * There are three possible types of input actions in
+ * the input action array (motion input actions are
+ * converted to jump input actions before being put
+ * into the input action array). Delay input actions
+ * are processed by the compute_action_time function
+ * which is called from XTestComputeWaitTime. The
+ * other two types of input actions are processed here.
+ */
+ if (action_array[read_index].type == XTestJUMP_ACTION)
+ {
+ XTestJumpPointer(
+ action_array[read_index].x,
+ action_array[read_index].y,
+ action_array[read_index].device);
+ }
+ if (action_array[read_index].type == XTestKEY_ACTION)
+ {
+ GetSpritePosition(&mousex, &mousey);
+ XTestGenerateEvent(
+ action_array[read_index].device,
+ action_array[read_index].keycode,
+ action_array[read_index].keystate,
+ mousex,
+ mousey);
+ }
+ read_index++;
+ /*
+ * if all input actions are processed, then restore
+ * the server state
+ */
+ if (read_index >= write_index)
+ {
+ waittime->tv_sec = saved_sec;
+ waittime->tv_usec = saved_usec;
+ time_saved = 0;
+ playback_on = 0;
+ if (acknowledge)
+ {
+ /*
+ * if the playback client is waiting
+ * for an xTestFakeAck event, send
+ * it to him
+ */
+ send_ack(playback_client);
+ acknowledge = 0;
+ }
+ write_index = 0;
+ read_index = 0;
+ playback_client = (ClientPtr) NULL;
+ play_clock = 0;
+ }
+ }
+ }
+ return(readable);
+}
+
+/******************************************************************************
+ *
+ * send_ack
+ *
+ * send an xTestFakeAck event to the client
+ */
+static void
+send_ack(client)
+ClientPtr client;
+{
+ xTestFakeAckEvent rep;
+
+ /*
+ * set the serial number of the xTestFakeAck event
+ */
+ rep.sequenceNumber = client->sequence;
+ rep.type = XTestFakeAckType;
+ WriteEventsToClient(client, 1, (xEvent *) &rep);
+}
+
+/******************************************************************************
+ *
+ * start_play_clock
+ *
+ * start the clock for play back.
+ */
+static void
+start_play_clock()
+{
+ X_GETTIMEOFDAY(&play_time);
+ /*
+ * flag that play_time is valid
+ */
+ play_clock = 1;
+}
+
+/******************************************************************************
+ *
+ * compute_action_time
+ *
+ * Set the play clock to the time when the next input action should be put
+ * into the server's input queue. Fill the rtime structure with values
+ * for the delta until the time for the next input action.
+ */
+static void
+compute_action_time(rtime)
+struct timeval *rtime;
+{
+ /*
+ * holds the delay time in milliseconds
+ */
+ unsigned long dtime;
+ /*
+ * holds the number of microseconds in the sum of the dtime value
+ * and the play_time value
+ */
+ unsigned long tot_usec;
+ /*
+ * holds the number of seconds and microseconds in the
+ * dtime value
+ */
+ unsigned long sec;
+ unsigned long usec;
+ /*
+ * holds the current time
+ */
+ struct timeval btime;
+
+ /*
+ * Put the time from the current input action in dtime
+ */
+ dtime = action_array[read_index].delay_time;
+ /*
+ * If the current input action is a delay input action,
+ * add in the time from the following input action.
+ */
+ if ((action_array[read_index].type == XTestDELAY_ACTION) &&
+ ((read_index + 1) < write_index))
+ {
+ read_index++;
+ dtime = dtime + action_array[read_index].delay_time;
+ }
+ /*
+ * compute the number of seconds and microseconds in the
+ * dtime value
+ */
+ sec = dtime / 1000;
+ usec = (dtime % 1000) * 1000;
+ /*
+ * get the current time in btime
+ */
+ X_GETTIMEOFDAY(&btime);
+ /*
+ * compute the number of microseconds in the sum of the dtime value
+ * and the current usec value
+ */
+ tot_usec = btime.tv_usec + usec;
+ /*
+ * if it is greater than one second's worth, adjust the seconds
+ */
+ if (tot_usec >= 1000000)
+ {
+ tot_usec -= 1000000;
+ sec++;
+ }
+ play_time.tv_usec = tot_usec;
+ play_time.tv_sec = btime.tv_sec + sec;
+ /*
+ * put the time until the next input action in rtime
+ */
+ rtime->tv_sec = sec;
+ rtime->tv_usec = usec;
+}
+
+/******************************************************************************
+ *
+ * find_residual_time
+ *
+ * Find the time interval from the current time to the value in play_time.
+ * This is the time to wait till putting the next input action into the
+ * server's input queue. If the time is already up, reset play_time to
+ * the current time.
+ */
+static int
+find_residual_time(the_residual)
+struct timeval *the_residual;
+{
+ /*
+ * if > 0, there is time to wait. If < 0, then don't wait
+ */
+ int wait = 1;
+ /*
+ * holds the current time
+ */
+ struct timeval btime;
+ /*
+ * holds the current time in seconds and microseconds
+ */
+ unsigned long bsec;
+ unsigned long busec;
+ /*
+ * holds the playback time in seconds and microseconds
+ */
+ unsigned long psec;
+ unsigned long pusec;
+
+ /*
+ * get the current time in btime
+ */
+ X_GETTIMEOFDAY(&btime);
+ /*
+ * get the current time in seconds and microseconds
+ */
+ bsec = btime.tv_sec;
+ busec = btime.tv_usec;
+ /*
+ * get the playback time in seconds and microseconds
+ */
+ psec = play_time.tv_sec;
+ pusec = play_time.tv_usec;
+ /*
+ * if the current time is already later than the playback time,
+ * we don't need to wait
+ */
+ if (bsec > psec)
+ {
+ wait = -1;
+ }
+ else
+ {
+ if (bsec == psec)
+ {
+ /*
+ * if the current and playback times have the same
+ * second value, then compare the microsecond values
+ */
+ if ( busec >= pusec)
+ {
+ /*
+ * if the current time is already later than
+ * the playback time, we don't need to wait
+ */
+ wait = -1;
+ }
+ else
+ {
+ the_residual->tv_usec = pusec - busec;
+ the_residual->tv_sec = 0;
+ }
+ }
+ else
+ {
+ if (busec > pusec)
+ {
+ /*
+ * 'borrow' a second's worth of microseconds
+ * from the seconds left to wait
+ */
+ the_residual->tv_usec = 1000000 - busec + pusec;
+ psec--;
+ the_residual->tv_sec = psec - bsec;
+ }
+ else
+ {
+ the_residual->tv_sec = psec - bsec;
+ the_residual->tv_usec = pusec - busec;
+ }
+ }
+ }
+ if (wait < 0)
+ {
+ /*
+ * if don't need to wait, set the playback time
+ * to the current time
+ */
+ X_GETTIMEOFDAY(&play_time);
+ /*
+ * set the time to wait to 0
+ */
+ the_residual->tv_sec = 0;
+ the_residual->tv_usec = 0;
+ }
+ return(wait);
+}
+
+/******************************************************************************
+ *
+ * abort_play_back
+ */
+void
+abort_play_back()
+{
+ /*
+ * If we were playing back input actions at the time of the abort,
+ * restore the original wait time for the select in the main wait
+ * loop of the server
+ */
+ if (playback_on)
+ {
+ restorewait->tv_sec = saved_sec;
+ restorewait->tv_usec = saved_usec;
+ }
+ /*
+ * make the input action array empty
+ */
+ read_index = 0;
+ write_index = 0;
+ /*
+ * we are no longer playing back anything
+ */
+ playback_on = 0;
+ play_clock = 0;
+ go_for_next = 1;
+ /*
+ * there is no valid wait time saved any more
+ */
+ time_saved = 0;
+ /*
+ * there are no valid clients using this extension
+ */
+ playback_client = (ClientPtr) NULL;
+ current_xtest_client = (ClientPtr) NULL;
+}
+
+/******************************************************************************
+ *
+ * return_input_array_size
+ *
+ * Return the number of input actions in the input action array.
+ */
+void
+return_input_array_size(client)
+/*
+ * which client to send the reply to
+ */
+ClientPtr client;
+{
+ xTestQueryInputSizeReply rep;
+
+ rep.type = X_Reply;
+ /*
+ * set the serial number of the reply
+ */
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.size_return = ACTION_ARRAY_SIZE;
+ WriteReplyToClient(client,
+ sizeof(xTestQueryInputSizeReply),
+ (void *) &rep);
+}
diff --git a/nx-X11/programs/Xserver/Xext/xtest1dd.h b/nx-X11/programs/Xserver/Xext/xtest1dd.h
new file mode 100644
index 000000000..5a3ee1781
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xtest1dd.h
@@ -0,0 +1,126 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef XTEST1DD_H
+#define XTEST1DD_H 1
+
+extern short xtest_mousex;
+extern short xtest_mousey;
+extern int playback_on;
+extern ClientPtr current_xtest_client;
+extern ClientPtr playback_client;
+extern KeyCode xtest_command_key;
+
+extern void stop_stealing_input(
+ void
+);
+
+extern void
+steal_input(
+ ClientPtr /* client */,
+ CARD32 /* mode */
+);
+
+extern void
+flush_input_actions(
+ void
+);
+
+extern void
+XTestStealJumpData(
+ int /* jx */,
+ int /* jy */,
+ int /* dev_type */
+);
+
+extern void
+XTestStealMotionData(
+ int /* dx */,
+ int /* dy */,
+ int /* dev_type */,
+ int /* mx */,
+ int /* my */
+);
+
+extern Bool
+XTestStealKeyData(
+ unsigned /* keycode */,
+ int /* keystate */,
+ int /* dev_type */,
+ int /* locx */,
+ int /* locy */
+);
+
+extern void
+parse_fake_input(
+ ClientPtr /* client */,
+ char * /* req */
+);
+
+extern void
+XTestComputeWaitTime(
+ struct timeval * /* waittime */
+);
+
+extern int
+XTestProcessInputAction(
+ int /* readable */,
+ struct timeval * /* waittime */
+);
+
+extern void
+abort_play_back(
+ void
+);
+
+extern void
+return_input_array_size(
+ ClientPtr /* client */
+);
+
+extern void XTestGenerateEvent(
+ int /* dev_type */,
+ int /* keycode */,
+ int /* keystate */,
+ int /* mousex */,
+ int /* mousey */
+);
+
+extern void XTestGetPointerPos(
+ short * /* fmousex */,
+ short * /* fmousey */
+);
+
+extern void XTestJumpPointer(
+ int /* jx */,
+ int /* jy */,
+ int /* dev_type */
+);
+
+#endif /* XTEST1DD_H */
diff --git a/nx-X11/programs/Xserver/Xext/xtest1di.c b/nx-X11/programs/Xserver/Xext/xtest1di.c
new file mode 100644
index 000000000..b1d69ef47
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xtest1di.c
@@ -0,0 +1,915 @@
+/*
+ * File: xtest1di.c
+ *
+ * This file contains the device independent parts of the input
+ * synthesis extension.
+ */
+
+/*
+
+
+Copyright 1986, 1987, 1988, 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.
+
+
+Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
+
+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 name of Hewlett-Packard not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Hewlett-Packard makes no representations about the
+suitability of this software for any purpose. It is provided
+"as is" without express or implied warranty.
+
+This software is not subject to any license of the American
+Telephone and Telegraph Company or of the Regents of the
+University of California.
+
+*/
+
+/*****************************************************************************
+ * include files
+ ****************************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#define XTestSERVER_SIDE
+#include <nx-X11/extensions/xtestext1.h>
+
+#include "xtest1dd.h"
+
+/*****************************************************************************
+ * defines
+ ****************************************************************************/
+
+/*****************************************************************************
+ * variables
+ ****************************************************************************/
+
+/*
+ * Holds the request type code for this extension. The request type code
+ * for this extension may vary depending on how many extensions are installed
+ * already, so the initial value given below will be added to the base request
+ * code that is aquired when this extension is installed.
+ */
+static int XTestReqCode = 0;
+/*
+ * Holds the two event type codes for this extension. The event type codes
+ * for this extension may vary depending on how many extensions are installed
+ * already, so the initial values given below will be added to the base event
+ * code that is aquired when this extension is installed.
+ */
+int XTestInputActionType = 0;
+int XTestFakeAckType = 1;
+/*
+ * true => monitor stealing input
+ */
+int on_steal_input = FALSE;
+/*
+ * true => monitor alone getting input
+ */
+int exclusive_steal = FALSE;
+/*
+ * holds the resource type assigned to this extension
+ */
+static RESTYPE XTestType;
+/*
+ * holds the resource ID for the client currently using XTestGetInput
+ */
+static XID current_client_id;
+
+/*****************************************************************************
+ * function declarations
+ ****************************************************************************/
+
+static DISPATCH_PROC(ProcXTestDispatch);
+static DISPATCH_PROC(SProcXTestDispatch);
+static DISPATCH_PROC(ProcTestFakeInput);
+static DISPATCH_PROC(SProcTestFakeInput);
+static DISPATCH_PROC(ProcTestGetInput);
+static DISPATCH_PROC(SProcTestGetInput);
+static DISPATCH_PROC(ProcTestStopInput);
+static DISPATCH_PROC(SProcTestStopInput);
+static DISPATCH_PROC(ProcTestReset);
+static DISPATCH_PROC(SProcTestReset);
+static DISPATCH_PROC(ProcTestQueryInputSize);
+static DISPATCH_PROC(SProcTestQueryInputSize);
+
+static void XTestResetProc(
+ ExtensionEntry * /* unused */
+ );
+static void SReplyXTestDispatch(
+ ClientPtr /* client_ptr */,
+ int /* size */,
+ char * /* reply_ptr */
+ );
+static void SEventXTestDispatch(
+ xEvent * /* from */,
+ xEvent * /* to */
+ );
+
+static int XTestCurrentClientGone(
+ void * /* value */,
+ XID /* id */
+ );
+
+/*****************************************************************************
+ *
+ * XTestExtension1Init
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ * XTestExtension1Init has no events or errors
+ * (other than the core errors).
+ */
+void
+XTestExtension1Init(void)
+{
+ /*
+ * holds the pointer to the extension entry structure
+ */
+ ExtensionEntry *extEntry;
+
+ extEntry = AddExtension(XTestEXTENSION_NAME,
+ XTestEVENT_COUNT,
+ 0,
+ ProcXTestDispatch,
+ SProcXTestDispatch,
+ XTestResetProc,
+ StandardMinorOpcode);
+ if (extEntry)
+ {
+ /*
+ * remember the request code assigned to this extension
+ */
+ XTestReqCode = extEntry->base;
+ /*
+ * make an atom saying that this extension is present
+ */
+ (void) MakeAtom(XTestEXTENSION_NAME,
+ strlen(XTestEXTENSION_NAME),
+ TRUE);
+ /*
+ * remember the event codes assigned to this extension
+ */
+ XTestInputActionType += extEntry->eventBase;
+ XTestFakeAckType += extEntry->eventBase;
+ /*
+ * install the routine to handle byte-swapping the replies
+ * for this extension in the ReplySwapVector table
+ */
+ ReplySwapVector[XTestReqCode] = (ReplySwapPtr) SReplyXTestDispatch;
+ /*
+ * install the routine to handle byte-swapping the events
+ * for this extension in the EventSwapVector table
+ */
+ EventSwapVector[XTestInputActionType] = SEventXTestDispatch;
+ EventSwapVector[XTestFakeAckType] = SEventXTestDispatch;
+ /*
+ * get the resource type for this extension
+ */
+ XTestType = CreateNewResourceType(XTestCurrentClientGone);
+ if (XTestType == 0)
+ {
+ FatalError("XTestExtension1Init: CreateNewResourceType failed\n");
+ }
+ }
+ else
+ {
+ FatalError("XTestExtension1Init: AddExtensions failed\n");
+ }
+}
+
+/*****************************************************************************
+ *
+ * ProcXTestDispatch
+ *
+ *
+ */
+static int
+ProcXTestDispatch(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ if (stuff->data == X_TestFakeInput)
+ {
+ return(ProcTestFakeInput(client));
+ }
+ else if (stuff->data == X_TestGetInput)
+ {
+ return(ProcTestGetInput(client));
+ }
+ else if (stuff->data == X_TestStopInput)
+ {
+ return(ProcTestStopInput(client));
+ }
+ else if (stuff->data == X_TestReset)
+ {
+ return(ProcTestReset(client));
+ }
+ else if (stuff->data == X_TestQueryInputSize)
+ {
+ return(ProcTestQueryInputSize(client));
+ }
+ else
+ {
+ SendErrorToClient(client,
+ XTestReqCode,
+ stuff->data,
+ None,
+ BadRequest);
+ return(BadRequest);
+ }
+}
+
+/*****************************************************************************
+ *
+ * SProcXTestDispatch
+ *
+ *
+ */
+static int
+SProcXTestDispatch(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ if (stuff->data == X_TestFakeInput)
+ {
+ return(SProcTestFakeInput(client));
+ }
+ else if (stuff->data == X_TestGetInput)
+ {
+ return(SProcTestGetInput(client));
+ }
+ else if (stuff->data == X_TestStopInput)
+ {
+ return(SProcTestStopInput(client));
+ }
+ else if (stuff->data == X_TestReset)
+ {
+ return(SProcTestReset(client));
+ }
+ else if (stuff->data == X_TestQueryInputSize)
+ {
+ return(SProcTestQueryInputSize(client));
+ }
+ else
+ {
+ SendErrorToClient(client,
+ XTestReqCode,
+ stuff->data,
+ None,
+ BadRequest);
+ return(BadRequest);
+ }
+}
+
+/*****************************************************************************
+ *
+ * SProcTestFakeInput
+ *
+ *
+ */
+static int
+SProcTestFakeInput(client)
+ register ClientPtr client;
+{
+ /*
+ * index counter
+ */
+ int i;
+ /*
+ * pointer to the next input action in the request
+ */
+ CARD8 *input_action_ptr;
+ /*
+ * holds the type of the next input action in the request
+ */
+ int input_action_type;
+
+ REQUEST(xTestFakeInputReq);
+ /*
+ * byte-swap the fields in the request
+ */
+ swaps(&stuff->length);
+ swapl(&stuff->ack);
+ /*
+ * have to parse and then byte-swap the input action list here
+ */
+ for (i = 0; i < XTestMAX_ACTION_LIST_SIZE;)
+ {
+ /*
+ * point to the next input action in the request
+ */
+ input_action_ptr = &(((xTestFakeInputReq *) stuff)->action_list[i]);
+ /*
+ * figure out what type of input action it is
+ */
+ input_action_type = (*input_action_ptr) & XTestACTION_TYPE_MASK;
+ /*
+ * byte-swap the input action according to it's type
+ */
+ switch (input_action_type)
+ {
+ case XTestKEY_ACTION:
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestKeyInfo);
+ break;
+ case XTestMOTION_ACTION:
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestMotionInfo);
+ break;
+ case XTestJUMP_ACTION:
+ /*
+ * byte-swap the jumpx field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx));
+ /*
+ * byte-swap the jumpy field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy));
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestJumpInfo);
+ break;
+ default:
+ /*
+ * if this is a delay input action, then byte-swap it,
+ * otherwise we have reached the end of the input
+ * actions in this request
+ */
+ if (XTestUnpackDeviceID(*input_action_ptr) ==
+ XTestDELAY_DEVICE_ID)
+ {
+ /*
+ * byte-swap the delay_time field
+ */
+ swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestDelayInfo);
+ }
+ else
+ {
+ /*
+ * if the input action header byte is 0 or
+ * ill-formed, then there are no more input
+ * actions in this request
+ */
+ i = XTestMAX_ACTION_LIST_SIZE;
+ }
+ break;
+ }
+ }
+ return(ProcTestFakeInput(client));
+}
+
+/*****************************************************************************
+ *
+ * SProcTestGetInput
+ *
+ *
+ */
+static int
+SProcTestGetInput(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestGetInputReq);
+ /*
+ * byte-swap the fields in the request
+ */
+ swaps(&stuff->length);
+ swapl(&stuff->mode);
+ return(ProcTestGetInput(client));
+}
+
+/*****************************************************************************
+ *
+ * SProcTestStopInput
+ *
+ *
+ */
+static int
+SProcTestStopInput(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestStopInputReq);
+ /*
+ * byte-swap the length field in the request
+ */
+ swaps(&stuff->length);
+ return(ProcTestStopInput(client));
+}
+
+/*****************************************************************************
+ *
+ * SProcTestReset
+ *
+ *
+ */
+static int
+SProcTestReset(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestResetReq);
+ /*
+ * byte-swap the length field in the request
+ */
+ swaps(&stuff->length);
+ return(ProcTestReset(client));
+}
+
+/*****************************************************************************
+ *
+ * SProcTestQueryInputSize
+ *
+ *
+ */
+static int
+SProcTestQueryInputSize(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestQueryInputSizeReq);
+ /*
+ * byte-swap the length field in the request
+ */
+ swaps(&stuff->length);
+ return(ProcTestQueryInputSize(client));
+}
+
+/*****************************************************************************
+ *
+ * ProcTestFakeInput
+ *
+ *
+ */
+static int
+ProcTestFakeInput(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestFakeInputReq);
+ REQUEST_SIZE_MATCH(xTestFakeInputReq);
+
+ if (playback_client == NULL)
+ {
+ playback_client = client;
+ current_client_id = FakeClientID(client->index);
+ AddResource(current_client_id,
+ XTestType,
+ 0);
+ MakeClientGrabImpervious(client);
+ }
+ if (playback_client == client)
+ {
+ /*
+ * This extension does not need to clean up any
+ * server state when a client using this function
+ * "goes away". The server will just process any
+ * input actions that have already been sent to it,
+ * and will then reset its association with a client.
+ */
+ parse_fake_input(client, (char *)stuff);
+ return(Success);
+ }
+ else
+ {
+ /*
+ * this is a request by another client to send fake
+ * input while the server is still being used
+ */
+ SendErrorToClient(client,
+ XTestReqCode,
+ X_TestFakeInput,
+ None,
+ BadAccess);
+ return(BadAccess);
+ }
+}
+
+/*****************************************************************************
+ *
+ * ProcTestGetInput
+ *
+ *
+ */
+static int
+ProcTestGetInput(client)
+ register ClientPtr client;
+{
+ REQUEST(xTestGetInputReq);
+ REQUEST_SIZE_MATCH(xTestGetInputReq);
+ if (on_steal_input)
+ {
+ /*
+ * this is a request by another client to get fake input
+ * while the server is still sending input to the first client
+ */
+ SendErrorToClient(client,
+ XTestReqCode,
+ X_TestGetInput,
+ None,
+ BadAccess);
+ return(BadAccess);
+ }
+ else
+ {
+ /*
+ * Set up a resource associated with the client using this
+ * function so that this extension gets called when the
+ * client "goes away". This allows this extension to
+ * clean up the server state.
+ */
+ current_client_id = FakeClientID(client->index);
+ AddResource(current_client_id,
+ XTestType,
+ 0);
+ /*
+ * indicate that a client is stealing input
+ */
+ on_steal_input = TRUE;
+ if ((stuff->mode & XTestEXCLUSIVE) == 0)
+ {
+ exclusive_steal = FALSE;
+ }
+ else
+ {
+ exclusive_steal = TRUE;
+ }
+ steal_input(client, stuff->mode);
+ return(Success);
+ }
+}
+
+/*****************************************************************************
+ *
+ * ProcTestStopInput
+ *
+ *
+ */
+static int
+ProcTestStopInput(client)
+ register ClientPtr client;
+{
+ REQUEST_SIZE_MATCH(xTestStopInputReq);
+ if (on_steal_input && (current_xtest_client == client))
+ {
+ on_steal_input = FALSE;
+ exclusive_steal = FALSE;
+ stop_stealing_input();
+ /*
+ * remove the resource associated with this client
+ */
+ FreeResource(current_client_id, RT_NONE);
+ return(Success);
+ }
+ else
+ {
+ /*
+ * this is a request to stop fake input when fake input has
+ * never been started or from a client that hasn't started
+ * fake input
+ */
+ SendErrorToClient(client,
+ XTestReqCode,
+ X_TestStopInput,
+ None,
+ BadAccess);
+ return(BadAccess);
+ }
+}
+
+/*****************************************************************************
+ *
+ * ProcTestReset
+ *
+ *
+ */
+static int
+ProcTestReset(client)
+ register ClientPtr client;
+{
+ REQUEST_SIZE_MATCH(xTestResetReq);
+ on_steal_input = FALSE;
+ exclusive_steal = FALSE;
+ /*
+ * defined in xtest1dd.c
+ */
+ stop_stealing_input();
+ /*
+ * defined in xtest1dd.c
+ */
+ abort_play_back();
+ return(Success);
+}
+
+/*****************************************************************************
+ *
+ * ProcTestQueryInputSize
+ *
+ *
+ */
+static int
+ProcTestQueryInputSize(client)
+ register ClientPtr client;
+{
+ REQUEST_SIZE_MATCH(xTestQueryInputSizeReq);
+ /*
+ * defined in xtest1dd.c
+ */
+ return_input_array_size(client);
+ return(Success);
+}
+
+/*****************************************************************************
+ *
+ * XTestResetProc
+ *
+ * This function is called by the server when the server has no clients
+ * connected to it. It must put eveything back the way it was before
+ * this extension was installed.
+ */
+/*ARGSUSED*/
+static void
+XTestResetProc(unused)
+ ExtensionEntry * unused;
+{
+ /*
+ * remove the routine to handle byte-swapping the replies
+ * for this extension in the ReplySwapVector table
+ */
+ ReplySwapVector[XTestReqCode] = ReplyNotSwappd;
+ /*
+ * remove the routine to handle byte-swapping the events
+ * for this extension in the EventSwapVector table
+ */
+ EventSwapVector[XTestInputActionType] = NotImplemented;
+ EventSwapVector[XTestFakeAckType] = NotImplemented;
+ /*
+ * reset the variables initialized just once at load time
+ */
+ XTestReqCode = 0;
+ XTestInputActionType = 0;
+ XTestFakeAckType = 1;
+ on_steal_input = FALSE;
+ exclusive_steal = FALSE;
+ playback_client = 0; /* Don't really need this but it looks nice */
+}
+
+/*****************************************************************************
+ *
+ * PXTestCurrentClientGone
+ *
+ * This routine is called when a client that has asked for input actions
+ * to be sent to it "goes away". This routine must clean up the
+ * server state.
+ */
+/*ARGSUSED*/
+static int
+XTestCurrentClientGone(value, id)
+ void * value;
+ XID id;
+{
+ /*
+ * defined in xtest1dd.c
+ */
+ on_steal_input = FALSE;
+ exclusive_steal = FALSE;
+ /*
+ * defined in xtestdd.c
+ */
+ playback_client = 0;
+ abort_play_back();
+ return TRUE;
+}
+
+/*****************************************************************************
+ *
+ * SReplyXTestDispatch
+ *
+ * Swap any replies defined in this extension.
+ */
+static void
+SReplyXTestDispatch(client_ptr, size, reply_ptr)
+ ClientPtr client_ptr;
+ int size;
+ char *reply_ptr;
+{
+ /*
+ * pointer to xTestQueryInputSizeReply
+ */
+ xTestQueryInputSizeReply *rep_ptr;
+
+ /*
+ * there is only one reply in this extension, so byte-swap it
+ */
+ rep_ptr = (xTestQueryInputSizeReply *) reply_ptr;
+ swaps(&(rep_ptr->sequenceNumber));
+ swapl(&(rep_ptr->length));
+ swapl(&(rep_ptr->size_return));
+ /*
+ * now write the swapped reply to the client
+ */
+ WriteToClient(client_ptr, size, reply_ptr);
+}
+
+/*****************************************************************************
+ *
+ * SEventXTestDispatch
+ *
+ * Swap any events defined in this extension.
+ */
+static void
+SEventXTestDispatch(from, to)
+ xEvent *from;
+ xEvent *to;
+{
+ /*
+ * index counter
+ */
+ int i;
+ /*
+ * pointer to the next input action in the event
+ */
+ CARD8 *input_action_ptr;
+ /*
+ * holds the type of the next input action in the event
+ */
+ int input_action_type;
+
+
+ /*
+ * copy the type information from the "from" event to the "to" event
+ */
+ ((xTestInputActionEvent *) to)->type =
+ ((xTestInputActionEvent *) from)->type;
+ /*
+ * copy the sequence number information from the "from" event to the
+ * "to" event
+ */
+ ((xTestInputActionEvent *) to)->sequenceNumber =
+ ((xTestInputActionEvent *) from)->sequenceNumber;
+ /*
+ * byte-swap the sequence number in the "to" event
+ */
+ swaps(&(((xTestInputActionEvent *) to)->sequenceNumber));
+ /*
+ * If the event is an xTestInputActionEvent, then it needs more
+ * processing. Otherwise, it is an xTestFakeAckEvent, which
+ * has no other information in it.
+ */
+ if ((((xTestInputActionEvent *) to)->type & 0x7f) ==
+ XTestInputActionType)
+ {
+ /*
+ * copy the input actions from the "from" event
+ * to the "to" event
+ */
+ for (i = 0; i < XTestACTIONS_SIZE; i++)
+ {
+ ((xTestInputActionEvent *) to)->actions[i] =
+ ((xTestInputActionEvent *) from)->actions[i];
+ }
+ /*
+ * byte-swap the input actions in the "to" event
+ */
+ for (i = 0; i < XTestACTIONS_SIZE; i++)
+ {
+ /*
+ * point to the next input action in the event
+ */
+ input_action_ptr = &(((xTestInputActionEvent *) to)->actions[i]);
+ /*
+ * figure out what type of input action it is
+ */
+ input_action_type = (*input_action_ptr) &
+ XTestACTION_TYPE_MASK;
+ /*
+ * byte-swap the input action according to it's type
+ */
+ switch (input_action_type)
+ {
+ case XTestKEY_ACTION:
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestKeyInfo);
+ break;
+ case XTestMOTION_ACTION:
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestMotionInfo);
+ break;
+ case XTestJUMP_ACTION:
+ /*
+ * byte-swap the jumpx field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx));
+ /*
+ * byte-swap the jumpy field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy));
+ /*
+ * byte-swap the delay_time field
+ */
+ swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestJumpInfo);
+ break;
+ default:
+ /*
+ * if this is a delay input action, then
+ * byte-swap it, otherwise we have reached the
+ * end of the input actions in this event
+ */
+ if (XTestUnpackDeviceID(*input_action_ptr) ==
+ XTestDELAY_DEVICE_ID)
+ {
+ /*
+ * byte-swap the delay_time field
+ */
+ swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time));
+ /*
+ * advance to the next input action
+ */
+ i += sizeof(XTestDelayInfo);
+ }
+ else
+ {
+ /*
+ * if the input action header byte is 0
+ * or ill-formed, then there are no
+ * more input actions in this event
+ */
+ i = XTestACTIONS_SIZE;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/Xext/xvdisp.c b/nx-X11/programs/Xserver/Xext/xvdisp.c
new file mode 100644
index 000000000..b33bfa493
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvdisp.c
@@ -0,0 +1,2190 @@
+/***********************************************************
+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.
+
+******************************************************************/
+
+/*
+** File:
+**
+** xvdisp.c --- Xv server extension dispatch module.
+**
+** 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
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include <nx-X11/extensions/Xv.h>
+#include <nx-X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include <X11/extensions/shmproto.h>
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+ ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+ ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryAdaptorsReply, _d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryExtensionReply, _d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryEncodingsReply, _d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+ if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+ else WriteToClient(_c, sz_xvAdaptorInfo, _d)
+
+#define _WriteAttributeInfo(_c,_d) \
+ if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+ else WriteToClient(_c, sz_xvAttributeInfo, _d)
+
+#define _WriteEncodingInfo(_c,_d) \
+ if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+ else WriteToClient(_c, sz_xvEncodingInfo, _d)
+
+#define _WriteFormat(_c,_d) \
+ if ((_c)->swapped) SWriteFormat(_c, _d); \
+ else WriteToClient(_c, sz_xvFormat, _d)
+
+#define _WriteGrabPortReply(_c,_d) \
+ if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+ else WriteToClient(_c, sz_xvGrabPortReply, _d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+ if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+ else WriteToClient(_c, sz_xvGetPortAttributeReply, _d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryBestSizeReply, _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryPortAttributesReply, _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+ if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+ else WriteToClient(_c, sz_xvQueryImageAttributesReply, _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+ if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+ else WriteToClient(_c, sz_xvListImageFormatsReply, _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+ if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+ else WriteToClient(_c, sz_xvImageFormatInfo, _d)
+
+#define _AllocatePort(_i,_p) \
+ ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+#if !defined(NXAGENT_SERVER) || defined(__sun) || defined(__CYGWIN__)
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: return(ProcXvQueryExtension(client));
+ case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client));
+ case xv_QueryEncodings: return(ProcXvQueryEncodings(client));
+ case xv_PutVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutVideo(client));
+ else
+#endif
+ return(ProcXvPutVideo(client));
+ case xv_PutStill:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutStill(client));
+ else
+#endif
+ return(ProcXvPutStill(client));
+ case xv_GetVideo: return(ProcXvGetVideo(client));
+ case xv_GetStill: return(ProcXvGetStill(client));
+ case xv_GrabPort: return(ProcXvGrabPort(client));
+ case xv_UngrabPort: return(ProcXvUngrabPort(client));
+ case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client));
+ case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client));
+ case xv_StopVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvStopVideo(client));
+ else
+#endif
+ return(ProcXvStopVideo(client));
+ case xv_SetPortAttribute:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvSetPortAttribute(client));
+ else
+#endif
+ return(ProcXvSetPortAttribute(client));
+ case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client));
+ case xv_QueryBestSize: return(ProcXvQueryBestSize(client));
+ case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client));
+ case xv_PutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvPutImage(client));
+ else
+#endif
+ return(ProcXvPutImage(client));
+#ifdef MITSHM
+ case xv_ShmPutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return(XineramaXvShmPutImage(client));
+ else
+#endif
+ return(ProcXvShmPutImage(client));
+#endif
+ case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client));
+ case xv_ListImageFormats: return(ProcXvListImageFormats(client));
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ return(BadImplementation);
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ return(BadRequest);
+ }
+ }
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: return(SProcXvQueryExtension(client));
+ case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client));
+ case xv_QueryEncodings: return(SProcXvQueryEncodings(client));
+ case xv_PutVideo: return(SProcXvPutVideo(client));
+ case xv_PutStill: return(SProcXvPutStill(client));
+ case xv_GetVideo: return(SProcXvGetVideo(client));
+ case xv_GetStill: return(SProcXvGetStill(client));
+ case xv_GrabPort: return(SProcXvGrabPort(client));
+ case xv_UngrabPort: return(SProcXvUngrabPort(client));
+ case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client));
+ case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client));
+ case xv_StopVideo: return(SProcXvStopVideo(client));
+ case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client));
+ case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client));
+ case xv_QueryBestSize: return(SProcXvQueryBestSize(client));
+ case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client));
+ case xv_PutImage: return(SProcXvPutImage(client));
+#ifdef MITSHM
+ case xv_ShmPutImage: return(SProcXvShmPutImage(client));
+#endif
+ case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client));
+ case xv_ListImageFormats: return(SProcXvListImageFormats(client));
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ return(BadImplementation);
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ return(BadRequest);
+ }
+ }
+}
+#endif /* !defined(NXAGENT_SERVER) || defined(__sun) || defined(__CYGWIN__) */
+
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+ xvQueryExtensionReply rep;
+ /* REQUEST(xvQueryExtensionReq); */
+ REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.version = XvVersion;
+ rep.revision = XvRevision;
+
+ _WriteQueryExtensionReply(client, &rep);
+
+ return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+ xvFormat format;
+ xvAdaptorInfo ainfo;
+ xvQueryAdaptorsReply rep;
+ int totalSize;
+ int na;
+ XvAdaptorPtr pa;
+ int nf;
+ XvFormatPtr pf;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+
+ REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+ if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+ {
+ client->errorValue = stuff->window;
+ return (BadWindow);
+ }
+
+ pScreen = pWin->drawable.pScreen;
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ if (!pxvs)
+ {
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_adaptors = 0;
+ rep.length = 0;
+
+ _WriteQueryAdaptorsReply(client, &rep);
+
+ return Success;
+ }
+
+ (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_adaptors = pxvs->nAdaptors;
+
+ /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+ totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+ /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+ na = pxvs->nAdaptors;
+ pa = pxvs->pAdaptors;
+ while (na--)
+ {
+ totalSize += (strlen(pa->name) + 3) & ~3;
+ totalSize += pa->nFormats * sz_xvFormat;
+ pa++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _WriteQueryAdaptorsReply(client, &rep);
+
+ na = pxvs->nAdaptors;
+ pa = pxvs->pAdaptors;
+ while (na--)
+ {
+
+ ainfo.base_id = pa->base_id;
+ ainfo.num_ports = pa->nPorts;
+ ainfo.type = pa->type;
+ ainfo.name_size = strlen(pa->name);
+ ainfo.num_formats = pa->nFormats;
+
+ _WriteAdaptorInfo(client, &ainfo);
+
+ WriteToClient(client, ainfo.name_size, pa->name);
+
+ nf = pa->nFormats;
+ pf = pa->pFormats;
+ while (nf--)
+ {
+ format.depth = pf->depth;
+ format.visual = pf->visual;
+ _WriteFormat(client, &format);
+ pf++;
+ }
+
+ pa++;
+
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+ xvEncodingInfo einfo;
+ xvQueryEncodingsReply rep;
+ int totalSize;
+ XvPortPtr pPort;
+ int ne;
+ XvEncodingPtr pe;
+ int status;
+
+ REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+ /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+ ne = pPort->pAdaptor->nEncodings;
+ pe = pPort->pAdaptor->pEncodings;
+ totalSize = ne * sz_xvEncodingInfo;
+ while (ne--)
+ {
+ totalSize += (strlen(pe->name) + 3) & ~3;
+ pe++;
+ }
+
+ rep.length = totalSize >> 2;
+
+ _WriteQueryEncodingsReply(client, &rep);
+
+ ne = pPort->pAdaptor->nEncodings;
+ pe = pPort->pAdaptor->pEncodings;
+ while (ne--)
+ {
+ einfo.encoding = pe->id;
+ einfo.name_size = strlen(pe->name);
+ einfo.width = pe->width;
+ einfo.height = pe->height;
+ einfo.rate.numerator = pe->rate.numerator;
+ einfo.rate.denominator = pe->rate.denominator;
+ _WriteEncodingInfo(client, &einfo);
+ WriteToClient(client, einfo.name_size, pe->name);
+ pe++;
+ }
+
+ return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvInputMask) ||
+ !(pPort->pAdaptor->type & XvVideoMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+ stuff->vid_x, stuff->vid_y,
+ stuff->vid_w, stuff->vid_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvInputMask) ||
+ !(pPort->pAdaptor->type & XvStillMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+ stuff->vid_x, stuff->vid_y,
+ stuff->vid_w, stuff->vid_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvOutputMask) ||
+ !(pPort->pAdaptor->type & XvVideoMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+ stuff->vid_x, stuff->vid_y,
+ stuff->vid_w, stuff->vid_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ register GCPtr pGC;
+ int status;
+
+ REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvOutputMask) ||
+ !(pPort->pAdaptor->type & XvStillMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+ stuff->vid_x, stuff->vid_y,
+ stuff->vid_w, stuff->vid_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+ if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadWindow);
+ }
+
+ return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+ int result, status;
+ XvPortPtr pPort;
+ xvGrabPortReply rep;
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+ if (status != Success)
+ {
+ return status;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.result = result;
+
+ _WriteGrabPortReply(client, &rep);
+
+ return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+ int status;
+ register DrawablePtr pDraw;
+ XvPortPtr pPort;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+ {
+ client->errorValue = stuff->drawable;
+ return (BadDrawable);
+ }
+
+ return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+ int status;
+ XvPortPtr pPort;
+ REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diSetPortAttribute)(client, pPort,
+ stuff->attribute, stuff->value);
+
+ if (status == BadMatch)
+ client->errorValue = stuff->attribute;
+ else
+ client->errorValue = stuff->value;
+
+ return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+ INT32 value;
+ int status;
+ XvPortPtr pPort;
+ xvGetPortAttributeReply rep;
+ REQUEST(xvGetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!ValidAtom(stuff->attribute))
+ {
+ client->errorValue = stuff->attribute;
+ return(BadAtom);
+ }
+
+ status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+ if (status != Success)
+ {
+ client->errorValue = stuff->attribute;
+ return status;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.value = value;
+
+ _WriteGetPortAttributeReply(client, &rep);
+
+ return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+ int status;
+ unsigned int actual_width, actual_height;
+ XvPortPtr pPort;
+ xvQueryBestSizeReply rep;
+ REQUEST(xvQueryBestSizeReq);
+ REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+
+ (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+ stuff->vid_w, stuff->vid_h,
+ stuff->drw_w, stuff->drw_h,
+ &actual_width, &actual_height);
+
+ rep.actual_width = actual_width;
+ rep.actual_height = actual_height;
+
+ _WriteQueryBestSizeReply(client, &rep);
+
+ return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+ int status, size, i;
+ XvPortPtr pPort;
+ XvAttributePtr pAtt;
+ xvQueryPortAttributesReply rep;
+ xvAttributeInfo Info;
+ REQUEST(xvQueryPortAttributesReq);
+ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_attributes = pPort->pAdaptor->nAttributes;
+ rep.text_size = 0;
+
+ for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
+ i < rep.num_attributes; i++, pAtt++)
+ {
+ rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+ }
+
+ rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+ rep.length >>= 2;
+
+ _WriteQueryPortAttributesReply(client, &rep);
+
+ for(i = 0, pAtt = pPort->pAdaptor->pAttributes;
+ i < rep.num_attributes; i++, pAtt++)
+ {
+ size = strlen(pAtt->name) + 1; /* pass the NULL */
+ Info.flags = pAtt->flags;
+ Info.min = pAtt->min_value;
+ Info.max = pAtt->max_value;
+ Info.size = (size + 3) & ~3L;
+
+ _WriteAttributeInfo(client, &Info);
+
+ WriteToClient(client, size, pAtt->name);
+ }
+
+ return Success;
+}
+
+
+
+static int
+ProcXvPutImage(ClientPtr client)
+{
+ DrawablePtr pDraw;
+ XvPortPtr pPort;
+ XvImagePtr pImage = NULL;
+ GCPtr pGC;
+ int status, i, size;
+ CARD16 width, height;
+
+ REQUEST(xvPutImageReq);
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvImageMask) ||
+ !(pPort->pAdaptor->type & XvInputMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+ if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+ pImage = &(pPort->pAdaptor->pImages[i]);
+ break;
+ }
+ }
+
+ if(!pImage)
+ return BadMatch;
+
+ width = stuff->width;
+ height = stuff->height;
+ size = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
+ pPort, pImage, &width, &height, NULL, NULL);
+ size += sizeof(xvPutImageReq);
+ size = (size + 3) >> 2;
+
+ if((width < stuff->width) || (height < stuff->height))
+ return BadValue;
+
+ if(client->req_len < size)
+ return BadLength;
+
+ return XVCALL(diPutImage)(client, pDraw, pPort, pGC,
+ stuff->src_x, stuff->src_y,
+ stuff->src_w, stuff->src_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h,
+ pImage, (unsigned char*)(&stuff[1]), FALSE,
+ stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int
+ProcXvShmPutImage(ClientPtr client)
+{
+ ShmDescPtr shmdesc;
+ DrawablePtr pDraw;
+ XvPortPtr pPort;
+ XvImagePtr pImage = NULL;
+ GCPtr pGC;
+ int status, size_needed, i;
+ CARD16 width, height;
+
+ REQUEST(xvShmPutImageReq);
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+ {
+ client->errorValue = stuff->port;
+ return (status);
+ }
+
+ if (!(pPort->pAdaptor->type & XvImageMask) ||
+ !(pPort->pAdaptor->type & XvInputMask))
+ {
+ client->errorValue = stuff->port;
+ return (BadMatch);
+ }
+
+ status = XVCALL(diMatchPort)(pPort, pDraw);
+ if (status != Success)
+ {
+ return status;
+ }
+
+ for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+ if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+ pImage = &(pPort->pAdaptor->pImages[i]);
+ break;
+ }
+ }
+
+ if(!pImage)
+ return BadMatch;
+
+ if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType)))
+ {
+ client->errorValue = stuff->shmseg;
+ return BadShmSegCode;
+ }
+
+ width = stuff->width;
+ height = stuff->height;
+ size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client,
+ pPort, pImage, &width, &height, NULL, NULL);
+ if((size_needed + stuff->offset) > shmdesc->size)
+ return BadAccess;
+
+ if((width < stuff->width) || (height < stuff->height))
+ return BadValue;
+
+ status = XVCALL(diPutImage)(client, pDraw, pPort, pGC,
+ stuff->src_x, stuff->src_y,
+ stuff->src_w, stuff->src_h,
+ stuff->drw_x, stuff->drw_y,
+ stuff->drw_w, stuff->drw_h, pImage,
+ (unsigned char *)shmdesc->addr + stuff->offset,
+ stuff->send_event, stuff->width, stuff->height);
+
+ if((status == Success) && stuff->send_event) {
+ xShmCompletionEvent ev;
+
+ ev.type = ShmCompletionCode;
+ ev.drawable = stuff->drawable;
+ ev.minorEvent = xv_ShmPutImage;
+ ev.majorEvent = XvReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return status;
+}
+#endif
+
+#ifdef XvMCExtension
+#include "xvmcext.h"
+#endif
+
+static int
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+ xvQueryImageAttributesReply rep;
+ int size, num_planes, i;
+ CARD16 width, height;
+ XvImagePtr pImage = NULL;
+ XvPortPtr pPort;
+ int *offsets;
+ int *pitches;
+ REQUEST(xvQueryImageAttributesReq);
+
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+ if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+ pImage = &(pPort->pAdaptor->pImages[i]);
+ break;
+ }
+ }
+
+#ifdef XvMCExtension
+ if(!pImage)
+ pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+ if(!pImage)
+ return BadMatch;
+
+ num_planes = pImage->num_planes;
+
+ if(!(offsets = malloc(num_planes << 3)))
+ return BadAlloc;
+ pitches = offsets + num_planes;
+
+ width = stuff->width;
+ height = stuff->height;
+
+ size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+ &width, &height, offsets, pitches);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = num_planes << 1;
+ rep.num_planes = num_planes;
+ rep.width = width;
+ rep.height = height;
+ rep.data_size = size;
+
+ _WriteQueryImageAttributesReply(client, &rep);
+ if(client->swapped)
+ SwapLongs((CARD32*)offsets, rep.length);
+ WriteToClient(client, rep.length << 2, offsets);
+
+ free(offsets);
+
+ return Success;
+}
+
+static int
+ProcXvListImageFormats(ClientPtr client)
+{
+ XvPortPtr pPort;
+ XvImagePtr pImage;
+ int i;
+ xvListImageFormatsReply rep;
+ xvImageFormatInfo info;
+ REQUEST(xvListImageFormatsReq);
+
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+ {
+ client->errorValue = stuff->port;
+ return (_XvBadPort);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num_formats = pPort->pAdaptor->nImages;
+ rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+ _WriteListImageFormatsReply(client, &rep);
+
+ pImage = pPort->pAdaptor->pImages;
+
+ for(i = 0; i < rep.num_formats; i++, pImage++) {
+ info.id = pImage->id;
+ info.type = pImage->type;
+ info.byte_order = pImage->byte_order;
+ memcpy(&info.guid, pImage->guid, 16);
+ info.bpp = pImage->bits_per_pixel;
+ info.num_planes = pImage->num_planes;
+ info.depth = pImage->depth;
+ info.red_mask = pImage->red_mask;
+ info.green_mask = pImage->green_mask;
+ info.blue_mask = pImage->blue_mask;
+ info.format = pImage->format;
+ info.y_sample_bits = pImage->y_sample_bits;
+ info.u_sample_bits = pImage->u_sample_bits;
+ info.v_sample_bits = pImage->v_sample_bits;
+ info.horz_y_period = pImage->horz_y_period;
+ info.horz_u_period = pImage->horz_u_period;
+ info.horz_v_period = pImage->horz_v_period;
+ info.vert_y_period = pImage->vert_y_period;
+ info.vert_u_period = pImage->vert_u_period;
+ info.vert_v_period = pImage->vert_v_period;
+ memcpy(&info.comp_order, pImage->component_order, 32);
+ info.scanline_order = pImage->scanline_order;
+ _WriteImageFormatInfo(client, &info);
+ }
+
+ return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+ REQUEST(xvQueryExtensionReq);
+ REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+ swaps(&stuff->length);
+ return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+ REQUEST(xvQueryAdaptorsReq);
+ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+ REQUEST(xvQueryEncodingsReq);
+ REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+ REQUEST(xvGrabPortReq);
+ REQUEST_SIZE_MATCH(xvGrabPortReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->time);
+ return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+ REQUEST(xvUngrabPortReq);
+ REQUEST_SIZE_MATCH(xvUngrabPortReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->time);
+ return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+ REQUEST(xvPutVideoReq);
+ REQUEST_SIZE_MATCH(xvPutVideoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->vid_x);
+ swaps(&stuff->vid_y);
+ swaps(&stuff->vid_w);
+ swaps(&stuff->vid_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+ REQUEST(xvPutStillReq);
+ REQUEST_SIZE_MATCH(xvPutStillReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->vid_x);
+ swaps(&stuff->vid_y);
+ swaps(&stuff->vid_w);
+ swaps(&stuff->vid_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+ REQUEST(xvGetVideoReq);
+ REQUEST_SIZE_MATCH(xvGetVideoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->vid_x);
+ swaps(&stuff->vid_y);
+ swaps(&stuff->vid_w);
+ swaps(&stuff->vid_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+ REQUEST(xvGetStillReq);
+ REQUEST_SIZE_MATCH(xvGetStillReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->vid_x);
+ swaps(&stuff->vid_y);
+ swaps(&stuff->vid_w);
+ swaps(&stuff->vid_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swapl(&stuff->id);
+ swaps(&stuff->src_x);
+ swaps(&stuff->src_y);
+ swaps(&stuff->src_w);
+ swaps(&stuff->src_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+ REQUEST(xvShmPutImageReq);
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swapl(&stuff->shmseg);
+ swapl(&stuff->id);
+ swapl(&stuff->offset);
+ swaps(&stuff->src_x);
+ swaps(&stuff->src_y);
+ swaps(&stuff->src_w);
+ swaps(&stuff->src_h);
+ swaps(&stuff->drw_x);
+ swaps(&stuff->drw_y);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+ REQUEST(xvSelectVideoNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+ REQUEST(xvSelectPortNotifyReq);
+ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->drawable);
+ return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+ REQUEST(xvSetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->attribute);
+ swapl(&stuff->value);
+ return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+ REQUEST(xvGetPortAttributeReq);
+ REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->attribute);
+ return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+ REQUEST(xvQueryBestSizeReq);
+ REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swaps(&stuff->vid_w);
+ swaps(&stuff->vid_h);
+ swaps(&stuff->drw_w);
+ swaps(&stuff->drw_h);
+ return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+ REQUEST(xvQueryPortAttributesReq);
+ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+ REQUEST(xvQueryImageAttributesReq);
+ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ swapl(&stuff->id);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+ REQUEST(xvListImageFormatsReq);
+ REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->port);
+ return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+ ClientPtr client,
+ xvQueryExtensionReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->version);
+ swaps(&rep->revision);
+
+ WriteToClient(client, sz_xvQueryExtensionReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+ ClientPtr client,
+ xvQueryAdaptorsReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->num_adaptors);
+
+ WriteToClient(client, sz_xvQueryAdaptorsReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+ ClientPtr client,
+ xvQueryEncodingsReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->num_encodings);
+
+ WriteToClient(client, sz_xvQueryEncodingsReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+ ClientPtr client,
+ xvAdaptorInfo *pAdaptor
+){
+ swapl(&pAdaptor->base_id);
+ swaps(&pAdaptor->name_size);
+ swaps(&pAdaptor->num_ports);
+ swaps(&pAdaptor->num_formats);
+
+ WriteToClient(client, sz_xvAdaptorInfo, pAdaptor);
+
+ return Success;
+}
+
+static int
+SWriteEncodingInfo(
+ ClientPtr client,
+ xvEncodingInfo *pEncoding
+){
+ swapl(&pEncoding->encoding);
+ swaps(&pEncoding->name_size);
+ swaps(&pEncoding->width);
+ swaps(&pEncoding->height);
+ swapl(&pEncoding->rate.numerator);
+ swapl(&pEncoding->rate.denominator);
+ WriteToClient(client, sz_xvEncodingInfo, pEncoding);
+
+ return Success;
+}
+
+static int
+SWriteFormat(
+ ClientPtr client,
+ xvFormat *pFormat
+){
+ swapl(&pFormat->visual);
+ WriteToClient(client, sz_xvFormat, pFormat);
+
+ return Success;
+}
+
+static int
+SWriteAttributeInfo(
+ ClientPtr client,
+ xvAttributeInfo *pAtt
+){
+ swapl(&pAtt->flags);
+ swapl(&pAtt->size);
+ swapl(&pAtt->min);
+ swapl(&pAtt->max);
+ WriteToClient(client, sz_xvAttributeInfo, pAtt);
+
+ return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+ ClientPtr client,
+ xvImageFormatInfo *pImage
+){
+ swapl(&pImage->id);
+ swapl(&pImage->red_mask);
+ swapl(&pImage->green_mask);
+ swapl(&pImage->blue_mask);
+ swapl(&pImage->y_sample_bits);
+ swapl(&pImage->u_sample_bits);
+ swapl(&pImage->v_sample_bits);
+ swapl(&pImage->horz_y_period);
+ swapl(&pImage->horz_u_period);
+ swapl(&pImage->horz_v_period);
+ swapl(&pImage->vert_y_period);
+ swapl(&pImage->vert_u_period);
+ swapl(&pImage->vert_v_period);
+
+ WriteToClient(client, sz_xvImageFormatInfo, pImage);
+
+ return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+ ClientPtr client,
+ xvGrabPortReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+
+ WriteToClient(client, sz_xvGrabPortReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+ ClientPtr client,
+ xvGetPortAttributeReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->value);
+
+ WriteToClient(client, sz_xvGetPortAttributeReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+ ClientPtr client,
+ xvQueryBestSizeReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->actual_width);
+ swaps(&rep->actual_height);
+
+ WriteToClient(client, sz_xvQueryBestSizeReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+ ClientPtr client,
+ xvQueryPortAttributesReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->num_attributes);
+ swapl(&rep->text_size);
+
+ WriteToClient(client, sz_xvQueryPortAttributesReply, &rep);
+
+ return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+ ClientPtr client,
+ xvQueryImageAttributesReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->num_planes);
+ swapl(&rep->data_size);
+ swaps(&rep->width);
+ swaps(&rep->height);
+
+ WriteToClient(client, sz_xvQueryImageAttributesReply, &rep);
+
+ return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+ ClientPtr client,
+ xvListImageFormatsReply *rep
+){
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->num_formats);
+
+ WriteToClient(client, sz_xvListImageFormatsReply, &rep);
+
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+ int result = Success, i;
+ PanoramiXRes *draw, *port;
+ REQUEST(xvStopVideoReq);
+ REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->drawable = draw->info[i].id;
+ stuff->port = port->info[i].id;
+ result = ProcXvStopVideo(client);
+ }
+ }
+
+ return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+ REQUEST(xvSetPortAttributeReq);
+ PanoramiXRes *port;
+ int result = Success, i;
+
+ REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->port = port->info[i].id;
+ result = ProcXvSetPortAttribute(client);
+ }
+ }
+ return result;
+}
+
+
+#ifdef MITSHM
+static int
+XineramaXvShmPutImage(ClientPtr client)
+{
+ REQUEST(xvShmPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool send_event = stuff->send_event;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ x = stuff->drw_x;
+ y = stuff->drw_y;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->drawable = draw->info[i].id;
+ stuff->port = port->info[i].id;
+ stuff->gc = gc->info[i].id;
+ stuff->drw_x = x;
+ stuff->drw_y = y;
+ if(isRoot) {
+ stuff->drw_x -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+ stuff->send_event = (send_event && !i) ? 1 : 0;
+
+ result = ProcXvShmPutImage(client);
+ }
+ }
+ return result;
+}
+#endif
+
+static int
+XineramaXvPutImage(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ x = stuff->drw_x;
+ y = stuff->drw_y;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->drawable = draw->info[i].id;
+ stuff->port = port->info[i].id;
+ stuff->gc = gc->info[i].id;
+ stuff->drw_x = x;
+ stuff->drw_y = y;
+ if(isRoot) {
+ stuff->drw_x -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutImage(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ x = stuff->drw_x;
+ y = stuff->drw_y;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->drawable = draw->info[i].id;
+ stuff->port = port->info[i].id;
+ stuff->gc = gc->info[i].id;
+ stuff->drw_x = x;
+ stuff->drw_y = y;
+ if(isRoot) {
+ stuff->drw_x -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutVideo(client);
+ }
+ }
+ return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+ REQUEST(xvPutImageReq);
+ PanoramiXRes *draw, *gc, *port;
+ Bool isRoot;
+ int result = Success, i, x, y;
+
+ REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+ if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+
+ if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->gc, XRT_GC, DixReadAccess)))
+ return BadGC;
+
+ if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+ client, stuff->port, XvXRTPort, DixReadAccess)))
+ return _XvBadPort;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ x = stuff->drw_x;
+ y = stuff->drw_y;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if(port->info[i].id) {
+ stuff->drawable = draw->info[i].id;
+ stuff->port = port->info[i].id;
+ stuff->gc = gc->info[i].id;
+ stuff->drw_x = x;
+ stuff->drw_y = y;
+ if(isRoot) {
+ stuff->drw_x -= panoramiXdataPtr[i].x;
+ stuff->drw_y -= panoramiXdataPtr[i].y;
+ }
+
+ result = ProcXvPutStill(client);
+ }
+ }
+ return result;
+}
+
+
+void XineramifyXv(void)
+{
+ ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+ XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+ XvAdaptorPtr refAdapt, pAdapt;
+ XvAttributePtr pAttr;
+ XvScreenPtr xvsp;
+ Bool isOverlay, hasOverlay;
+ PanoramiXRes *port;
+ XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+ int i, j, k, l;
+
+ XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+ if(!xvsp0) return;
+
+ for(i = 0; i < xvsp0->nAdaptors; i++) {
+ refAdapt = xvsp0->pAdaptors + i;
+
+ bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+
+ MatchingAdaptors[0] = refAdapt;
+
+ if(!(refAdapt->type & XvInputMask)) continue;
+
+ isOverlay = FALSE;
+ for(j = 0; j < refAdapt->nAttributes; j++) {
+ pAttr = refAdapt->pAttributes + j;
+ if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+ isOverlay = TRUE;
+ break;
+ }
+ }
+
+ for(j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen = screenInfo.screens[j];
+ xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* Do not try to go on if xv is not supported on this screen */
+ if (xvsp==NULL) continue ;
+
+ /* if the adaptor has the same name it's a perfect match */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if(!strcmp(refAdapt->name, pAdapt->name)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* otherwise we only look for XvImage adaptors */
+ if(!(refAdapt->type & XvImageMask)) continue;
+ if(refAdapt->nImages <= 0) continue;
+
+ /* prefer overlay/overlay non-overlay/non-overlay pairing */
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ hasOverlay = FALSE;
+ for(l = 0; l < pAdapt->nAttributes; l++) {
+ if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+ hasOverlay = TRUE;
+ break;
+ }
+ }
+ if(isOverlay && hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ else if(!isOverlay && !hasOverlay) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ if(MatchingAdaptors[j]) continue; /* found it */
+
+ /* but we'll take any XvImage pairing if we can get it */
+
+ for(k = 0; k < xvsp->nAdaptors; k++) {
+ pAdapt = xvsp->pAdaptors + k;
+ if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+ MatchingAdaptors[j] = pAdapt;
+ break;
+ }
+ }
+ }
+
+ /* now create a resource for each port */
+ for(j = 0; j < refAdapt->nPorts; j++) {
+ if(!(port = malloc(sizeof(PanoramiXRes))))
+ break;
+ port->info[0].id = MatchingAdaptors[0]->base_id + j;
+ AddResource(port->info[0].id, XvXRTPort, port);
+
+ for(k = 1; k < PanoramiXNumScreens; k++) {
+ if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j))
+ port->info[k].id = MatchingAdaptors[k]->base_id + j;
+ else
+ port->info[k].id = 0;
+ }
+ }
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/Xext/xvdisp.h b/nx-X11/programs/Xserver/Xext/xvdisp.h
new file mode 100644
index 000000000..75cacddcc
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvdisp.h
@@ -0,0 +1 @@
+extern void XineramifyXv(void);
diff --git a/nx-X11/programs/Xserver/Xext/xvdix.h b/nx-X11/programs/Xserver/Xext/xvdix.h
new file mode 100644
index 000000000..973c39b76
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvdix.h
@@ -0,0 +1,290 @@
+/***********************************************************
+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.
+
+******************************************************************/
+
+#ifndef XVDIX_H
+#define XVDIX_H
+/*
+** File:
+**
+** xvdix.h --- Xv device independent header file
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 29.08.91 Carver
+** - removed UnrealizeWindow wrapper unrealizing windows no longer
+** preempts video
+**
+** 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 "scrnintstr.h"
+#include <nx-X11/extensions/Xvproto.h>
+
+extern int XvScreenIndex;
+extern unsigned long XvExtensionGeneration;
+extern unsigned long XvScreenGeneration;
+extern unsigned long XvResourceGeneration;
+
+extern int XvReqCode;
+extern int XvEventBase;
+extern int XvErrorBase;
+
+extern unsigned long XvRTPort;
+extern unsigned long XvRTEncoding;
+extern unsigned long XvRTGrab;
+extern unsigned long XvRTVideoNotify;
+extern unsigned long XvRTVideoNotifyList;
+extern unsigned long XvRTPortNotify;
+
+typedef struct {
+ int numerator;
+ int denominator;
+} XvRationalRec, *XvRationalPtr;
+
+typedef struct {
+ char depth;
+ unsigned long visual;
+} XvFormatRec, *XvFormatPtr;
+
+typedef struct {
+ unsigned long id;
+ ClientPtr client;
+} XvGrabRec, *XvGrabPtr;
+
+typedef struct _XvVideoNotifyRec {
+ struct _XvVideoNotifyRec *next;
+ ClientPtr client;
+ unsigned long id;
+ unsigned long mask;
+} XvVideoNotifyRec, *XvVideoNotifyPtr;
+
+typedef struct _XvPortNotifyRec {
+ struct _XvPortNotifyRec *next;
+ ClientPtr client;
+ unsigned long id;
+} XvPortNotifyRec, *XvPortNotifyPtr;
+
+typedef struct {
+ int id;
+ ScreenPtr pScreen;
+ char *name;
+ unsigned short width, height;
+ XvRationalRec rate;
+} XvEncodingRec, *XvEncodingPtr;
+
+typedef struct _XvAttributeRec {
+ int flags;
+ int min_value;
+ int max_value;
+ char *name;
+} XvAttributeRec, *XvAttributePtr;
+
+typedef struct {
+ int id;
+ int type;
+ int byte_order;
+ char guid[16];
+ int bits_per_pixel;
+ int format;
+ 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];
+ int scanline_order;
+} XvImageRec, *XvImagePtr;
+
+typedef struct {
+ unsigned long base_id;
+ unsigned char type;
+ char *name;
+ int nEncodings;
+ XvEncodingPtr pEncodings;
+ int nFormats;
+ XvFormatPtr pFormats;
+ int nAttributes;
+ XvAttributePtr pAttributes;
+ int nImages;
+ XvImagePtr pImages;
+ int nPorts;
+ struct _XvPortRec *pPorts;
+ ScreenPtr pScreen;
+ int (* ddAllocatePort)(unsigned long, struct _XvPortRec*,
+ struct _XvPortRec**);
+ int (* ddFreePort)(struct _XvPortRec*);
+ int (* ddPutVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+ int (* ddPutStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+ int (* ddGetVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+ int (* ddGetStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+ int (* ddStopVideo)(ClientPtr, struct _XvPortRec*, DrawablePtr);
+ int (* ddSetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32);
+ int (* ddGetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32*);
+ int (* ddQueryBestSize)(ClientPtr, struct _XvPortRec*, CARD8,
+ CARD16, CARD16,CARD16, CARD16,
+ unsigned int*, unsigned int*);
+ int (* ddPutImage)(ClientPtr, DrawablePtr, struct _XvPortRec*, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+ int (* ddQueryImageAttributes)(ClientPtr, struct _XvPortRec*, XvImagePtr,
+ CARD16*, CARD16*, int*, int*);
+ DevUnion devPriv;
+} XvAdaptorRec, *XvAdaptorPtr;
+
+typedef struct _XvPortRec {
+ unsigned long id;
+ XvAdaptorPtr pAdaptor;
+ XvPortNotifyPtr pNotify;
+ DrawablePtr pDraw;
+ ClientPtr client;
+ XvGrabRec grab;
+ TimeStamp time;
+ DevUnion devPriv;
+} XvPortRec, *XvPortPtr;
+
+#define LOOKUP_PORT(_id, client)\
+ ((XvPortPtr)LookupIDByType(_id, XvRTPort))
+
+#define LOOKUP_ENCODING(_id, client)\
+ ((XvEncodingPtr)LookupIDByType(_id, XvRTEncoding))
+
+#define LOOKUP_VIDEONOTIFY_LIST(_id, client)\
+ ((XvVideoNotifyPtr)LookupIDByType(_id, XvRTVideoNotifyList))
+
+#define LOOKUP_PORTNOTIFY_LIST(_id, client)\
+ ((XvPortNotifyPtr)LookupIDByType(_id, XvRTPortNotifyList))
+
+typedef struct {
+ int version, revision;
+ int nAdaptors;
+ XvAdaptorPtr pAdaptors;
+ DestroyWindowProcPtr DestroyWindow;
+ DestroyPixmapProcPtr DestroyPixmap;
+ CloseScreenProcPtr CloseScreen;
+ Bool (* ddCloseScreen)(ScreenPtr);
+ int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*);
+ DevUnion devPriv;
+} XvScreenRec, *XvScreenPtr;
+
+#define SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((XvScreenPtr) \
+ (pScreen)->devPrivates[XvScreenIndex].ptr)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+/* Errors */
+
+#define _XvBadPort (XvBadPort+XvErrorBase)
+#define _XvBadEncoding (XvBadEncoding+XvErrorBase)
+
+extern int ProcXvDispatch(ClientPtr);
+extern int SProcXvDispatch(ClientPtr);
+
+extern void XvExtensionInit(void);
+extern int XvScreenInit(ScreenPtr);
+extern int XvGetScreenIndex(void);
+extern unsigned long XvGetRTPort(void);
+extern int XvdiSendPortNotify(XvPortPtr, Atom, INT32);
+extern int XvdiVideoStopped(XvPortPtr, int);
+
+extern int XvdiPutVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+extern int XvdiPutStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+extern int XvdiGetVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+extern int XvdiGetStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+extern int XvdiPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+extern int XvdiSelectVideoNotify(ClientPtr, DrawablePtr, BOOL);
+extern int XvdiSelectPortNotify(ClientPtr, XvPortPtr, BOOL);
+extern int XvdiSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
+extern int XvdiGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
+extern int XvdiStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
+extern int XvdiPreemptVideo(ClientPtr, XvPortPtr, DrawablePtr);
+extern int XvdiMatchPort(XvPortPtr, DrawablePtr);
+extern int XvdiGrabPort(ClientPtr, XvPortPtr, Time, int *);
+extern int XvdiUngrabPort( ClientPtr, XvPortPtr, Time);
+
+
+#if !defined(UNIXCPP)
+
+#define XVCALL(name) Xv##name
+
+#else
+
+#define XVCALL(name) Xv/**/name
+
+#endif
+
+
+#endif /* XVDIX_H */
+
diff --git a/nx-X11/programs/Xserver/Xext/xvmain.c b/nx-X11/programs/Xserver/Xext/xvmain.c
new file mode 100644
index 000000000..397f8dc81
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvmain.c
@@ -0,0 +1,1198 @@
+/***********************************************************
+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.
+
+******************************************************************/
+
+/*
+** File:
+**
+** xvmain.c --- Xv server extension main device independent module.
+**
+** Author:
+**
+** David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+** 04.09.91 Carver
+** - change: stop video always generates an event even when video
+** wasn't active
+**
+** 29.08.91 Carver
+** - change: unrealizing windows no longer preempts video
+**
+** 11.06.91 Carver
+** - changed SetPortControl to SetPortAttribute
+** - changed GetPortControl to GetPortAttribute
+** - changed QueryBestSize
+**
+** 28.05.91 Carver
+** - fixed Put and Get requests to not preempt operations to same drawable
+**
+** 15.05.91 Carver
+** - version 2.0 upgrade
+**
+** 19.03.91 Carver
+** - fixed Put and Get requests to honor grabbed ports.
+** - fixed Video requests to update di structure with new drawable, and
+** client after calling ddx.
+**
+** 24.01.91 Carver
+** - version 1.4 upgrade
+**
+** Notes:
+**
+** Port structures reference client structures in a two different
+** ways: when grabs, or video is active. Each reference is encoded
+** as fake client resources and thus when the client is goes away so
+** does the reference (it is zeroed). No other action is taken, so
+** video doesn't necessarily stop. It probably will as a result of
+** other resources going away, but if a client starts video using
+** none of its own resources, then the video will continue to play
+** after the client disappears.
+**
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gc.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include "input.h"
+
+#define GLOBAL
+
+#include <nx-X11/extensions/Xv.h>
+#include <nx-X11/extensions/Xvproto.h>
+#include "xvdix.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#include "xvdisp.h"
+#endif
+
+int XvScreenIndex = -1;
+unsigned long XvExtensionGeneration = 0;
+unsigned long XvScreenGeneration = 0;
+unsigned long XvResourceGeneration = 0;
+
+int XvReqCode;
+int XvEventBase;
+int XvErrorBase;
+
+unsigned long XvRTPort;
+unsigned long XvRTEncoding;
+unsigned long XvRTGrab;
+unsigned long XvRTVideoNotify;
+unsigned long XvRTVideoNotifyList;
+unsigned long XvRTPortNotify;
+
+
+
+/* EXTERNAL */
+
+extern XID clientErrorValue;
+
+static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *);
+static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *);
+static Bool CreateResourceTypes(void);
+
+static Bool XvCloseScreen(ScreenPtr);
+static Bool XvDestroyPixmap(PixmapPtr);
+static Bool XvDestroyWindow(WindowPtr);
+static void XvResetProc(ExtensionEntry*);
+static int XvdiDestroyGrab(void *, XID);
+static int XvdiDestroyEncoding(void *, XID);
+static int XvdiDestroyVideoNotify(void *, XID);
+static int XvdiDestroyPortNotify(void *, XID);
+static int XvdiDestroyVideoNotifyList(void *, XID);
+static int XvdiDestroyPort(void *, XID);
+static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int);
+
+
+
+
+/*
+** XvExtensionInit
+**
+**
+*/
+
+void
+XvExtensionInit()
+{
+ ExtensionEntry *extEntry;
+
+ /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN
+ INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */
+ if (XvScreenGeneration != serverGeneration)
+ {
+ if (!CreateResourceTypes())
+ {
+ ErrorF("XvExtensionInit: Unable to allocate resource types\n");
+ return;
+ }
+ XvScreenIndex = AllocateScreenPrivateIndex ();
+ if (XvScreenIndex < 0)
+ {
+ ErrorF("XvExtensionInit: Unable to allocate screen private index\n");
+ return;
+ }
+#ifdef PANORAMIX
+ XineramaRegisterConnectionBlockCallback(XineramifyXv);
+#endif
+ XvScreenGeneration = serverGeneration;
+ }
+
+ if (XvExtensionGeneration != serverGeneration)
+ {
+ XvExtensionGeneration = serverGeneration;
+
+ extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors,
+ ProcXvDispatch, SProcXvDispatch,
+ XvResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ {
+ FatalError("XvExtensionInit: AddExtensions failed\n");
+ }
+
+ XvReqCode = extEntry->base;
+ XvEventBase = extEntry->eventBase;
+ XvErrorBase = extEntry->errorBase;
+
+ EventSwapVector[XvEventBase+XvVideoNotify] =
+ (EventSwapPtr)WriteSwappedVideoNotifyEvent;
+ EventSwapVector[XvEventBase+XvPortNotify] =
+ (EventSwapPtr)WriteSwappedPortNotifyEvent;
+
+ (void)MakeAtom(XvName, strlen(XvName), xTrue);
+
+ }
+}
+
+static Bool
+CreateResourceTypes()
+
+{
+
+ if (XvResourceGeneration == serverGeneration) return TRUE;
+
+ XvResourceGeneration = serverGeneration;
+
+ if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate port resource.\n");
+ return FALSE;
+ }
+
+ if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate grab resource.\n");
+ return FALSE;
+ }
+
+ if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n");
+ return FALSE;
+ }
+
+ if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n");
+ return FALSE;
+ }
+
+ if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n");
+ return FALSE;
+ }
+
+ if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify)))
+ {
+ ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+int
+XvScreenInit(ScreenPtr pScreen)
+{
+ XvScreenPtr pxvs;
+
+ if (XvScreenGeneration != serverGeneration)
+ {
+ if (!CreateResourceTypes())
+ {
+ ErrorF("XvScreenInit: Unable to allocate resource types\n");
+ return BadAlloc;
+ }
+ XvScreenIndex = AllocateScreenPrivateIndex ();
+ if (XvScreenIndex < 0)
+ {
+ ErrorF("XvScreenInit: Unable to allocate screen private index\n");
+ return BadAlloc;
+ }
+#ifdef PANORAMIX
+ XineramaRegisterConnectionBlockCallback(XineramifyXv);
+#endif
+ XvScreenGeneration = serverGeneration;
+ }
+
+ if (pScreen->devPrivates[XvScreenIndex].ptr)
+ {
+ ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n");
+ }
+
+ /* ALLOCATE SCREEN PRIVATE RECORD */
+
+ pxvs = (XvScreenPtr) malloc (sizeof (XvScreenRec));
+ if (!pxvs)
+ {
+ ErrorF("XvScreenInit: Unable to allocate screen private structure\n");
+ return BadAlloc;
+ }
+
+ pScreen->devPrivates[XvScreenIndex].ptr = (void *)pxvs;
+
+
+ pxvs->DestroyPixmap = pScreen->DestroyPixmap;
+ pxvs->DestroyWindow = pScreen->DestroyWindow;
+ pxvs->CloseScreen = pScreen->CloseScreen;
+
+ pScreen->DestroyPixmap = XvDestroyPixmap;
+ pScreen->DestroyWindow = XvDestroyWindow;
+ pScreen->CloseScreen = XvCloseScreen;
+
+ return Success;
+}
+
+static Bool
+XvCloseScreen(
+ ScreenPtr pScreen
+){
+
+ XvScreenPtr pxvs;
+
+ pxvs = (XvScreenPtr) pScreen->devPrivates[XvScreenIndex].ptr;
+
+ pScreen->DestroyPixmap = pxvs->DestroyPixmap;
+ pScreen->DestroyWindow = pxvs->DestroyWindow;
+ pScreen->CloseScreen = pxvs->CloseScreen;
+
+ (* pxvs->ddCloseScreen)(pScreen);
+
+ free(pxvs);
+
+ pScreen->devPrivates[XvScreenIndex].ptr = (void *)NULL;
+
+ return (*pScreen->CloseScreen)(pScreen);
+
+}
+
+static void
+XvResetProc(ExtensionEntry* extEntry)
+{
+}
+
+int
+XvGetScreenIndex()
+{
+ return XvScreenIndex;
+}
+
+unsigned long
+XvGetRTPort()
+{
+ return XvRTPort;
+}
+
+static Bool
+XvDestroyPixmap(PixmapPtr pPix)
+{
+ Bool status;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+ XvAdaptorPtr pa;
+ int na;
+ XvPortPtr pp;
+ int np;
+
+ pScreen = pPix->drawable.pScreen;
+
+ SCREEN_PROLOGUE(pScreen, DestroyPixmap);
+
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* CHECK TO SEE IF THIS PORT IS IN USE */
+
+ pa = pxvs->pAdaptors;
+ na = pxvs->nAdaptors;
+ while (na--)
+ {
+ np = pa->nPorts;
+ pp = pa->pPorts;
+
+ while (np--)
+ {
+ if (pp->pDraw == (DrawablePtr)pPix)
+ {
+ XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
+
+ (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp,
+ pp->pDraw);
+
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ }
+ pp++;
+ }
+ pa++;
+ }
+
+ status = (* pScreen->DestroyPixmap)(pPix);
+
+ SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap);
+
+ return status;
+
+}
+
+static Bool
+XvDestroyWindow(WindowPtr pWin)
+{
+ Bool status;
+ ScreenPtr pScreen;
+ XvScreenPtr pxvs;
+ XvAdaptorPtr pa;
+ int na;
+ XvPortPtr pp;
+ int np;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE(pScreen, DestroyWindow);
+
+ pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+ /* CHECK TO SEE IF THIS PORT IS IN USE */
+
+ pa = pxvs->pAdaptors;
+ na = pxvs->nAdaptors;
+ while (na--)
+ {
+ np = pa->nPorts;
+ pp = pa->pPorts;
+
+ while (np--)
+ {
+ if (pp->pDraw == (DrawablePtr)pWin)
+ {
+ XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted);
+
+ (void)(* pp->pAdaptor->ddStopVideo)((ClientPtr)NULL, pp,
+ pp->pDraw);
+
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ }
+ pp++;
+ }
+ pa++;
+ }
+
+
+ status = (* pScreen->DestroyWindow)(pWin);
+
+ SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow);
+
+ return status;
+
+}
+
+/* The XvdiVideoStopped procedure is a hook for the device dependent layer.
+ It provides a way for the dd layer to inform the di layer that video has
+ stopped in a port for reasons that the di layer had no control over; note
+ that it doesn't call back into the dd layer */
+
+int
+XvdiVideoStopped(XvPortPtr pPort, int reason)
+{
+
+ /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
+
+ if (!pPort->pDraw) return Success;
+
+ XvdiSendVideoNotify(pPort, pPort->pDraw, reason);
+
+ pPort->pDraw = (DrawablePtr)NULL;
+ pPort->client = (ClientPtr)NULL;
+ pPort->time = currentTime;
+
+ return Success;
+
+}
+
+static int
+XvdiDestroyPort(void * pPort, XID id)
+{
+ return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort);
+}
+
+static int
+XvdiDestroyGrab(void * pGrab, XID id)
+{
+ ((XvGrabPtr)pGrab)->client = (ClientPtr)NULL;
+ return Success;
+}
+
+static int
+XvdiDestroyVideoNotify(void * pn, XID id)
+{
+ /* JUST CLEAR OUT THE client POINTER FIELD */
+
+ ((XvVideoNotifyPtr)pn)->client = (ClientPtr)NULL;
+ return Success;
+}
+
+static int
+XvdiDestroyPortNotify(void * pn, XID id)
+{
+ /* JUST CLEAR OUT THE client POINTER FIELD */
+
+ ((XvPortNotifyPtr)pn)->client = (ClientPtr)NULL;
+ return Success;
+}
+
+static int
+XvdiDestroyVideoNotifyList(void * pn, XID id)
+{
+ XvVideoNotifyPtr npn,cpn;
+
+ /* ACTUALLY DESTROY THE NOTITY LIST */
+
+ cpn = (XvVideoNotifyPtr)pn;
+
+ while (cpn)
+ {
+ npn = cpn->next;
+ if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify);
+ free(cpn);
+ cpn = npn;
+ }
+ return Success;
+}
+
+static int
+XvdiDestroyEncoding(void * value, XID id)
+{
+ return Success;
+}
+
+static int
+XvdiSendVideoNotify(pPort, pDraw, reason)
+
+XvPortPtr pPort;
+DrawablePtr pDraw;
+int reason;
+
+{
+ xvEvent event;
+ XvVideoNotifyPtr pn;
+
+ pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
+
+ while (pn)
+ {
+ if (pn->client)
+ {
+ event.u.u.type = XvEventBase + XvVideoNotify;
+ event.u.u.sequenceNumber = pn->client->sequence;
+ event.u.videoNotify.time = currentTime.milliseconds;
+ event.u.videoNotify.drawable = pDraw->id;
+ event.u.videoNotify.port = pPort->id;
+ event.u.videoNotify.reason = reason;
+ (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
+ NoEventMask, NullGrab);
+ }
+ pn = pn->next;
+ }
+
+ return Success;
+
+}
+
+
+int
+XvdiSendPortNotify(
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+ xvEvent event;
+ XvPortNotifyPtr pn;
+
+ pn = pPort->pNotify;
+
+ while (pn)
+ {
+ if (pn->client)
+ {
+ event.u.u.type = XvEventBase + XvPortNotify;
+ event.u.u.sequenceNumber = pn->client->sequence;
+ event.u.portNotify.time = currentTime.milliseconds;
+ event.u.portNotify.port = pPort->id;
+ event.u.portNotify.attribute = attribute;
+ event.u.portNotify.value = value;
+ (void) TryClientEvents(pn->client, (xEventPtr)&event, 1, NoEventMask,
+ NoEventMask, NullGrab);
+ }
+ pn = pn->next;
+ }
+
+ return Success;
+
+}
+
+
+#define CHECK_SIZE(dw, dh, sw, sh) { \
+ if(!dw || !dh || !sw || !sh) return Success; \
+ /* The region code will break these if they are too large */ \
+ if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \
+ return BadValue; \
+}
+
+
+int
+XvdiPutVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ DrawablePtr pOldDraw;
+
+ CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
+
+ /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
+
+ UpdateCurrentTime();
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if (pPort->grab.client && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
+ EVENTS TO ANY CLIENTS WHO WANT THEM */
+
+ pOldDraw = pPort->pDraw;
+ if ((pOldDraw) && (pOldDraw != pDraw))
+ {
+ XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
+ }
+
+ (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC,
+ vid_x, vid_y, vid_w, vid_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+ if ((pPort->pDraw) && (pOldDraw != pDraw))
+ {
+ pPort->client = client;
+ XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
+ }
+
+ pPort->time = currentTime;
+
+ return (Success);
+
+}
+
+int
+XvdiPutStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ int status;
+
+ CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
+
+ /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
+
+ UpdateCurrentTime();
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if (pPort->grab.client && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ pPort->time = currentTime;
+
+ status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC,
+ vid_x, vid_y, vid_w, vid_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+ return status;
+
+}
+
+int
+XvdiPutImage(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 src_x, INT16 src_y,
+ CARD16 src_w, CARD16 src_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h,
+ XvImagePtr image,
+ unsigned char* data,
+ Bool sync,
+ CARD16 width, CARD16 height
+){
+ CHECK_SIZE(drw_w, drw_h, src_w, src_h);
+
+ /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
+
+ UpdateCurrentTime();
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if (pPort->grab.client && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ pPort->time = currentTime;
+
+ return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC,
+ src_x, src_y, src_w, src_h,
+ drw_x, drw_y, drw_w, drw_h,
+ image, data, sync, width, height);
+}
+
+
+int
+XvdiGetVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ DrawablePtr pOldDraw;
+
+ CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
+
+ /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
+
+ UpdateCurrentTime();
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if (pPort->grab.client && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED
+ EVENTS TO ANY CLIENTS WHO WANT THEM */
+
+ pOldDraw = pPort->pDraw;
+ if ((pOldDraw) && (pOldDraw != pDraw))
+ {
+ XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
+ }
+
+ (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC,
+ vid_x, vid_y, vid_w, vid_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+ if ((pPort->pDraw) && (pOldDraw != pDraw))
+ {
+ pPort->client = client;
+ XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted);
+ }
+
+ pPort->time = currentTime;
+
+ return (Success);
+
+}
+
+int
+XvdiGetStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ int status;
+
+ CHECK_SIZE(drw_w, drw_h, vid_w, vid_h);
+
+ /* UPDATE TIME VARIABLES FOR USE IN EVENTS */
+
+ UpdateCurrentTime();
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if (pPort->grab.client && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC,
+ vid_x, vid_y, vid_w, vid_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+ pPort->time = currentTime;
+
+ return status;
+
+}
+
+int
+XvdiGrabPort(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Time ctime,
+ int *p_result
+){
+ unsigned long id;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(ctime);
+
+ if (pPort->grab.client && (client != pPort->grab.client))
+ {
+ *p_result = XvAlreadyGrabbed;
+ return Success;
+ }
+
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, pPort->time) == EARLIER))
+ {
+ *p_result = XvInvalidTime;
+ return Success;
+ }
+
+ if (client == pPort->grab.client)
+ {
+ *p_result = Success;
+ return Success;
+ }
+
+ id = FakeClientID(client->index);
+
+ if (!AddResource(id, XvRTGrab, &pPort->grab))
+ {
+ return BadAlloc;
+ }
+
+ /* IF THERE IS ACTIVE VIDEO THEN STOP IT */
+
+ if ((pPort->pDraw) && (client != pPort->client))
+ {
+ XVCALL(diStopVideo)((ClientPtr)NULL, pPort, pPort->pDraw);
+ }
+
+ pPort->grab.client = client;
+ pPort->grab.id = id;
+
+ pPort->time = currentTime;
+
+ *p_result = Success;
+
+ return Success;
+
+}
+
+int
+XvdiUngrabPort(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Time ctime
+){
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(ctime);
+
+ if ((!pPort->grab.client) || (client != pPort->grab.client))
+ {
+ return Success;
+ }
+
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, pPort->time) == EARLIER))
+ {
+ return Success;
+ }
+
+ /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */
+
+ FreeResource(pPort->grab.id, XvRTGrab);
+ pPort->grab.client = (ClientPtr)NULL;
+
+ pPort->time = currentTime;
+
+ return Success;
+
+}
+
+
+int
+XvdiSelectVideoNotify(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ BOOL onoff
+){
+ XvVideoNotifyPtr pn,tpn,fpn;
+
+ /* FIND VideoNotify LIST */
+
+ pn = (XvVideoNotifyPtr)LookupIDByType(pDraw->id, XvRTVideoNotifyList);
+
+ /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */
+
+ if (!onoff && !pn) return Success;
+
+ /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST
+ WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */
+
+ if (!pn)
+ {
+ if (!(tpn = (XvVideoNotifyPtr)malloc(sizeof(XvVideoNotifyRec))))
+ return BadAlloc;
+ tpn->next = (XvVideoNotifyPtr)NULL;
+ if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn))
+ {
+ free(tpn);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ /* LOOK TO SEE IF ENTRY ALREADY EXISTS */
+
+ fpn = (XvVideoNotifyPtr)NULL;
+ tpn = pn;
+ while (tpn)
+ {
+ if (tpn->client == client)
+ {
+ if (!onoff) tpn->client = (ClientPtr)NULL;
+ return Success;
+ }
+ if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */
+ tpn = tpn->next;
+ }
+
+ /* IF TUNNING OFF, THEN JUST RETURN */
+
+ if (!onoff) return Success;
+
+ /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */
+
+ if (fpn)
+ {
+ tpn = fpn;
+ }
+ else
+ {
+ if (!(tpn = (XvVideoNotifyPtr)malloc(sizeof(XvVideoNotifyRec))))
+ return BadAlloc;
+ tpn->next = pn->next;
+ pn->next = tpn;
+ }
+ }
+
+ /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */
+ /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */
+
+ tpn->client = (ClientPtr)NULL;
+ tpn->id = FakeClientID(client->index);
+ AddResource(tpn->id, XvRTVideoNotify, tpn);
+
+ tpn->client = client;
+ return Success;
+
+}
+
+int
+XvdiSelectPortNotify(
+ ClientPtr client,
+ XvPortPtr pPort,
+ BOOL onoff
+){
+ XvPortNotifyPtr pn,tpn;
+
+ /* SEE IF CLIENT IS ALREADY IN LIST */
+
+ tpn = (XvPortNotifyPtr)NULL;
+ pn = pPort->pNotify;
+ while (pn)
+ {
+ if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */
+ if (pn->client == client) break;
+ pn = pn->next;
+ }
+
+ /* IS THE CLIENT ALREADY ON THE LIST? */
+
+ if (pn)
+ {
+ /* REMOVE IT? */
+
+ if (!onoff)
+ {
+ pn->client = (ClientPtr)NULL;
+ FreeResource(pn->id, XvRTPortNotify);
+ }
+
+ return Success;
+ }
+
+ /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE
+ CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */
+
+ if (!tpn)
+ {
+ if (!(tpn = (XvPortNotifyPtr)malloc(sizeof(XvPortNotifyRec))))
+ return BadAlloc;
+ tpn->next = pPort->pNotify;
+ pPort->pNotify = tpn;
+ }
+
+ tpn->client = client;
+ tpn->id = FakeClientID(client->index);
+ AddResource(tpn->id, XvRTPortNotify, tpn);
+
+ return Success;
+
+}
+
+int
+XvdiStopVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ int status;
+
+ /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
+
+ if (!pPort->pDraw || (pPort->pDraw != pDraw))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvStopped);
+ return Success;
+ }
+
+ /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN
+ INFORM CLIENT OF ITS FAILURE */
+
+ if ((client) && (pPort->grab.client) && (pPort->grab.client != client))
+ {
+ XvdiSendVideoNotify(pPort, pDraw, XvBusy);
+ return Success;
+ }
+
+ XvdiSendVideoNotify(pPort, pDraw, XvStopped);
+
+ status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw);
+
+ pPort->pDraw = (DrawablePtr)NULL;
+ pPort->client = (ClientPtr)client;
+ pPort->time = currentTime;
+
+ return status;
+
+}
+
+int
+XvdiPreemptVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ int status;
+
+ /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */
+
+ if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success;
+
+ XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted);
+
+ status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw);
+
+ pPort->pDraw = (DrawablePtr)NULL;
+ pPort->client = (ClientPtr)client;
+ pPort->time = currentTime;
+
+ return status;
+
+}
+
+int
+XvdiMatchPort(
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+
+ XvAdaptorPtr pa;
+ XvFormatPtr pf;
+ int nf;
+
+ pa = pPort->pAdaptor;
+
+ if (pa->pScreen != pDraw->pScreen) return BadMatch;
+
+ nf = pa->nFormats;
+ pf = pa->pFormats;
+
+ while (nf--)
+ {
+ if ((pf->depth == pDraw->depth)
+#if 0
+ && ((pDraw->type == DRAWABLE_PIXMAP) ||
+ (wVisual(((WindowPtr)pDraw)) == pf->visual))
+#endif
+ )
+ return Success;
+ pf++;
+ }
+
+ return BadMatch;
+
+}
+
+int
+XvdiSetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+
+ XvdiSendPortNotify(pPort, attribute, value);
+
+ return
+ (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value);
+
+}
+
+int
+XvdiGetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 *p_value
+){
+
+ return
+ (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value);
+
+}
+
+static void
+WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to)
+
+{
+
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.videoNotify.sequenceNumber,
+ to->u.videoNotify.sequenceNumber);
+ cpswapl(from->u.videoNotify.time, to->u.videoNotify.time);
+ cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable);
+ cpswapl(from->u.videoNotify.port, to->u.videoNotify.port);
+
+}
+
+static void
+WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to)
+
+{
+
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber);
+ cpswapl(from->u.portNotify.time, to->u.portNotify.time);
+ cpswapl(from->u.portNotify.port, to->u.portNotify.port);
+ cpswapl(from->u.portNotify.value, to->u.portNotify.value);
+
+}
diff --git a/nx-X11/programs/Xserver/Xext/xvmc.c b/nx-X11/programs/Xserver/Xext/xvmc.c
new file mode 100644
index 000000000..fcd170efd
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvmc.c
@@ -0,0 +1,790 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <nx-X11/Xfuncproto.h>
+#include "xvdix.h"
+#include <nx-X11/extensions/XvMC.h>
+#include <nx-X11/extensions/Xvproto.h>
+#include <nx-X11/extensions/XvMCproto.h>
+#include "xvmcext.h"
+
+#ifdef HAS_XVMCSHM
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#endif /* HAS_XVMCSHM */
+
+
+
+#define DR_CLIENT_DRIVER_NAME_SIZE 48
+#define DR_BUSID_SIZE 48
+
+int XvMCScreenIndex = -1;
+
+unsigned long XvMCGeneration = 0;
+
+int XvMCReqCode;
+int XvMCEventBase;
+int XvMCErrorBase;
+
+unsigned long XvMCRTContext;
+unsigned long XvMCRTSurface;
+unsigned long XvMCRTSubpicture;
+
+typedef struct {
+ int num_adaptors;
+ XvMCAdaptorPtr adaptors;
+ CloseScreenProcPtr CloseScreen;
+ char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
+ char busID[DR_BUSID_SIZE];
+ int major;
+ int minor;
+ int patchLevel;
+} XvMCScreenRec, *XvMCScreenPtr;
+
+#define XVMC_GET_PRIVATE(pScreen) \
+ (XvMCScreenPtr)((pScreen)->devPrivates[XvMCScreenIndex].ptr)
+
+
+static int
+XvMCDestroyContextRes(void * data, XID id)
+{
+ XvMCContextPtr pContext = (XvMCContextPtr)data;
+
+ pContext->refcnt--;
+
+ if(!pContext->refcnt) {
+ XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
+ (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext);
+ free(pContext);
+ }
+
+ return Success;
+}
+
+static int
+XvMCDestroySurfaceRes(void * data, XID id)
+{
+ XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data;
+ XvMCContextPtr pContext = pSurface->context;
+ XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
+
+ (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface);
+ free(pSurface);
+
+ XvMCDestroyContextRes((void *)pContext, pContext->context_id);
+
+ return Success;
+}
+
+
+static int
+XvMCDestroySubpictureRes(void * data, XID id)
+{
+ XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data;
+ XvMCContextPtr pContext = pSubpict->context;
+ XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
+
+ (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict);
+ free(pSubpict);
+
+ XvMCDestroyContextRes((void *)pContext, pContext->context_id);
+
+ return Success;
+}
+
+static void
+XvMCResetProc (ExtensionEntry *extEntry)
+{
+}
+
+
+static int
+ProcXvMCQueryVersion(ClientPtr client)
+{
+ xvmcQueryVersionReply rep;
+ /* REQUEST(xvmcQueryVersionReq); */
+ REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.major = XvMCVersion;
+ rep.minor = XvMCRevision;
+ WriteToClient(client, sizeof(xvmcQueryVersionReply), &rep);
+ return Success;
+}
+
+
+static int
+ProcXvMCListSurfaceTypes(ClientPtr client)
+{
+ XvPortPtr pPort;
+ int i;
+ XvMCScreenPtr pScreenPriv;
+ xvmcListSurfaceTypesReply rep;
+ xvmcSurfaceInfo info;
+ XvMCAdaptorPtr adaptor = NULL;
+ XvMCSurfaceInfoPtr surface;
+ REQUEST(xvmcListSurfaceTypesReq);
+ REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
+ client->errorValue = stuff->port;
+ return _XvBadPort;
+ }
+
+ if(XvMCScreenIndex >= 0) { /* any adaptors at all */
+ ScreenPtr pScreen = pPort->pAdaptor->pScreen;
+ if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */
+ for(i = 0; i < pScreenPriv->num_adaptors; i++) {
+ if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
+ adaptor = &(pScreenPriv->adaptors[i]);
+ break;
+ }
+ }
+ }
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num = (adaptor) ? adaptor->num_surfaces : 0;
+ rep.length = rep.num * sizeof(xvmcSurfaceInfo) >> 2;
+
+ WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), &rep);
+
+ for(i = 0; i < rep.num; i++) {
+ surface = adaptor->surfaces[i];
+ info.surface_type_id = surface->surface_type_id;
+ info.chroma_format = surface->chroma_format;
+ info.max_width = surface->max_width;
+ info.max_height = surface->max_height;
+ info.subpicture_max_width = surface->subpicture_max_width;
+ info.subpicture_max_height = surface->subpicture_max_height;
+ info.mc_type = surface->mc_type;
+ info.flags = surface->flags;
+ WriteToClient(client, sizeof(xvmcSurfaceInfo), &info);
+ }
+
+ return Success;
+}
+
+static int
+ProcXvMCCreateContext(ClientPtr client)
+{
+ XvPortPtr pPort;
+ CARD32 *data = NULL;
+ int dwords = 0;
+ int i, result, adapt_num = -1;
+ ScreenPtr pScreen;
+ XvMCContextPtr pContext;
+ XvMCScreenPtr pScreenPriv;
+ XvMCAdaptorPtr adaptor = NULL;
+ XvMCSurfaceInfoPtr surface = NULL;
+ xvmcCreateContextReply rep;
+ REQUEST(xvmcCreateContextReq);
+ REQUEST_SIZE_MATCH(xvmcCreateContextReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
+ client->errorValue = stuff->port;
+ return _XvBadPort;
+ }
+
+ pScreen = pPort->pAdaptor->pScreen;
+
+ if(XvMCScreenIndex < 0) /* no XvMC adaptors */
+ return BadMatch;
+
+ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */
+ return BadMatch;
+
+ for(i = 0; i < pScreenPriv->num_adaptors; i++) {
+ if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
+ adaptor = &(pScreenPriv->adaptors[i]);
+ adapt_num = i;
+ break;
+ }
+ }
+
+ if(adapt_num < 0) /* none this port */
+ return BadMatch;
+
+ for(i = 0; i < adaptor->num_surfaces; i++) {
+ if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
+ surface = adaptor->surfaces[i];
+ break;
+ }
+ }
+
+ /* adaptor doesn't support this suface_type_id */
+ if(!surface) return BadMatch;
+
+
+ if((stuff->width > surface->max_width) ||
+ (stuff->height > surface->max_height))
+ return BadValue;
+
+ if(!(pContext = malloc(sizeof(XvMCContextRec)))) {
+ return BadAlloc;
+ }
+
+
+ pContext->pScreen = pScreen;
+ pContext->adapt_num = adapt_num;
+ pContext->context_id = stuff->context_id;
+ pContext->surface_type_id = stuff->surface_type_id;
+ pContext->width = stuff->width;
+ pContext->height = stuff->height;
+ pContext->flags = stuff->flags;
+ pContext->refcnt = 1;
+
+ result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data);
+
+ if(result != Success) {
+ free(pContext);
+ return result;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.width_actual = pContext->width;
+ rep.height_actual = pContext->height;
+ rep.flags_return = pContext->flags;
+ rep.length = dwords;
+
+ WriteToClient(client, sizeof(xvmcCreateContextReply), &rep);
+ if(dwords)
+ WriteToClient(client, dwords << 2, data);
+ AddResource(pContext->context_id, XvMCRTContext, pContext);
+
+ if(data)
+ free(data);
+
+ return Success;
+}
+
+static int
+ProcXvMCDestroyContext(ClientPtr client)
+{
+ REQUEST(xvmcDestroyContextReq);
+ REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
+
+ if(!LookupIDByType(stuff->context_id, XvMCRTContext))
+ return (XvMCBadContext + XvMCErrorBase);
+
+ FreeResource(stuff->context_id, RT_NONE);
+
+ return Success;
+}
+
+static int
+ProcXvMCCreateSurface(ClientPtr client)
+{
+ CARD32 *data = NULL;
+ int dwords = 0;
+ int result;
+ XvMCContextPtr pContext;
+ XvMCSurfacePtr pSurface;
+ XvMCScreenPtr pScreenPriv;
+ xvmcCreateSurfaceReply rep;
+ REQUEST(xvmcCreateSurfaceReq);
+ REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
+
+ if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext)))
+ return (XvMCBadContext + XvMCErrorBase);
+
+ pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
+
+ if(!(pSurface = malloc(sizeof(XvMCSurfaceRec))))
+ return BadAlloc;
+
+ pSurface->surface_id = stuff->surface_id;
+ pSurface->surface_type_id = pContext->surface_type_id;
+ pSurface->context = pContext;
+
+ result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)(
+ pSurface, &dwords, &data);
+
+ if(result != Success) {
+ free(pSurface);
+ return result;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = dwords;
+
+ WriteToClient(client, sizeof(xvmcCreateSurfaceReply), &rep);
+ if(dwords)
+ WriteToClient(client, dwords << 2, data);
+ AddResource(pSurface->surface_id, XvMCRTSurface, pSurface);
+
+ if(data)
+ free(data);
+
+ pContext->refcnt++;
+
+ return Success;
+}
+
+static int
+ProcXvMCDestroySurface(ClientPtr client)
+{
+ REQUEST(xvmcDestroySurfaceReq);
+ REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
+
+ if(!LookupIDByType(stuff->surface_id, XvMCRTSurface))
+ return (XvMCBadSurface + XvMCErrorBase);
+
+ FreeResource(stuff->surface_id, RT_NONE);
+
+ return Success;
+}
+
+static int
+ProcXvMCCreateSubpicture(ClientPtr client)
+{
+ Bool image_supported = FALSE;
+ CARD32 *data = NULL;
+ int i, result, dwords = 0;
+ XvMCContextPtr pContext;
+ XvMCSubpicturePtr pSubpicture;
+ XvMCScreenPtr pScreenPriv;
+ xvmcCreateSubpictureReply rep;
+ XvMCAdaptorPtr adaptor;
+ XvMCSurfaceInfoPtr surface = NULL;
+ REQUEST(xvmcCreateSubpictureReq);
+ REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
+
+ if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext)))
+ return (XvMCBadContext + XvMCErrorBase);
+
+ pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
+
+ adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]);
+
+ /* find which surface this context supports */
+ for(i = 0; i < adaptor->num_surfaces; i++) {
+ if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){
+ surface = adaptor->surfaces[i];
+ break;
+ }
+ }
+
+ if(!surface) return BadMatch;
+
+ /* make sure this surface supports that xvimage format */
+ if(!surface->compatible_subpictures) return BadMatch;
+
+ for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
+ if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) {
+ image_supported = TRUE;
+ break;
+ }
+ }
+
+ if(!image_supported) return BadMatch;
+
+ /* make sure the size is OK */
+ if((stuff->width > surface->subpicture_max_width) ||
+ (stuff->height > surface->subpicture_max_height))
+ return BadValue;
+
+ if(!(pSubpicture = malloc(sizeof(XvMCSubpictureRec))))
+ return BadAlloc;
+
+ pSubpicture->subpicture_id = stuff->subpicture_id;
+ pSubpicture->xvimage_id = stuff->xvimage_id;
+ pSubpicture->width = stuff->width;
+ pSubpicture->height = stuff->height;
+ pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
+ pSubpicture->entry_bytes = 0; /* overwritten by DDX */
+ pSubpicture->component_order[0] = 0; /* overwritten by DDX */
+ pSubpicture->component_order[1] = 0;
+ pSubpicture->component_order[2] = 0;
+ pSubpicture->component_order[3] = 0;
+ pSubpicture->context = pContext;
+
+ result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)(
+ pSubpicture, &dwords, &data);
+
+ if(result != Success) {
+ free(pSubpicture);
+ return result;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.width_actual = pSubpicture->width;
+ rep.height_actual = pSubpicture->height;
+ rep.num_palette_entries = pSubpicture->num_palette_entries;
+ rep.entry_bytes = pSubpicture->entry_bytes;
+ rep.component_order[0] = pSubpicture->component_order[0];
+ rep.component_order[1] = pSubpicture->component_order[1];
+ rep.component_order[2] = pSubpicture->component_order[2];
+ rep.component_order[3] = pSubpicture->component_order[3];
+ rep.length = dwords;
+
+ WriteToClient(client, sizeof(xvmcCreateSubpictureReply), &rep);
+ if(dwords)
+ WriteToClient(client, dwords << 2, data);
+ AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture);
+
+ if(data)
+ free(data);
+
+ pContext->refcnt++;
+
+ return Success;
+}
+
+static int
+ProcXvMCDestroySubpicture(ClientPtr client)
+{
+ REQUEST(xvmcDestroySubpictureReq);
+ REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
+
+ if(!LookupIDByType(stuff->subpicture_id, XvMCRTSubpicture))
+ return (XvMCBadSubpicture + XvMCErrorBase);
+
+ FreeResource(stuff->subpicture_id, RT_NONE);
+
+ return Success;
+}
+
+
+static int
+ProcXvMCListSubpictureTypes(ClientPtr client)
+{
+ XvPortPtr pPort;
+ xvmcListSubpictureTypesReply rep;
+ XvMCScreenPtr pScreenPriv;
+ ScreenPtr pScreen;
+ XvMCAdaptorPtr adaptor = NULL;
+ XvMCSurfaceInfoPtr surface = NULL;
+ xvImageFormatInfo info;
+ XvImagePtr pImage;
+ int i, j;
+ REQUEST(xvmcListSubpictureTypesReq);
+ REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq);
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
+ client->errorValue = stuff->port;
+ return _XvBadPort;
+ }
+
+ pScreen = pPort->pAdaptor->pScreen;
+
+ if(XvMCScreenIndex < 0) /* No XvMC adaptors */
+ return BadMatch;
+
+ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
+ return BadMatch; /* None this screen */
+
+ for(i = 0; i < pScreenPriv->num_adaptors; i++) {
+ if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
+ adaptor = &(pScreenPriv->adaptors[i]);
+ break;
+ }
+ }
+
+ if(!adaptor) return BadMatch;
+
+ for(i = 0; i < adaptor->num_surfaces; i++) {
+ if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) {
+ surface = adaptor->surfaces[i];
+ break;
+ }
+ }
+
+ if(!surface) return BadMatch;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.num = 0;
+ if(surface->compatible_subpictures)
+ rep.num = surface->compatible_subpictures->num_xvimages;
+
+ rep.length = rep.num * sizeof(xvImageFormatInfo) >> 2;
+
+ WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), &rep);
+
+ for(i = 0; i < rep.num; i++) {
+ pImage = NULL;
+ for(j = 0; j < adaptor->num_subpictures; j++) {
+ if(surface->compatible_subpictures->xvimage_ids[i] ==
+ adaptor->subpictures[j]->id)
+ {
+ pImage = adaptor->subpictures[j];
+ break;
+ }
+ }
+ if(!pImage) return BadImplementation;
+
+ info.id = pImage->id;
+ info.type = pImage->type;
+ info.byte_order = pImage->byte_order;
+ memcpy(&info.guid, pImage->guid, 16);
+ info.bpp = pImage->bits_per_pixel;
+ info.num_planes = pImage->num_planes;
+ info.depth = pImage->depth;
+ info.red_mask = pImage->red_mask;
+ info.green_mask = pImage->green_mask;
+ info.blue_mask = pImage->blue_mask;
+ info.format = pImage->format;
+ info.y_sample_bits = pImage->y_sample_bits;
+ info.u_sample_bits = pImage->u_sample_bits;
+ info.v_sample_bits = pImage->v_sample_bits;
+ info.horz_y_period = pImage->horz_y_period;
+ info.horz_u_period = pImage->horz_u_period;
+ info.horz_v_period = pImage->horz_v_period;
+ info.vert_y_period = pImage->vert_y_period;
+ info.vert_u_period = pImage->vert_u_period;
+ info.vert_v_period = pImage->vert_v_period;
+ memcpy(&info.comp_order, pImage->component_order, 32);
+ info.scanline_order = pImage->scanline_order;
+ WriteToClient(client, sizeof(xvImageFormatInfo), &info);
+ }
+
+ return Success;
+}
+
+static int
+ProcXvMCGetDRInfo(ClientPtr client)
+{
+ xvmcGetDRInfoReply rep;
+ XvPortPtr pPort;
+ ScreenPtr pScreen;
+ XvMCScreenPtr pScreenPriv;
+
+#ifdef HAS_XVMCSHM
+ volatile CARD32 *patternP;
+#endif
+
+ REQUEST(xvmcGetDRInfoReq);
+ REQUEST_SIZE_MATCH(xvmcGetDRInfoReq);
+
+
+ if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
+ client->errorValue = stuff->port;
+ return _XvBadPort;
+ }
+
+ pScreen = pPort->pAdaptor->pScreen;
+ pScreenPriv = XVMC_GET_PRIVATE(pScreen);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.major = pScreenPriv->major;
+ rep.minor = pScreenPriv->minor;
+ rep.patchLevel = pScreenPriv->patchLevel;
+ rep.nameLen = (strlen(pScreenPriv->clientDriverName) + 4) >> 2;
+ rep.busIDLen = (strlen(pScreenPriv->busID) + 4) >> 2;
+
+ rep.length = rep.nameLen + rep.busIDLen;
+ rep.nameLen <<=2;
+ rep.busIDLen <<=2;
+
+ /*
+ * Read back to the client what she has put in the shared memory
+ * segment she prepared for us.
+ */
+
+ rep.isLocal = 1;
+#ifdef HAS_XVMCSHM
+ patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY );
+ if ( -1 != (long) patternP) {
+ register volatile CARD32 *patternC = patternP;
+ register int i;
+ CARD32 magic = stuff->magic;
+
+ rep.isLocal = 1;
+ i = 1024 / sizeof(CARD32);
+
+ while ( i-- ) {
+ if (*patternC++ != magic) {
+ rep.isLocal = 0;
+ break;
+ }
+ magic = ~magic;
+ }
+ shmdt( (char *)patternP );
+ }
+#endif /* HAS_XVMCSHM */
+
+ WriteToClient(client, sizeof(xvmcGetDRInfoReply),
+ &rep);
+ if (rep.length) {
+ WriteToClient(client, rep.nameLen,
+ pScreenPriv->clientDriverName);
+ WriteToClient(client, rep.busIDLen,
+ pScreenPriv->busID);
+ }
+ return Success;
+}
+
+
+int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = {
+ ProcXvMCQueryVersion,
+ ProcXvMCListSurfaceTypes,
+ ProcXvMCCreateContext,
+ ProcXvMCDestroyContext,
+ ProcXvMCCreateSurface,
+ ProcXvMCDestroySurface,
+ ProcXvMCCreateSubpicture,
+ ProcXvMCDestroySubpicture,
+ ProcXvMCListSubpictureTypes,
+ ProcXvMCGetDRInfo
+};
+
+static int
+ProcXvMCDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if(stuff->data < xvmcNumRequest)
+ return (*ProcXvMCVector[stuff->data])(client);
+ else
+ return BadRequest;
+}
+
+static int
+SProcXvMCDispatch (ClientPtr client)
+{
+ /* We only support local */
+ return BadImplementation;
+}
+
+void
+XvMCExtensionInit()
+{
+ ExtensionEntry *extEntry;
+
+ if(XvMCScreenIndex < 0) /* nobody supports it */
+ return;
+
+ if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes)))
+ return;
+
+ if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes)))
+ return;
+
+ if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes)))
+ return;
+
+ extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors,
+ ProcXvMCDispatch, SProcXvMCDispatch,
+ XvMCResetProc, StandardMinorOpcode);
+
+ if(!extEntry) return;
+
+ XvMCReqCode = extEntry->base;
+ XvMCEventBase = extEntry->eventBase;
+ XvMCErrorBase = extEntry->errorBase;
+}
+
+static Bool
+XvMCCloseScreen (ScreenPtr pScreen)
+{
+ XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
+ free(pScreenPriv);
+
+ return (*pScreen->CloseScreen)(pScreen);
+}
+
+
+int
+XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
+{
+ XvMCScreenPtr pScreenPriv;
+
+ if(XvMCGeneration != serverGeneration) {
+ if((XvMCScreenIndex = AllocateScreenPrivateIndex()) < 0)
+ return BadAlloc;
+
+ XvMCGeneration = serverGeneration;
+ }
+
+ if(!(pScreenPriv = (XvMCScreenPtr)malloc(sizeof(XvMCScreenRec))))
+ return BadAlloc;
+
+ pScreen->devPrivates[XvMCScreenIndex].ptr = (void *)pScreenPriv;
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = XvMCCloseScreen;
+
+ pScreenPriv->num_adaptors = num;
+ pScreenPriv->adaptors = pAdapt;
+ pScreenPriv->clientDriverName[0] = 0;
+ pScreenPriv->busID[0] = 0;
+ pScreenPriv->major = 0;
+ pScreenPriv->minor = 0;
+ pScreenPriv->patchLevel = 0;
+
+ return Success;
+}
+
+XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
+{
+ XvImagePtr pImage = NULL;
+ ScreenPtr pScreen = pPort->pAdaptor->pScreen;
+ XvMCScreenPtr pScreenPriv;
+ XvMCAdaptorPtr adaptor = NULL;
+ int i;
+
+ if(XvMCScreenIndex < 0) return NULL;
+
+ if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen)))
+ return NULL;
+
+ for(i = 0; i < pScreenPriv->num_adaptors; i++) {
+ if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
+ adaptor = &(pScreenPriv->adaptors[i]);
+ break;
+ }
+ }
+
+ if(!adaptor) return NULL;
+
+ for(i = 0; i < adaptor->num_subpictures; i++) {
+ if(adaptor->subpictures[i]->id == id) {
+ pImage = adaptor->subpictures[i];
+ break;
+ }
+ }
+
+ return pImage;
+}
+
+int
+xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
+ char *busID, int major, int minor,
+ int patchLevel)
+{
+ XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
+ strncpy(pScreenPriv->clientDriverName, name,
+ DR_CLIENT_DRIVER_NAME_SIZE);
+ strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
+ pScreenPriv->major = major;
+ pScreenPriv->minor = minor;
+ pScreenPriv->patchLevel = patchLevel;
+ pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0;
+ pScreenPriv->busID[DR_BUSID_SIZE-1] = 0;
+ return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/Xext/xvmcext.h b/nx-X11/programs/Xserver/Xext/xvmcext.h
new file mode 100644
index 000000000..c1826b44c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xext/xvmcext.h
@@ -0,0 +1,115 @@
+
+#ifndef _XVMC_H
+#define _XVMC_H
+#include <nx-X11/extensions/Xv.h>
+#include "xvdix.h"
+
+typedef struct {
+ int num_xvimages;
+ int *xvimage_ids;
+} XvMCImageIDList;
+
+typedef struct {
+ int surface_type_id;
+ int chroma_format;
+ int color_description;
+ unsigned short max_width;
+ unsigned short max_height;
+ unsigned short subpicture_max_width;
+ unsigned short subpicture_max_height;
+ int mc_type;
+ int flags;
+ XvMCImageIDList *compatible_subpictures;
+} XvMCSurfaceInfoRec, *XvMCSurfaceInfoPtr;
+
+typedef struct {
+ XID context_id;
+ ScreenPtr pScreen;
+ int adapt_num;
+ int surface_type_id;
+ unsigned short width;
+ unsigned short height;
+ CARD32 flags;
+ int refcnt;
+ void * port_priv;
+ void * driver_priv;
+} XvMCContextRec, *XvMCContextPtr;
+
+typedef struct {
+ XID surface_id;
+ int surface_type_id;
+ XvMCContextPtr context;
+ void * driver_priv;
+} XvMCSurfaceRec, *XvMCSurfacePtr;
+
+
+typedef struct {
+ XID subpicture_id;
+ int xvimage_id;
+ unsigned short width;
+ unsigned short height;
+ int num_palette_entries;
+ int entry_bytes;
+ char component_order[4];
+ XvMCContextPtr context;
+ void * driver_priv;
+} XvMCSubpictureRec, *XvMCSubpicturePtr;
+
+typedef int (*XvMCCreateContextProcPtr) (
+ XvPortPtr port,
+ XvMCContextPtr context,
+ int *num_priv,
+ CARD32 **priv
+);
+
+typedef void (*XvMCDestroyContextProcPtr) (
+ XvMCContextPtr context
+);
+
+typedef int (*XvMCCreateSurfaceProcPtr) (
+ XvMCSurfacePtr surface,
+ int *num_priv,
+ CARD32 **priv
+);
+
+typedef void (*XvMCDestroySurfaceProcPtr) (
+ XvMCSurfacePtr surface
+);
+
+typedef int (*XvMCCreateSubpictureProcPtr) (
+ XvMCSubpicturePtr subpicture,
+ int *num_priv,
+ CARD32 **priv
+);
+
+typedef void (*XvMCDestroySubpictureProcPtr) (
+ XvMCSubpicturePtr subpicture
+);
+
+
+typedef struct {
+ XvAdaptorPtr xv_adaptor;
+ int num_surfaces;
+ XvMCSurfaceInfoPtr *surfaces;
+ int num_subpictures;
+ XvImagePtr *subpictures;
+ XvMCCreateContextProcPtr CreateContext;
+ XvMCDestroyContextProcPtr DestroyContext;
+ XvMCCreateSurfaceProcPtr CreateSurface;
+ XvMCDestroySurfaceProcPtr DestroySurface;
+ XvMCCreateSubpictureProcPtr CreateSubpicture;
+ XvMCDestroySubpictureProcPtr DestroySubpicture;
+} XvMCAdaptorRec, *XvMCAdaptorPtr;
+
+void XvMCExtensionInit(void);
+
+int XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr adapt);
+
+XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id);
+
+int xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
+ char *busID, int major, int minor,
+ int patchLevel);
+
+
+#endif /* _XVMC_H */
diff --git a/nx-X11/programs/Xserver/Xi/Imakefile b/nx-X11/programs/Xserver/Xi/Imakefile
new file mode 100644
index 000000000..746e57eaa
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/Imakefile
@@ -0,0 +1,93 @@
+#include <Server.tmpl>
+
+ SRCS = allowev.c \
+ chgkbd.c \
+ chgdctl.c \
+ chgfctl.c \
+ chgkmap.c \
+ chgprop.c \
+ chgptr.c \
+ closedev.c \
+ devbell.c \
+ exevents.c \
+ extinit.c \
+ getdctl.c \
+ getfctl.c \
+ getfocus.c \
+ getbmap.c \
+ getkmap.c \
+ getmmap.c \
+ getprop.c \
+ getselev.c \
+ getvers.c \
+ gtmotion.c \
+ grabdev.c \
+ grabdevb.c \
+ grabdevk.c \
+ listdev.c \
+ opendev.c \
+ queryst.c \
+ selectev.c \
+ sendexev.c \
+ setdval.c \
+ setfocus.c \
+ setmode.c \
+ setbmap.c \
+ setmmap.c \
+ stubs.c \
+ ungrdev.c \
+ ungrdevb.c \
+ ungrdevk.c
+
+ OBJS = allowev.o \
+ chgkbd.o \
+ chgdctl.o \
+ chgfctl.o \
+ chgkmap.o \
+ chgprop.o \
+ chgptr.o \
+ closedev.o \
+ devbell.o \
+ exevents.o \
+ extinit.o \
+ getdctl.o \
+ getfctl.o \
+ getfocus.o \
+ getbmap.o \
+ getkmap.o \
+ getmmap.o \
+ getprop.o \
+ getselev.o \
+ getvers.o \
+ gtmotion.o \
+ grabdev.o \
+ grabdevb.o \
+ grabdevk.o \
+ listdev.o \
+ opendev.o \
+ queryst.o \
+ selectev.o \
+ sendexev.o \
+ setdval.o \
+ setfocus.o \
+ setmode.o \
+ setbmap.o \
+ setmmap.o \
+ ungrdev.o \
+ ungrdevb.o \
+ ungrdevk.o
+ INCLUDES = -I../include -I$(EXTINCSRC) -I$(XINCLUDESRC) `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ DEFINES = $(NX_DEFINES)
+
+NormalLibraryTarget(xinput,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(xinput,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/Xi/allowev.c b/nx-X11/programs/Xserver/Xi/allowev.c
new file mode 100644
index 000000000..a814e3c3d
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/allowev.c
@@ -0,0 +1,139 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Function to allow frozen events to be routed from extension input devices.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "allowev.h"
+#include "dixevents.h"
+
+/***********************************************************************
+ *
+ * This procedure allows frozen events to be routed.
+ *
+ */
+
+int
+SProcXAllowDeviceEvents(client)
+ register ClientPtr client;
+ {
+ REQUEST(xAllowDeviceEventsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xAllowDeviceEventsReq);
+ swapl(&stuff->time);
+ return(ProcXAllowDeviceEvents(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure allows frozen events to be routed.
+ *
+ */
+
+int
+ProcXAllowDeviceEvents(client)
+ register ClientPtr client;
+ {
+ TimeStamp time;
+ DeviceIntPtr thisdev;
+
+ REQUEST(xAllowDeviceEventsReq);
+ REQUEST_SIZE_MATCH(xAllowDeviceEventsReq);
+
+ thisdev = LookupDeviceIntRec (stuff->deviceid);
+ if (thisdev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_AllowDeviceEvents, 0, BadDevice);
+ return Success;
+ }
+ time = ClientTimeToServerTime(stuff->time);
+
+ switch (stuff->mode)
+ {
+ case ReplayThisDevice:
+ AllowSome(client, time, thisdev, NOT_GRABBED);
+ break;
+ case SyncThisDevice:
+ AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncThisDevice:
+ AllowSome(client, time, thisdev, THAWED);
+ break;
+ case AsyncOtherDevices:
+ AllowSome(client, time, thisdev, THAW_OTHERS);
+ break;
+ case SyncAll:
+ AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncAll:
+ AllowSome(client, time, thisdev, THAWED_BOTH);
+ break;
+ default:
+ SendErrorToClient(client, IReqCode, X_AllowDeviceEvents, 0,
+ BadValue);
+ client->errorValue = stuff->mode;
+ return Success;
+ }
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/allowev.h b/nx-X11/programs/Xserver/Xi/allowev.h
new file mode 100644
index 000000000..5315667df
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/allowev.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef ALLOWEV_H
+#define ALLOWEV_H 1
+
+int
+SProcXAllowDeviceEvents(
+ ClientPtr /* client */
+ );
+
+int
+ProcXAllowDeviceEvents(
+ ClientPtr /* client */
+ );
+
+#endif /* ALLOWEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgdctl.c b/nx-X11/programs/Xserver/Xi/chgdctl.c
new file mode 100644
index 000000000..b07885f9c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgdctl.c
@@ -0,0 +1,211 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Change Device control attributes for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h> /* control constants */
+#include "XIstubs.h"
+
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "chgdctl.h"
+
+/***********************************************************************
+ *
+ * This procedure changes the control attributes for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXChangeDeviceControl(client)
+ register ClientPtr client;
+ {
+ REQUEST(xChangeDeviceControlReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
+ swaps(&stuff->control);
+ return(ProcXChangeDeviceControl(client));
+ }
+
+/***********************************************************************
+ *
+ * Change the control attributes.
+ *
+ */
+
+int
+ProcXChangeDeviceControl(client)
+ ClientPtr client;
+ {
+ unsigned len;
+ int i, status;
+ DeviceIntPtr dev;
+ xDeviceResolutionCtl *r;
+ xChangeDeviceControlReply rep;
+ AxisInfoPtr a;
+ CARD32 *resolution;
+
+ REQUEST(xChangeDeviceControlReq);
+ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl));
+
+ len = stuff->length - (sizeof(xChangeDeviceControlReq) >>2);
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl, 0,
+ BadDevice);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_ChangeDeviceControl;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ switch (stuff->control)
+ {
+ case DEVICE_RESOLUTION:
+ r = (xDeviceResolutionCtl *) &stuff[1];
+ if ((len < (sizeof(xDeviceResolutionCtl)>>2)) ||
+ (len != (sizeof(xDeviceResolutionCtl)>>2) +
+ r->num_valuators))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl,
+ 0, BadLength);
+ return Success;
+ }
+ if (!dev->valuator)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl, 0,
+ BadMatch);
+ return Success;
+ }
+ if ((dev->grab) && !SameClient(dev->grab, client))
+ {
+ rep.status = AlreadyGrabbed;
+ WriteReplyToClient(client, sizeof(xChangeDeviceControlReply),
+ &rep);
+ return Success;
+ }
+ resolution = (CARD32 *) (r + 1);
+ if (r->first_valuator + r->num_valuators > dev->valuator->numAxes)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl, 0,
+ BadValue);
+ return Success;
+ }
+ status = ChangeDeviceControl(client, dev, (xDeviceCtl*) r);
+ if (status == Success)
+ {
+ a = &dev->valuator->axes[r->first_valuator];
+ for (i=0; i<r->num_valuators; i++)
+ if (*(resolution+i) < (a+i)->min_resolution ||
+ *(resolution+i) > (a+i)->max_resolution)
+ {
+ SendErrorToClient (client, IReqCode,
+ X_ChangeDeviceControl, 0, BadValue);
+ return Success;
+ }
+ for (i=0; i<r->num_valuators; i++)
+ (a++)->resolution = *resolution++;
+ }
+ else if (status == DeviceBusy)
+ {
+ rep.status = DeviceBusy;
+ WriteReplyToClient(client, sizeof(xChangeDeviceControlReply),
+ &rep);
+ return Success;
+ }
+ else
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl, 0,
+ BadMatch);
+ return Success;
+ }
+ break;
+ default:
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceControl, 0,
+ BadValue);
+ return Success;
+ }
+ WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), &rep);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the xChangeDeviceControl function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXChangeDeviceControl (client, size, rep)
+ ClientPtr client;
+ int size;
+ xChangeDeviceControlReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
+
diff --git a/nx-X11/programs/Xserver/Xi/chgdctl.h b/nx-X11/programs/Xserver/Xi/chgdctl.h
new file mode 100644
index 000000000..1d1a6214d
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgdctl.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGDCTL_H
+#define CHGDCTL_H 1
+
+int
+SProcXChangeDeviceControl(
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangeDeviceControl(
+ ClientPtr /* client */
+ );
+
+void
+SRepXChangeDeviceControl (
+ ClientPtr /* client */,
+ int /* size */,
+ xChangeDeviceControlReply * /* rep */
+ );
+
+#endif /* CHGDCTL_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgfctl.c b/nx-X11/programs/Xserver/Xi/chgfctl.c
new file mode 100644
index 000000000..341c794ce
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgfctl.c
@@ -0,0 +1,645 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Change feedback control attributes for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h> /* control constants */
+
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "chgfctl.h"
+
+#define DO_ALL (-1)
+
+/***********************************************************************
+ *
+ * This procedure changes the control attributes for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXChangeFeedbackControl(client)
+ register ClientPtr client;
+ {
+ REQUEST(xChangeFeedbackControlReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
+ swapl(&stuff->mask);
+ return(ProcXChangeFeedbackControl(client));
+ }
+
+/***********************************************************************
+ *
+ * Change the control attributes.
+ *
+ */
+
+int
+ProcXChangeFeedbackControl(client)
+ ClientPtr client;
+ {
+ unsigned len;
+ DeviceIntPtr dev;
+ KbdFeedbackPtr k;
+ PtrFeedbackPtr p;
+ IntegerFeedbackPtr i;
+ StringFeedbackPtr s;
+ BellFeedbackPtr b;
+ LedFeedbackPtr l;
+
+ REQUEST(xChangeFeedbackControlReq);
+ REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq);
+
+ len = stuff->length - (sizeof(xChangeFeedbackControlReq) >>2);
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadDevice);
+ return Success;
+ }
+
+ switch (stuff->feedbackid)
+ {
+ case KbdFeedbackClass:
+ if (len != (sizeof(xKbdFeedbackCtl)>>2))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (k=dev->kbdfeed; k; k=k->next)
+ if (k->ctrl.id == ((xKbdFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangeKbdFeedback (client, dev, stuff->mask, k, (xKbdFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ case PtrFeedbackClass:
+ if (len != (sizeof(xPtrFeedbackCtl)>>2))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (p=dev->ptrfeed; p; p=p->next)
+ if (p->ctrl.id == ((xPtrFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangePtrFeedback (client, dev, stuff->mask, p, (xPtrFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ case StringFeedbackClass:
+ {
+ xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]);
+ if (client->swapped)
+ {
+ if (len < (sizeof(xStringFeedbackCtl) + 3) >> 2)
+ return BadLength;
+ swaps(&f->num_keysyms);
+ }
+ if (len != ((sizeof(xStringFeedbackCtl)>>2) + f->num_keysyms))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (s=dev->stringfeed; s; s=s->next)
+ if (s->ctrl.id == ((xStringFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangeStringFeedback (client, dev, stuff->mask,s,(xStringFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ }
+ case IntegerFeedbackClass:
+ if (len != (sizeof(xIntegerFeedbackCtl)>>2))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (i=dev->intfeed; i; i=i->next)
+ if (i->ctrl.id == ((xIntegerFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangeIntegerFeedback (client, dev,stuff->mask,i,(xIntegerFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ case LedFeedbackClass:
+ if (len != (sizeof(xLedFeedbackCtl)>>2))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (l=dev->leds; l; l=l->next)
+ if (l->ctrl.id == ((xLedFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangeLedFeedback (client, dev, stuff->mask, l, (xLedFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ case BellFeedbackClass:
+ if (len != (sizeof(xBellFeedbackCtl)>>2))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl,
+ 0, BadLength);
+ return Success;
+ }
+ for (b=dev->bell; b; b=b->next)
+ if (b->ctrl.id == ((xBellFeedbackCtl *) &stuff[1])->id)
+ {
+ ChangeBellFeedback (client, dev, stuff->mask, b, (xBellFeedbackCtl *)&stuff[1]);
+ return Success;
+ }
+ break;
+ default:
+ break;
+ }
+
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0, BadMatch);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes KbdFeedbackClass data.
+ *
+ */
+
+int
+ChangeKbdFeedback (client, dev, mask, k, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ KbdFeedbackPtr k;
+ xKbdFeedbackCtl *f;
+ {
+ KeybdCtrl kctrl;
+ int t;
+ int key = DO_ALL;
+
+ if (client->swapped)
+ {
+ swaps(&f->length);
+ swaps(&f->pitch);
+ swaps(&f->duration);
+ swapl(&f->led_mask);
+ swapl(&f->led_values);
+ }
+
+ kctrl = k->ctrl;
+ if (mask & DvKeyClickPercent)
+ {
+ t = f->click;
+ if (t == -1)
+ t = defaultKeyboardControl.click;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ kctrl.click = t;
+ }
+
+ if (mask & DvPercent)
+ {
+ t = f->percent;
+ if (t == -1)
+ t = defaultKeyboardControl.bell;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ kctrl.bell = t;
+ }
+
+ if (mask & DvPitch)
+ {
+ t = f->pitch;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_pitch;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ kctrl.bell_pitch = t;
+ }
+
+ if (mask & DvDuration)
+ {
+ t = f->duration;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_duration;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ kctrl.bell_duration = t;
+ }
+
+ if (mask & DvLed)
+ {
+ kctrl.leds &= ~(f->led_mask);
+ kctrl.leds |= (f->led_mask & f->led_values);
+ }
+
+ if (mask & DvKey)
+ {
+ key = (KeyCode) f->key;
+ if (key < 8 || key > 255)
+ {
+ client->errorValue = key;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ if (!(mask & DvAutoRepeatMode))
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+
+ if (mask & DvAutoRepeatMode)
+ {
+ int inx = (key >> 3);
+ int kmask = (1 << (key & 7));
+ t = (CARD8) f->auto_repeat_mode;
+ if (t == AutoRepeatModeOff)
+ {
+ if (key == DO_ALL)
+ kctrl.autoRepeat = FALSE;
+ else
+ kctrl.autoRepeats[inx] &= ~kmask;
+ }
+ else if (t == AutoRepeatModeOn)
+ {
+ if (key == DO_ALL)
+ kctrl.autoRepeat = TRUE;
+ else
+ kctrl.autoRepeats[inx] |= kmask;
+ }
+ else if (t == AutoRepeatModeDefault)
+ {
+ if (key == DO_ALL)
+ kctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+ else
+ kctrl.autoRepeats[inx] &= ~kmask;
+ kctrl.autoRepeats[inx] =
+ (kctrl.autoRepeats[inx] & ~kmask) |
+ (defaultKeyboardControl.autoRepeats[inx] & kmask);
+ }
+ else
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ }
+
+ k->ctrl = kctrl;
+ (*k->CtrlProc)(dev, &k->ctrl);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes PtrFeedbackClass data.
+ *
+ */
+
+int
+ChangePtrFeedback (client, dev, mask, p, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ PtrFeedbackPtr p;
+ xPtrFeedbackCtl *f;
+ {
+ PtrCtrl pctrl; /* might get BadValue part way through */
+
+ if (client->swapped)
+ {
+ swaps(&f->length);
+ swaps(&f->num);
+ swaps(&f->denom);
+ swaps(&f->thresh);
+ }
+
+ pctrl = p->ctrl;
+ if (mask & DvAccelNum)
+ {
+ int accelNum;
+
+ accelNum = f->num;
+ if (accelNum == -1)
+ pctrl.num = defaultPointerControl.num;
+ else if (accelNum < 0)
+ {
+ client->errorValue = accelNum;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ else pctrl.num = accelNum;
+ }
+
+ if (mask & DvAccelDenom)
+ {
+ int accelDenom;
+
+ accelDenom = f->denom;
+ if (accelDenom == -1)
+ pctrl.den = defaultPointerControl.den;
+ else if (accelDenom <= 0)
+ {
+ client->errorValue = accelDenom;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ else pctrl.den = accelDenom;
+ }
+
+ if (mask & DvThreshold)
+ {
+ int threshold;
+
+ threshold = f->thresh;
+ if (threshold == -1)
+ pctrl.threshold = defaultPointerControl.threshold;
+ else if (threshold < 0)
+ {
+ client->errorValue = threshold;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ else pctrl.threshold = threshold;
+ }
+
+ p->ctrl = pctrl;
+ (*p->CtrlProc)(dev, &p->ctrl);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes IntegerFeedbackClass data.
+ *
+ */
+
+int
+ChangeIntegerFeedback (client, dev, mask, i, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ IntegerFeedbackPtr i;
+ xIntegerFeedbackCtl *f;
+ {
+ if (client->swapped)
+ {
+ swaps(&f->length);
+ swapl(&f->int_to_display);
+ }
+
+ i->ctrl.integer_displayed = f->int_to_display;
+ (*i->CtrlProc)(dev, &i->ctrl);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes StringFeedbackClass data.
+ *
+ */
+
+int
+ChangeStringFeedback (client, dev, mask, s, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ StringFeedbackPtr s;
+ xStringFeedbackCtl *f;
+ {
+ int i, j;
+ KeySym *syms, *sup_syms;
+
+ syms = (KeySym *) (f+1);
+ if (client->swapped)
+ {
+ swaps(&f->length); /* swapped num_keysyms in calling proc */
+ SwapLongs((CARD32 *) syms, f->num_keysyms);
+ }
+
+ if (f->num_keysyms > s->ctrl.max_symbols)
+ {
+ SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ sup_syms = s->ctrl.symbols_supported;
+ for (i=0; i<f->num_keysyms; i++)
+ {
+ for (j=0; j<s->ctrl.num_symbols_supported; j++)
+ if (*(syms+i) == *(sup_syms+j))
+ break;
+ if (j==s->ctrl.num_symbols_supported)
+ {
+ SendErrorToClient(client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+
+ s->ctrl.num_symbols_displayed = f->num_keysyms;
+ for (i=0; i<f->num_keysyms; i++)
+ *(s->ctrl.symbols_displayed+i) = *(syms+i);
+ (*s->CtrlProc)(dev, &s->ctrl);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes BellFeedbackClass data.
+ *
+ */
+
+int
+ChangeBellFeedback (client, dev, mask, b, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ BellFeedbackPtr b;
+ xBellFeedbackCtl *f;
+ {
+ int t;
+ BellCtrl bctrl; /* might get BadValue part way through */
+
+ if (client->swapped)
+ {
+ swaps(&f->length);
+ swaps(&f->pitch);
+ swaps(&f->duration);
+ }
+
+ bctrl = b->ctrl;
+ if (mask & DvPercent)
+ {
+ t = f->percent;
+ if (t == -1)
+ t = defaultKeyboardControl.bell;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ bctrl.percent = t;
+ }
+
+ if (mask & DvPitch)
+ {
+ t = f->pitch;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_pitch;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ bctrl.pitch = t;
+ }
+
+ if (mask & DvDuration)
+ {
+ t = f->duration;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_duration;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ SendErrorToClient (client, IReqCode, X_ChangeFeedbackControl, 0,
+ BadValue);
+ return Success;
+ }
+ bctrl.duration = t;
+ }
+ b->ctrl = bctrl;
+ (*b->CtrlProc)(dev, &b->ctrl);
+ return Success;
+ }
+
+/******************************************************************************
+ *
+ * This procedure changes LedFeedbackClass data.
+ *
+ */
+
+int
+ChangeLedFeedback (client, dev, mask, l, f)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ unsigned long mask;
+ LedFeedbackPtr l;
+ xLedFeedbackCtl *f;
+ {
+ LedCtrl lctrl; /* might get BadValue part way through */
+
+ if (client->swapped)
+ {
+ swaps(&f->length);
+ swapl(&f->led_values);
+ swapl(&f->led_mask);
+ }
+
+ f->led_mask &= l->ctrl.led_mask; /* set only supported leds */
+ f->led_values &= l->ctrl.led_mask; /* set only supported leds */
+ if (mask & DvLed)
+ {
+ lctrl.led_mask = f->led_mask;
+ lctrl.led_values = f->led_values;
+ (*l->CtrlProc)(dev, &lctrl);
+ l->ctrl.led_values &= ~(f->led_mask); /* zero changed leds */
+ l->ctrl.led_values |= (f->led_mask & f->led_values);/* OR in set leds*/
+ }
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/chgfctl.h b/nx-X11/programs/Xserver/Xi/chgfctl.h
new file mode 100644
index 000000000..ffcb3be8a
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgfctl.h
@@ -0,0 +1,97 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGFCTL_H
+#define CHGFCTL_H 1
+
+int
+SProcXChangeFeedbackControl(
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangeFeedbackControl(
+ ClientPtr /* client */
+ );
+
+int
+ChangeKbdFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ KbdFeedbackPtr /* k */,
+ xKbdFeedbackCtl * /* f */
+ );
+
+int
+ChangePtrFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ PtrFeedbackPtr /* p */,
+ xPtrFeedbackCtl * /* f */
+ );
+
+int
+ChangeIntegerFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ IntegerFeedbackPtr /* i */,
+ xIntegerFeedbackCtl * /* f */
+ );
+
+int
+ChangeStringFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ StringFeedbackPtr /* s */,
+ xStringFeedbackCtl * /* f */
+ );
+
+int
+ChangeBellFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ BellFeedbackPtr /* b */,
+ xBellFeedbackCtl * /* f */
+ );
+
+int
+ChangeLedFeedback (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned long /* mask */,
+ LedFeedbackPtr /* l */,
+ xLedFeedbackCtl * /* f */
+ );
+
+#endif /* CHGFCTL_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgkbd.c b/nx-X11/programs/Xserver/Xi/chgkbd.c
new file mode 100644
index 000000000..1d45023cf
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgkbd.c
@@ -0,0 +1,208 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to change the keyboard device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "globals.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "chgkbd.h"
+#include "chgptr.h"
+
+/***********************************************************************
+ *
+ * This procedure changes the keyboard device.
+ *
+ */
+
+int
+SProcXChangeKeyboardDevice(client)
+ register ClientPtr client;
+ {
+ REQUEST(xChangeKeyboardDeviceReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xChangeKeyboardDeviceReq);
+ return(ProcXChangeKeyboardDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure is invoked to swap the request bytes if the server and
+ * client have a different byte order.
+ *
+ */
+
+int
+ProcXChangeKeyboardDevice (client)
+ register ClientPtr client;
+ {
+ int i;
+ DeviceIntPtr xkbd = inputInfo.keyboard;
+ DeviceIntPtr dev;
+ FocusClassPtr xf = xkbd->focus;
+ FocusClassPtr df;
+ KeyClassPtr k;
+ xChangeKeyboardDeviceReply rep;
+ changeDeviceNotify ev;
+
+ REQUEST(xChangeKeyboardDeviceReq);
+ REQUEST_SIZE_MATCH(xChangeKeyboardDeviceReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_ChangeKeyboardDevice;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ rep.status = -1;
+ SendErrorToClient(client, IReqCode, X_ChangeKeyboardDevice, 0,
+ BadDevice);
+ return Success;
+ }
+
+ k = dev->key;
+ if (k == NULL)
+ {
+ rep.status = -1;
+ SendErrorToClient(client, IReqCode, X_ChangeKeyboardDevice, 0,
+ BadMatch);
+ return Success;
+ }
+
+ if (((dev->grab) && !SameClient(dev->grab, client)) ||
+ ((xkbd->grab) && !SameClient(xkbd->grab, client)))
+ rep.status = AlreadyGrabbed;
+ else if ((dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client)) ||
+ (xkbd->sync.frozen &&
+ xkbd->sync.other && !SameClient(xkbd->sync.other, client)))
+ rep.status = GrabFrozen;
+ else
+ {
+ if (ChangeKeyboardDevice (xkbd, dev) != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_ChangeKeyboardDevice, 0,
+ BadDevice);
+ return Success;
+ }
+ if (!dev->focus)
+ InitFocusClassDeviceStruct (dev);
+ if (!dev->kbdfeed)
+ InitKbdFeedbackClassDeviceStruct(dev, (BellProcPtr)NoopDDA,
+ (KbdCtrlProcPtr)NoopDDA);
+ df = dev->focus;
+ df->win = xf->win;
+ df->revert = xf->revert;
+ df->time = xf->time;
+ df->traceGood = xf->traceGood;
+ if (df->traceSize != xf->traceSize)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ df->trace = (WindowPtr *) realloc(df->trace,
+ xf->traceSize * sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ df->traceSize = xf->traceSize;
+ for (i=0; i<df->traceSize; i++)
+ df->trace[i] = xf->trace[i];
+ RegisterOtherDevice (xkbd);
+ RegisterKeyboardDevice (dev);
+
+ ev.type = ChangeDeviceNotify;
+ ev.deviceid = stuff->deviceid;
+ ev.time = currentTime.milliseconds;
+ ev.request = NewKeyboard;
+
+ SendEventToAllWindows (dev, ChangeDeviceNotifyMask, (xEvent *)&ev, 1);
+ SendMappingNotify (MappingKeyboard, k->curKeySyms.minKeyCode,
+ k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode + 1,client);
+
+ rep.status = 0;
+ }
+
+ WriteReplyToClient (client, sizeof (xChangeKeyboardDeviceReply),
+ &rep);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XChangeKeyboardDevice
+ * function, if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXChangeKeyboardDevice (client, size, rep)
+ ClientPtr client;
+ int size;
+ xChangeKeyboardDeviceReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/chgkbd.h b/nx-X11/programs/Xserver/Xi/chgkbd.h
new file mode 100644
index 000000000..b7ed198f7
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgkbd.h
@@ -0,0 +1,51 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGKBD_H
+#define CHGKBD_H 1
+
+int
+SProcXChangeKeyboardDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangeKeyboardDevice (
+ ClientPtr /* client */
+ );
+
+void
+SRepXChangeKeyboardDevice (
+ ClientPtr /* client */,
+ int /* size */,
+ xChangeKeyboardDeviceReply * /* rep */
+ );
+
+
+#endif /* CHGKBD_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgkmap.c b/nx-X11/programs/Xserver/Xi/chgkmap.c
new file mode 100644
index 000000000..8d5199848
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgkmap.c
@@ -0,0 +1,130 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Change key mapping for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "chgkmap.h"
+
+/***********************************************************************
+ *
+ * This procedure swaps the request when the client and
+ * server have different byte orderings.
+ *
+ */
+
+int
+SProcXChangeDeviceKeyMapping(client)
+ register ClientPtr client;
+ {
+ unsigned int count;
+
+ REQUEST(xChangeDeviceKeyMappingReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeDeviceKeyMappingReq);
+ count = stuff->keyCodes * stuff->keySymsPerKeyCode;
+ REQUEST_FIXED_SIZE(xChangeDeviceKeyMappingReq, count * sizeof(CARD32));
+ SwapLongs((CARD32 *) (&stuff[1]), count);
+ return(ProcXChangeDeviceKeyMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * Change the device key mapping.
+ *
+ */
+
+int
+ProcXChangeDeviceKeyMapping(client)
+ register ClientPtr client;
+ {
+ int ret;
+ unsigned len;
+ DeviceIntPtr dev;
+ unsigned int count;
+
+ REQUEST(xChangeDeviceKeyMappingReq);
+ REQUEST_AT_LEAST_SIZE(xChangeDeviceKeyMappingReq);
+
+ count = stuff->keyCodes * stuff->keySymsPerKeyCode;
+ REQUEST_FIXED_SIZE(xChangeDeviceKeyMappingReq, count * sizeof(CARD32));
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceKeyMapping, 0,
+ BadDevice);
+ return Success;
+ }
+ len = stuff->length - (sizeof(xChangeDeviceKeyMappingReq) >> 2);
+
+ ret = ChangeKeyMapping (client, dev, len, DeviceMappingNotify,
+ stuff->firstKeyCode, stuff->keyCodes, stuff->keySymsPerKeyCode,
+ (KeySym *)&stuff[1]);
+
+ if (ret != Success)
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceKeyMapping, 0,
+ ret);
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/chgkmap.h b/nx-X11/programs/Xserver/Xi/chgkmap.h
new file mode 100644
index 000000000..22cab11ba
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgkmap.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGKMAP_H
+#define CHGKMAP_H 1
+
+int
+SProcXChangeDeviceKeyMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangeDeviceKeyMapping(
+ ClientPtr /* client */
+ );
+
+#endif /* CHGKMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgprop.c b/nx-X11/programs/Xserver/Xi/chgprop.c
new file mode 100644
index 000000000..80b8aea5f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgprop.c
@@ -0,0 +1,163 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Function to modify the dont-propagate-list for an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h"
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "chgprop.h"
+#include "grabdev.h"
+
+/***********************************************************************
+ *
+ * This procedure returns the extension version.
+ *
+ */
+
+int
+SProcXChangeDeviceDontPropagateList(client)
+ register ClientPtr client;
+ {
+ REQUEST(xChangeDeviceDontPropagateListReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeDeviceDontPropagateListReq);
+ swapl(&stuff->window);
+ swaps(&stuff->count);
+ REQUEST_FIXED_SIZE(xChangeDeviceDontPropagateListReq,
+ stuff->count * sizeof(CARD32));
+ SwapLongs((CARD32 *) (&stuff[1]), stuff->count);
+ return(ProcXChangeDeviceDontPropagateList(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure changes the dont-propagate list for the specified window.
+ *
+ */
+
+int
+ProcXChangeDeviceDontPropagateList (client)
+ register ClientPtr client;
+ {
+ int i;
+ WindowPtr pWin;
+ struct tmask tmp[EMASKSIZE];
+ OtherInputMasks *others;
+
+ REQUEST(xChangeDeviceDontPropagateListReq);
+ REQUEST_AT_LEAST_SIZE(xChangeDeviceDontPropagateListReq);
+
+ if (stuff->length !=(sizeof(xChangeDeviceDontPropagateListReq)>>2) +
+ stuff->count)
+ {
+ SendErrorToClient (client, IReqCode, X_ChangeDeviceDontPropagateList, 0,
+ BadLength);
+ return Success;
+ }
+
+ pWin = (WindowPtr) LookupWindow (stuff->window, client);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ SendErrorToClient(client, IReqCode, X_ChangeDeviceDontPropagateList, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if (stuff->mode != AddToList && stuff->mode != DeleteFromList)
+ {
+ client->errorValue = stuff->window;
+ SendErrorToClient(client, IReqCode, X_ChangeDeviceDontPropagateList, 0,
+ BadMode);
+ return Success;
+ }
+
+ if (CreateMaskFromList (client, (XEventClass *)&stuff[1],
+ stuff->count, tmp, NULL, X_ChangeDeviceDontPropagateList) != Success)
+ return Success;
+
+ others = wOtherInputMasks(pWin);
+ if (!others && stuff->mode == DeleteFromList)
+ return Success;
+ for (i=0; i<EMASKSIZE; i++)
+ {
+ if (tmp[i].mask == 0)
+ continue;
+
+ if (stuff->mode == DeleteFromList)
+ tmp[i].mask = (others->dontPropagateMask[i] & ~tmp[i].mask);
+ else if (others)
+ tmp[i].mask |= others->dontPropagateMask[i];
+
+ if (DeviceEventSuppressForWindow (pWin,client,tmp[i].mask,i) != Success)
+ {
+ SendErrorToClient ( client, IReqCode, X_ChangeDeviceDontPropagateList, 0,
+ BadClass);
+ return Success;
+ }
+ }
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/chgprop.h b/nx-X11/programs/Xserver/Xi/chgprop.h
new file mode 100644
index 000000000..19d091c10
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgprop.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGPROP_H
+#define CHGPROP_H 1
+
+int
+SProcXChangeDeviceDontPropagateList (
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangeDeviceDontPropagateList (
+ ClientPtr /* client */
+ );
+
+#endif /* CHGPROP_H */
diff --git a/nx-X11/programs/Xserver/Xi/chgptr.c b/nx-X11/programs/Xserver/Xi/chgptr.c
new file mode 100644
index 000000000..7fef2a104
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgptr.c
@@ -0,0 +1,254 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to change the pointer device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+
+#include "dixevents.h"
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "chgptr.h"
+
+/***********************************************************************
+ *
+ * This procedure is invoked to swap the request bytes if the server and
+ * client have a different byte order.
+ *
+ */
+
+int
+SProcXChangePointerDevice(client)
+ register ClientPtr client;
+ {
+ REQUEST(xChangePointerDeviceReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xChangePointerDeviceReq);
+ return(ProcXChangePointerDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure changes the device used as the X pointer.
+ *
+ */
+
+int
+ProcXChangePointerDevice (client)
+ register ClientPtr client;
+ {
+ DeviceIntPtr xptr = inputInfo.pointer;
+ DeviceIntPtr dev;
+ ValuatorClassPtr v;
+ xChangePointerDeviceReply rep;
+ changeDeviceNotify ev;
+
+ REQUEST(xChangePointerDeviceReq);
+ REQUEST_SIZE_MATCH(xChangePointerDeviceReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_ChangePointerDevice;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ rep.status = -1;
+ SendErrorToClient(client, IReqCode, X_ChangePointerDevice, 0,
+ BadDevice);
+ return Success;
+ }
+
+ v = dev->valuator;
+ if (v == NULL || v->numAxes < 2 ||
+ stuff->xaxis >= v->numAxes ||
+ stuff->yaxis >= v->numAxes)
+ {
+ rep.status = -1;
+ SendErrorToClient(client, IReqCode, X_ChangePointerDevice, 0, BadMatch);
+ return Success;
+ }
+
+ if (((dev->grab) && !SameClient(dev->grab, client)) ||
+ ((xptr->grab) && !SameClient(xptr->grab, client)))
+ rep.status = AlreadyGrabbed;
+ else if ((dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client)) ||
+ (xptr->sync.frozen &&
+ xptr->sync.other && !SameClient(xptr->sync.other, client)))
+ rep.status = GrabFrozen;
+ else
+ {
+ if (ChangePointerDevice (
+ xptr, dev, stuff->xaxis, stuff->yaxis) != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_ChangePointerDevice, 0,
+ BadDevice);
+ return Success;
+ }
+ if (dev->focus)
+ DeleteFocusClassDeviceStruct(dev);
+ if (!dev->button)
+ InitButtonClassDeviceStruct (dev, 0, NULL);
+ if (!dev->ptrfeed)
+ InitPtrFeedbackClassDeviceStruct(dev, (PtrCtrlProcPtr)NoopDDA);
+ RegisterOtherDevice (xptr);
+ RegisterPointerDevice (dev);
+
+ ev.type = ChangeDeviceNotify;
+ ev.deviceid = stuff->deviceid;
+ ev.time = currentTime.milliseconds;
+ ev.request = NewPointer;
+
+ SendEventToAllWindows (dev, ChangeDeviceNotifyMask, (xEvent *)&ev, 1);
+ SendMappingNotify (MappingPointer, 0, 0, client);
+
+ rep.status = 0;
+ }
+
+ WriteReplyToClient (client, sizeof (xChangePointerDeviceReply),
+ &rep);
+ return Success;
+ }
+
+void
+DeleteFocusClassDeviceStruct(dev)
+ DeviceIntPtr dev;
+ {
+ free(dev->focus->trace);
+ free(dev->focus);
+ dev->focus = NULL;
+ }
+
+/***********************************************************************
+ *
+ * Send an event to interested clients in all windows on all screens.
+ *
+ */
+
+void
+SendEventToAllWindows (dev, mask, ev, count)
+ DeviceIntPtr dev;
+ Mask mask;
+ xEvent *ev;
+ int count;
+ {
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ pWin = screenInfo.screens[i]->root;
+ (void)DeliverEventsToWindow(pWin, ev, count, mask, NullGrab, dev->id);
+ p1 = pWin->firstChild;
+ FindInterestedChildren (dev, p1, mask, ev, count);
+ }
+ }
+
+/***********************************************************************
+ *
+ * Walk through the window tree, finding all clients that want to know
+ * about the ChangeDeviceNotify Event.
+ *
+ */
+
+void
+FindInterestedChildren (dev, p1, mask, ev, count)
+ DeviceIntPtr dev;
+ WindowPtr p1;
+ Mask mask;
+ xEvent *ev;
+ int count;
+ {
+ WindowPtr p2;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ (void)DeliverEventsToWindow(p1, ev, count, mask, NullGrab, dev->id);
+ FindInterestedChildren (dev, p2, mask, ev, count);
+ p1 = p1->nextSib;
+ }
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XChangePointerDevice
+ * function, if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXChangePointerDevice (client, size, rep)
+ ClientPtr client;
+ int size;
+ xChangePointerDeviceReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/chgptr.h b/nx-X11/programs/Xserver/Xi/chgptr.h
new file mode 100644
index 000000000..f63d96876
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/chgptr.h
@@ -0,0 +1,72 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHGPTR_H
+#define CHGPTR_H 1
+
+int
+SProcXChangePointerDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXChangePointerDevice (
+ ClientPtr /* client */
+ );
+
+void
+DeleteFocusClassDeviceStruct(
+ DeviceIntPtr /* dev */
+ );
+
+void
+SendEventToAllWindows (
+ DeviceIntPtr /* dev */,
+ Mask /* mask */,
+ xEvent * /* ev */,
+ int /* count */
+ );
+
+void
+FindInterestedChildren ( /* FIXME: could be static? */
+ DeviceIntPtr /* dev */,
+ WindowPtr /* p1 */,
+ Mask /* mask */,
+ xEvent * /* ev */,
+ int /* count */
+ );
+
+void
+SRepXChangePointerDevice (
+ ClientPtr /* client */,
+ int /* size */,
+ xChangePointerDeviceReply * /* rep */
+ );
+
+#endif /* CHGPTR_H */
diff --git a/nx-X11/programs/Xserver/Xi/closedev.c b/nx-X11/programs/Xserver/Xi/closedev.c
new file mode 100644
index 000000000..2ba90d0d1
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/closedev.c
@@ -0,0 +1,185 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to close an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include "scrnintstr.h" /* screen structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "closedev.h"
+
+/***********************************************************************
+ *
+ * This procedure closes an input device.
+ *
+ */
+
+int
+SProcXCloseDevice(client)
+ register ClientPtr client;
+ {
+ REQUEST(xCloseDeviceReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCloseDeviceReq);
+ return(ProcXCloseDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure closes an input device.
+ *
+ */
+
+int
+ProcXCloseDevice(client)
+ register ClientPtr client;
+ {
+ int i;
+ WindowPtr pWin, p1;
+ DeviceIntPtr d;
+
+ REQUEST(xCloseDeviceReq);
+ REQUEST_SIZE_MATCH(xCloseDeviceReq);
+
+ d = LookupDeviceIntRec (stuff->deviceid);
+ if (d == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_CloseDevice, 0, BadDevice);
+ return Success;
+ }
+
+ if (d->grab && SameClient(d->grab, client))
+ (*d->DeactivateGrab)(d); /* release active grab */
+
+ /* Remove event selections from all windows for events from this device
+ and selected by this client.
+ Delete passive grabs from all windows for this device. */
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ pWin = screenInfo.screens[i]->root;
+ DeleteDeviceEvents (d, pWin, client);
+ p1 = pWin->firstChild;
+ DeleteEventsFromChildren (d, p1, client);
+ }
+
+ CloseInputDevice (d, client);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * Walk througth the window tree, deleting event selections for this client
+ * from this device from all windows.
+ *
+ */
+
+void
+DeleteEventsFromChildren(dev, p1, client)
+ DeviceIntPtr dev;
+ WindowPtr p1;
+ ClientPtr client;
+ {
+ WindowPtr p2;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ DeleteDeviceEvents (dev, p1, client);
+ DeleteEventsFromChildren(dev, p2, client);
+ p1 = p1->nextSib;
+ }
+ }
+
+/***********************************************************************
+ *
+ * Clear out event selections and passive grabs from a window for the
+ * specified device.
+ *
+ */
+
+void
+DeleteDeviceEvents (dev, pWin, client)
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ ClientPtr client;
+ {
+ InputClientsPtr others;
+ OtherInputMasks *pOthers;
+ GrabPtr grab, next;
+
+ if ((pOthers = wOtherInputMasks(pWin)) != 0)
+ for (others=pOthers->inputClients; others;
+ others = others->next)
+ if (SameClient(others,client))
+ others->mask[dev->id] = NoEventMask;
+
+ for (grab = wPassiveGrabs(pWin); grab; grab=next)
+ {
+ next = grab->next;
+ if ((grab->device == dev) &&
+ (client->clientAsMask == CLIENT_BITS(grab->resource)))
+ FreeResource (grab->resource, RT_NONE);
+ }
+ }
diff --git a/nx-X11/programs/Xserver/Xi/closedev.h b/nx-X11/programs/Xserver/Xi/closedev.h
new file mode 100644
index 000000000..61e42e2f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/closedev.h
@@ -0,0 +1,57 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CLOSEDEV_H
+#define CLOSEDEV_H 1
+
+int
+SProcXCloseDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXCloseDevice(
+ ClientPtr /* client */
+ );
+
+void
+DeleteEventsFromChildren(
+ DeviceIntPtr /* dev */,
+ WindowPtr /* p1 */,
+ ClientPtr /* client */
+ );
+
+void
+DeleteDeviceEvents (
+ DeviceIntPtr /* dev */,
+ WindowPtr /* pWin */,
+ ClientPtr /* client */
+ );
+
+#endif /* CLOSEDEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/devbell.c b/nx-X11/programs/Xserver/Xi/devbell.c
new file mode 100644
index 000000000..7fac4f972
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/devbell.c
@@ -0,0 +1,167 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to change the keyboard device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "devbell.h"
+
+/***********************************************************************
+ *
+ * This procedure is invoked to swap the request bytes if the server and
+ * client have a different byte order.
+ *
+ */
+
+int
+SProcXDeviceBell(client)
+ register ClientPtr client;
+ {
+ REQUEST(xDeviceBellReq);
+ swaps(&stuff->length);
+ return(ProcXDeviceBell(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure rings a bell on an extension device.
+ *
+ */
+
+int
+ProcXDeviceBell (client)
+ register ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ KbdFeedbackPtr k;
+ BellFeedbackPtr b;
+ int base;
+ int newpercent;
+ CARD8 class;
+ void * ctrl;
+ BellProcPtr proc;
+
+ REQUEST(xDeviceBellReq);
+ REQUEST_SIZE_MATCH(xDeviceBellReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ client->errorValue = stuff->deviceid;
+ SendErrorToClient(client, IReqCode, X_DeviceBell, 0, BadDevice);
+ return Success;
+ }
+
+ if (stuff->percent < -100 || stuff->percent > 100)
+ {
+ client->errorValue = stuff->percent;
+ SendErrorToClient(client, IReqCode, X_DeviceBell, 0, BadValue);
+ return Success;
+ }
+ if (stuff->feedbackclass == KbdFeedbackClass)
+ {
+ for (k=dev->kbdfeed; k; k=k->next)
+ if (k->ctrl.id == stuff->feedbackid)
+ break;
+ if (!k)
+ {
+ client->errorValue = stuff->feedbackid;
+ SendErrorToClient(client, IReqCode, X_DeviceBell, 0, BadValue);
+ return Success;
+ }
+ base = k->ctrl.bell;
+ proc = k->BellProc;
+ ctrl = (void *) &(k->ctrl);
+ class = KbdFeedbackClass;
+ }
+ else if (stuff->feedbackclass == BellFeedbackClass)
+ {
+ for (b=dev->bell; b; b=b->next)
+ if (b->ctrl.id == stuff->feedbackid)
+ break;
+ if (!b)
+ {
+ client->errorValue = stuff->feedbackid;
+ SendErrorToClient(client, IReqCode, X_DeviceBell, 0, BadValue);
+ return Success;
+ }
+ base = b->ctrl.percent;
+ proc = b->BellProc;
+ ctrl = (void *) &(b->ctrl);
+ class = BellFeedbackClass;
+ }
+ else
+ {
+ client->errorValue = stuff->feedbackclass;
+ SendErrorToClient(client, IReqCode, X_DeviceBell, 0, BadValue);
+ return Success;
+ }
+ newpercent = (base * stuff->percent) / 100;
+ if (stuff->percent < 0)
+ newpercent = base + newpercent;
+ else
+ newpercent = base - newpercent + stuff->percent;
+ (*proc)(newpercent, dev, ctrl, class);
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/devbell.h b/nx-X11/programs/Xserver/Xi/devbell.h
new file mode 100644
index 000000000..d1289bedf
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/devbell.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef DEVBELL_H
+#define DEVBELL_H 1
+
+int
+SProcXDeviceBell (
+ ClientPtr /* client */
+ );
+
+int
+ProcXDeviceBell (
+ ClientPtr /* client */
+ );
+
+#endif /* DEVBELL_H */
diff --git a/nx-X11/programs/Xserver/Xi/exevents.c b/nx-X11/programs/Xserver/Xi/exevents.c
new file mode 100644
index 000000000..3b5a070b6
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/exevents.c
@@ -0,0 +1,1363 @@
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Routines to register and initialize extension input devices.
+ * This also contains ProcessOtherEvent, the routine called from DDX
+ * to route extension events.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "inputstr.h"
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "exevents.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "dixevents.h" /* DeliverFocusedEvent */
+#include "dixgrabs.h" /* CreateGrab() */
+
+#include "chgptr.h"
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define Motion_Filter(class) (DevicePointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+static Bool ShouldFreeInputMasks(
+ WindowPtr /* pWin */,
+ Bool /* ignoreSelectedEvents */
+ );
+static Bool MakeInputMasks (
+ WindowPtr /* pWin */
+ );
+
+/**************************************************************************
+ *
+ * Procedures for extension device event routing.
+ *
+ */
+
+void
+RegisterOtherDevice (device)
+ DeviceIntPtr device;
+ {
+ device->public.processInputProc = ProcessOtherEvent;
+ device->public.realInputProc = ProcessOtherEvent;
+ (device)->ActivateGrab = ActivateKeyboardGrab;
+ (device)->DeactivateGrab = DeactivateKeyboardGrab;
+ }
+
+/*ARGSUSED*/
+void
+ProcessOtherEvent (xE, other, count)
+ xEventPtr xE;
+ register DeviceIntPtr other;
+ int count;
+ {
+ register BYTE *kptr;
+ register int i;
+ register CARD16 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = other->grab;
+ Bool deactivateDeviceGrab = FALSE;
+ int key = 0, bit = 0, rootX, rootY;
+ ButtonClassPtr b = other->button;
+ KeyClassPtr k = other->key;
+ ValuatorClassPtr v = other->valuator;
+ deviceValuator *xV = (deviceValuator *) xE;
+
+ if (xE->u.u.type != DeviceValuator) {
+ GetSpritePosition(&rootX, &rootY);
+ xE->u.keyButtonPointer.rootX = rootX;
+ xE->u.keyButtonPointer.rootY = rootY;
+ key = xE->u.u.detail;
+ NoticeEventTime(xE);
+ xE->u.keyButtonPointer.state = inputInfo.keyboard->key->state |
+ inputInfo.pointer->button->state;
+ bit = 1 << (key & 7);
+ }
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = (xEventPtr) xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
+ }
+ for (i=1; i<count; i++)
+ if ((++xV)->type == DeviceValuator)
+ {
+ int first = xV->first_valuator;
+ int *axisvals;
+
+ if (xV->num_valuators && (!v || (xV->num_valuators && (first + xV->num_valuators > v->numAxes))))
+ FatalError("Bad valuators reported for device %s\n",other->name);
+ xV->device_state = 0;
+ if (k)
+ xV->device_state |= k->state;
+ if (b)
+ xV->device_state |= b->state;
+ if (v && v->axisVal)
+ {
+ axisvals = v->axisVal;
+ switch (xV->num_valuators) {
+ case 6:
+ *(axisvals+first+5) = xV->valuator5;
+ case 5:
+ *(axisvals+first+4) = xV->valuator4;
+ case 4:
+ *(axisvals+first+3) = xV->valuator3;
+ case 3:
+ *(axisvals+first+2) = xV->valuator2;
+ case 2:
+ *(axisvals+first+1) = xV->valuator1;
+ case 1:
+ *(axisvals+first) = xV->valuator0;
+ case 0:
+ default:
+ break;
+ }
+ }
+ }
+
+ if (xE->u.u.type == DeviceKeyPress)
+ {
+ modifiers = k->modifierMap[key];
+ kptr = &k->down[key >> 3];
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = DeviceKeyRelease;
+ ProcessOtherEvent(xE, other, count);
+ xE->u.u.type = DeviceKeyPress;
+ /* release can have side effects, don't fall through */
+ ProcessOtherEvent(xE, other, count);
+ }
+ return;
+ }
+ if (other->valuator)
+ other->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ k->prev_state = k->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ k->modifierKeyCount[i]++;
+ k->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(other, xE, 0, count))
+ {
+ other->activatingKey = key;
+ return;
+ }
+ }
+ else if (xE->u.u.type == DeviceKeyRelease)
+ {
+ kptr = &k->down[key >> 3];
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ modifiers = k->modifierMap[key];
+ if (other->valuator)
+ other->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ k->prev_state = k->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ if (--k->modifierKeyCount[i] <= 0)
+ {
+ k->modifierKeyCount[i] = 0;
+ k->state &= ~mask;
+ }
+ modifiers &= ~mask;
+ }
+ }
+
+ if (other->fromPassiveGrab && (key == other->activatingKey))
+ deactivateDeviceGrab = TRUE;
+ }
+ else if (xE->u.u.type == DeviceButtonPress)
+ {
+ kptr = &b->down[key >> 3];
+ *kptr |= bit;
+ if (other->valuator)
+ other->valuator->motionHintWindow = NullWindow;
+ b->buttonsDown++;
+ b->motionMask = DeviceButtonMotionMask;
+ xE->u.u.detail = b->map[key];
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ b->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
+ if (!grab)
+ if (CheckDeviceGrabs(other, xE, 0, count))
+ return;
+
+ }
+ else if (xE->u.u.type == DeviceButtonRelease)
+ {
+ kptr = &b->down[key >> 3];
+ *kptr &= ~bit;
+ if (other->valuator)
+ other->valuator->motionHintWindow = NullWindow;
+ if (!--b->buttonsDown)
+ b->motionMask = 0;
+ xE->u.u.detail = b->map[key];
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ b->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
+ if (!b->state && other->fromPassiveGrab)
+ deactivateDeviceGrab = TRUE;
+ }
+ else if (xE->u.u.type == ProximityIn)
+ other->valuator->mode &= ~OutOfProximity;
+ else if (xE->u.u.type == ProximityOut)
+ other->valuator->mode |= OutOfProximity;
+
+ if (grab)
+ DeliverGrabbedEvent(xE, other, deactivateDeviceGrab, count);
+ else if (other->focus)
+ DeliverFocusedEvent(other, xE, GetSpriteWindow(), count);
+ else
+ DeliverDeviceEvents(GetSpriteWindow(), xE, NullGrab, NullWindow,
+ other, count);
+
+ if (deactivateDeviceGrab == TRUE)
+ (*other->DeactivateGrab)(other);
+ }
+
+int
+InitProximityClassDeviceStruct( DeviceIntPtr dev)
+{
+ register ProximityClassPtr proxc;
+
+ proxc = (ProximityClassPtr)malloc(sizeof(ProximityClassRec));
+ if (!proxc)
+ return FALSE;
+ dev->proximity = proxc;
+ return TRUE;
+}
+
+void
+InitValuatorAxisStruct( DeviceIntPtr dev,
+ int axnum,
+ int minval,
+ int maxval,
+ int resolution,
+ int min_res,
+ int max_res )
+{
+ register AxisInfoPtr ax = dev->valuator->axes + axnum;
+
+ ax->min_value = minval;
+ ax->max_value = maxval;
+ ax->resolution = resolution;
+ ax->min_resolution = min_res;
+ ax->max_resolution = max_res;
+}
+
+static void
+FixDeviceStateNotify (
+ DeviceIntPtr dev,
+ deviceStateNotify *ev,
+ KeyClassPtr k,
+ ButtonClassPtr b,
+ ValuatorClassPtr v,
+ int first)
+{
+ ev->type = DeviceStateNotify;
+ ev->deviceid = dev->id;
+ ev->time = currentTime.milliseconds;
+ ev->classes_reported = 0;
+ ev->num_keys = 0;
+ ev->num_buttons = 0;
+ ev->num_valuators = 0;
+
+ if (b) {
+ ev->classes_reported |= (1 << ButtonClass);
+ ev->num_buttons = b->numButtons;
+ memmove((char *) &ev->buttons[0], (char *) b->down, 4);
+ }
+ else if (k) {
+ ev->classes_reported |= (1 << KeyClass);
+ ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ memmove((char *) &ev->keys[0], (char *) k->down, 4);
+ }
+ if (v) {
+ int nval = v->numAxes - first;
+ ev->classes_reported |= (1 << ValuatorClass);
+ ev->classes_reported |= (dev->valuator->mode << ModeBitsShift);
+ ev->num_valuators = nval < 3 ? nval : 3;
+ switch (ev->num_valuators)
+ {
+ case 3:
+ ev->valuator2 = v->axisVal[first+2];
+ case 2:
+ ev->valuator1 = v->axisVal[first+1];
+ case 1:
+ ev->valuator0 = v->axisVal[first];
+ break;
+ }
+ }
+ }
+
+static void
+FixDeviceValuator (
+ DeviceIntPtr dev,
+ deviceValuator *ev,
+ ValuatorClassPtr v,
+ int first)
+{
+ int nval = v->numAxes - first;
+
+ ev->type = DeviceValuator;
+ ev->deviceid = dev->id;
+ ev->num_valuators = nval < 3 ? nval : 3;
+ ev->first_valuator = first;
+ switch (ev->num_valuators) {
+ case 3:
+ ev->valuator2 = v->axisVal[first+2];
+ case 2:
+ ev->valuator1 = v->axisVal[first+1];
+ case 1:
+ ev->valuator0 = v->axisVal[first];
+ break;
+ }
+ first += ev->num_valuators;
+ }
+
+void
+DeviceFocusEvent(dev, type, mode, detail, pWin)
+ DeviceIntPtr dev;
+ int type, mode, detail;
+ register WindowPtr pWin;
+ {
+ deviceFocus event;
+
+ if (type == FocusIn)
+ type = DeviceFocusIn;
+ else
+ type = DeviceFocusOut;
+
+ event.deviceid = dev->id;
+ event.mode = mode;
+ event.type = type;
+ event.detail = detail;
+ event.window = pWin->drawable.id;
+ event.time = currentTime.milliseconds;
+
+ (void) DeliverEventsToWindow(pWin, (xEvent *)&event, 1,
+ DeviceFocusChangeMask, NullGrab, dev->id);
+
+ if ((type == DeviceFocusIn) &&
+ (wOtherInputMasks(pWin)) &&
+ (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
+ {
+ int evcount = 1;
+ deviceStateNotify *ev, *sev;
+ deviceKeyStateNotify *kev;
+ deviceButtonStateNotify *bev;
+
+ KeyClassPtr k;
+ ButtonClassPtr b;
+ ValuatorClassPtr v;
+ int nval=0, nkeys=0, nbuttons=0, first=0;
+
+ if ((b=dev->button) != NULL) {
+ nbuttons = b->numButtons;
+ if (nbuttons > 32)
+ evcount++;
+ }
+ if ((k=dev->key) != NULL) {
+ nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ if (nkeys > 32)
+ evcount++;
+ if (nbuttons > 0) {
+ evcount++;
+ }
+ }
+ if ((v=dev->valuator) != NULL) {
+ nval = v->numAxes;
+
+ if (nval > 3)
+ evcount++;
+ if (nval > 6) {
+ if (!(k && b))
+ evcount++;
+ if (nval > 9)
+ evcount += ((nval - 7) / 3);
+ }
+ }
+
+ sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
+ FixDeviceStateNotify (dev, ev, NULL, NULL, NULL, first);
+
+ if (b != NULL) {
+ FixDeviceStateNotify (dev, ev++, NULL, b, v, first);
+ first += 3;
+ nval -= 3;
+ if (nbuttons > 32) {
+ (ev-1)->deviceid |= MORE_EVENTS;
+ bev = (deviceButtonStateNotify *) ev++;
+ bev->type = DeviceButtonStateNotify;
+ bev->deviceid = dev->id;
+ memmove((char *) &bev->buttons[0], (char *) &b->down[4], 28);
+ }
+ if (nval > 0) {
+ (ev-1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ if (k != NULL) {
+ FixDeviceStateNotify (dev, ev++, k, NULL, v, first);
+ first += 3;
+ nval -= 3;
+ if (nkeys > 32) {
+ (ev-1)->deviceid |= MORE_EVENTS;
+ kev = (deviceKeyStateNotify *) ev++;
+ kev->type = DeviceKeyStateNotify;
+ kev->deviceid = dev->id;
+ memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
+ }
+ if (nval > 0) {
+ (ev-1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ while (nval > 0) {
+ FixDeviceStateNotify (dev, ev++, NULL, NULL, v, first);
+ first += 3;
+ nval -= 3;
+ if (nval > 0) {
+ (ev-1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ (void) DeliverEventsToWindow(pWin, (xEvent *)sev, evcount,
+ DeviceStateNotifyMask, NullGrab, dev->id);
+ free (sev);
+ }
+ }
+
+int
+GrabButton(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ BYTE this_device_mode,
+ BYTE other_devices_mode,
+ CARD16 modifiers,
+ DeviceIntPtr modifier_device,
+ CARD8 button,
+ Window grabWindow,
+ BOOL ownerEvents,
+ Cursor rcursor,
+ Window rconfineTo,
+ Mask eventMask)
+{
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ if ((this_device_mode != GrabModeSync) &&
+ (this_device_mode != GrabModeAsync))
+ {
+ client->errorValue = this_device_mode;
+ return BadValue;
+ }
+ if ((other_devices_mode != GrabModeSync) &&
+ (other_devices_mode != GrabModeAsync))
+ {
+ client->errorValue = other_devices_mode;
+ return BadValue;
+ }
+ if ((modifiers != AnyModifier) &&
+ (modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = modifiers;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = LookupWindow(grabWindow, client);
+ if (!pWin)
+ return BadWindow;
+ if (rconfineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = LookupWindow(rconfineTo, client);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (rcursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)LookupIDByType(rcursor, RT_CURSOR);
+ if (!cursor)
+ {
+ client->errorValue = rcursor;
+ return BadCursor;
+ }
+ }
+
+ grab = CreateGrab(client->index, dev, pWin, eventMask,
+ (Bool)ownerEvents, (Bool) this_device_mode, (Bool)other_devices_mode,
+ modifier_device, modifiers, DeviceButtonPress, button, confineTo,
+ cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+ }
+
+int
+GrabKey(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ BYTE this_device_mode,
+ BYTE other_devices_mode,
+ CARD16 modifiers,
+ DeviceIntPtr modifier_device,
+ CARD8 key,
+ Window grabWindow,
+ BOOL ownerEvents,
+ Mask mask)
+{
+ WindowPtr pWin;
+ GrabPtr grab;
+ KeyClassPtr k = dev->key;
+
+ if (k==NULL)
+ return BadMatch;
+ if ((other_devices_mode != GrabModeSync) &&
+ (other_devices_mode != GrabModeAsync))
+ {
+ client->errorValue = other_devices_mode;
+ return BadValue;
+ }
+ if ((this_device_mode != GrabModeSync) &&
+ (this_device_mode != GrabModeAsync))
+ {
+ client->errorValue = this_device_mode;
+ return BadValue;
+ }
+ if (((key > k->curKeySyms.maxKeyCode) ||
+ (key < k->curKeySyms.minKeyCode))
+ && (key != AnyKey))
+ {
+ client->errorValue = key;
+ return BadValue;
+ }
+ if ((modifiers != AnyModifier) &&
+ (modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = modifiers;
+ return BadValue;
+ }
+ if ((ownerEvents != xTrue) && (ownerEvents != xFalse))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = LookupWindow(grabWindow, client);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, dev, pWin,
+ mask, ownerEvents, this_device_mode, other_devices_mode,
+ modifier_device, modifiers, DeviceKeyPress, key, NullWindow,
+ NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+ }
+
+int
+SelectForWindow(dev, pWin, client, mask, exclusivemasks, validmasks)
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ ClientPtr client;
+ Mask mask;
+ Mask exclusivemasks;
+ Mask validmasks;
+{
+ int mskidx = dev->id;
+ int i, ret;
+ Mask check;
+ InputClientsPtr others;
+
+ if (mask & ~validmasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & exclusivemasks);
+ if (wOtherInputMasks(pWin))
+ {
+ if (check & wOtherInputMasks(pWin)->inputEvents[mskidx])
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for maskcheck. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ for (others = wOtherInputMasks(pWin)->inputClients; others;
+ others = others->next)
+ {
+ if (!SameClient(others, client) && (check &
+ others->mask[mskidx]))
+ return BadAccess;
+ }
+ }
+ for (others = wOtherInputMasks(pWin)->inputClients; others;
+ others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask[mskidx];
+ others->mask[mskidx] = mask;
+ if (mask == 0)
+ {
+ for (i=0; i<EMASKSIZE; i++)
+ if (i != mskidx && others->mask[i] != 0)
+ break;
+ if (i == EMASKSIZE)
+ {
+ RecalculateDeviceDeliverableEvents(pWin);
+ if (ShouldFreeInputMasks(pWin, FALSE))
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ }
+ goto maskSet;
+ }
+ }
+ }
+ check = 0;
+ if ((ret = AddExtensionClient (pWin, client, mask, mskidx)) != Success)
+ return ret;
+maskSet:
+ if (dev->valuator)
+ if ((dev->valuator->motionHintWindow == pWin) &&
+ (mask & DevicePointerMotionHintMask) &&
+ !(check & DevicePointerMotionHintMask) &&
+ !dev->grab)
+ dev->valuator->motionHintWindow = NullWindow;
+ RecalculateDeviceDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+AddExtensionClient (pWin, client, mask, mskidx)
+ WindowPtr pWin;
+ ClientPtr client;
+ Mask mask;
+ int mskidx;
+ {
+ InputClientsPtr others;
+
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (InputClients *) malloc(sizeof(InputClients));
+ if (!others)
+ return BadAlloc;
+ if (!pWin->optional->inputMasks && !MakeInputMasks (pWin))
+ return BadAlloc;
+ bzero((char *) &others->mask[0], sizeof(Mask)*EMASKSIZE);
+ others->mask[mskidx] = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->inputMasks->inputClients;
+ pWin->optional->inputMasks->inputClients = others;
+ if (!AddResource(others->resource, RT_INPUTCLIENT, (void *)pWin))
+ return BadAlloc;
+ return Success;
+ }
+
+static Bool
+MakeInputMasks (pWin)
+ WindowPtr pWin;
+ {
+ struct _OtherInputMasks *imasks;
+
+ imasks = (struct _OtherInputMasks *)
+ malloc (sizeof (struct _OtherInputMasks));
+ if (!imasks)
+ return FALSE;
+ bzero((char *) imasks, sizeof (struct _OtherInputMasks));
+ pWin->optional->inputMasks = imasks;
+ return TRUE;
+ }
+
+void
+RecalculateDeviceDeliverableEvents(pWin)
+ WindowPtr pWin;
+ {
+ register InputClientsPtr others;
+ struct _OtherInputMasks *inputMasks; /* default: NULL */
+ register WindowPtr pChild, tmp;
+ int i;
+
+ pChild = pWin;
+ while (1)
+ {
+ if ((inputMasks = wOtherInputMasks(pChild)) != 0)
+ {
+ for (others = inputMasks->inputClients; others;
+ others = others->next)
+ {
+ for (i=0; i<EMASKSIZE; i++)
+ inputMasks->inputEvents[i] |= others->mask[i];
+ }
+ for (i=0; i<EMASKSIZE; i++)
+ inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
+ for (tmp = pChild->parent; tmp; tmp=tmp->parent)
+ if (wOtherInputMasks(tmp))
+ for (i=0; i<EMASKSIZE; i++)
+ inputMasks->deliverableEvents[i] |=
+ (wOtherInputMasks(tmp)->deliverableEvents[i]
+ & ~inputMasks->dontPropagateMask[i] & PropagateMask[i]);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+
+int
+InputClientGone(pWin, id)
+ register WindowPtr pWin;
+ XID id;
+ {
+ register InputClientsPtr other, prev;
+ if (!wOtherInputMasks(pWin))
+ return(Success);
+ prev = 0;
+ for (other = wOtherInputMasks(pWin)->inputClients; other;
+ other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ {
+ prev->next = other->next;
+ free(other);
+ }
+ else if (!(other->next))
+ {
+ if (ShouldFreeInputMasks(pWin, TRUE))
+ {
+ wOtherInputMasks(pWin)->inputClients = other->next;
+ free(wOtherInputMasks(pWin));
+ pWin->optional->inputMasks = (OtherInputMasks *) NULL;
+ CheckWindowOptionalNeed (pWin);
+ free(other);
+ }
+ else
+ {
+ other->resource = FakeClientID(0);
+ if (!AddResource(other->resource, RT_INPUTCLIENT,
+ (void *)pWin))
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ wOtherInputMasks(pWin)->inputClients = other->next;
+ free(other);
+ }
+ RecalculateDeviceDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on device event list");
+ /*NOTREACHED*/
+ }
+
+int
+SendEvent (client, d, dest, propagate, ev, mask, count)
+ ClientPtr client;
+ DeviceIntPtr d;
+ Window dest;
+ Bool propagate;
+ xEvent *ev;
+ Mask mask;
+ int count;
+ {
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ WindowPtr spriteWin=GetSpriteWindow();
+
+ if (dest == PointerWindow)
+ pWin = spriteWin;
+ else if (dest == InputFocus)
+ {
+ WindowPtr inputFocus;
+
+ if (!d->focus)
+ inputFocus = spriteWin;
+ else
+ inputFocus = d->focus->win;
+
+ if (inputFocus == FollowKeyboardWin)
+ inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = GetCurrentRootWindow();
+
+ if (IsParent(inputFocus, spriteWin))
+ {
+ effectiveFocus = inputFocus;
+ pWin = spriteWin;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = LookupWindow(dest, client);
+ if (!pWin)
+ return BadWindow;
+ if ((propagate != xFalse) && (propagate != xTrue))
+ {
+ client->errorValue = propagate;
+ return BadValue;
+ }
+ ev->u.u.type |= 0x80;
+ if (propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ if (wOtherInputMasks(pWin))
+ mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
+ if (!mask)
+ break;
+ }
+ }
+ else
+ (void)(DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id));
+ return Success;
+ }
+
+int
+SetButtonMapping (client, dev, nElts, map)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ int nElts;
+ BYTE *map;
+ {
+ register int i;
+ ButtonClassPtr b = dev->button;
+
+ if (b == NULL)
+ return BadMatch;
+
+ if (nElts != b->numButtons)
+ {
+ client->errorValue = nElts;
+ return BadValue;
+ }
+ if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
+ return BadValue;
+ for (i=0; i < nElts; i++)
+ if ((b->map[i + 1] != map[i]) &&
+ BitIsOn(b->down, i + 1))
+ return MappingBusy;
+ for (i = 0; i < nElts; i++)
+ b->map[i + 1] = map[i];
+ return Success;
+ }
+
+int
+SetModifierMapping(client, dev, len, rlen, numKeyPerModifier, inputMap, k)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ int len;
+ int rlen;
+ int numKeyPerModifier;
+ KeyCode *inputMap;
+ KeyClassPtr *k;
+{
+ KeyCode *map = NULL;
+ int inputMapLen;
+ register int i;
+
+ *k = dev->key;
+ if (*k == NULL)
+ return BadMatch;
+ if (len != ((numKeyPerModifier<<1) + rlen))
+ return BadLength;
+
+ inputMapLen = 8*numKeyPerModifier;
+
+ /*
+ * Now enforce the restriction that "all of the non-zero keycodes must be
+ * in the range specified by min-keycode and max-keycode in the
+ * connection setup (else a Value error)"
+ */
+ i = inputMapLen;
+ while (i--) {
+ if (inputMap[i]
+ && (inputMap[i] < (*k)->curKeySyms.minKeyCode
+ || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
+ client->errorValue = inputMap[i];
+ return -1; /* BadValue collides with MappingFailed */
+ }
+ }
+
+ /*
+ * Now enforce the restriction that none of the old or new
+ * modifier keys may be down while we change the mapping, and
+ * that the DDX layer likes the choice.
+ */
+ if (!AllModifierKeysAreUp (dev, (*k)->modifierKeyMap,
+ (int)(*k)->maxKeysPerModifier, inputMap, (int)numKeyPerModifier)
+ ||
+ !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
+ (*k)->modifierKeyMap, (int)(*k)->maxKeysPerModifier)) {
+ return MappingBusy;
+ } else {
+ for (i = 0; i < inputMapLen; i++) {
+ if (inputMap[i] && !LegalModifier(inputMap[i], (DevicePtr)dev)) {
+ return MappingFailed;
+ }
+ }
+ }
+
+ /*
+ * Now build the keyboard's modifier bitmap from the
+ * list of keycodes.
+ */
+ if (inputMapLen) {
+ map = (KeyCode *)malloc(inputMapLen);
+ if (!map)
+ return BadAlloc;
+ }
+ if ((*k)->modifierKeyMap)
+ free((*k)->modifierKeyMap);
+ if (inputMapLen) {
+ (*k)->modifierKeyMap = map;
+ memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen);
+ } else
+ (*k)->modifierKeyMap = NULL;
+
+ (*k)->maxKeysPerModifier = numKeyPerModifier;
+ for (i = 0; i < MAP_LENGTH; i++)
+ (*k)->modifierMap[i] = 0;
+ for (i = 0; i < inputMapLen; i++) if (inputMap[i]) {
+ (*k)->modifierMap[inputMap[i]]
+ |= (1<<(i/ (*k)->maxKeysPerModifier));
+ }
+
+ return(MappingSuccess);
+ }
+
+void
+SendDeviceMappingNotify(
+ CARD8 request,
+ KeyCode firstKeyCode,
+ CARD8 count,
+ DeviceIntPtr dev)
+{
+ xEvent event;
+ deviceMappingNotify *ev = (deviceMappingNotify *) &event;
+
+ ev->type = DeviceMappingNotify;
+ ev->request = request;
+ ev->deviceid = dev->id;
+ ev->time = currentTime.milliseconds;
+ if (request == MappingKeyboard)
+ {
+ ev->firstKeyCode = firstKeyCode;
+ ev->count = count;
+ }
+
+ SendEventToAllWindows (dev, DeviceMappingNotifyMask, (xEvent *)ev, 1);
+ }
+
+int
+ChangeKeyMapping(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ unsigned len,
+ int type,
+ KeyCode firstKeyCode,
+ CARD8 keyCodes,
+ CARD8 keySymsPerKeyCode,
+ KeySym *map)
+{
+ KeySymsRec keysyms;
+ KeyClassPtr k = dev->key;
+
+ if (k == NULL)
+ return (BadMatch);
+
+ if (len != (keyCodes * keySymsPerKeyCode))
+ return BadLength;
+
+ if ((firstKeyCode < k->curKeySyms.minKeyCode) ||
+ (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode))
+ {
+ client->errorValue = firstKeyCode;
+ return BadValue;
+ }
+ if (keySymsPerKeyCode == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ keysyms.minKeyCode = firstKeyCode;
+ keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
+ keysyms.mapWidth = keySymsPerKeyCode;
+ keysyms.map = map;
+ if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
+ return BadAlloc;
+ SendDeviceMappingNotify(MappingKeyboard, firstKeyCode, keyCodes,
+ dev);
+ return client->noClientException;
+ }
+
+void
+DeleteWindowFromAnyExtEvents(pWin, freeResources)
+ WindowPtr pWin;
+ Bool freeResources;
+ {
+ int i;
+ DeviceIntPtr dev;
+ InputClientsPtr ic;
+ struct _OtherInputMasks *inputMasks;
+
+ for (dev=inputInfo.devices; dev; dev=dev->next)
+ {
+ if (dev == inputInfo.pointer ||
+ dev == inputInfo.keyboard)
+ continue;
+ DeleteDeviceFromAnyExtEvents(pWin, dev);
+ }
+
+ for (dev=inputInfo.off_devices; dev; dev=dev->next)
+ DeleteDeviceFromAnyExtEvents(pWin, dev);
+
+ if (freeResources)
+ while ((inputMasks = wOtherInputMasks(pWin)) != 0)
+ {
+ ic = inputMasks->inputClients;
+ for (i=0; i<EMASKSIZE; i++)
+ inputMasks->dontPropagateMask[i] = 0;
+ FreeResource(ic->resource, RT_NONE);
+ }
+ }
+
+void
+DeleteDeviceFromAnyExtEvents(pWin, dev)
+ WindowPtr pWin;
+ DeviceIntPtr dev;
+ {
+ WindowPtr parent;
+
+ /* Deactivate any grabs performed on this window, before making
+ any input focus changes.
+ Deactivating a device grab should cause focus events. */
+
+ if (dev->grab && (dev->grab->window == pWin))
+ (*dev->DeactivateGrab)(dev);
+
+ /* If the focus window is a root window (ie. has no parent)
+ then don't delete the focus from it. */
+
+ if (dev->focus && (pWin==dev->focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (dev->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (dev->focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ dev->focus->win = NoneWin;
+ dev->focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ dev->focus->traceGood--;
+ } while (!parent->realized);
+ DoFocusEvents(dev, pWin, parent, focusEventMode);
+ dev->focus->win = parent;
+ dev->focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
+ dev->focus->win = PointerRootWin;
+ dev->focus->traceGood = 0;
+ break;
+ case RevertToFollowKeyboard:
+ if (inputInfo.keyboard->focus->win) {
+ DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win,
+ focusEventMode);
+ dev->focus->win = FollowKeyboardWin;
+ dev->focus->traceGood = 0;
+ } else {
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ dev->focus->win = NoneWin;
+ dev->focus->traceGood = 0;
+ }
+ break;
+ }
+ }
+
+ if (dev->valuator)
+ if (dev->valuator->motionHintWindow == pWin)
+ dev->valuator->motionHintWindow = NullWindow;
+ }
+
+int
+MaybeSendDeviceMotionNotifyHint (pEvents, mask)
+ deviceKeyButtonPointer *pEvents;
+ Mask mask;
+ {
+ DeviceIntPtr dev;
+
+ dev = LookupDeviceIntRec (pEvents->deviceid & DEVICE_BITS);
+ if (pEvents->type == DeviceMotionNotify)
+ {
+ if (mask & DevicePointerMotionHintMask)
+ {
+ if (WID(dev->valuator->motionHintWindow) == pEvents->event)
+ {
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->detail = NotifyNormal;
+ }
+ }
+ return (0);
+ }
+
+void
+CheckDeviceGrabAndHintWindow (pWin, type, xE, grab, client, deliveryMask)
+ WindowPtr pWin;
+ int type;
+ deviceKeyButtonPointer *xE;
+ GrabPtr grab;
+ ClientPtr client;
+ Mask deliveryMask;
+ {
+ DeviceIntPtr dev;
+
+ dev = LookupDeviceIntRec (xE->deviceid & DEVICE_BITS);
+ if (type == DeviceMotionNotify)
+ dev->valuator->motionHintWindow = pWin;
+ else if ((type == DeviceButtonPress) && (!grab) &&
+ (deliveryMask & DeviceButtonGrabMask))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = dev;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*dev->ActivateGrab)(dev, &tempGrab, currentTime, TRUE);
+ }
+ }
+
+Mask
+DeviceEventMaskForClient(dev, pWin, client)
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ ClientPtr client;
+ {
+ register InputClientsPtr other;
+
+ if (!wOtherInputMasks(pWin))
+ return 0;
+ for (other = wOtherInputMasks(pWin)->inputClients; other;
+ other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask[dev->id];
+ }
+ return 0;
+ }
+
+void
+MaybeStopDeviceHint(dev, client)
+ register DeviceIntPtr dev;
+ ClientPtr client;
+{
+ WindowPtr pWin;
+ GrabPtr grab = dev->grab;
+ pWin = dev->valuator->motionHintWindow;
+
+ if ((grab && SameClient(grab, client) &&
+ ((grab->eventMask & DevicePointerMotionHintMask) ||
+ (grab->ownerEvents &&
+ (DeviceEventMaskForClient(dev, pWin, client) &
+ DevicePointerMotionHintMask)))) ||
+ (!grab &&
+ (DeviceEventMaskForClient(dev, pWin, client) &
+ DevicePointerMotionHintMask)))
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+DeviceEventSuppressForWindow(pWin, client, mask, maskndx)
+ WindowPtr pWin;
+ ClientPtr client;
+ Mask mask;
+ int maskndx;
+ {
+ struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
+
+ if (mask & ~PropagateMask[maskndx])
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+
+ if (mask == 0)
+ {
+ if (inputMasks)
+ inputMasks->dontPropagateMask[maskndx] = mask;
+ }
+ else
+ {
+ if (!inputMasks)
+ AddExtensionClient (pWin, client, 0, 0);
+ inputMasks = wOtherInputMasks(pWin);
+ inputMasks->dontPropagateMask[maskndx] = mask;
+ }
+ RecalculateDeviceDeliverableEvents(pWin);
+ if (ShouldFreeInputMasks(pWin, FALSE))
+ FreeResource(inputMasks->inputClients->resource, RT_NONE);
+ return Success;
+ }
+
+static Bool
+ShouldFreeInputMasks (pWin, ignoreSelectedEvents)
+ WindowPtr pWin;
+ Bool ignoreSelectedEvents;
+ {
+ int i;
+ Mask allInputEventMasks = 0;
+ struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
+
+ for (i=0; i<EMASKSIZE; i++)
+ allInputEventMasks |= inputMasks->dontPropagateMask[i];
+ if (!ignoreSelectedEvents)
+ for (i=0; i<EMASKSIZE; i++)
+ allInputEventMasks |= inputMasks->inputEvents[i];
+ if (allInputEventMasks == 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/exglobals.h b/nx-X11/programs/Xserver/Xi/exglobals.h
new file mode 100644
index 000000000..e8d84e25f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/exglobals.h
@@ -0,0 +1,79 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/*****************************************************************
+ *
+ * Globals referenced elsewhere in the server.
+ *
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef EXGLOBALS_H
+#define EXGLOBALS_H 1
+
+extern int IReqCode;
+extern int BadDevice;
+extern int BadEvent;
+extern int BadMode;
+extern int DeviceBusy;
+extern int BadClass;
+
+extern Mask DevicePointerMotionMask;
+extern Mask DevicePointerMotionHintMask;
+extern Mask DeviceFocusChangeMask;
+extern Mask DeviceStateNotifyMask;
+extern Mask ChangeDeviceNotifyMask;
+extern Mask DeviceMappingNotifyMask;
+extern Mask DeviceOwnerGrabButtonMask;
+extern Mask DeviceButtonGrabMask;
+extern Mask DeviceButtonMotionMask;
+extern Mask PropagateMask[];
+
+extern int DeviceValuator;
+extern int DeviceKeyPress;
+extern int DeviceKeyRelease;
+extern int DeviceButtonPress;
+extern int DeviceButtonRelease;
+extern int DeviceMotionNotify;
+extern int DeviceFocusIn;
+extern int DeviceFocusOut;
+extern int ProximityIn;
+extern int ProximityOut;
+extern int DeviceStateNotify;
+extern int DeviceKeyStateNotify;
+extern int DeviceButtonStateNotify;
+extern int DeviceMappingNotify;
+extern int ChangeDeviceNotify;
+
+extern int RT_INPUTCLIENT;
+
+#if 0
+/* FIXME: in dix */
+extern InputInfo inputInfo;
+#endif
+
+#endif /* EXGLOBALS_H */
diff --git a/nx-X11/programs/Xserver/Xi/extinit.c b/nx-X11/programs/Xserver/Xi/extinit.c
new file mode 100644
index 000000000..d0052b1fb
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/extinit.c
@@ -0,0 +1,1002 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Dispatch routines and initialization routines for the X input extension.
+ *
+ */
+
+#define NUMTYPES 15
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "inputstr.h"
+#include "gcstruct.h" /* pointer for extnsionst.h*/
+#include "extnsionst.h" /* extension entry */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+
+#include "dixevents.h"
+#include "exevents.h"
+#include "extinit.h"
+#include "exglobals.h"
+#include "swaprep.h"
+#include "protocol-versions.h"
+
+/* modules local to Xi */
+#include "allowev.h"
+#include "chgdctl.h"
+#include "chgfctl.h"
+#include "chgkbd.h"
+#include "chgprop.h"
+#include "chgptr.h"
+#include "closedev.h"
+#include "devbell.h"
+#include "getbmap.h"
+#include "getbmap.h"
+#include "getdctl.h"
+#include "getfctl.h"
+#include "getfocus.h"
+#include "getkmap.h"
+#include "getmmap.h"
+#include "getprop.h"
+#include "getselev.h"
+#include "getvers.h"
+#include "getvers.h"
+#include "grabdev.h"
+#include "grabdevb.h"
+#include "grabdevk.h"
+#include "gtmotion.h"
+#include "listdev.h"
+#include "opendev.h"
+#include "queryst.h"
+#include "selectev.h"
+#include "sendexev.h"
+#include "chgkmap.h"
+#include "setbmap.h"
+#include "setdval.h"
+#include "setfocus.h"
+#include "setmmap.h"
+#include "setmode.h"
+#include "ungrdev.h"
+#include "ungrdevb.h"
+#include "ungrdevk.h"
+
+static Mask lastExtEventMask = 1;
+int ExtEventIndex;
+Mask ExtValidMasks[EMASKSIZE];
+Mask ExtExclusiveMasks[EMASKSIZE];
+
+struct dev_type
+ {
+ Atom type;
+ char *name;
+ }dev_type [] = {{0,XI_KEYBOARD},
+ {0,XI_MOUSE},
+ {0,XI_TABLET},
+ {0,XI_TOUCHSCREEN},
+ {0,XI_TOUCHPAD},
+ {0,XI_BARCODE},
+ {0,XI_BUTTONBOX},
+ {0,XI_KNOB_BOX},
+ {0,XI_ONE_KNOB},
+ {0,XI_NINE_KNOB},
+ {0,XI_TRACKBALL},
+ {0,XI_QUADRATURE},
+ {0,XI_ID_MODULE},
+ {0,XI_SPACEBALL},
+ {0,XI_DATAGLOVE},
+ {0,XI_EYETRACKER},
+ {0,XI_CURSORKEYS},
+ {0,XI_FOOTMOUSE}};
+
+CARD8 event_base [numInputClasses];
+XExtEventInfo EventInfo[32];
+
+/*****************************************************************
+ *
+ * Globals referenced elsewhere in the server.
+ *
+ */
+
+int IReqCode = 0;
+int BadDevice = 0;
+int BadEvent = 1;
+int BadMode = 2;
+int DeviceBusy = 3;
+int BadClass = 4;
+
+Mask DevicePointerMotionMask;
+Mask DevicePointerMotionHintMask;
+Mask DeviceFocusChangeMask;
+Mask DeviceStateNotifyMask;
+Mask ChangeDeviceNotifyMask;
+Mask DeviceMappingNotifyMask;
+Mask DeviceOwnerGrabButtonMask;
+Mask DeviceButtonGrabMask;
+Mask DeviceButtonMotionMask;
+
+int DeviceValuator;
+int DeviceKeyPress;
+int DeviceKeyRelease;
+int DeviceButtonPress;
+int DeviceButtonRelease;
+int DeviceMotionNotify;
+int DeviceFocusIn;
+int DeviceFocusOut;
+int ProximityIn;
+int ProximityOut;
+int DeviceStateNotify;
+int DeviceKeyStateNotify;
+int DeviceButtonStateNotify;
+int DeviceMappingNotify;
+int ChangeDeviceNotify;
+
+int RT_INPUTCLIENT;
+
+/*****************************************************************
+ *
+ * Externs defined elsewhere in the X server.
+ *
+ */
+
+extern XExtensionVersion AllExtensionVersions[];
+
+Mask PropagateMask[MAX_DEVICES];
+
+/*****************************************************************
+ *
+ * Declarations of local routines.
+ *
+ */
+
+static XExtensionVersion thisversion =
+ {XI_Present,
+ SERVER_XI_MAJOR_VERSION,
+ SERVER_XI_MINOR_VERSION,
+ };
+
+/**********************************************************************
+ *
+ * IExtensionInit - initialize the input extension.
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ * This extension has several events and errors.
+ *
+ */
+
+void
+XInputExtensionInit()
+{
+ ExtensionEntry *extEntry;
+
+ extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
+ SProcIDispatch, IResetProc, StandardMinorOpcode);
+ if (extEntry)
+ {
+ IReqCode = extEntry->base;
+ AllExtensionVersions[IReqCode-128] = thisversion;
+ MakeDeviceTypeAtoms ();
+ RT_INPUTCLIENT = CreateNewResourceType((DeleteType)InputClientGone);
+ FixExtensionEvents (extEntry);
+ ReplySwapVector[IReqCode] = (ReplySwapPtr)SReplyIDispatch;
+ EventSwapVector[DeviceValuator] = SEventIDispatch;
+ EventSwapVector[DeviceKeyPress] = SEventIDispatch;
+ EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
+ EventSwapVector[DeviceButtonPress] = SEventIDispatch;
+ EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
+ EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
+ EventSwapVector[DeviceFocusIn] = SEventIDispatch;
+ EventSwapVector[DeviceFocusOut] = SEventIDispatch;
+ EventSwapVector[ProximityIn] = SEventIDispatch;
+ EventSwapVector[ProximityOut] = SEventIDispatch;
+ EventSwapVector[DeviceStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
+ EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
+ EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
+ }
+ else
+ {
+ FatalError("IExtensionInit: AddExtensions failed\n");
+ }
+ }
+
+/*************************************************************************
+ *
+ * ProcIDispatch - main dispatch routine for requests to this extension.
+ * This routine is used if server and client have the same byte ordering.
+ *
+ */
+
+int
+ProcIDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ if (stuff->data == X_GetExtensionVersion)
+ return(ProcXGetExtensionVersion(client));
+ if (stuff->data == X_ListInputDevices)
+ return(ProcXListInputDevices(client));
+ else if (stuff->data == X_OpenDevice)
+ return(ProcXOpenDevice(client));
+ else if (stuff->data == X_CloseDevice)
+ return(ProcXCloseDevice(client));
+ else if (stuff->data == X_SetDeviceMode)
+ return(ProcXSetDeviceMode(client));
+ else if (stuff->data == X_SelectExtensionEvent)
+ return(ProcXSelectExtensionEvent(client));
+ else if (stuff->data == X_GetSelectedExtensionEvents)
+ return(ProcXGetSelectedExtensionEvents(client));
+ else if (stuff->data == X_ChangeDeviceDontPropagateList)
+ return(ProcXChangeDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceDontPropagateList)
+ return(ProcXGetDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceMotionEvents)
+ return(ProcXGetDeviceMotionEvents(client));
+ else if (stuff->data == X_ChangeKeyboardDevice)
+ return(ProcXChangeKeyboardDevice(client));
+ else if (stuff->data == X_ChangePointerDevice)
+ return(ProcXChangePointerDevice(client));
+ else if (stuff->data == X_GrabDevice)
+ return(ProcXGrabDevice(client));
+ else if (stuff->data == X_UngrabDevice)
+ return(ProcXUngrabDevice(client));
+ else if (stuff->data == X_GrabDeviceKey)
+ return(ProcXGrabDeviceKey(client));
+ else if (stuff->data == X_UngrabDeviceKey)
+ return(ProcXUngrabDeviceKey(client));
+ else if (stuff->data == X_GrabDeviceButton)
+ return(ProcXGrabDeviceButton(client));
+ else if (stuff->data == X_UngrabDeviceButton)
+ return(ProcXUngrabDeviceButton(client));
+ else if (stuff->data == X_AllowDeviceEvents)
+ return(ProcXAllowDeviceEvents(client));
+ else if (stuff->data == X_GetDeviceFocus)
+ return(ProcXGetDeviceFocus(client));
+ else if (stuff->data == X_SetDeviceFocus)
+ return(ProcXSetDeviceFocus(client));
+ else if (stuff->data == X_GetFeedbackControl)
+ return(ProcXGetFeedbackControl(client));
+ else if (stuff->data == X_ChangeFeedbackControl)
+ return(ProcXChangeFeedbackControl(client));
+ else if (stuff->data == X_GetDeviceKeyMapping)
+ return(ProcXGetDeviceKeyMapping(client));
+ else if (stuff->data == X_ChangeDeviceKeyMapping)
+ return(ProcXChangeDeviceKeyMapping(client));
+ else if (stuff->data == X_GetDeviceModifierMapping)
+ return(ProcXGetDeviceModifierMapping(client));
+ else if (stuff->data == X_SetDeviceModifierMapping)
+ return(ProcXSetDeviceModifierMapping(client));
+ else if (stuff->data == X_GetDeviceButtonMapping)
+ return(ProcXGetDeviceButtonMapping(client));
+ else if (stuff->data == X_SetDeviceButtonMapping)
+ return(ProcXSetDeviceButtonMapping(client));
+ else if (stuff->data == X_QueryDeviceState)
+ return(ProcXQueryDeviceState(client));
+ else if (stuff->data == X_SendExtensionEvent)
+ return(ProcXSendExtensionEvent(client));
+ else if (stuff->data == X_DeviceBell)
+ return(ProcXDeviceBell(client));
+ else if (stuff->data == X_SetDeviceValuators)
+ return(ProcXSetDeviceValuators(client));
+ else if (stuff->data == X_GetDeviceControl)
+ return(ProcXGetDeviceControl(client));
+ else if (stuff->data == X_ChangeDeviceControl)
+ return(ProcXChangeDeviceControl(client));
+ else
+ {
+ SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
+ }
+ return(BadRequest);
+ }
+
+/*******************************************************************************
+ *
+ * SProcXDispatch
+ *
+ * Main swapped dispatch routine for requests to this extension.
+ * This routine is used if server and client do not have the same byte ordering.
+ *
+ */
+
+int
+SProcIDispatch(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ if (stuff->data == X_GetExtensionVersion)
+ return(SProcXGetExtensionVersion(client));
+ if (stuff->data == X_ListInputDevices)
+ return(SProcXListInputDevices(client));
+ else if (stuff->data == X_OpenDevice)
+ return(SProcXOpenDevice(client));
+ else if (stuff->data == X_CloseDevice)
+ return(SProcXCloseDevice(client));
+ else if (stuff->data == X_SetDeviceMode)
+ return(SProcXSetDeviceMode(client));
+ else if (stuff->data == X_SelectExtensionEvent)
+ return(SProcXSelectExtensionEvent(client));
+ else if (stuff->data == X_GetSelectedExtensionEvents)
+ return(SProcXGetSelectedExtensionEvents(client));
+ else if (stuff->data == X_ChangeDeviceDontPropagateList)
+ return(SProcXChangeDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceDontPropagateList)
+ return(SProcXGetDeviceDontPropagateList(client));
+ else if (stuff->data == X_GetDeviceMotionEvents)
+ return(SProcXGetDeviceMotionEvents(client));
+ else if (stuff->data == X_ChangeKeyboardDevice)
+ return(SProcXChangeKeyboardDevice(client));
+ else if (stuff->data == X_ChangePointerDevice)
+ return(SProcXChangePointerDevice(client));
+ else if (stuff->data == X_GrabDevice)
+ return(SProcXGrabDevice(client));
+ else if (stuff->data == X_UngrabDevice)
+ return(SProcXUngrabDevice(client));
+ else if (stuff->data == X_GrabDeviceKey)
+ return(SProcXGrabDeviceKey(client));
+ else if (stuff->data == X_UngrabDeviceKey)
+ return(SProcXUngrabDeviceKey(client));
+ else if (stuff->data == X_GrabDeviceButton)
+ return(SProcXGrabDeviceButton(client));
+ else if (stuff->data == X_UngrabDeviceButton)
+ return(SProcXUngrabDeviceButton(client));
+ else if (stuff->data == X_AllowDeviceEvents)
+ return(SProcXAllowDeviceEvents(client));
+ else if (stuff->data == X_GetDeviceFocus)
+ return(SProcXGetDeviceFocus(client));
+ else if (stuff->data == X_SetDeviceFocus)
+ return(SProcXSetDeviceFocus(client));
+ else if (stuff->data == X_GetFeedbackControl)
+ return(SProcXGetFeedbackControl(client));
+ else if (stuff->data == X_ChangeFeedbackControl)
+ return(SProcXChangeFeedbackControl(client));
+ else if (stuff->data == X_GetDeviceKeyMapping)
+ return(SProcXGetDeviceKeyMapping(client));
+ else if (stuff->data == X_ChangeDeviceKeyMapping)
+ return(SProcXChangeDeviceKeyMapping(client));
+ else if (stuff->data == X_GetDeviceModifierMapping)
+ return(SProcXGetDeviceModifierMapping(client));
+ else if (stuff->data == X_SetDeviceModifierMapping)
+ return(SProcXSetDeviceModifierMapping(client));
+ else if (stuff->data == X_GetDeviceButtonMapping)
+ return(SProcXGetDeviceButtonMapping(client));
+ else if (stuff->data == X_SetDeviceButtonMapping)
+ return(SProcXSetDeviceButtonMapping(client));
+ else if (stuff->data == X_QueryDeviceState)
+ return(SProcXQueryDeviceState(client));
+ else if (stuff->data == X_SendExtensionEvent)
+ return(SProcXSendExtensionEvent(client));
+ else if (stuff->data == X_DeviceBell)
+ return(SProcXDeviceBell(client));
+ else if (stuff->data == X_SetDeviceValuators)
+ return(SProcXSetDeviceValuators(client));
+ else if (stuff->data == X_GetDeviceControl)
+ return(SProcXGetDeviceControl(client));
+ else if (stuff->data == X_ChangeDeviceControl)
+ return(SProcXChangeDeviceControl(client));
+ else
+ {
+ SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
+ }
+ return(BadRequest);
+ }
+
+/**********************************************************************
+ *
+ * SReplyIDispatch
+ * Swap any replies defined in this extension.
+ *
+ */
+
+/* FIXME: this would be more concise and readable in ANSI C */
+#define DISPATCH(code) \
+ if (rep->RepType == X_##code) \
+ SRepX##code (client, len, (x##code##Reply *) rep)
+
+void
+SReplyIDispatch (client, len, rep)
+ ClientPtr client;
+ int len;
+ xGrabDeviceReply *rep; /* All we look at is the type field */
+{ /* This is common to all replies */
+ if (rep->RepType == X_GetExtensionVersion)
+ SRepXGetExtensionVersion (client, len, (xGetExtensionVersionReply *)rep);
+ else if (rep->RepType == X_ListInputDevices)
+ SRepXListInputDevices (client, len, (xListInputDevicesReply *)rep);
+ else if (rep->RepType == X_OpenDevice)
+ SRepXOpenDevice (client, len, (xOpenDeviceReply *)rep);
+ else if (rep->RepType == X_SetDeviceMode)
+ SRepXSetDeviceMode (client, len, (xSetDeviceModeReply *) rep);
+ else if (rep->RepType == X_GetSelectedExtensionEvents)
+ SRepXGetSelectedExtensionEvents (client, len, (xGetSelectedExtensionEventsReply *) rep);
+ else if (rep->RepType == X_GetDeviceDontPropagateList)
+ SRepXGetDeviceDontPropagateList (client, len, (xGetDeviceDontPropagateListReply *)rep);
+ else if (rep->RepType == X_GetDeviceMotionEvents)
+ SRepXGetDeviceMotionEvents (client, len, (xGetDeviceMotionEventsReply *) rep);
+ else if (rep->RepType == X_ChangeKeyboardDevice)
+ SRepXChangeKeyboardDevice (client, len, (xChangeKeyboardDeviceReply *) rep);
+ else if (rep->RepType == X_ChangePointerDevice)
+ SRepXChangePointerDevice (client, len, (xChangePointerDeviceReply *)rep);
+ else if (rep->RepType == X_GrabDevice)
+ SRepXGrabDevice (client, len, (xGrabDeviceReply *)rep);
+ else if (rep->RepType == X_GetDeviceFocus)
+ SRepXGetDeviceFocus (client, len, (xGetDeviceFocusReply *)rep);
+ else if (rep->RepType == X_GetFeedbackControl)
+ SRepXGetFeedbackControl (client, len, (xGetFeedbackControlReply *)rep);
+ else if (rep->RepType == X_GetDeviceKeyMapping)
+ SRepXGetDeviceKeyMapping (client, len, (xGetDeviceKeyMappingReply *)rep);
+ else if (rep->RepType == X_GetDeviceModifierMapping)
+ SRepXGetDeviceModifierMapping (client, len, (xGetDeviceModifierMappingReply *)rep);
+ else if (rep->RepType == X_SetDeviceModifierMapping)
+ SRepXSetDeviceModifierMapping (client, len, (xSetDeviceModifierMappingReply *)rep);
+ else if (rep->RepType == X_GetDeviceButtonMapping)
+ SRepXGetDeviceButtonMapping (client, len, (xGetDeviceButtonMappingReply *)rep);
+ else if (rep->RepType == X_SetDeviceButtonMapping)
+ SRepXSetDeviceButtonMapping (client, len, (xSetDeviceButtonMappingReply *)rep);
+ else if (rep->RepType == X_QueryDeviceState)
+ SRepXQueryDeviceState (client, len, (xQueryDeviceStateReply *)rep);
+ else if (rep->RepType == X_SetDeviceValuators)
+ SRepXSetDeviceValuators (client, len, (xSetDeviceValuatorsReply *)rep);
+ else if (rep->RepType == X_GetDeviceControl)
+ SRepXGetDeviceControl (client, len, (xGetDeviceControlReply *)rep);
+ else if (rep->RepType == X_ChangeDeviceControl)
+ SRepXChangeDeviceControl (client, len, (xChangeDeviceControlReply *)rep);
+ else
+ {
+ FatalError("XINPUT confused sending swapped reply");
+ }
+ }
+
+/*****************************************************************************
+ *
+ * SEventIDispatch
+ *
+ * Swap any events defined in this extension.
+ */
+#define DO_SWAP(func,type) func ((type *)from, (type *)to)
+
+void
+SEventIDispatch (from, to)
+ xEvent *from;
+ xEvent *to;
+{
+ int type = from->u.u.type & 0177;
+
+ if (type == DeviceValuator)
+ DO_SWAP(SEventDeviceValuator, deviceValuator);
+ else if (type == DeviceKeyPress)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceKeyRelease)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceButtonPress)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceButtonRelease)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceMotionNotify)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceFocusIn)
+ DO_SWAP(SEventFocus, deviceFocus);
+ else if (type == DeviceFocusOut)
+ DO_SWAP(SEventFocus, deviceFocus);
+ else if (type == ProximityIn)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == ProximityOut)
+ {
+ SKeyButtonPtrEvent (from, to);
+ to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
+ }
+ else if (type == DeviceStateNotify)
+ DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
+ else if (type == DeviceKeyStateNotify)
+ DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
+ else if (type == DeviceButtonStateNotify)
+ DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
+ else if (type == DeviceMappingNotify)
+ DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
+ else if (type == ChangeDeviceNotify)
+ DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
+ else
+ {
+ FatalError("XInputExtension: Impossible event!\n");
+ }
+ }
+
+/************************************************************************
+ *
+ * This function swaps the DeviceValuator event.
+ *
+ */
+
+void
+SEventDeviceValuator (from, to)
+ deviceValuator *from;
+ deviceValuator *to;
+ {
+ register int i;
+ INT32 *ip B32;
+
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ swaps(&to->device_state);
+ ip = &to->valuator0;
+ for (i=0; i<6; i++)
+ {
+ swapl((ip+i)); /* macro - braces are required */
+ }
+ }
+
+void
+SEventFocus (from, to)
+ deviceFocus *from;
+ deviceFocus *to;
+{
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ swapl(&to->time);
+ swapl(&to->window);
+ }
+
+void
+SDeviceStateNotifyEvent (from, to)
+ deviceStateNotify *from;
+ deviceStateNotify *to;
+{
+ register int i;
+ INT32 *ip B32;
+
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ swapl(&to->time);
+ ip = &to->valuator0;
+ for (i=0; i<3; i++)
+ {
+ swapl((ip+i)); /* macro - braces are required */
+ }
+ }
+
+void
+SDeviceKeyStateNotifyEvent (from, to)
+ deviceKeyStateNotify *from;
+ deviceKeyStateNotify *to;
+{
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ }
+
+void
+SDeviceButtonStateNotifyEvent (from, to)
+ deviceButtonStateNotify *from;
+ deviceButtonStateNotify *to;
+{
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ }
+
+void
+SChangeDeviceNotifyEvent (from, to)
+ changeDeviceNotify *from;
+ changeDeviceNotify *to;
+{
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ swapl(&to->time);
+ }
+
+void
+SDeviceMappingNotifyEvent (from, to)
+ deviceMappingNotify *from;
+ deviceMappingNotify *to;
+{
+ *to = *from;
+ swaps(&to->sequenceNumber);
+ swapl(&to->time);
+ }
+
+/************************************************************************
+ *
+ * This function sets up extension event types and masks.
+ *
+ */
+
+void
+FixExtensionEvents (extEntry)
+ ExtensionEntry *extEntry;
+{
+ Mask mask;
+
+ DeviceValuator = extEntry->eventBase;
+ DeviceKeyPress = DeviceValuator + 1;
+ DeviceKeyRelease = DeviceKeyPress + 1;
+ DeviceButtonPress = DeviceKeyRelease + 1;
+ DeviceButtonRelease = DeviceButtonPress + 1;
+ DeviceMotionNotify = DeviceButtonRelease + 1;
+ DeviceFocusIn = DeviceMotionNotify + 1;
+ DeviceFocusOut = DeviceFocusIn + 1;
+ ProximityIn = DeviceFocusOut + 1;
+ ProximityOut = ProximityIn + 1;
+ DeviceStateNotify = ProximityOut + 1;
+ DeviceMappingNotify = DeviceStateNotify + 1;
+ ChangeDeviceNotify = DeviceMappingNotify + 1;
+ DeviceKeyStateNotify = ChangeDeviceNotify + 1;
+ DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
+
+ event_base[KeyClass] = DeviceKeyPress;
+ event_base[ButtonClass] = DeviceButtonPress;
+ event_base[ValuatorClass] = DeviceMotionNotify;
+ event_base[ProximityClass] = ProximityIn;
+ event_base[FocusClass] = DeviceFocusIn;
+ event_base[OtherClass] = DeviceStateNotify;
+
+ BadDevice += extEntry->errorBase;
+ BadEvent += extEntry->errorBase;
+ BadMode += extEntry->errorBase;
+ DeviceBusy += extEntry->errorBase;
+ BadClass += extEntry->errorBase;
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, DeviceKeyPress);
+ AllowPropagateSuppress (mask);
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, DeviceKeyRelease);
+ AllowPropagateSuppress (mask);
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, DeviceButtonPress);
+ AllowPropagateSuppress (mask);
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, DeviceButtonRelease);
+ AllowPropagateSuppress (mask);
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, ProximityIn);
+ SetMaskForExtEvent (mask, ProximityOut);
+ AllowPropagateSuppress (mask);
+
+ mask = GetNextExtEventMask ();
+ DeviceStateNotifyMask = mask;
+ SetMaskForExtEvent (mask, DeviceStateNotify);
+
+ mask = GetNextExtEventMask ();
+ DevicePointerMotionMask = mask;
+ SetMaskForExtEvent (mask, DeviceMotionNotify);
+ AllowPropagateSuppress (mask);
+
+ DevicePointerMotionHintMask = GetNextExtEventMask();
+ SetEventInfo (DevicePointerMotionHintMask, _devicePointerMotionHint);
+ SetEventInfo (GetNextExtEventMask(), _deviceButton1Motion);
+ SetEventInfo (GetNextExtEventMask(), _deviceButton2Motion);
+ SetEventInfo (GetNextExtEventMask(), _deviceButton3Motion);
+ SetEventInfo (GetNextExtEventMask(), _deviceButton4Motion);
+ SetEventInfo (GetNextExtEventMask(), _deviceButton5Motion);
+ DeviceButtonMotionMask = GetNextExtEventMask();
+ SetEventInfo (DeviceButtonMotionMask, _deviceButtonMotion);
+
+ DeviceFocusChangeMask = GetNextExtEventMask ();
+ SetMaskForExtEvent (DeviceFocusChangeMask, DeviceFocusIn);
+ SetMaskForExtEvent (DeviceFocusChangeMask, DeviceFocusOut);
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, DeviceMappingNotify);
+ DeviceMappingNotifyMask = mask;
+
+ mask = GetNextExtEventMask ();
+ SetMaskForExtEvent (mask, ChangeDeviceNotify);
+ ChangeDeviceNotifyMask = mask;
+
+ DeviceButtonGrabMask = GetNextExtEventMask();
+ SetEventInfo (DeviceButtonGrabMask, _deviceButtonGrab);
+ SetExclusiveAccess (DeviceButtonGrabMask);
+
+ DeviceOwnerGrabButtonMask = GetNextExtEventMask();
+ SetEventInfo (DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
+ SetEventInfo (0, _noExtensionEvent);
+ }
+
+/************************************************************************
+ *
+ * This function restores extension event types and masks to their
+ * initial state.
+ *
+ */
+
+void
+RestoreExtensionEvents ()
+{
+ int i;
+
+ IReqCode = 0;
+
+ for (i=0; i<ExtEventIndex-1; i++)
+ {
+ if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
+ SetMaskForEvent(0,EventInfo[i].type);
+ EventInfo[i].mask = 0;
+ EventInfo[i].type = 0;
+ }
+ ExtEventIndex = 0;
+ lastExtEventMask = 1;
+ DeviceValuator = 0;
+ DeviceKeyPress = 1;
+ DeviceKeyRelease = 2;
+ DeviceButtonPress = 3;
+ DeviceButtonRelease = 4;
+ DeviceMotionNotify = 5;
+ DeviceFocusIn = 6;
+ DeviceFocusOut = 7;
+ ProximityIn = 8;
+ ProximityOut = 9;
+ DeviceStateNotify = 10;
+ DeviceMappingNotify = 11;
+ ChangeDeviceNotify = 12;
+ DeviceKeyStateNotify = 13;
+ DeviceButtonStateNotify = 13;
+
+ BadDevice = 0;
+ BadEvent = 1;
+ BadMode = 2;
+ DeviceBusy = 3;
+ BadClass = 4;
+
+ }
+
+/***********************************************************************
+ *
+ * IResetProc.
+ * Remove reply-swapping routine.
+ * Remove event-swapping routine.
+ *
+ */
+
+void
+IResetProc(unused)
+ ExtensionEntry *unused;
+ {
+
+ ReplySwapVector[IReqCode] = ReplyNotSwappd;
+ EventSwapVector[DeviceValuator] = NotImplemented;
+ EventSwapVector[DeviceKeyPress] = NotImplemented;
+ EventSwapVector[DeviceKeyRelease] = NotImplemented;
+ EventSwapVector[DeviceButtonPress] = NotImplemented;
+ EventSwapVector[DeviceButtonRelease] = NotImplemented;
+ EventSwapVector[DeviceMotionNotify] = NotImplemented;
+ EventSwapVector[DeviceFocusIn] = NotImplemented;
+ EventSwapVector[DeviceFocusOut] = NotImplemented;
+ EventSwapVector[ProximityIn] = NotImplemented;
+ EventSwapVector[ProximityOut] = NotImplemented;
+ EventSwapVector[DeviceStateNotify] = NotImplemented;
+ EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
+ EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
+ EventSwapVector[DeviceMappingNotify] = NotImplemented;
+ EventSwapVector[ChangeDeviceNotify] = NotImplemented;
+ RestoreExtensionEvents ();
+ }
+
+/***********************************************************************
+ *
+ * Assign an id and type to an input device.
+ *
+ */
+
+void
+AssignTypeAndName (dev, type, name)
+ DeviceIntPtr dev;
+ Atom type;
+ char *name;
+{
+ dev->type = type;
+ dev->name = (char *) malloc(strlen(name)+1);
+ strcpy (dev->name, name);
+ }
+
+/***********************************************************************
+ *
+ * Make device type atoms.
+ *
+ */
+
+void
+MakeDeviceTypeAtoms ()
+ {
+ int i;
+
+ for (i=0; i<NUMTYPES; i++)
+ dev_type[i].type =
+ MakeAtom (dev_type[i].name, strlen(dev_type[i].name), 1);
+ }
+
+/**************************************************************************
+ *
+ * Return a DeviceIntPtr corresponding to a specified device id.
+ * This will not return the pointer or keyboard, or devices that are not on.
+ *
+ */
+
+DeviceIntPtr
+LookupDeviceIntRec (
+ CARD8 id)
+{
+ DeviceIntPtr dev;
+
+ for (dev=inputInfo.devices; dev; dev=dev->next)
+ {
+ if (dev->id == id)
+ {
+ if (id == inputInfo.pointer->id || id == inputInfo.keyboard->id)
+ return (NULL);
+ return (dev);
+ }
+ }
+ return (NULL);
+ }
+
+/**************************************************************************
+ *
+ * Allow the specified event to be restricted to being selected by one
+ * client at a time.
+ * The default is to allow more than one client to select the event.
+ *
+ */
+
+void
+SetExclusiveAccess (mask)
+ Mask mask;
+ {
+ int i;
+
+ for (i=0; i<MAX_DEVICES; i++)
+ ExtExclusiveMasks[i] |= mask;
+ }
+
+/**************************************************************************
+ *
+ * Allow the specified event to have its propagation suppressed.
+ * The default is to not allow suppression of propagation.
+ *
+ */
+
+void
+AllowPropagateSuppress (mask)
+ Mask mask;
+ {
+ int i;
+
+ for (i=0; i<MAX_DEVICES; i++)
+ PropagateMask[i] |= mask;
+ }
+
+/**************************************************************************
+ *
+ * Return the next available extension event mask.
+ *
+ */
+
+Mask
+GetNextExtEventMask ()
+ {
+ int i;
+ Mask mask = lastExtEventMask;
+
+ if (lastExtEventMask == 0)
+ {
+ FatalError("GetNextExtEventMask: no more events are available.");
+ }
+ lastExtEventMask <<= 1;
+
+ for (i=0; i<MAX_DEVICES; i++)
+ ExtValidMasks[i] |= mask;
+ return mask;
+ }
+
+/**************************************************************************
+ *
+ * Assign the specified mask to the specified event.
+ *
+ */
+
+void
+SetMaskForExtEvent(mask, event)
+ Mask mask;
+ int event;
+ {
+
+ EventInfo[ExtEventIndex].mask = mask;
+ EventInfo[ExtEventIndex++].type = event;
+
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("MaskForExtensionEvent: bogus event number");
+ SetMaskForEvent(mask,event);
+ }
+
+/**************************************************************************
+ *
+ * Record an event mask where there is no unique corresponding event type.
+ * We can't call SetMaskForEvent, since that would clobber the existing
+ * mask for that event. MotionHint and ButtonMotion are examples.
+ *
+ * Since extension event types will never be less than 64, we can use
+ * 0-63 in the EventInfo array as the "type" to be used to look up this
+ * mask. This means that the corresponding macros such as
+ * DevicePointerMotionHint must have access to the same constants.
+ *
+ */
+
+void
+SetEventInfo(mask, constant)
+ Mask mask;
+ int constant;
+ {
+ EventInfo[ExtEventIndex].mask = mask;
+ EventInfo[ExtEventIndex++].type = constant;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getbmap.c b/nx-X11/programs/Xserver/Xi/getbmap.c
new file mode 100644
index 000000000..af497869c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getbmap.c
@@ -0,0 +1,146 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to return the version of the extension.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getbmap.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the button mapping for the specified device.
+ *
+ */
+
+int
+SProcXGetDeviceButtonMapping(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceButtonMappingReq);
+ swaps(&stuff->length);
+ return(ProcXGetDeviceButtonMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure gets the button mapping for the specified device.
+ *
+ */
+
+int
+ProcXGetDeviceButtonMapping (client)
+ register ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ xGetDeviceButtonMappingReply rep;
+ ButtonClassPtr b;
+
+ REQUEST(xGetDeviceButtonMappingReq);
+ REQUEST_SIZE_MATCH(xGetDeviceButtonMappingReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceButtonMapping;
+ rep.nElts = 0;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceButtonMapping, 0,
+ BadDevice);
+ return Success;
+ }
+
+ b = dev->button;
+ if (b == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceButtonMapping, 0,
+ BadMatch);
+ return Success;
+ }
+ rep.nElts = b->numButtons;
+ rep.length = (rep.nElts + (4-1))/4;
+ WriteReplyToClient (client, sizeof (xGetDeviceButtonMappingReply), &rep);
+ WriteToClient(client, rep.nElts,
+ (char *)&b->map[1]);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetDeviceButtonMapping function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceButtonMapping (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceButtonMappingReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getbmap.h b/nx-X11/programs/Xserver/Xi/getbmap.h
new file mode 100644
index 000000000..85d2e63e9
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getbmap.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETBMAP_H
+#define GETBMAP_H 1
+
+int
+SProcXGetDeviceButtonMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceButtonMapping (
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetDeviceButtonMapping (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceButtonMappingReply * /* rep */
+ );
+
+#endif /* GETBMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/getdctl.c b/nx-X11/programs/Xserver/Xi/getdctl.c
new file mode 100644
index 000000000..c315f0bb6
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getdctl.c
@@ -0,0 +1,221 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Get Device control attributes for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getdctl.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the control attributes for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXGetDeviceControl(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceControlReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetDeviceControlReq);
+ swaps(&stuff->control);
+ return(ProcXGetDeviceControl(client));
+ }
+
+/***********************************************************************
+ *
+ * Get the state of the specified device control.
+ *
+ */
+
+int
+ProcXGetDeviceControl(client)
+ ClientPtr client;
+ {
+ int total_length = 0;
+ char *buf, *savbuf;
+ register DeviceIntPtr dev;
+ xGetDeviceControlReply rep;
+
+ REQUEST(xGetDeviceControlReq);
+ REQUEST_SIZE_MATCH(xGetDeviceControlReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceControl, 0,
+ BadDevice);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceControl;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ switch (stuff->control)
+ {
+ case DEVICE_RESOLUTION:
+ if (!dev->valuator)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceControl, 0,
+ BadMatch);
+ return Success;
+ }
+ total_length = sizeof (xDeviceResolutionState) +
+ (3 * sizeof(int) * dev->valuator->numAxes);
+ break;
+ default:
+ SendErrorToClient (client, IReqCode, X_GetDeviceControl, 0,
+ BadValue);
+ return Success;
+ }
+
+ buf = (char *) malloc (total_length);
+ if (!buf)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceControl, 0,
+ BadAlloc);
+ return Success;
+ }
+ savbuf=buf;
+
+ switch (stuff->control)
+ {
+ case DEVICE_RESOLUTION:
+ CopySwapDeviceResolution(client, dev->valuator, buf,
+ total_length);
+ break;
+ default:
+ break;
+ }
+
+ rep.length = (total_length+3) >> 2;
+ WriteReplyToClient(client, sizeof(xGetDeviceControlReply), &rep);
+ WriteToClient(client, total_length, savbuf);
+ free (savbuf);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies DeviceResolution data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapDeviceResolution (client, v, buf, length)
+ ClientPtr client;
+ ValuatorClassPtr v;
+ char *buf;
+ int length;
+ {
+ AxisInfoPtr a;
+ xDeviceResolutionState *r;
+ int i, *iptr;
+
+ r = (xDeviceResolutionState *) buf;
+ r->control = DEVICE_RESOLUTION;
+ r->length = length;
+ r->num_valuators = v->numAxes;
+ buf += sizeof (xDeviceResolutionState);
+ iptr = (int *) buf;
+ for (i=0,a=v->axes; i<v->numAxes; i++,a++)
+ *iptr++ = a->resolution;
+ for (i=0,a=v->axes; i<v->numAxes; i++,a++)
+ *iptr++ = a->min_resolution;
+ for (i=0,a=v->axes; i<v->numAxes; i++,a++)
+ *iptr++ = a->max_resolution;
+ if (client->swapped)
+ {
+ swaps (&r->control);
+ swaps (&r->length);
+ swapl (&r->num_valuators);
+ iptr = (int *) buf;
+ for (i=0; i < (3 * v->numAxes); i++,iptr++)
+ {
+ swapl (iptr);
+ }
+ }
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the xGetDeviceControl function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceControl (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceControlReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
+
diff --git a/nx-X11/programs/Xserver/Xi/getdctl.h b/nx-X11/programs/Xserver/Xi/getdctl.h
new file mode 100644
index 000000000..0618b4d01
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getdctl.h
@@ -0,0 +1,58 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETDCTL_H
+#define GETDCTL_H 1
+
+int
+SProcXGetDeviceControl (
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceControl (
+ ClientPtr /* client */
+ );
+
+void
+CopySwapDeviceResolution (
+ ClientPtr /* client */,
+ ValuatorClassPtr /* v */,
+ char * /* buf */,
+ int /* length */
+ );
+
+void
+SRepXGetDeviceControl (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceControlReply * /* rep */
+ );
+
+#endif /* GETDCTL_H */
diff --git a/nx-X11/programs/Xserver/Xi/getfctl.c b/nx-X11/programs/Xserver/Xi/getfctl.c
new file mode 100644
index 000000000..a8845c72b
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getfctl.c
@@ -0,0 +1,408 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Get feedback control attributes for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getfctl.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the control attributes for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXGetFeedbackControl(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetFeedbackControlReq);
+ swaps(&stuff->length);
+ return(ProcXGetFeedbackControl(client));
+ }
+
+/***********************************************************************
+ *
+ * Get the feedback control state.
+ *
+ */
+
+int
+ProcXGetFeedbackControl(client)
+ ClientPtr client;
+ {
+ int total_length = 0;
+ char *buf, *savbuf;
+ register DeviceIntPtr dev;
+ KbdFeedbackPtr k;
+ PtrFeedbackPtr p;
+ IntegerFeedbackPtr i;
+ StringFeedbackPtr s;
+ BellFeedbackPtr b;
+ LedFeedbackPtr l;
+ xGetFeedbackControlReply rep;
+
+ REQUEST(xGetFeedbackControlReq);
+ REQUEST_SIZE_MATCH(xGetFeedbackControlReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetFeedbackControl, 0,
+ BadDevice);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetFeedbackControl;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.num_feedbacks = 0;
+
+ for (k=dev->kbdfeed; k; k=k->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xKbdFeedbackState);
+ }
+ for (p=dev->ptrfeed; p; p=p->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xPtrFeedbackState);
+ }
+ for (s=dev->stringfeed; s; s=s->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xStringFeedbackState) +
+ (s->ctrl.num_symbols_supported * sizeof (KeySym));
+ }
+ for (i=dev->intfeed; i; i=i->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xIntegerFeedbackState);
+ }
+ for (l=dev->leds; l; l=l->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xLedFeedbackState);
+ }
+ for (b=dev->bell; b; b=b->next)
+ {
+ rep.num_feedbacks++;
+ total_length += sizeof(xBellFeedbackState);
+ }
+
+ if (total_length == 0)
+ {
+ SendErrorToClient(client, IReqCode, X_GetFeedbackControl, 0,
+ BadMatch);
+ return Success;
+ }
+
+ buf = (char *) malloc (total_length);
+ if (!buf)
+ {
+ SendErrorToClient(client, IReqCode, X_GetFeedbackControl, 0,
+ BadAlloc);
+ return Success;
+ }
+ savbuf=buf;
+
+ for (k=dev->kbdfeed; k; k=k->next)
+ CopySwapKbdFeedback (client, k, &buf);
+ for (p=dev->ptrfeed; p; p=p->next)
+ CopySwapPtrFeedback (client, p, &buf);
+ for (s=dev->stringfeed; s; s=s->next)
+ CopySwapStringFeedback (client, s, &buf);
+ for (i=dev->intfeed; i; i=i->next)
+ CopySwapIntegerFeedback (client, i, &buf);
+ for (l=dev->leds; l; l=l->next)
+ CopySwapLedFeedback (client, l, &buf);
+ for (b=dev->bell; b; b=b->next)
+ CopySwapBellFeedback (client, b, &buf);
+
+ rep.length = (total_length+3) >> 2;
+ WriteReplyToClient(client, sizeof(xGetFeedbackControlReply), &rep);
+ WriteToClient(client, total_length, savbuf);
+ free (savbuf);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies KbdFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapKbdFeedback (client, k, buf)
+ ClientPtr client;
+ KbdFeedbackPtr k;
+ char **buf;
+ {
+ int i;
+ xKbdFeedbackState *k2;
+
+ k2 = (xKbdFeedbackState *) *buf;
+ k2->class = KbdFeedbackClass;
+ k2->length = sizeof (xKbdFeedbackState);
+ k2->id = k->ctrl.id;
+ k2->click = k->ctrl.click;
+ k2->percent = k->ctrl.bell;
+ k2->pitch = k->ctrl.bell_pitch;
+ k2->duration = k->ctrl.bell_duration;
+ k2->led_mask = k->ctrl.leds;
+ k2->global_auto_repeat = k->ctrl.autoRepeat;
+ for (i=0; i<32; i++)
+ k2->auto_repeats[i] = k->ctrl.autoRepeats[i];
+ if (client->swapped)
+ {
+ swaps(&k2->length);
+ swaps(&k2->pitch);
+ swaps(&k2->duration);
+ swapl(&k2->led_mask);
+ swapl(&k2->led_values);
+ }
+ *buf += sizeof (xKbdFeedbackState);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies PtrFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapPtrFeedback (client, p, buf)
+ ClientPtr client;
+ PtrFeedbackPtr p;
+ char **buf;
+ {
+ xPtrFeedbackState *p2;
+
+ p2 = (xPtrFeedbackState *) *buf;
+ p2->class = PtrFeedbackClass;
+ p2->length = sizeof (xPtrFeedbackState);
+ p2->id = p->ctrl.id;
+ p2->accelNum = p->ctrl.num;
+ p2->accelDenom = p->ctrl.den;
+ p2->threshold = p->ctrl.threshold;
+ if (client->swapped)
+ {
+ swaps(&p2->length);
+ swaps(&p2->accelNum);
+ swaps(&p2->accelDenom);
+ swaps(&p2->threshold);
+ }
+ *buf += sizeof (xPtrFeedbackState);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies IntegerFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapIntegerFeedback (client, i, buf)
+ ClientPtr client;
+ IntegerFeedbackPtr i;
+ char **buf;
+ {
+ xIntegerFeedbackState *i2;
+
+ i2 = (xIntegerFeedbackState *) *buf;
+ i2->class = IntegerFeedbackClass;
+ i2->length = sizeof (xIntegerFeedbackState);
+ i2->id = i->ctrl.id;
+ i2->resolution = i->ctrl.resolution;
+ i2->min_value = i->ctrl.min_value;
+ i2->max_value = i->ctrl.max_value;
+ if (client->swapped)
+ {
+ swaps(&i2->length);
+ swapl(&i2->resolution);
+ swapl(&i2->min_value);
+ swapl(&i2->max_value);
+ }
+ *buf += sizeof (xIntegerFeedbackState);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies StringFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapStringFeedback (client, s, buf)
+ ClientPtr client;
+ StringFeedbackPtr s;
+ char **buf;
+ {
+ int i;
+ xStringFeedbackState *s2;
+ KeySym *kptr;
+
+ s2 = (xStringFeedbackState *) *buf;
+ s2->class = StringFeedbackClass;
+ s2->length = sizeof (xStringFeedbackState) +
+ s->ctrl.num_symbols_supported * sizeof (KeySym);
+ s2->id = s->ctrl.id;
+ s2->max_symbols = s->ctrl.max_symbols;
+ s2->num_syms_supported = s->ctrl.num_symbols_supported;
+ *buf += sizeof (xStringFeedbackState);
+ kptr = (KeySym *) (*buf);
+ for (i=0; i<s->ctrl.num_symbols_supported; i++)
+ *kptr++ = *(s->ctrl.symbols_supported+i);
+ if (client->swapped)
+ {
+ swaps(&s2->length);
+ swaps(&s2->max_symbols);
+ swaps(&s2->num_syms_supported);
+ kptr = (KeySym *) (*buf);
+ for (i=0; i<s->ctrl.num_symbols_supported; i++,kptr++)
+ {
+ swapl(kptr);
+ }
+ }
+ *buf += (s->ctrl.num_symbols_supported * sizeof (KeySym));
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies LedFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapLedFeedback (client, l, buf)
+ ClientPtr client;
+ LedFeedbackPtr l;
+ char **buf;
+ {
+ xLedFeedbackState *l2;
+
+ l2 = (xLedFeedbackState *) *buf;
+ l2->class = LedFeedbackClass;
+ l2->length = sizeof (xLedFeedbackState);
+ l2->id = l->ctrl.id;
+ l2->led_values = l->ctrl.led_values;
+ l2->led_mask = l->ctrl.led_mask;
+ if (client->swapped)
+ {
+ swaps(&l2->length);
+ swapl(&l2->led_values);
+ swapl(&l2->led_mask);
+ }
+ *buf += sizeof (xLedFeedbackState);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies BellFeedbackClass data, swapping if necessary.
+ *
+ */
+
+void
+CopySwapBellFeedback (client, b, buf)
+ ClientPtr client;
+ BellFeedbackPtr b;
+ char **buf;
+ {
+ xBellFeedbackState *b2;
+
+ b2 = (xBellFeedbackState *) *buf;
+ b2->class = BellFeedbackClass;
+ b2->length = sizeof (xBellFeedbackState);
+ b2->id = b->ctrl.id;
+ b2->percent = b->ctrl.percent;
+ b2->pitch = b->ctrl.pitch;
+ b2->duration = b->ctrl.duration;
+ if (client->swapped)
+ {
+ swaps(&b2->length);
+ swaps(&b2->pitch);
+ swaps(&b2->duration);
+ }
+ *buf += sizeof (xBellFeedbackState);
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the xGetFeedbackControl function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetFeedbackControl (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetFeedbackControlReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->num_feedbacks);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getfctl.h b/nx-X11/programs/Xserver/Xi/getfctl.h
new file mode 100644
index 000000000..f8441b0b3
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getfctl.h
@@ -0,0 +1,92 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETFCTL_H
+#define GETFCTL_H 1
+
+int
+SProcXGetFeedbackControl(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetFeedbackControl(
+ ClientPtr /* client */
+ );
+
+void
+CopySwapKbdFeedback (
+ ClientPtr /* client */,
+ KbdFeedbackPtr /* k */,
+ char ** /* buf */
+ );
+
+void
+CopySwapPtrFeedback (
+ ClientPtr /* client */,
+ PtrFeedbackPtr /* p */,
+ char ** /* buf */
+ );
+
+void
+CopySwapIntegerFeedback (
+ ClientPtr /* client */,
+ IntegerFeedbackPtr /* i */,
+ char ** /* buf */
+ );
+
+void
+CopySwapStringFeedback (
+ ClientPtr /* client */,
+ StringFeedbackPtr /* s */,
+ char ** /* buf */
+ );
+
+void
+CopySwapLedFeedback (
+ ClientPtr /* client */,
+ LedFeedbackPtr /* l */,
+ char ** /* buf */
+ );
+
+void
+CopySwapBellFeedback (
+ ClientPtr /* client */,
+ BellFeedbackPtr /* b */,
+ char ** /* buf */
+ );
+
+void
+SRepXGetFeedbackControl (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetFeedbackControlReply * /* rep */
+ );
+
+#endif /* GETFCTL_H */
diff --git a/nx-X11/programs/Xserver/Xi/getfocus.c b/nx-X11/programs/Xserver/Xi/getfocus.c
new file mode 100644
index 000000000..6f30b011a
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getfocus.c
@@ -0,0 +1,149 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to get the focus for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "windowstr.h" /* focus struct */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getfocus.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the focus for a device.
+ *
+ */
+
+int
+SProcXGetDeviceFocus(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceFocusReq);
+ swaps(&stuff->length);
+ return(ProcXGetDeviceFocus(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure gets the focus for a device.
+ *
+ */
+
+int
+ProcXGetDeviceFocus(client)
+ ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ FocusClassPtr focus;
+ xGetDeviceFocusReply rep;
+
+ REQUEST(xGetDeviceFocusReq);
+ REQUEST_SIZE_MATCH(xGetDeviceFocusReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL || !dev->focus)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceFocus, 0, BadDevice);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceFocus;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ focus = dev->focus;
+
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else if (focus->win == FollowKeyboardWin)
+ rep.focus = FollowKeyboard;
+ else
+ rep.focus = focus->win->drawable.id;
+
+ rep.time = focus->time.milliseconds;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient (client, sizeof(xGetDeviceFocusReply), &rep);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the GetDeviceFocus function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceFocus (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceFocusReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->focus);
+ swapl(&rep->time);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getfocus.h b/nx-X11/programs/Xserver/Xi/getfocus.h
new file mode 100644
index 000000000..a404ee422
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getfocus.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETFOCUS_H
+#define GETFOCUS_H 1
+
+int
+SProcXGetDeviceFocus(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceFocus(
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetDeviceFocus (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceFocusReply * /* rep */
+ );
+
+#endif /* GETFOCUS_H */
diff --git a/nx-X11/programs/Xserver/Xi/getkmap.c b/nx-X11/programs/Xserver/Xi/getkmap.c
new file mode 100644
index 000000000..84f8a10a8
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getkmap.c
@@ -0,0 +1,170 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Get the key mapping for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "swaprep.h"
+
+#include "getkmap.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the key mapping for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXGetDeviceKeyMapping(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceKeyMappingReq);
+ swaps(&stuff->length);
+ return(ProcXGetDeviceKeyMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * Get the device key mapping.
+ *
+ */
+
+int
+ProcXGetDeviceKeyMapping(client)
+ register ClientPtr client;
+ {
+ xGetDeviceKeyMappingReply rep;
+ DeviceIntPtr dev;
+ KeySymsPtr k;
+
+ REQUEST(xGetDeviceKeyMappingReq);
+ REQUEST_SIZE_MATCH(xGetDeviceKeyMappingReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceKeyMapping, 0,
+ BadDevice);
+ return Success;
+ }
+
+ if (dev->key == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceKeyMapping, 0,
+ BadMatch);
+ return Success;
+ }
+ k = &dev->key->curKeySyms;
+
+ if ((stuff->firstKeyCode < k->minKeyCode) ||
+ (stuff->firstKeyCode > k->maxKeyCode))
+ {
+ client->errorValue = stuff->firstKeyCode;
+ SendErrorToClient (client, IReqCode, X_GetDeviceKeyMapping, 0,
+ BadValue);
+ return Success;
+ }
+
+ if (stuff->firstKeyCode + stuff->count > k->maxKeyCode + 1)
+ {
+ client->errorValue = stuff->count;
+ SendErrorToClient (client, IReqCode, X_GetDeviceKeyMapping, 0,
+ BadValue);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceKeyMapping;
+ rep.sequenceNumber = client->sequence;
+ rep.keySymsPerKeyCode = k->mapWidth;
+ rep.length = (k->mapWidth * stuff->count); /* KeySyms are 4 bytes */
+ WriteReplyToClient(client, sizeof(xGetDeviceKeyMappingReply), &rep);
+
+ client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
+ WriteSwappedDataToClient(
+ client,
+ k->mapWidth * stuff->count * sizeof(KeySym),
+ &k->map[(stuff->firstKeyCode - k->minKeyCode) *
+ k->mapWidth]);
+
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetDeviceKeyMapping function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceKeyMapping (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceKeyMappingReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
+
diff --git a/nx-X11/programs/Xserver/Xi/getkmap.h b/nx-X11/programs/Xserver/Xi/getkmap.h
new file mode 100644
index 000000000..4e8b4ba3a
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getkmap.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETKMAP_H
+#define GETKMAP_H 1
+
+int
+SProcXGetDeviceKeyMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceKeyMapping(
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetDeviceKeyMapping (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceKeyMappingReply * /* rep */
+ );
+
+#endif /* GETKMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/getmmap.c b/nx-X11/programs/Xserver/Xi/getmmap.c
new file mode 100644
index 000000000..53f2a6aec
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getmmap.c
@@ -0,0 +1,150 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Get the modifier mapping for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h> /* Request macro */
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getmmap.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the modifier mapping for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXGetDeviceModifierMapping(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceModifierMappingReq);
+ swaps(&stuff->length);
+ return(ProcXGetDeviceModifierMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * Get the device Modifier mapping.
+ *
+ */
+
+int
+ProcXGetDeviceModifierMapping(client)
+ ClientPtr client;
+ {
+ CARD8 maxkeys;
+ DeviceIntPtr dev;
+ xGetDeviceModifierMappingReply rep;
+ KeyClassPtr kp;
+
+ REQUEST(xGetDeviceModifierMappingReq);
+ REQUEST_SIZE_MATCH(xGetDeviceModifierMappingReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceModifierMapping, 0,
+ BadDevice);
+ return Success;
+ }
+
+ kp = dev->key;
+ if (kp == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_GetDeviceModifierMapping, 0,
+ BadMatch);
+ return Success;
+ }
+ maxkeys = kp->maxKeysPerModifier;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceModifierMapping;
+ rep.numKeyPerModifier = maxkeys;
+ rep.sequenceNumber = client->sequence;
+ /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
+ rep.length = 2*maxkeys;
+
+ WriteReplyToClient(client, sizeof(xGetDeviceModifierMappingReply), &rep);
+
+ /* Reply with the (modified by DDX) map that SetModifierMapping passed in */
+ WriteToClient(client, 8*maxkeys, kp->modifierKeyMap);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetDeviceModifierMapping function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceModifierMapping (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceModifierMappingReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getmmap.h b/nx-X11/programs/Xserver/Xi/getmmap.h
new file mode 100644
index 000000000..32d7061e2
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getmmap.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETMMAP_H
+#define GETMMAP_H 1
+
+int
+SProcXGetDeviceModifierMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceModifierMapping(
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetDeviceModifierMapping (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceModifierMappingReply * /* rep */
+ );
+
+#endif /* GETMMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/getprop.c b/nx-X11/programs/Xserver/Xi/getprop.c
new file mode 100644
index 000000000..569efcd1f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getprop.c
@@ -0,0 +1,207 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Function to return the dont-propagate-list for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structs */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "swaprep.h"
+
+#include "getprop.h"
+
+extern XExtEventInfo EventInfo[];
+extern int ExtEventIndex;
+
+/***********************************************************************
+ *
+ * Handle a request from a client with a different byte order.
+ *
+ */
+
+int
+SProcXGetDeviceDontPropagateList(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetDeviceDontPropagateListReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq);
+ swapl(&stuff->window);
+ return(ProcXGetDeviceDontPropagateList(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure lists the input devices available to the server.
+ *
+ */
+
+int
+ProcXGetDeviceDontPropagateList (client)
+ register ClientPtr client;
+ {
+ CARD16 count = 0;
+ int i;
+ XEventClass *buf = NULL, *tbuf;
+ WindowPtr pWin;
+ xGetDeviceDontPropagateListReply rep;
+ OtherInputMasks *others;
+
+ REQUEST(xGetDeviceDontPropagateListReq);
+ REQUEST_SIZE_MATCH(xGetDeviceDontPropagateListReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceDontPropagateList;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.count = 0;
+
+ pWin = (WindowPtr) LookupWindow (stuff->window, client);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ SendErrorToClient(client, IReqCode, X_GetDeviceDontPropagateList, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if ((others = wOtherInputMasks(pWin)) != 0)
+ {
+ for (i=0; i<EMASKSIZE; i++)
+ tbuf = ClassFromMask (NULL, others->dontPropagateMask[i], i,
+ &count, COUNT);
+ if (count)
+ {
+ rep.count = count;
+ buf = (XEventClass *) malloc (rep.count * sizeof(XEventClass));
+ rep.length = (rep.count * sizeof (XEventClass) + 3) >> 2;
+
+ tbuf = buf;
+ for (i=0; i<EMASKSIZE; i++)
+ tbuf = ClassFromMask (tbuf, others->dontPropagateMask[i], i,
+ NULL, CREATE);
+ }
+ }
+
+ WriteReplyToClient (client, sizeof (xGetDeviceDontPropagateListReply),
+ &rep);
+
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient( client, count * sizeof(XEventClass), buf);
+ free (buf);
+ }
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure gets a list of event classes from a mask word.
+ * A single mask may translate to more than one event class.
+ *
+ */
+
+XEventClass
+*ClassFromMask (buf, mask, maskndx, count, mode)
+ XEventClass *buf;
+ Mask mask;
+ int maskndx;
+ CARD16 *count;
+ int mode;
+ {
+ int i,j;
+ int id = maskndx;
+ Mask tmask = 0x80000000;
+
+ for (i=0; i<32; i++,tmask>>=1)
+ if (tmask & mask)
+ {
+ for (j=0; j<ExtEventIndex; j++)
+ if (EventInfo[j].mask == tmask)
+ {
+ if (mode == COUNT)
+ (*count)++;
+ else
+ *buf++ = (id << 8) | EventInfo[j].type;
+ }
+ }
+ return (buf);
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetDeviceDontPropagateList function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceDontPropagateList (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceDontPropagateListReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->count);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getprop.h b/nx-X11/programs/Xserver/Xi/getprop.h
new file mode 100644
index 000000000..fd9011603
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getprop.h
@@ -0,0 +1,59 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETPROP_H
+#define GETPROP_H 1
+
+int
+SProcXGetDeviceDontPropagateList(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceDontPropagateList (
+ ClientPtr /* client */
+ );
+
+XEventClass *
+ClassFromMask (
+ XEventClass * /* buf */,
+ Mask /* mask */,
+ int /* maskndx */,
+ CARD16 * /* count */,
+ int /* mode */
+ );
+
+void
+SRepXGetDeviceDontPropagateList (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceDontPropagateListReply * /* rep */
+ );
+
+#endif /* GETPROP_H */
diff --git a/nx-X11/programs/Xserver/Xi/getselev.c b/nx-X11/programs/Xserver/Xi/getselev.c
new file mode 100644
index 000000000..bac74317b
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getselev.c
@@ -0,0 +1,188 @@
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+
+/***********************************************************************
+ *
+ * Extension function to get the current selected events for a given window.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window struct */
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "swaprep.h"
+
+#include "getprop.h"
+#include "getselev.h"
+
+/***********************************************************************
+ *
+ * This procedure gets the current selected extension events.
+ *
+ */
+
+int
+SProcXGetSelectedExtensionEvents(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetSelectedExtensionEventsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq);
+ swapl(&stuff->window);
+ return(ProcXGetSelectedExtensionEvents(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure gets the current device select mask,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+int
+ProcXGetSelectedExtensionEvents(client)
+ register ClientPtr client;
+ {
+ int i;
+ int total_length = 0;
+ xGetSelectedExtensionEventsReply rep;
+ WindowPtr pWin;
+ XEventClass *buf = NULL;
+ XEventClass *tclient;
+ XEventClass *aclient;
+ OtherInputMasks *pOthers;
+ InputClientsPtr others;
+
+ REQUEST(xGetSelectedExtensionEventsReq);
+ REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GetSelectedExtensionEvents;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.this_client_count = 0;
+ rep.all_clients_count = 0;
+
+ if (!(pWin = LookupWindow(stuff->window, client)))
+ {
+ SendErrorToClient(client, IReqCode, X_GetSelectedExtensionEvents, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if ((pOthers = wOtherInputMasks(pWin)) != 0)
+ {
+ for (others = pOthers->inputClients; others; others=others->next)
+ for (i=0; i<EMASKSIZE; i++)
+ tclient = ClassFromMask (NULL, others->mask[i], i,
+ &rep.all_clients_count, COUNT);
+
+ for (others = pOthers->inputClients; others; others=others->next)
+ if (SameClient(others, client))
+ {
+ for (i=0; i<EMASKSIZE; i++)
+ tclient = ClassFromMask (NULL, others->mask[i], i,
+ &rep.this_client_count, COUNT);
+ break;
+ }
+
+ total_length = (rep.all_clients_count + rep.this_client_count) *
+ sizeof (XEventClass);
+ rep.length = (total_length + 3) >> 2;
+ buf = (XEventClass *) malloc (total_length);
+
+ tclient = buf;
+ aclient = buf + rep.this_client_count;
+ if (others)
+ for (i=0; i<EMASKSIZE; i++)
+ tclient = ClassFromMask (tclient, others->mask[i], i, NULL, CREATE);
+
+ for (others = pOthers->inputClients; others; others=others->next)
+ for (i=0; i<EMASKSIZE; i++)
+ aclient = ClassFromMask (aclient, others->mask[i], i, NULL, CREATE);
+ }
+
+ WriteReplyToClient (client, sizeof(xGetSelectedExtensionEventsReply), &rep);
+
+ if (total_length)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient( client, total_length, buf);
+ free (buf);
+ }
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetSelectedExtensionEvents function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetSelectedExtensionEvents (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetSelectedExtensionEventsReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->this_client_count);
+ swaps(&rep->all_clients_count);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getselev.h b/nx-X11/programs/Xserver/Xi/getselev.h
new file mode 100644
index 000000000..ef9e3b606
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getselev.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETSELEV_H
+#define GETSELEV_H 1
+
+int
+SProcXGetSelectedExtensionEvents(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetSelectedExtensionEvents(
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetSelectedExtensionEvents (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetSelectedExtensionEventsReply * /* rep */
+ );
+
+#endif /* GETSELEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/getvers.c b/nx-X11/programs/Xserver/Xi/getvers.c
new file mode 100644
index 000000000..00381a91c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getvers.c
@@ -0,0 +1,150 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to return the version of the extension.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "getvers.h"
+
+XExtensionVersion AllExtensionVersions[128];
+
+/***********************************************************************
+ *
+ * Handle a request from a client with a different byte order than us.
+ *
+ */
+
+int
+SProcXGetExtensionVersion(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGetExtensionVersionReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
+ swaps(&stuff->nbytes);
+ return(ProcXGetExtensionVersion(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure lists the input devices available to the server.
+ *
+ */
+
+int
+ProcXGetExtensionVersion (client)
+ register ClientPtr client;
+ {
+ xGetExtensionVersionReply rep;
+
+ REQUEST(xGetExtensionVersionReq);
+ REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
+
+ if (stuff->length != (sizeof(xGetExtensionVersionReq) +
+ stuff->nbytes + 3)>>2)
+ {
+ SendErrorToClient(client, IReqCode, X_GetExtensionVersion, 0,
+ BadLength);
+ return Success;
+ }
+
+ memset(&rep, 0, sizeof(xGetExtensionVersionReply));
+ rep.repType = X_Reply;
+ rep.RepType = X_GetExtensionVersion;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.major_version = 0;
+ rep.minor_version = 0;
+
+ rep.present = TRUE;
+ if (rep.present)
+ {
+ rep.major_version =
+ AllExtensionVersions[IReqCode-128].major_version;
+ rep.minor_version =
+ AllExtensionVersions[IReqCode-128].minor_version;
+ }
+ WriteReplyToClient (client, sizeof (xGetExtensionVersionReply), &rep);
+
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetExtensionVersion function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetExtensionVersion (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetExtensionVersionReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->major_version);
+ swaps(&rep->minor_version);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/getvers.h b/nx-X11/programs/Xserver/Xi/getvers.h
new file mode 100644
index 000000000..a09e2da2d
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/getvers.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GETVERS_H
+#define GETVERS_H 1
+
+int
+SProcXGetExtensionVersion(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetExtensionVersion (
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetExtensionVersion (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetExtensionVersionReply * /* rep */
+ );
+
+#endif /* GETVERS_H */
diff --git a/nx-X11/programs/Xserver/Xi/grabdev.c b/nx-X11/programs/Xserver/Xi/grabdev.c
new file mode 100644
index 000000000..8d8a5491e
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdev.c
@@ -0,0 +1,221 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to grab an extension device.
+ *
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "dixevents.h" /* GrabDevice */
+
+#include "grabdev.h"
+
+extern XExtEventInfo EventInfo[];
+extern int ExtEventIndex;
+
+/***********************************************************************
+ *
+ * Swap the request if the requestor has a different byte order than us.
+ *
+ */
+
+int
+SProcXGrabDevice(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGrabDeviceReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceReq);
+ swapl(&stuff->grabWindow);
+ swapl(&stuff->time);
+ swaps(&stuff->event_count);
+
+ if (stuff->length != (sizeof(xGrabDeviceReq) >> 2) + stuff->event_count)
+ return BadLength;
+
+ SwapLongs((CARD32 *) (&stuff[1]), stuff->event_count);
+
+ return(ProcXGrabDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * Grab an extension device.
+ *
+ */
+
+int
+ProcXGrabDevice(client)
+ ClientPtr client;
+ {
+ int error;
+ xGrabDeviceReply rep;
+ DeviceIntPtr dev;
+ struct tmask tmp[EMASKSIZE];
+
+ REQUEST(xGrabDeviceReq);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceReq);
+
+ if (stuff->length !=(sizeof(xGrabDeviceReq)>>2) + stuff->event_count)
+ {
+ SendErrorToClient (client, IReqCode, X_GrabDevice, 0, BadLength);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_GrabDevice;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDevice, 0, BadDevice);
+ return Success;
+ }
+
+ if (CreateMaskFromList (client, (XEventClass *)&stuff[1],
+ stuff->event_count, tmp, dev, X_GrabDevice) != Success)
+ return Success;
+
+ error = GrabDevice (client, dev, stuff->this_device_mode,
+ stuff->other_devices_mode, stuff->grabWindow, stuff->ownerEvents,
+ stuff->time, tmp[stuff->deviceid].mask, &rep.status);
+
+ if (error != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDevice, 0, error);
+ return Success;
+ }
+ WriteReplyToClient(client, sizeof(xGrabDeviceReply), &rep);
+ return Success;
+ }
+
+
+/***********************************************************************
+ *
+ * This procedure creates an event mask from a list of XEventClasses.
+ *
+ */
+
+int
+CreateMaskFromList (client, list, count, mask, dev, req)
+ ClientPtr client;
+ XEventClass *list;
+ int count;
+ struct tmask mask[];
+ DeviceIntPtr dev;
+ int req;
+ {
+ int i,j;
+ int device;
+ DeviceIntPtr tdev;
+
+ for (i=0; i<EMASKSIZE; i++)
+ {
+ mask[i].mask = 0;
+ mask[i].dev = NULL;
+ }
+
+ for (i=0; i<count; i++, list++)
+ {
+ device = *list >> 8;
+ if (device > 255)
+ {
+ SendErrorToClient(client, IReqCode, req, 0, BadClass);
+ return BadClass;
+ }
+ tdev = LookupDeviceIntRec (device);
+ if (tdev==NULL || (dev != NULL && tdev != dev))
+ {
+ SendErrorToClient(client, IReqCode, req, 0, BadClass);
+ return BadClass;
+ }
+
+ for (j=0; j<ExtEventIndex; j++)
+ if (EventInfo[j].type == (*list & 0xff))
+ {
+ mask[device].mask |= EventInfo[j].mask;
+ mask[device].dev = (Pointer) tdev;
+ break;
+ }
+ }
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGrabDevice function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGrabDevice (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGrabDeviceReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/grabdev.h b/nx-X11/programs/Xserver/Xi/grabdev.h
new file mode 100644
index 000000000..9e9196c47
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdev.h
@@ -0,0 +1,60 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GRABDEV_H
+#define GRABDEV_H 1
+
+int
+SProcXGrabDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGrabDevice(
+ ClientPtr /* client */
+ );
+
+int
+CreateMaskFromList (
+ ClientPtr /* client */,
+ XEventClass * /* list */,
+ int /* count */,
+ struct tmask /* mask */[],
+ DeviceIntPtr /* dev */,
+ int /* req */
+ );
+
+void
+SRepXGrabDevice (
+ ClientPtr /* client */,
+ int /* size */,
+ xGrabDeviceReply * /* rep */
+ );
+
+#endif /* GRABDEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/grabdevb.c b/nx-X11/programs/Xserver/Xi/grabdevb.c
new file mode 100644
index 000000000..edf1d763b
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdevb.c
@@ -0,0 +1,159 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to grab a button on an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "grabdev.h"
+#include "grabdevb.h"
+
+/***********************************************************************
+ *
+ * Handle requests from clients with a different byte order.
+ *
+ */
+
+int
+SProcXGrabDeviceButton(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGrabDeviceButtonReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceButtonReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ swaps(&stuff->event_count);
+ REQUEST_FIXED_SIZE(xGrabDeviceButtonReq,
+ stuff->event_count * sizeof(CARD32));
+ SwapLongs((CARD32 *) (&stuff[1]), stuff->event_count);
+
+ return(ProcXGrabDeviceButton(client));
+ }
+
+/***********************************************************************
+ *
+ * Grab a button on an extension device.
+ *
+ */
+
+int
+ProcXGrabDeviceButton(client)
+ ClientPtr client;
+ {
+ int ret;
+ DeviceIntPtr dev;
+ DeviceIntPtr mdev;
+ XEventClass *class;
+ struct tmask tmp[EMASKSIZE];
+
+ REQUEST(xGrabDeviceButtonReq);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceButtonReq);
+
+ if (stuff->length !=(sizeof(xGrabDeviceButtonReq)>>2) + stuff->event_count)
+ {
+ SendErrorToClient (client, IReqCode, X_GrabDeviceButton, 0, BadLength);
+ return Success;
+ }
+
+ dev = LookupDeviceIntRec (stuff->grabbed_device);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceButton, 0,
+ BadDevice);
+ return Success;
+ }
+ if (stuff->modifier_device != UseXKeyboard)
+ {
+ mdev = LookupDeviceIntRec (stuff->modifier_device);
+ if (mdev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceButton, 0,
+ BadDevice);
+ return Success;
+ }
+ if (mdev->key == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceButton, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+ else
+ mdev = (DeviceIntPtr) LookupKeyboardDevice();
+
+ class = (XEventClass *) (&stuff[1]); /* first word of values */
+
+ if ((ret = CreateMaskFromList (client, class,
+ stuff->event_count, tmp, dev, X_GrabDeviceButton)) != Success)
+ return Success;
+ ret = GrabButton(client, dev, stuff->this_device_mode,
+ stuff->other_devices_mode, stuff->modifiers, mdev, stuff->button,
+ stuff->grabWindow, stuff->ownerEvents, (Cursor)0, (Window)0,
+ tmp[stuff->grabbed_device].mask);
+
+ if (ret != Success)
+ SendErrorToClient(client, IReqCode, X_GrabDeviceButton, 0, ret);
+ return(Success);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/grabdevb.h b/nx-X11/programs/Xserver/Xi/grabdevb.h
new file mode 100644
index 000000000..29f0401e1
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdevb.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GRABDEVB_H
+#define GRABDEVB_H 1
+
+int
+SProcXGrabDeviceButton(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGrabDeviceButton(
+ ClientPtr /* client */
+ );
+
+#endif /* GRABDEVB_H */
diff --git a/nx-X11/programs/Xserver/Xi/grabdevk.c b/nx-X11/programs/Xserver/Xi/grabdevk.c
new file mode 100644
index 000000000..cc7d2f034
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdevk.c
@@ -0,0 +1,162 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to grab a key on an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "grabdev.h"
+#include "grabdevk.h"
+
+/***********************************************************************
+ *
+ * Handle requests from clients with a different byte order.
+ *
+ */
+
+int
+SProcXGrabDeviceKey(client)
+ register ClientPtr client;
+ {
+ REQUEST(xGrabDeviceKeyReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceKeyReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ swaps(&stuff->event_count);
+ REQUEST_FIXED_SIZE(xGrabDeviceKeyReq, stuff->event_count * sizeof(CARD32));
+ SwapLongs((CARD32 *) (&stuff[1]), stuff->event_count);
+ return(ProcXGrabDeviceKey(client));
+ }
+
+/***********************************************************************
+ *
+ * Grab a key on an extension device.
+ *
+ */
+
+int
+ProcXGrabDeviceKey(client)
+ ClientPtr client;
+ {
+ int ret;
+ DeviceIntPtr dev;
+ DeviceIntPtr mdev;
+ XEventClass *class;
+ struct tmask tmp[EMASKSIZE];
+
+ REQUEST(xGrabDeviceKeyReq);
+ REQUEST_AT_LEAST_SIZE(xGrabDeviceKeyReq);
+
+ if (stuff->length !=(sizeof(xGrabDeviceKeyReq)>>2) + stuff->event_count)
+ {
+ SendErrorToClient (client, IReqCode, X_GrabDeviceKey, 0, BadLength);
+ return Success;
+ }
+
+ dev = LookupDeviceIntRec (stuff->grabbed_device);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceKey, 0,
+ BadDevice);
+ return Success;
+ }
+
+ if (stuff->modifier_device != UseXKeyboard)
+ {
+ mdev = LookupDeviceIntRec (stuff->modifier_device);
+ if (mdev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceKey, 0,
+ BadDevice);
+ return Success;
+ }
+ if (mdev->key == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceKey, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+ else
+ mdev = (DeviceIntPtr) LookupKeyboardDevice();
+
+ class = (XEventClass *) (&stuff[1]); /* first word of values */
+
+ if ((ret = CreateMaskFromList (client, class,
+ stuff->event_count, tmp, dev, X_GrabDeviceKey)) != Success)
+ return Success;
+
+ ret = GrabKey(client, dev, stuff->this_device_mode,
+ stuff->other_devices_mode, stuff->modifiers, mdev, stuff->key,
+ stuff->grabWindow, stuff->ownerEvents, tmp[stuff->grabbed_device].mask);
+
+ if (ret != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_GrabDeviceKey, 0, ret);
+ return Success;
+ }
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/grabdevk.h b/nx-X11/programs/Xserver/Xi/grabdevk.h
new file mode 100644
index 000000000..baa2d1533
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/grabdevk.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GRABDEVK_H
+#define GRABDEVK_H 1
+
+int
+SProcXGrabDeviceKey(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGrabDeviceKey(
+ ClientPtr /* client */
+ );
+
+#endif /* GRABDEVK_H */
diff --git a/nx-X11/programs/Xserver/Xi/gtmotion.c b/nx-X11/programs/Xserver/Xi/gtmotion.c
new file mode 100644
index 000000000..9c04ca30e
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/gtmotion.c
@@ -0,0 +1,203 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to get the motion history from an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "gtmotion.h"
+
+/***********************************************************************
+ *
+ * Swap the request if server and client have different byte ordering.
+ *
+ */
+
+int
+SProcXGetDeviceMotionEvents(client)
+register ClientPtr client;
+ {
+ REQUEST(xGetDeviceMotionEventsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq);
+ swapl(&stuff->start);
+ swapl(&stuff->stop);
+ return(ProcXGetDeviceMotionEvents(client));
+ }
+
+/****************************************************************************
+ *
+ * Get the motion history for an extension pointer devices.
+ *
+ */
+
+int
+ProcXGetDeviceMotionEvents(client)
+ ClientPtr client;
+{
+ INT32 *coords = NULL, *bufptr;
+ xGetDeviceMotionEventsReply rep;
+ unsigned long i;
+ int num_events, axes, size = 0, tsize;
+ unsigned long nEvents;
+ DeviceIntPtr dev;
+ TimeStamp start, stop;
+ int length = 0;
+ ValuatorClassPtr v;
+
+ REQUEST(xGetDeviceMotionEventsReq);
+
+ REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq);
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceMotionEvents, 0,
+ BadDevice);
+ return Success;
+ }
+ v = dev->valuator;
+ if (v==NULL || v->numAxes == 0)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceMotionEvents, 0,
+ BadMatch);
+ return Success;
+ }
+ if (dev->valuator->motionHintWindow)
+ MaybeStopDeviceHint(dev, client);
+ axes = v->numAxes;
+ rep.repType = X_Reply;
+ rep.RepType = X_GetDeviceMotionEvents;
+ rep.sequenceNumber = client->sequence;
+ rep.nEvents = 0;
+ rep.axes = axes;
+ rep.mode = v->mode & DeviceMode;
+ rep.length = 0;
+ start = ClientTimeToServerTime(stuff->start);
+ stop = ClientTimeToServerTime(stuff->stop);
+ if (CompareTimeStamps(start, stop) == LATER ||
+ CompareTimeStamps(start, currentTime) == LATER)
+ {
+ WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep);
+ return Success;
+ }
+ if (CompareTimeStamps(stop, currentTime) == LATER)
+ stop = currentTime;
+ num_events = v->numMotionEvents;
+ if (num_events)
+ {
+ size = sizeof(Time) + (axes * sizeof (INT32));
+ tsize = num_events * size;
+ coords = (INT32 *) malloc(tsize);
+ if (!coords)
+ {
+ SendErrorToClient(client, IReqCode, X_GetDeviceMotionEvents, 0,
+ BadAlloc);
+ return Success;
+ }
+ rep.nEvents = (v->GetMotionProc) (
+ dev, (xTimecoord *)coords, /* XXX */
+ start.milliseconds, stop.milliseconds, (ScreenPtr)NULL);
+ }
+ if (rep.nEvents > 0)
+ {
+ length = (rep.nEvents * size +3) >> 2;
+ rep.length = length;
+ }
+ nEvents = rep.nEvents;
+ WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep);
+ if (nEvents)
+ {
+ if (client->swapped)
+ {
+ bufptr = coords;
+ for (i=0; i<nEvents * (axes+1); i++)
+ {
+ swapl(bufptr);
+ bufptr++;
+ }
+ }
+ WriteToClient(client, length * 4, coords);
+ }
+ if (coords)
+ free(coords);
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XGetDeviceMotionEvents function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXGetDeviceMotionEvents (client, size, rep)
+ ClientPtr client;
+ int size;
+ xGetDeviceMotionEventsReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->nEvents);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/gtmotion.h b/nx-X11/programs/Xserver/Xi/gtmotion.h
new file mode 100644
index 000000000..986eb5bad
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/gtmotion.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef GTMOTION_H
+#define GTMOTION_H 1
+
+int
+SProcXGetDeviceMotionEvents(
+ ClientPtr /* client */
+ );
+
+int
+ProcXGetDeviceMotionEvents(
+ ClientPtr /* client */
+ );
+
+void
+SRepXGetDeviceMotionEvents (
+ ClientPtr /* client */,
+ int /* size */,
+ xGetDeviceMotionEventsReply * /* rep */
+ );
+
+#endif /* GTMOTION_H */
diff --git a/nx-X11/programs/Xserver/Xi/listdev.c b/nx-X11/programs/Xserver/Xi/listdev.c
new file mode 100644
index 000000000..95896d49d
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/listdev.c
@@ -0,0 +1,396 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Extension function to list the available input devices.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h" /* FIXME */
+
+#include "listdev.h"
+
+#define VPC 20 /* Max # valuators per chunk */
+
+/***********************************************************************
+ *
+ * This procedure lists the input devices available to the server.
+ *
+ */
+
+int
+SProcXListInputDevices(client)
+ register ClientPtr client;
+ {
+ REQUEST(xListInputDevicesReq);
+ swaps(&stuff->length);
+ return(ProcXListInputDevices(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure lists the input devices available to the server.
+ *
+ */
+
+int
+ProcXListInputDevices (client)
+ register ClientPtr client;
+ {
+ xListInputDevicesReply rep;
+ int numdevs;
+ int namesize = 1; /* need 1 extra byte for strcpy */
+ int size = 0;
+ int total_length;
+ char *devbuf;
+ char *classbuf;
+ char *namebuf;
+ char *savbuf;
+ xDeviceInfo *dev;
+ DeviceIntPtr d;
+
+ REQUEST_SIZE_MATCH(xListInputDevicesReq);
+
+ memset(&rep, 0, sizeof(xListInputDevicesReply));
+ rep.repType = X_Reply;
+ rep.RepType = X_ListInputDevices;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ AddOtherInputDevices ();
+ numdevs = inputInfo.numDevices;
+
+ for (d=inputInfo.devices; d; d=d->next)
+ SizeDeviceInfo (d, &namesize, &size);
+ for (d=inputInfo.off_devices; d; d=d->next)
+ SizeDeviceInfo (d, &namesize, &size);
+
+ total_length = numdevs * sizeof (xDeviceInfo) + size + namesize;
+ devbuf = (char *) calloc (1, total_length);
+ classbuf = devbuf + (numdevs * sizeof (xDeviceInfo));
+ namebuf = classbuf + size;
+ savbuf = devbuf;
+
+ dev = (xDeviceInfoPtr) devbuf;
+ for (d=inputInfo.devices; d; d=d->next,dev++)
+ ListDeviceInfo (client, d, dev, &devbuf, &classbuf, &namebuf);
+ for (d=inputInfo.off_devices; d; d=d->next,dev++)
+ ListDeviceInfo (client, d, dev, &devbuf, &classbuf, &namebuf);
+
+ rep.ndevices = numdevs;
+ rep.length = (total_length + 3) >> 2;
+ WriteReplyToClient (client, sizeof (xListInputDevicesReply), &rep);
+ WriteToClient(client, total_length, savbuf);
+ free (savbuf);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure calculates the size of the information to be returned
+ * for an input device.
+ *
+ */
+
+void
+SizeDeviceInfo (d, namesize, size)
+ DeviceIntPtr d;
+ int *namesize;
+ int *size;
+ {
+ int chunks;
+
+ *namesize += 1;
+ if (d->name)
+ *namesize += strlen (d->name);
+ if (d->key != NULL)
+ *size += sizeof (xKeyInfo);
+ if (d->button != NULL)
+ *size += sizeof (xButtonInfo);
+ if (d->valuator != NULL)
+ {
+ chunks = ((int) d->valuator->numAxes + 19) / VPC;
+ *size += (chunks * sizeof(xValuatorInfo) +
+ d->valuator->numAxes * sizeof(xAxisInfo));
+ }
+ }
+
+/***********************************************************************
+ *
+ * This procedure lists information to be returned for an input device.
+ *
+ */
+
+void
+ListDeviceInfo (client, d, dev, devbuf, classbuf, namebuf)
+ ClientPtr client;
+ DeviceIntPtr d;
+ xDeviceInfoPtr dev;
+ char **devbuf;
+ char **classbuf;
+ char **namebuf;
+ {
+ CopyDeviceName (namebuf, d->name);
+ CopySwapDevice (client, d, 0, devbuf);
+ if (d->key != NULL)
+ {
+ CopySwapKeyClass(client, d->key, classbuf);
+ dev->num_classes++;
+ }
+ if (d->button != NULL)
+ {
+ CopySwapButtonClass(client, d->button, classbuf);
+ dev->num_classes++;
+ }
+ if (d->valuator != NULL)
+ {
+ dev->num_classes += CopySwapValuatorClass(client, d->valuator, classbuf);
+ }
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies data to the DeviceInfo struct, swapping if necessary.
+ *
+ * We need the extra byte in the allocated buffer, because the trailing null
+ * hammers one extra byte, which is overwritten by the next name except for
+ * the last name copied.
+ *
+ */
+
+void
+CopyDeviceName (namebuf, name)
+ char **namebuf;
+ char *name;
+ {
+ char *nameptr = (char *) *namebuf;
+
+ if (name)
+ {
+ *nameptr++ = strlen (name);
+ strcpy (nameptr, name);
+ *namebuf += (strlen (name)+1);
+ }
+ else
+ {
+ *nameptr++ = 0;
+ *namebuf += 1;
+ }
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies data to the DeviceInfo struct, swapping if necessary.
+ *
+ */
+
+void
+CopySwapDevice (client, d, num_classes, buf)
+ register ClientPtr client;
+ DeviceIntPtr d;
+ int num_classes;
+ char **buf;
+ {
+ xDeviceInfoPtr dev;
+
+ dev = (xDeviceInfoPtr) *buf;
+
+ dev->id = d->id;
+ dev->type = d->type;
+ dev->num_classes = num_classes;
+ if (d == inputInfo.keyboard)
+ dev->use = IsXKeyboard;
+ else if (d == inputInfo.pointer)
+ dev->use = IsXPointer;
+ else
+ dev->use = IsXExtensionDevice;
+ if (client->swapped)
+ {
+ swapl(&dev->type); /* macro - braces are required */
+ }
+ *buf += sizeof (xDeviceInfo);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies KeyClass information, swapping if necessary.
+ *
+ */
+
+void
+CopySwapKeyClass (client, k, buf)
+ register ClientPtr client;
+ KeyClassPtr k;
+ char **buf;
+ {
+ xKeyInfoPtr k2;
+
+ k2 = (xKeyInfoPtr) *buf;
+ k2->class = KeyClass;
+ k2->length = sizeof (xKeyInfo);
+ k2->min_keycode = k->curKeySyms.minKeyCode;
+ k2->max_keycode = k->curKeySyms.maxKeyCode;
+ k2->num_keys = k2->max_keycode - k2->min_keycode + 1;
+ if (client->swapped)
+ {
+ swaps(&k2->num_keys);
+ }
+ *buf += sizeof (xKeyInfo);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies ButtonClass information, swapping if necessary.
+ *
+ */
+
+void
+CopySwapButtonClass (client, b, buf)
+ register ClientPtr client;
+ ButtonClassPtr b;
+ char **buf;
+ {
+ xButtonInfoPtr b2;
+
+ b2 = (xButtonInfoPtr) *buf;
+ b2->class = ButtonClass;
+ b2->length = sizeof (xButtonInfo);
+ b2->num_buttons = b->numButtons;
+ if (client->swapped)
+ {
+ swaps(&b2->num_buttons); /* macro - braces are required */
+ }
+ *buf += sizeof (xButtonInfo);
+ }
+
+/***********************************************************************
+ *
+ * This procedure copies ValuatorClass information, swapping if necessary.
+ *
+ * Devices may have up to 255 valuators. The length of a ValuatorClass is
+ * defined to be sizeof(ValuatorClassInfo) + num_axes * sizeof (xAxisInfo).
+ * The maximum length is therefore (8 + 255 * 12) = 3068. However, the
+ * length field is one byte. If a device has more than 20 valuators, we
+ * must therefore return multiple valuator classes to the client.
+ *
+ */
+
+int
+CopySwapValuatorClass (client, v, buf)
+ register ClientPtr client;
+ ValuatorClassPtr v;
+ char **buf;
+{
+ int i, j, axes, t_axes;
+ xValuatorInfoPtr v2;
+ AxisInfo *a;
+ xAxisInfoPtr a2;
+
+ for (i=0,axes=v->numAxes; i < ((v->numAxes+19)/VPC); i++, axes-=VPC) {
+ t_axes = axes < VPC ? axes : VPC;
+ if (t_axes < 0)
+ t_axes = v->numAxes % VPC;
+ v2 = (xValuatorInfoPtr) *buf;
+ v2->class = ValuatorClass;
+ v2->length = sizeof (xValuatorInfo) + t_axes * sizeof (xAxisInfo);
+ v2->num_axes = t_axes;
+ v2->mode = v->mode & DeviceMode;
+ v2->motion_buffer_size = v->numMotionEvents;
+ if (client->swapped)
+ {
+ swapl(&v2->motion_buffer_size);
+ }
+ *buf += sizeof (xValuatorInfo);
+ a = v->axes + (VPC * i);
+ a2 = (xAxisInfoPtr) *buf;
+ for (j=0; j<t_axes; j++) {
+ a2->min_value = a->min_value;
+ a2->max_value = a->max_value;
+ a2->resolution = a->resolution;
+ if (client->swapped) {
+ swapl(&a2->min_value);
+ swapl(&a2->max_value);
+ swapl(&a2->resolution);
+ }
+ a2++;
+ a++;
+ *buf += sizeof (xAxisInfo);
+ }
+ }
+ return (i);
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XListInputDevices function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXListInputDevices (client, size, rep)
+ ClientPtr client;
+ int size;
+ xListInputDevicesReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/listdev.h b/nx-X11/programs/Xserver/Xi/listdev.h
new file mode 100644
index 000000000..629dca215
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/listdev.h
@@ -0,0 +1,102 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef LISTDEV_H
+#define LISTDEV_H 1
+
+int
+SProcXListInputDevices(
+ ClientPtr /* client */
+ );
+
+int
+ProcXListInputDevices (
+ ClientPtr /* client */
+ );
+
+void
+SizeDeviceInfo (
+ DeviceIntPtr /* d */,
+ int * /* namesize */,
+ int * /* size */
+ );
+
+void
+ListDeviceInfo (
+ ClientPtr /* client */,
+ DeviceIntPtr /* d */,
+ xDeviceInfoPtr /* dev */,
+ char ** /* devbuf */,
+ char ** /* classbuf */,
+ char ** /* namebuf */
+ );
+
+void
+CopyDeviceName (
+ char ** /* namebuf */,
+ char * /* name */
+ );
+
+void
+CopySwapDevice (
+ ClientPtr /* client */,
+ DeviceIntPtr /* d */,
+ int /* num_classes */,
+ char ** /* buf */
+ );
+
+void
+CopySwapKeyClass (
+ ClientPtr /* client */,
+ KeyClassPtr /* k */,
+ char ** /* buf */
+ );
+
+void
+CopySwapButtonClass (
+ ClientPtr /* client */,
+ ButtonClassPtr /* b */,
+ char ** /* buf */
+ );
+
+int
+CopySwapValuatorClass (
+ ClientPtr /* client */,
+ ValuatorClassPtr /* v */,
+ char ** /* buf */
+ );
+
+void
+SRepXListInputDevices (
+ ClientPtr /* client */,
+ int /* size */,
+ xListInputDevicesReply * /* rep */
+ );
+
+#endif /* LISTDEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/opendev.c b/nx-X11/programs/Xserver/Xi/opendev.c
new file mode 100644
index 000000000..1b0a2476b
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/opendev.c
@@ -0,0 +1,198 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to open an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "windowstr.h" /* window structure */
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "opendev.h"
+
+extern CARD8 event_base [];
+
+/***********************************************************************
+ *
+ * This procedure swaps the request if the server and client have different
+ * byte orderings.
+ *
+ */
+
+int
+SProcXOpenDevice(client)
+ register ClientPtr client;
+ {
+ REQUEST(xOpenDeviceReq);
+ swaps(&stuff->length);
+ return(ProcXOpenDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure causes the server to open an input device.
+ *
+ */
+
+int
+ProcXOpenDevice(client)
+ register ClientPtr client;
+ {
+ xInputClassInfo evbase [numInputClasses];
+ Bool enableit = FALSE;
+ int j=0;
+ int status = Success;
+ xOpenDeviceReply rep;
+ DeviceIntPtr dev;
+
+ REQUEST(xOpenDeviceReq);
+ REQUEST_SIZE_MATCH(xOpenDeviceReq);
+
+ if (stuff->deviceid == inputInfo.pointer->id ||
+ stuff->deviceid == inputInfo.keyboard->id)
+ {
+ SendErrorToClient(client, IReqCode, X_OpenDevice, 0, BadDevice);
+ return Success;
+ }
+
+ if ((dev = LookupDeviceIntRec(stuff->deviceid)) == NULL) /* not open */
+ {
+ for (dev=inputInfo.off_devices; dev; dev=dev->next)
+ if (dev->id == stuff->deviceid)
+ break;
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_OpenDevice, 0, BadDevice);
+ return Success;
+ }
+ enableit = TRUE;
+ }
+
+ OpenInputDevice (dev, client, &status);
+ if (status != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_OpenDevice, 0, status);
+ return Success;
+ }
+ if (enableit && dev->inited && dev->startup)
+ (void)EnableDevice(dev);
+
+ memset(&rep, 0, sizeof(xOpenDeviceReply));
+ rep.repType = X_Reply;
+ rep.RepType = X_OpenDevice;
+ rep.sequenceNumber = client->sequence;
+ if (dev->key != NULL)
+ {
+ evbase[j].class = KeyClass;
+ evbase[j++].event_type_base = event_base[KeyClass];
+ }
+ if (dev->button != NULL)
+ {
+ evbase[j].class = ButtonClass;
+ evbase[j++].event_type_base = event_base[ButtonClass];
+ }
+ if (dev->valuator != NULL)
+ {
+ evbase[j].class = ValuatorClass;
+ evbase[j++].event_type_base = event_base[ValuatorClass];
+ }
+ if (dev->kbdfeed != NULL || dev->ptrfeed != NULL || dev->leds != NULL ||
+ dev->intfeed != NULL || dev->bell != NULL || dev->stringfeed != NULL)
+ {
+ evbase[j].class = FeedbackClass;
+ evbase[j++].event_type_base = event_base[FeedbackClass];
+ }
+ if (dev->focus != NULL)
+ {
+ evbase[j].class = FocusClass;
+ evbase[j++].event_type_base = event_base[FocusClass];
+ }
+ if (dev->proximity != NULL)
+ {
+ evbase[j].class = ProximityClass;
+ evbase[j++].event_type_base = event_base[ProximityClass];
+ }
+ evbase[j].class = OtherClass;
+ evbase[j++].event_type_base = event_base[OtherClass];
+ rep.length = (j * sizeof (xInputClassInfo) + 3) >> 2;
+ rep.num_classes = j;
+ WriteReplyToClient (client, sizeof (xOpenDeviceReply), &rep);
+ WriteToClient(client, j * sizeof (xInputClassInfo), evbase);
+ return (Success);
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XOpenDevice function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXOpenDevice (client, size, rep)
+ ClientPtr client;
+ int size;
+ xOpenDeviceReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/opendev.h b/nx-X11/programs/Xserver/Xi/opendev.h
new file mode 100644
index 000000000..68b89da4c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/opendev.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef OPENDEV_H
+#define OPENDEV_H 1
+
+int
+SProcXOpenDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXOpenDevice(
+ ClientPtr /* client */
+ );
+
+void
+SRepXOpenDevice (
+ ClientPtr /* client */,
+ int /* size */,
+ xOpenDeviceReply * /* rep */
+ );
+
+#endif /* OPENDEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/queryst.c b/nx-X11/programs/Xserver/Xi/queryst.c
new file mode 100644
index 000000000..4eeba4c5f
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/queryst.c
@@ -0,0 +1,206 @@
+/*
+
+Copyright 1998, 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.
+
+*/
+
+/***********************************************************************
+ *
+ * Request to query the state of an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "queryst.h"
+
+/***********************************************************************
+ *
+ * This procedure allows a client to query the state of a device.
+ *
+ */
+
+int
+SProcXQueryDeviceState(client)
+ register ClientPtr client;
+ {
+ REQUEST(xQueryDeviceStateReq);
+ swaps(&stuff->length);
+ return(ProcXQueryDeviceState(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure allows frozen events to be routed.
+ *
+ */
+
+int
+ProcXQueryDeviceState(client)
+ register ClientPtr client;
+ {
+ int i;
+ int num_classes = 0;
+ int total_length = 0;
+ char *buf, *savbuf;
+ KeyClassPtr k;
+ xKeyState *tk;
+ ButtonClassPtr b;
+ xButtonState *tb;
+ ValuatorClassPtr v;
+ xValuatorState *tv;
+ xQueryDeviceStateReply rep;
+ DeviceIntPtr dev;
+ int *values;
+
+ REQUEST(xQueryDeviceStateReq);
+ REQUEST_SIZE_MATCH(xQueryDeviceStateReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_QueryDeviceState;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_QueryDeviceState, 0,
+ BadDevice);
+ return Success;
+ }
+
+ v = dev->valuator;
+ if (v != NULL && v->motionHintWindow != NULL)
+ MaybeStopDeviceHint(dev, client);
+
+ k = dev->key;
+ if (k != NULL)
+ {
+ total_length += sizeof (xKeyState);
+ num_classes++;
+ }
+
+ b = dev->button;
+ if (b != NULL)
+ {
+ total_length += sizeof (xButtonState);
+ num_classes++;
+ }
+
+ if (v != NULL)
+ {
+ total_length += (sizeof(xValuatorState) +
+ (v->numAxes * sizeof(int)));
+ num_classes++;
+ }
+ buf = (char *) malloc (total_length);
+ if (!buf)
+ {
+ SendErrorToClient(client, IReqCode, X_QueryDeviceState, 0,
+ BadAlloc);
+ return Success;
+ }
+ savbuf = buf;
+
+ if (k != NULL)
+ {
+ tk = (xKeyState *) buf;
+ tk->class = KeyClass;
+ tk->length = sizeof (xKeyState);
+ tk->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode + 1;
+ for (i = 0; i<32; i++)
+ tk->keys[i] = k->down[i];
+ buf += sizeof (xKeyState);
+ }
+
+ if (b != NULL)
+ {
+ tb = (xButtonState *) buf;
+ tb->class = ButtonClass;
+ tb->length = sizeof (xButtonState);
+ tb->num_buttons = b->numButtons;
+ for (i = 0; i<32; i++)
+ tb->buttons[i] = b->down[i];
+ buf += sizeof (xButtonState);
+ }
+
+ if (v != NULL)
+ {
+ tv = (xValuatorState *) buf;
+ tv->class = ValuatorClass;
+ tv->length = sizeof (xValuatorState);
+ tv->num_valuators = v->numAxes;
+ tv->mode = v->mode;
+ buf += sizeof(xValuatorState);
+ for (i=0, values=v->axisVal; i<v->numAxes; i++)
+ {
+ *((int *) buf) = *values++;
+ if (client->swapped)
+ {
+ swapl ((int *) buf);/* macro - braces needed */
+ }
+ buf += sizeof(int);
+ }
+ }
+
+ rep.num_classes = num_classes;
+ rep.length = (total_length + 3) >> 2;
+ WriteReplyToClient (client, sizeof(xQueryDeviceStateReply), &rep);
+ if (total_length > 0)
+ WriteToClient (client, total_length, savbuf);
+ free (savbuf);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XQueryDeviceState function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXQueryDeviceState (client, size, rep)
+ ClientPtr client;
+ int size;
+ xQueryDeviceStateReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/queryst.h b/nx-X11/programs/Xserver/Xi/queryst.h
new file mode 100644
index 000000000..53378bb6c
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/queryst.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef QUERYST_H
+#define QUERYST_H 1
+
+int
+SProcXQueryDeviceState(
+ ClientPtr /* client */
+ );
+
+int
+ProcXQueryDeviceState(
+ ClientPtr /* client */
+ );
+
+void
+SRepXQueryDeviceState (
+ ClientPtr /* client */,
+ int /* size */,
+ xQueryDeviceStateReply * /* rep */
+ );
+
+#endif /* QUERYST_H */
diff --git a/nx-X11/programs/Xserver/Xi/selectev.c b/nx-X11/programs/Xserver/Xi/selectev.c
new file mode 100644
index 000000000..6887967ac
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/selectev.c
@@ -0,0 +1,148 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to select input from an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "grabdev.h"
+#include "selectev.h"
+
+extern Mask ExtExclusiveMasks[];
+extern Mask ExtValidMasks[];
+
+/***********************************************************************
+ *
+ * Handle requests from clients with a different byte order.
+ *
+ */
+
+int
+SProcXSelectExtensionEvent (client)
+register ClientPtr client;
+ {
+ REQUEST(xSelectExtensionEventReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSelectExtensionEventReq);
+ swapl(&stuff->window);
+ swaps(&stuff->count);
+ REQUEST_FIXED_SIZE(xSelectExtensionEventReq,
+ stuff->count * sizeof(CARD32));
+ SwapLongs((CARD32 *) (&stuff[1]), stuff->count);
+
+ return(ProcXSelectExtensionEvent(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure selects input from an extension device.
+ *
+ */
+
+int
+ProcXSelectExtensionEvent (client)
+ register ClientPtr client;
+ {
+ int ret;
+ int i;
+ WindowPtr pWin;
+ struct tmask tmp[EMASKSIZE];
+
+ REQUEST(xSelectExtensionEventReq);
+ REQUEST_AT_LEAST_SIZE(xSelectExtensionEventReq);
+
+ if (stuff->length !=(sizeof(xSelectExtensionEventReq)>>2) + stuff->count)
+ {
+ SendErrorToClient (client, IReqCode, X_SelectExtensionEvent, 0,
+ BadLength);
+ return Success;
+ }
+
+ pWin = (WindowPtr) LookupWindow (stuff->window, client);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ SendErrorToClient(client, IReqCode, X_SelectExtensionEvent, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if ((ret = CreateMaskFromList (client, (XEventClass *)&stuff[1],
+ stuff->count, tmp, NULL, X_SelectExtensionEvent)) != Success)
+ return Success;
+
+ for (i=0; i<EMASKSIZE; i++)
+ if (tmp[i].dev != NULL)
+ {
+ if ((ret = SelectForWindow((DeviceIntPtr)tmp[i].dev, pWin, client, tmp[i].mask,
+ ExtExclusiveMasks[i], ExtValidMasks[i])) != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_SelectExtensionEvent, 0,
+ ret);
+ return Success;
+ }
+ }
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/selectev.h b/nx-X11/programs/Xserver/Xi/selectev.h
new file mode 100644
index 000000000..69f8d65bc
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/selectev.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SELECTEV_H
+#define SELECTEV_H 1
+
+int
+SProcXSelectExtensionEvent (
+ ClientPtr /* client */
+ );
+
+int
+ProcXSelectExtensionEvent (
+ ClientPtr /* client */
+ );
+
+#endif /* SELECTEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/sendexev.c b/nx-X11/programs/Xserver/Xi/sendexev.c
new file mode 100644
index 000000000..a851c5120
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/sendexev.c
@@ -0,0 +1,186 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to send an extension event.
+ *
+ */
+
+#define EXTENSION_EVENT_BASE 64
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* Window */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "grabdev.h"
+#include "sendexev.h"
+
+extern int lastEvent; /* Defined in extension.c */
+
+/***********************************************************************
+ *
+ * Handle requests from clients with a different byte order than us.
+ *
+ */
+
+int
+SProcXSendExtensionEvent(client)
+ register ClientPtr client;
+ {
+ CARD32 *p;
+ register int i;
+ xEvent eventT;
+ xEvent *eventP;
+ EventSwapPtr proc;
+
+ REQUEST(xSendExtensionEventReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);
+ swapl(&stuff->destination);
+ swaps(&stuff->count);
+
+ if (stuff->length != (sizeof(xSendExtensionEventReq) >> 2) + stuff->count +
+ (stuff->num_events * (sizeof(xEvent) >> 2)))
+ return BadLength;
+
+ eventP = (xEvent *) &stuff[1];
+ for (i=0; i<stuff->num_events; i++,eventP++)
+ {
+ proc = EventSwapVector[eventP->u.u.type & 0177];
+ if (proc == NotImplemented) /* no swapping proc; invalid event type? */
+ return (BadValue);
+ (*proc)(eventP, &eventT);
+ *eventP = eventT;
+ }
+
+ p = (CARD32 *)(((xEvent *) & stuff[1]) + stuff->num_events);
+ SwapLongs(p, stuff->count);
+ return(ProcXSendExtensionEvent(client));
+ }
+
+/***********************************************************************
+ *
+ * Send an event to some client, as if it had come from an extension input
+ * device.
+ *
+ */
+
+int
+ProcXSendExtensionEvent (client)
+ register ClientPtr client;
+ {
+ int ret;
+ DeviceIntPtr dev;
+ xEvent *first;
+ XEventClass *list;
+ struct tmask tmp[EMASKSIZE];
+
+ REQUEST(xSendExtensionEventReq);
+ REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);
+
+ if (stuff->length !=(sizeof(xSendExtensionEventReq)>>2) + stuff->count +
+ (stuff->num_events * (sizeof (xEvent) >> 2)))
+ {
+ SendErrorToClient (client, IReqCode, X_SendExtensionEvent, 0,
+ BadLength);
+ return Success;
+ }
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_SendExtensionEvent, 0,
+ BadDevice);
+ return Success;
+ }
+
+ /*
+ the previous code here returned the unitialized variable ret,
+ so using Success we have defined returncode at least. FIXME:
+ Upstream works different here, we must check this!
+ */
+ if (stuff->num_events == 0)
+ /* return ret; */
+ return Success;
+
+ /* The client's event type must be one defined by an extension. */
+
+ first = ((xEvent *) &stuff[1]);
+ if ( ! ((EXTENSION_EVENT_BASE <= first->u.u.type) &&
+ (first->u.u.type < lastEvent)) )
+ {
+ client->errorValue = first->u.u.type;
+ SendErrorToClient(client, IReqCode, X_SendExtensionEvent, 0,
+ BadValue);
+ return Success;
+ }
+
+ list = (XEventClass *) (first + stuff->num_events);
+ if ((ret = CreateMaskFromList (client, list, stuff->count, tmp, dev,
+ X_SendExtensionEvent)) != Success)
+ return Success;
+
+ ret = (SendEvent (client, dev, stuff->destination,
+ stuff->propagate, (xEvent *)&stuff[1], tmp[stuff->deviceid].mask,
+ stuff->num_events));
+
+ if (ret != Success)
+ SendErrorToClient(client, IReqCode, X_SendExtensionEvent, 0, ret);
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/sendexev.h b/nx-X11/programs/Xserver/Xi/sendexev.h
new file mode 100644
index 000000000..e52eda6f1
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/sendexev.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SENDEXEV_H
+#define SENDEXEV_H 1
+
+int
+SProcXSendExtensionEvent(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSendExtensionEvent(
+ ClientPtr /* client */
+ );
+
+#endif /* SENDEXEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/setbmap.c b/nx-X11/programs/Xserver/Xi/setbmap.c
new file mode 100644
index 000000000..edaea78c7
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setbmap.c
@@ -0,0 +1,162 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to change the button mapping of an extension device.
+ *
+ */
+
+#define IsOn(ptr, bit) \
+ (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "setbmap.h"
+
+/***********************************************************************
+ *
+ * This procedure changes the button mapping.
+ *
+ */
+
+int
+SProcXSetDeviceButtonMapping(client)
+ register ClientPtr client;
+ {
+ REQUEST(xSetDeviceButtonMappingReq);
+ swaps(&stuff->length);
+ return(ProcXSetDeviceButtonMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure lists the input devices available to the server.
+ *
+ */
+
+int
+ProcXSetDeviceButtonMapping (client)
+ register ClientPtr client;
+ {
+ int ret;
+ xSetDeviceButtonMappingReply rep;
+ DeviceIntPtr dev;
+
+ REQUEST(xSetDeviceButtonMappingReq);
+ REQUEST_AT_LEAST_SIZE(xSetDeviceButtonMappingReq);
+
+ if (stuff->length != (sizeof(xSetDeviceButtonMappingReq) +
+ stuff->map_length + 3)>>2)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceButtonMapping, 0,
+ BadLength);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_SetDeviceButtonMapping;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.status = MappingSuccess;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceButtonMapping, 0,
+ BadDevice);
+ return Success;
+ }
+
+ ret = SetButtonMapping (client, dev, stuff->map_length, (BYTE *)&stuff[1]);
+
+ if (ret == BadValue || ret == BadMatch)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceButtonMapping, 0,
+ ret);
+ return Success;
+ }
+ else
+ {
+ rep.status = ret;
+ WriteReplyToClient(client, sizeof(xSetDeviceButtonMappingReply), &rep);
+ }
+
+ if (ret != MappingBusy)
+ SendDeviceMappingNotify(MappingPointer, 0, 0, dev);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XSetDeviceButtonMapping function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXSetDeviceButtonMapping (client, size, rep)
+ ClientPtr client;
+ int size;
+ xSetDeviceButtonMappingReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/setbmap.h b/nx-X11/programs/Xserver/Xi/setbmap.h
new file mode 100644
index 000000000..7dd00c416
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setbmap.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETBMAP_H
+#define SETBMAP_H 1
+
+int
+SProcXSetDeviceButtonMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSetDeviceButtonMapping(
+ ClientPtr /* client */
+ );
+
+void
+SRepXSetDeviceButtonMapping(
+ ClientPtr /* client */,
+ int /* size */,
+ xSetDeviceButtonMappingReply * /* rep */
+ );
+
+#endif /* SETBMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/setdval.c b/nx-X11/programs/Xserver/Xi/setdval.c
new file mode 100644
index 000000000..bb6db7bcb
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setdval.c
@@ -0,0 +1,166 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to change the mode of an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "setdval.h"
+
+/***********************************************************************
+ *
+ * Handle a request from a client with a different byte order.
+ *
+ */
+
+int
+SProcXSetDeviceValuators(client)
+ register ClientPtr client;
+ {
+ REQUEST(xSetDeviceValuatorsReq);
+ swaps(&stuff->length);
+ return(ProcXSetDeviceValuators(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure sets the value of valuators on an extension input device.
+ *
+ */
+
+int
+ProcXSetDeviceValuators(client)
+ register ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ xSetDeviceValuatorsReply rep;
+
+ REQUEST(xSetDeviceValuatorsReq);
+ REQUEST_AT_LEAST_SIZE(xSetDeviceValuatorsReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_SetDeviceValuators;
+ rep.length = 0;
+ rep.status = Success;
+ rep.sequenceNumber = client->sequence;
+
+ if (stuff->length !=(sizeof(xSetDeviceValuatorsReq)>>2) +
+ stuff->num_valuators)
+ {
+ SendErrorToClient (client, IReqCode, X_SetDeviceValuators, 0,
+ BadLength);
+ return Success;
+ }
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_SetDeviceValuators, 0,
+ BadDevice);
+ return Success;
+ }
+ if (dev->valuator == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceValuators, 0,
+ BadMatch);
+ return Success;
+ }
+
+ if (stuff->first_valuator + stuff->num_valuators > dev->valuator->numAxes)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceValuators, 0,
+ BadValue);
+ return Success;
+ }
+
+ if ((dev->grab) && !SameClient(dev->grab, client))
+ rep.status = AlreadyGrabbed;
+ else
+ rep.status = SetDeviceValuators (client, dev, (int *) &stuff[1],
+ stuff->first_valuator, stuff->num_valuators);
+
+ if (rep.status != Success && rep.status != AlreadyGrabbed)
+ SendErrorToClient(client, IReqCode, X_SetDeviceValuators, 0,
+ rep.status);
+ else
+ WriteReplyToClient (client, sizeof (xSetDeviceValuatorsReply), &rep);
+
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XSetDeviceValuators function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXSetDeviceValuators (client, size, rep)
+ ClientPtr client;
+ int size;
+ xSetDeviceValuatorsReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/setdval.h b/nx-X11/programs/Xserver/Xi/setdval.h
new file mode 100644
index 000000000..2817b2688
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setdval.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETDVAL_H
+#define SETDVAL_H 1
+
+int
+SProcXSetDeviceValuators(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSetDeviceValuators(
+ ClientPtr /* client */
+ );
+
+void
+SRepXSetDeviceValuators(
+ ClientPtr /* client */,
+ int /* size */,
+ xSetDeviceValuatorsReply * /* rep */
+ );
+
+#endif /* SETDVAL_H */
diff --git a/nx-X11/programs/Xserver/Xi/setfocus.c b/nx-X11/programs/Xserver/Xi/setfocus.c
new file mode 100644
index 000000000..b88a9ba02
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setfocus.c
@@ -0,0 +1,120 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to set the focus for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "windowstr.h" /* focus struct */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+
+#include "dixevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "setfocus.h"
+
+/***********************************************************************
+ *
+ * This procedure sets the focus for a device.
+ *
+ */
+
+int
+SProcXSetDeviceFocus(client)
+ register ClientPtr client;
+ {
+ REQUEST(xSetDeviceFocusReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSetDeviceFocusReq);
+ swapl(&stuff->focus);
+ swapl(&stuff->time);
+ return(ProcXSetDeviceFocus(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure sets the focus for a device.
+ *
+ */
+
+int
+ProcXSetDeviceFocus(client)
+ register ClientPtr client;
+ {
+ int ret;
+ register DeviceIntPtr dev;
+
+ REQUEST(xSetDeviceFocusReq);
+ REQUEST_SIZE_MATCH(xSetDeviceFocusReq);
+
+ dev = LookupDeviceIntRec (stuff->device);
+ if (dev==NULL || !dev->focus)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceFocus, 0, BadDevice);
+ return Success;
+ }
+
+ ret = SetInputFocus (client, dev, stuff->focus, stuff->revertTo,
+ stuff->time, TRUE);
+ if (ret != Success)
+ SendErrorToClient(client, IReqCode, X_SetDeviceFocus, 0, ret);
+
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/setfocus.h b/nx-X11/programs/Xserver/Xi/setfocus.h
new file mode 100644
index 000000000..44f9457d7
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setfocus.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETFOCUS_H
+#define SETFOCUS_H 1
+
+int
+SProcXSetDeviceFocus(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSetDeviceFocus(
+ ClientPtr /* client */
+ );
+
+#endif /* SETFOCUS_H */
diff --git a/nx-X11/programs/Xserver/Xi/setmmap.c b/nx-X11/programs/Xserver/Xi/setmmap.c
new file mode 100644
index 000000000..f50447952
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setmmap.c
@@ -0,0 +1,156 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Set modifier mapping for an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "setmmap.h"
+
+/***********************************************************************
+ *
+ * This procedure sets the modifier mapping for an extension device,
+ * for clients on machines with a different byte ordering than the server.
+ *
+ */
+
+int
+SProcXSetDeviceModifierMapping(client)
+ register ClientPtr client;
+ {
+ REQUEST(xSetDeviceModifierMappingReq);
+ swaps(&stuff->length);
+ return(ProcXSetDeviceModifierMapping(client));
+ }
+
+/***********************************************************************
+ *
+ * Set the device Modifier mapping.
+ *
+ */
+
+int
+ProcXSetDeviceModifierMapping(client)
+ ClientPtr client;
+ {
+ int ret;
+ xSetDeviceModifierMappingReply rep;
+ DeviceIntPtr dev;
+ KeyClassPtr kp;
+
+ REQUEST(xSetDeviceModifierMappingReq);
+ REQUEST_AT_LEAST_SIZE(xSetDeviceModifierMappingReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_SetDeviceModifierMapping, 0,
+ BadDevice);
+ return Success;
+ }
+
+ rep.repType = X_Reply;
+ rep.RepType = X_SetDeviceModifierMapping;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ ret = SetModifierMapping(client, dev, stuff->length,
+ (sizeof (xSetDeviceModifierMappingReq)>>2), stuff->numKeyPerModifier,
+ (BYTE *)&stuff[1], &kp);
+
+ if (ret==MappingSuccess || ret==MappingBusy || ret==MappingFailed)
+ {
+ rep.success = ret;
+ if (ret == MappingSuccess)
+ SendDeviceMappingNotify(MappingModifier, 0, 0, dev);
+ WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),&rep);
+ }
+ else
+ {
+ if (ret==-1)
+ ret=BadValue;
+ SendErrorToClient (client, IReqCode, X_SetDeviceModifierMapping, 0,ret);
+ }
+
+
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XSetDeviceModifierMapping function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXSetDeviceModifierMapping (client, size, rep)
+ ClientPtr client;
+ int size;
+ xSetDeviceModifierMappingReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
+
diff --git a/nx-X11/programs/Xserver/Xi/setmmap.h b/nx-X11/programs/Xserver/Xi/setmmap.h
new file mode 100644
index 000000000..7deb8bbf2
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setmmap.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETMMAP_H
+#define SETMMAP_H 1
+
+int
+SProcXSetDeviceModifierMapping(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSetDeviceModifierMapping(
+ ClientPtr /* client */
+ );
+
+void
+SRepXSetDeviceModifierMapping(
+ ClientPtr /* client */,
+ int /* size */,
+ xSetDeviceModifierMappingReply * /* rep */
+ );
+
+#endif /* SETMMAP_H */
diff --git a/nx-X11/programs/Xserver/Xi/setmode.c b/nx-X11/programs/Xserver/Xi/setmode.c
new file mode 100644
index 000000000..91287088d
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setmode.c
@@ -0,0 +1,150 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to change the mode of an extension input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "setmode.h"
+
+/***********************************************************************
+ *
+ * Handle a request from a client with a different byte order.
+ *
+ */
+
+int
+SProcXSetDeviceMode(client)
+ register ClientPtr client;
+ {
+ REQUEST(xSetDeviceModeReq);
+ swaps(&stuff->length);
+ return(ProcXSetDeviceMode(client));
+ }
+
+/***********************************************************************
+ *
+ * This procedure sets the mode of a device.
+ *
+ */
+
+int
+ProcXSetDeviceMode(client)
+ register ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ xSetDeviceModeReply rep;
+
+ REQUEST(xSetDeviceModeReq);
+ REQUEST_SIZE_MATCH(xSetDeviceModeReq);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_SetDeviceMode;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient (client, IReqCode, X_SetDeviceMode, 0, BadDevice);
+ return Success;
+ }
+ if (dev->valuator == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceMode, 0, BadMatch);
+ return Success;
+ }
+ if ((dev->grab) && !SameClient(dev->grab, client))
+ rep.status = AlreadyGrabbed;
+ else
+ rep.status = SetDeviceMode (client, dev, stuff->mode);
+
+ if (rep.status == Success)
+ dev->valuator->mode = stuff->mode;
+ else if (rep.status != AlreadyGrabbed)
+ {
+ SendErrorToClient(client, IReqCode, X_SetDeviceMode, 0, rep.status);
+ return Success;
+ }
+
+ WriteReplyToClient (client, sizeof (xSetDeviceModeReply), &rep);
+ return Success;
+ }
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XSetDeviceMode function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXSetDeviceMode (client, size, rep)
+ ClientPtr client;
+ int size;
+ xSetDeviceModeReply *rep;
+ {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ WriteToClient(client, size, rep);
+ }
diff --git a/nx-X11/programs/Xserver/Xi/setmode.h b/nx-X11/programs/Xserver/Xi/setmode.h
new file mode 100644
index 000000000..95d90b7f4
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/setmode.h
@@ -0,0 +1,50 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SETMODE_H
+#define SETMODE_H 1
+
+int
+SProcXSetDeviceMode(
+ ClientPtr /* client */
+ );
+
+int
+ProcXSetDeviceMode(
+ ClientPtr /* client */
+ );
+
+void
+SRepXSetDeviceMode(
+ ClientPtr /* client */,
+ int /* size */,
+ xSetDeviceModeReply * /* rep */
+ );
+
+#endif /* SETMODE_H */
diff --git a/nx-X11/programs/Xserver/Xi/stubs.c b/nx-X11/programs/Xserver/Xi/stubs.c
new file mode 100644
index 000000000..e71db6051
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/stubs.c
@@ -0,0 +1,314 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/*
+ * stubs.c -- stub routines for the X server side of the XINPUT
+ * extension. This file is mainly to be used only as documentation.
+ * There is not much code here, and you can't get a working XINPUT
+ * server just using this.
+ * The Xvfb server uses this file so it will compile with the same
+ * object files as the real X server for a platform that has XINPUT.
+ * Xnest could do the same thing.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "inputstr.h"
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "XIstubs.h"
+
+/***********************************************************************
+ *
+ * Caller: ProcXChangeKeyboardDevice
+ *
+ * This procedure does the implementation-dependent portion of the work
+ * needed to change the keyboard device.
+ *
+ * The X keyboard device has a FocusRec. If the device that has been
+ * made into the new X keyboard did not have a FocusRec,
+ * ProcXChangeKeyboardDevice will allocate one for it.
+ *
+ * If you do not want clients to be able to focus the old X keyboard
+ * device, call DeleteFocusClassDeviceStruct to free the FocusRec.
+ *
+ * If you support input devices with keys that you do not want to be
+ * used as the X keyboard, you need to check for them here and return
+ * a BadDevice error.
+ *
+ * The default implementation is to do nothing (assume you do want
+ * clients to be able to focus the old X keyboard). The commented-out
+ * sample code shows what you might do if you don't want the default.
+ *
+ */
+
+int
+ChangeKeyboardDevice (old_dev, new_dev)
+ DeviceIntPtr old_dev;
+ DeviceIntPtr new_dev;
+ {
+ /***********************************************************************
+ DeleteFocusClassDeviceStruct(old_dev); * defined in xchgptr.c *
+ **********************************************************************/
+ return BadMatch;
+ }
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXChangePointerDevice
+ *
+ * This procedure does the implementation-dependent portion of the work
+ * needed to change the pointer device.
+ *
+ * The X pointer device does not have a FocusRec. If the device that
+ * has been made into the new X pointer had a FocusRec,
+ * ProcXChangePointerDevice will free it.
+ *
+ * If you want clients to be able to focus the old pointer device that
+ * has now become accessible through the input extension, you need to
+ * add a FocusRec to it here.
+ *
+ * The XChangePointerDevice protocol request also allows the client
+ * to choose which axes of the new pointer device are used to move
+ * the X cursor in the X- and Y- directions. If the axes are different
+ * than the default ones, you need to keep track of that here.
+ *
+ * If you support input devices with valuators that you do not want to be
+ * used as the X pointer, you need to check for them here and return a
+ * BadDevice error.
+ *
+ * The default implementation is to do nothing (assume you don't want
+ * clients to be able to focus the old X pointer). The commented-out
+ * sample code shows what you might do if you don't want the default.
+ *
+ */
+
+int
+ChangePointerDevice (
+ DeviceIntPtr old_dev,
+ DeviceIntPtr new_dev,
+ unsigned char x,
+ unsigned char y)
+ {
+ /***********************************************************************
+ InitFocusClassDeviceStruct(old_dev); * allow focusing old ptr*
+
+ x_axis = x; * keep track of new x-axis*
+ y_axis = y; * keep track of new y-axis*
+ if (x_axis != 0 || y_axis != 1)
+ axes_changed = TRUE; * remember axes have changed*
+ else
+ axes_changed = FALSE;
+ *************************************************************************/
+ return BadMatch;
+ }
+
+/***********************************************************************
+ *
+ * Caller: ProcXCloseDevice
+ *
+ * Take care of implementation-dependent details of closing a device.
+ * Some implementations may actually close the device, others may just
+ * remove this clients interest in that device.
+ *
+ * The default implementation is to do nothing (assume all input devices
+ * are initialized during X server initialization and kept open).
+ *
+ */
+
+void
+CloseInputDevice (d, client)
+ DeviceIntPtr d;
+ ClientPtr client;
+ {
+ }
+
+/***********************************************************************
+ *
+ * Caller: ProcXListInputDevices
+ *
+ * This is the implementation-dependent routine to initialize an input
+ * device to the point that information about it can be listed.
+ * Some implementations open all input devices when the server is first
+ * initialized, and never close them. Other implementations open only
+ * the X pointer and keyboard devices during server initialization,
+ * and only open other input devices when some client makes an
+ * XOpenDevice request. If some other process has the device open, the
+ * server may not be able to get information about the device to list it.
+ *
+ * This procedure should be used by implementations that do not initialize
+ * all input devices at server startup. It should do device-dependent
+ * initialization for any devices not previously initialized, and call
+ * AddInputDevice for each of those devices so that a DeviceIntRec will be
+ * created for them.
+ *
+ * The default implementation is to do nothing (assume all input devices
+ * are initialized during X server initialization and kept open).
+ * The commented-out sample code shows what you might do if you don't want
+ * the default.
+ *
+ */
+
+void
+AddOtherInputDevices ()
+ {
+ /**********************************************************************
+ for each uninitialized device, do something like:
+
+ DeviceIntPtr dev;
+ DeviceProc deviceProc;
+ void * private;
+
+ dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
+ dev->public.devicePrivate = private;
+ RegisterOtherDevice(dev);
+ dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
+ ************************************************************************/
+
+ }
+
+/***********************************************************************
+ *
+ * Caller: ProcXOpenDevice
+ *
+ * This is the implementation-dependent routine to open an input device.
+ * Some implementations open all input devices when the server is first
+ * initialized, and never close them. Other implementations open only
+ * the X pointer and keyboard devices during server initialization,
+ * and only open other input devices when some client makes an
+ * XOpenDevice request. This entry point is for the latter type of
+ * implementation.
+ *
+ * If the physical device is not already open, do it here. In this case,
+ * you need to keep track of the fact that one or more clients has the
+ * device open, and physically close it when the last client that has
+ * it open does an XCloseDevice.
+ *
+ * The default implementation is to do nothing (assume all input devices
+ * are opened during X server initialization and kept open).
+ *
+ */
+
+void
+OpenInputDevice (dev, client, status)
+ DeviceIntPtr dev;
+ ClientPtr client;
+ int *status;
+ {
+ }
+
+/****************************************************************************
+ *
+ * Caller: ProcXSetDeviceMode
+ *
+ * Change the mode of an extension device.
+ * This function is used to change the mode of a device from reporting
+ * relative motion to reporting absolute positional information, and
+ * vice versa.
+ * The default implementation below is that no such devices are supported.
+ *
+ */
+
+int
+SetDeviceMode (client, dev, mode)
+ register ClientPtr client;
+ DeviceIntPtr dev;
+ int mode;
+ {
+ return BadMatch;
+ }
+
+/****************************************************************************
+ *
+ * Caller: ProcXSetDeviceValuators
+ *
+ * Set the value of valuators on an extension input device.
+ * This function is used to set the initial value of valuators on
+ * those input devices that are capable of reporting either relative
+ * motion or an absolute position, and allow an initial position to be set.
+ * The default implementation below is that no such devices are supported.
+ *
+ */
+
+int
+SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators)
+ register ClientPtr client;
+ DeviceIntPtr dev;
+ int *valuators;
+ int first_valuator;
+ int num_valuators;
+ {
+ return BadMatch;
+ }
+
+/****************************************************************************
+ *
+ * Caller: ProcXChangeDeviceControl
+ *
+ * Change the specified device controls on an extension input device.
+ *
+ */
+
+int
+ChangeDeviceControl (client, dev, control)
+ register ClientPtr client;
+ DeviceIntPtr dev;
+ xDeviceCtl *control;
+ {
+ switch (control->control)
+ {
+ case DEVICE_RESOLUTION:
+ return (BadMatch);
+ default:
+ return (BadMatch);
+ }
+ }
diff --git a/nx-X11/programs/Xserver/Xi/ungrdev.c b/nx-X11/programs/Xserver/Xi/ungrdev.c
new file mode 100644
index 000000000..ea7f0f6f1
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdev.c
@@ -0,0 +1,117 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to release a grab of an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+
+#include "ungrdev.h"
+
+/***********************************************************************
+ *
+ * Handle requests from a client with a different byte order.
+ *
+ */
+
+int
+SProcXUngrabDevice(client)
+register ClientPtr client;
+ {
+ REQUEST(xUngrabDeviceReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xUngrabDeviceReq);
+ swapl(&stuff->time);
+ return(ProcXUngrabDevice(client));
+ }
+
+/***********************************************************************
+ *
+ * Release a grab of an extension device.
+ *
+ */
+
+int
+ProcXUngrabDevice(client)
+register ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ GrabPtr grab;
+ TimeStamp time;
+
+ REQUEST(xUngrabDeviceReq);
+ REQUEST_SIZE_MATCH(xUngrabDeviceReq);
+
+ dev = LookupDeviceIntRec (stuff->deviceid);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDevice, 0, BadDevice);
+ return Success;
+ }
+ grab = dev->grab;
+
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, dev->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*dev->DeactivateGrab)(dev);
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/ungrdev.h b/nx-X11/programs/Xserver/Xi/ungrdev.h
new file mode 100644
index 000000000..6ecfa5f67
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdev.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef UNGRDEV_H
+#define UNGRDEV_H 1
+
+int
+SProcXUngrabDevice(
+ ClientPtr /* client */
+ );
+
+int
+ProcXUngrabDevice(
+ ClientPtr /* client */
+ );
+
+#endif /* UNGRDEV_H */
diff --git a/nx-X11/programs/Xserver/Xi/ungrdevb.c b/nx-X11/programs/Xserver/Xi/ungrdevb.c
new file mode 100644
index 000000000..bbf3575ea
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdevb.c
@@ -0,0 +1,172 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to release a grab of a button on an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "dixgrabs.h"
+
+#include "ungrdevb.h"
+
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+
+/***********************************************************************
+ *
+ * Handle requests from a client with a different byte order.
+ *
+ */
+
+int
+SProcXUngrabDeviceButton(client)
+ register ClientPtr client;
+ {
+ REQUEST(xUngrabDeviceButtonReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xUngrabDeviceButtonReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ return(ProcXUngrabDeviceButton(client));
+ }
+
+/***********************************************************************
+ *
+ * Release a grab of a button on an extension device.
+ *
+ */
+
+int
+ProcXUngrabDeviceButton(client)
+ ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ DeviceIntPtr mdev;
+ WindowPtr pWin;
+ GrabRec temporaryGrab;
+
+ REQUEST(xUngrabDeviceButtonReq);
+ REQUEST_SIZE_MATCH(xUngrabDeviceButtonReq);
+
+ dev = LookupDeviceIntRec (stuff->grabbed_device);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadDevice);
+ return Success;
+ }
+ if (dev->button == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadMatch);
+ return Success;
+ }
+
+ if (stuff->modifier_device != UseXKeyboard)
+ {
+ mdev = LookupDeviceIntRec (stuff->modifier_device);
+ if (mdev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadDevice);
+ return Success;
+ }
+ if (mdev->key == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+ else
+ mdev = (DeviceIntPtr) LookupKeyboardDevice();
+
+ pWin = LookupWindow(stuff->grabWindow, client);
+ if (!pWin)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadWindow);
+ return Success;
+ }
+
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceButton, 0,
+ BadValue);
+ return Success;
+ }
+
+ temporaryGrab.resource = client->clientAsMask;
+ temporaryGrab.device = dev;
+ temporaryGrab.window = pWin;
+ temporaryGrab.type = DeviceButtonPress;
+ temporaryGrab.modifierDevice = mdev;
+ temporaryGrab.modifiersDetail.exact = stuff->modifiers;
+ temporaryGrab.modifiersDetail.pMask = NULL;
+ temporaryGrab.detail.exact = stuff->button;
+ temporaryGrab.detail.pMask = NULL;
+
+ DeletePassiveGrabFromList(&temporaryGrab);
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/ungrdevb.h b/nx-X11/programs/Xserver/Xi/ungrdevb.h
new file mode 100644
index 000000000..29dd761b5
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdevb.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef UNGRDEVB_H
+#define UNGRDEVB_H 1
+
+int
+SProcXUngrabDeviceButton(
+ ClientPtr /* client */
+ );
+
+int
+ProcXUngrabDeviceButton(
+ ClientPtr /* client */
+ );
+
+#endif /* UNGRDEVB_H */
diff --git a/nx-X11/programs/Xserver/Xi/ungrdevk.c b/nx-X11/programs/Xserver/Xi/ungrdevk.c
new file mode 100644
index 000000000..af3bb2348
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdevk.c
@@ -0,0 +1,178 @@
+
+/************************************************************
+
+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.
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD 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.
+
+********************************************************/
+
+/***********************************************************************
+ *
+ * Request to release a grab of a key on an extension device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h> /* for inputstr.h */
+#include <nx-X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exglobals.h"
+#include "dixgrabs.h"
+
+#include "ungrdevk.h"
+
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+
+/***********************************************************************
+ *
+ * Handle requests from a client with a different byte order.
+ *
+ */
+
+int
+SProcXUngrabDeviceKey(client)
+ register ClientPtr client;
+ {
+ REQUEST(xUngrabDeviceKeyReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xUngrabDeviceKeyReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ return(ProcXUngrabDeviceKey(client));
+ }
+
+/***********************************************************************
+ *
+ * Release a grab of a key on an extension device.
+ *
+ */
+
+int
+ProcXUngrabDeviceKey(client)
+ ClientPtr client;
+ {
+ DeviceIntPtr dev;
+ DeviceIntPtr mdev;
+ WindowPtr pWin;
+ GrabRec temporaryGrab;
+
+ REQUEST(xUngrabDeviceKeyReq);
+ REQUEST_SIZE_MATCH(xUngrabDeviceKeyReq);
+
+ dev = LookupDeviceIntRec (stuff->grabbed_device);
+ if (dev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadDevice);
+ return Success;
+ }
+ if (dev->key == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0, BadMatch);
+ return Success;
+ }
+
+ if (stuff->modifier_device != UseXKeyboard)
+ {
+ mdev = LookupDeviceIntRec (stuff->modifier_device);
+ if (mdev == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadDevice);
+ return Success;
+ }
+ if (mdev->key == NULL)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadMatch);
+ return Success;
+ }
+ }
+ else
+ mdev = (DeviceIntPtr) LookupKeyboardDevice();
+
+ pWin = LookupWindow(stuff->grabWindow, client);
+ if (!pWin)
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadWindow);
+ return Success;
+ }
+ if (((stuff->key > dev->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < dev->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadValue);
+ return Success;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ SendErrorToClient(client, IReqCode, X_UngrabDeviceKey, 0,
+ BadValue);
+ return Success;
+ }
+
+ temporaryGrab.resource = client->clientAsMask;
+ temporaryGrab.device = dev;
+ temporaryGrab.window = pWin;
+ temporaryGrab.type = DeviceKeyPress;
+ temporaryGrab.modifierDevice = mdev;
+ temporaryGrab.modifiersDetail.exact = stuff->modifiers;
+ temporaryGrab.modifiersDetail.pMask = NULL;
+ temporaryGrab.detail.exact = stuff->key;
+ temporaryGrab.detail.pMask = NULL;
+
+ DeletePassiveGrabFromList(&temporaryGrab);
+ return Success;
+ }
diff --git a/nx-X11/programs/Xserver/Xi/ungrdevk.h b/nx-X11/programs/Xserver/Xi/ungrdevk.h
new file mode 100644
index 000000000..be383b519
--- /dev/null
+++ b/nx-X11/programs/Xserver/Xi/ungrdevk.h
@@ -0,0 +1,43 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef UNGRDEVK_H
+#define UNGRDEVK_H 1
+
+int
+SProcXUngrabDeviceKey(
+ ClientPtr /* client */
+ );
+
+int
+ProcXUngrabDeviceKey(
+ ClientPtr /* client */
+ );
+
+#endif /* UNGRDEVK_H */
diff --git a/nx-X11/programs/Xserver/composite/.gitignore b/nx-X11/programs/Xserver/composite/.gitignore
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/.gitignore
diff --git a/nx-X11/programs/Xserver/composite/Imakefile b/nx-X11/programs/Xserver/composite/Imakefile
new file mode 100644
index 000000000..cf44ded4a
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/Imakefile
@@ -0,0 +1,29 @@
+#include <Server.tmpl>
+
+ NULL =
+
+ SRCS = compalloc.c compext.c compinit.c compoverlay.c compwindow.c
+
+ OBJS = compalloc.o compext.o compinit.o compoverlay.o compwindow.o
+
+ INCLUDES = -I../include -I../mi -I../Xext -I../render -I../xfixes \
+ -I../damageext -I../miext/damage -I$(EXTINCSRC) \
+ -I$(XINCLUDESRC) \
+ `pkg-config --cflags-only-I pixman-1`
+
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ DEFINES = \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryTarget(composite,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(composite,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/composite/compalloc.c b/nx-X11/programs/Xserver/composite/compalloc.c
new file mode 100644
index 000000000..22b036265
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compalloc.c
@@ -0,0 +1,710 @@
+/*
+ * $Id: compalloc.c,v 1.7 2005/07/03 07:37:34 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "compint.h"
+
+static void
+compScreenUpdate(ScreenPtr pScreen)
+{
+ compCheckTree(pScreen);
+ compPaintChildrenToWindow(pScreen, pScreen->root);
+}
+
+static void
+compBlockHandler(int i, void *blockData, void *pTimeout, void *pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ pScreen->BlockHandler = cs->BlockHandler;
+ compScreenUpdate(pScreen);
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+ /* Next damage will restore the block handler */
+ cs->BlockHandler = NULL;
+}
+
+static void
+compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompWindowPtr cw = GetCompWindow(pWin);
+
+ if (!cs->BlockHandler) {
+ cs->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = compBlockHandler;
+ }
+ cs->damaged = TRUE;
+ cw->damaged = TRUE;
+
+ /* Mark the ancestors */
+ /* We can't do this, Dave. No damagedDescendants support. */
+ /*
+ pWin = pWin->parent;
+ while (pWin) {
+ if (pWin->damagedDescendants)
+ break;
+ pWin->damagedDescendants = TRUE;
+ pWin = pWin->parent;
+ }
+ */
+}
+
+static void
+compDestroyDamage(DamagePtr pDamage, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ CompWindowPtr cw = GetCompWindow(pWin);
+
+ cw->damage = 0;
+}
+
+static Bool
+compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ if (!pWin->viewable)
+ return FALSE;
+
+ (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
+ (*pScreen->MarkWindow) (pLayerWin->parent);
+
+ *ppLayerWin = pLayerWin;
+
+ return TRUE;
+}
+
+static void
+compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures) (pLayerWin->parent);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
+}
+
+/*
+ * Redirect one window for one client
+ */
+int
+compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow(pWin);
+ CompClientWindowPtr ccw;
+ CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+ WindowPtr pLayerWin;
+ Bool anyMarked = FALSE;
+
+ if (pWin == cs->pOverlayWin) {
+ return Success;
+ }
+
+ if (!pWin->parent)
+ return BadMatch;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (cw && update == CompositeRedirectManual)
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = malloc (sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!cw)
+ {
+ cw = malloc (sizeof (CompWindowRec));
+ if (!cw)
+ {
+ free (ccw);
+ return BadAlloc;
+ }
+ cw->damage = DamageCreate (compReportDamage,
+ compDestroyDamage,
+ DamageReportNonEmpty,
+ FALSE,
+ pWin->drawable.pScreen,
+ pWin);
+ if (!cw->damage)
+ {
+ free (ccw);
+ free (cw);
+ return BadAlloc;
+ }
+
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ RegionNull(&cw->borderClip);
+ cw->update = CompositeRedirectAutomatic;
+ cw->clients = 0;
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ cw->damaged = FALSE;
+ cw->pOldPixmap = NullPixmap;
+ FAKE_DIX_SET_WINDOW_PRIVATE(pWin, cw);
+ }
+ ccw->next = cw->clients;
+ cw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ if (!anyMarked)
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ if (cw->damageRegistered) {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ }
+ cw->update = CompositeRedirectManual;
+ }
+ else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
+ if (!anyMarked)
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+ }
+
+ if (!compCheckRedirect (pWin))
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return BadAlloc;
+ }
+
+ if (anyMarked)
+ compHandleMarkedWindows(pWin, pLayerWin);
+
+ return Success;
+}
+
+void
+compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+
+ if (pParent->drawable.depth == pWin->drawable.depth) {
+ GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen);
+ int bw = (int) pWin->borderWidth;
+ int x = bw;
+ int y = bw;
+ int w = pWin->drawable.width;
+ int h = pWin->drawable.height;
+
+ if (pGC) {
+ ChangeGCVal val;
+
+ val.val = IncludeInferiors;
+ dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
+ ValidateGC(&pWin->drawable, pGC);
+ (*pGC->ops->CopyArea) (&pPixmap->drawable,
+ &pWin->drawable, pGC, x, y, w, h, 0, 0);
+ FreeScratchGC(pGC);
+ }
+ }
+}
+
+/*
+ * Free one of the per-client per-window resources, clearing
+ * redirect and the per-window pointer as appropriate
+ */
+void
+compFreeClientWindow (WindowPtr pWin, XID id)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw, *prev;
+ Bool anyMarked = FALSE;
+ WindowPtr pLayerWin;
+ PixmapPtr pPixmap = NULL;
+
+ if (!cw)
+ return;
+ for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ cw->update = CompositeRedirectAutomatic;
+ free (ccw);
+ break;
+ }
+ }
+ if (!cw->clients)
+ {
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ compSetParentPixmap(pWin);
+ }
+
+ if (cw->damage)
+ DamageDestroy (cw->damage);
+
+ RegionUninit(&cw->borderClip);
+
+ FAKE_DIX_SET_WINDOW_PRIVATE(pWin, NULL);
+ free (cw);
+ }
+ else if (cw->update == CompositeRedirectAutomatic &&
+ !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
+ {
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
+ }
+
+ if (anyMarked)
+ compHandleMarkedWindows(pWin, pLayerWin);
+
+ if (pPixmap) {
+ compRestoreWindow(pWin, pPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!cw)
+ return BadValue;
+
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Redirect all subwindows for one client
+ */
+
+int
+compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+ WindowPtr pChild;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (csw && update == CompositeRedirectManual)
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = malloc (sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!csw)
+ {
+ csw = malloc (sizeof (CompSubwindowsRec));
+ if (!csw)
+ {
+ free (ccw);
+ return BadAlloc;
+ }
+ csw->update = CompositeRedirectAutomatic;
+ csw->clients = 0;
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, csw);
+ }
+ /*
+ * Redirect all existing windows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ int ret = compRedirectWindow (pClient, pChild, update);
+ if (ret != Success)
+ {
+ for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib)
+ (void) compUnredirectWindow (pClient, pChild, update);
+ if (!csw->clients)
+ {
+ free (csw);
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
+ }
+ free (ccw);
+ return ret;
+ }
+ }
+ /*
+ * Hook into subwindows list
+ */
+ ccw->next = csw->clients;
+ csw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ csw->update = CompositeRedirectManual;
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, TRUE);
+ }
+ return Success;
+}
+
+/*
+ * Free one of the per-client per-subwindows resources,
+ * which frees one redirect per subwindow
+ */
+void
+compFreeClientSubwindows (WindowPtr pWin, XID id)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw, *prev;
+ WindowPtr pChild;
+
+ if (!csw)
+ return;
+ for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ ClientPtr pClient = clients[CLIENT_ID(id)];
+
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, FALSE);
+ csw->update = CompositeRedirectAutomatic;
+ if (pWin->mapped)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE);
+ }
+
+ /*
+ * Unredirect all existing subwindows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ (void) compUnredirectWindow (pClient, pChild, ccw->update);
+
+ free (ccw);
+ break;
+ }
+ }
+
+ /*
+ * Check if all of the per-client records are gone
+ */
+ if (!csw->clients)
+ {
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
+ free (csw);
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return BadValue;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Add redirection information for one subwindow (during reparent)
+ */
+
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+/*
+ * Remove redirection information for one subwindow (during reparent)
+ */
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+static PixmapPtr
+compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+ PixmapPtr pPixmap;
+
+ /* usage_hint unsupported by our old server infrastructure. */
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+
+ if (!pPixmap)
+ return 0;
+
+ pPixmap->screen_x = x;
+ pPixmap->screen_y = y;
+
+ if (pParent->drawable.depth == pWin->drawable.depth) {
+ GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ /*
+ * Copy bits from the parent into the new pixmap so that it will
+ * have "reasonable" contents in case for background None areas.
+ */
+ if (pGC)
+ {
+ ChangeGCVal val;
+
+ val.val = IncludeInferiors;
+ dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
+ ValidateGC(&pPixmap->drawable, pGC);
+ (*pGC->ops->CopyArea) (&pParent->drawable,
+ &pPixmap->drawable,
+ pGC,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ w, h, 0, 0);
+ FreeScratchGC (pGC);
+ }
+ }
+ else {
+ PictFormatPtr pSrcFormat = compWindowFormat (pParent);
+ PictFormatPtr pDstFormat = compWindowFormat (pWin);
+ XID inferiors = IncludeInferiors;
+ int error;
+
+ PicturePtr pSrcPicture = CreatePicture(None,
+ &pParent->drawable,
+ pSrcFormat,
+ CPSubwindowMode,
+ &inferiors,
+ serverClient, &error);
+
+ PicturePtr pDstPicture = CreatePicture(None,
+ &pPixmap->drawable,
+ pDstFormat,
+ 0, 0,
+ serverClient, &error);
+
+ if (pSrcPicture && pDstPicture) {
+ CompositePicture(PictOpSrc,
+ pSrcPicture,
+ NULL,
+ pDstPicture,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y, 0, 0, 0, 0, w, h);
+ }
+ if (pSrcPicture)
+ FreePicture(pSrcPicture, 0);
+ if (pDstPicture)
+ FreePicture(pDstPicture, 0);
+ }
+ return pPixmap;
+}
+
+Bool
+compAllocPixmap (WindowPtr pWin)
+{
+ int bw = (int) pWin->borderWidth;
+ int x = pWin->drawable.x - bw;
+ int y = pWin->drawable.y - bw;
+ int w = pWin->drawable.width + (bw << 1);
+ int h = pWin->drawable.height + (bw << 1);
+ PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (!pPixmap)
+ return FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ else
+ pWin->redirectDraw = RedirectDrawManual;
+
+ compSetPixmap (pWin, pPixmap);
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ {
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ }
+
+ /* Make sure our borderClip is up to date */
+ RegionUninit(&cw->borderClip);
+ RegionCopy(&cw->borderClip, &pWin->borderClip);
+ cw->borderClipX = pWin->drawable.x;
+ cw->borderClipY = pWin->drawable.y;
+
+ return TRUE;
+}
+
+void
+compSetParentPixmap (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pParentPixmap;
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (cw->damageRegistered)
+ {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ DamageEmpty (cw->damage);
+ }
+ /*
+ * Move the parent-constrained border clip region back into
+ * the window so that ValidateTree will handle the unmap
+ * case correctly. Unmap adds the window borderClip to the
+ * parent exposed area; regions beyond the parent cause crashes
+ */
+ RegionCopy(&pWin->borderClip, &cw->borderClip);
+ pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
+ pWin->redirectDraw = RedirectDrawNone;
+ compSetPixmap (pWin, pParentPixmap);
+}
+
+/*
+ * Make sure the pixmap is the right size and offset. Allocate a new
+ * pixmap to change size, adjust origin to change offset, leaving the
+ * old pixmap in cw->pOldPixmap so bits can be recovered
+ */
+Bool
+compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
+ unsigned int w, unsigned int h, int bw)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
+ PixmapPtr pNew;
+ CompWindowPtr cw = GetCompWindow (pWin);
+ int pix_x, pix_y;
+ int pix_w, pix_h;
+
+ assert (cw && pWin->redirectDraw != RedirectDrawNone);
+ cw->oldx = pOld->screen_x;
+ cw->oldy = pOld->screen_y;
+ pix_x = draw_x - bw;
+ pix_y = draw_y - bw;
+ pix_w = w + (bw << 1);
+ pix_h = h + (bw << 1);
+ if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
+ {
+ pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
+ if (!pNew)
+ return FALSE;
+ cw->pOldPixmap = pOld;
+ compSetPixmap (pWin, pNew);
+ }
+ else
+ {
+ pNew = pOld;
+ cw->pOldPixmap = 0;
+ }
+ pNew->screen_x = pix_x;
+ pNew->screen_y = pix_y;
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/composite/compext.c b/nx-X11/programs/Xserver/composite/compext.c
new file mode 100644
index 000000000..8513c6d73
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compext.c
@@ -0,0 +1,1063 @@
+/*
+ * $Id: compext.c,v 1.5 2005/07/03 07:37:34 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "compint.h"
+#include "XI.h"
+#include "XIproto.h"
+#include "protocol-versions.h"
+#include "extinit.h"
+
+static CARD8 CompositeReqCode;
+
+#ifndef NXAGENT_SERVER
+static DevPrivateKeyRec CompositeClientPrivateKeyRec;
+
+#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
+#else /* !defined(NXAGENT_SERVER) */
+static int CompositeClientPrivIndex = -1;
+#endif /* !defined(NXAGENT_SERVER) */
+
+RESTYPE CompositeClientWindowType;
+RESTYPE CompositeClientSubwindowsType;
+RESTYPE CompositeClientOverlayType;
+
+typedef struct _CompositeClient {
+ int major_version;
+ int minor_version;
+} CompositeClientRec, *CompositeClientPtr;
+
+#ifndef NXAGENT_SERVER
+#define GetCompositeClient(pClient) ((CompositeClientPtr) \
+ dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
+#else /* !defined(NXAGENT_SERVER) */
+#define GetCompositeClient(pClient) ((CompositeClientPtr) \
+ (pClient)->devPrivates[CompositeClientPrivIndex].ptr)
+#endif /* !edefined(NXAGENT_SERVER) */
+
+static void
+CompositeClientCallback (CallbackListPtr *list,
+ void *closure,
+ void *data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ CompositeClientPtr pCompositeClient = GetCompositeClient (pClient);
+
+ pCompositeClient->major_version = 0;
+ pCompositeClient->minor_version = 0;
+}
+
+static void
+CompositeResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static int
+FreeCompositeClientWindow(void *value, XID ccwid)
+{
+ WindowPtr pWin = value;
+
+ compFreeClientWindow(pWin, ccwid);
+ return Success;
+}
+
+static int
+FreeCompositeClientSubwindows(void *value, XID ccwid)
+{
+ WindowPtr pWin = value;
+
+ compFreeClientSubwindows(pWin, ccwid);
+ return Success;
+}
+
+static int
+FreeCompositeClientOverlay(void *value, XID ccwid)
+{
+ CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
+
+ compFreeOverlayClient(pOc);
+ return Success;
+}
+
+static int
+ProcCompositeQueryVersion (ClientPtr client)
+{
+ CompositeClientPtr pCompositeClient = GetCompositeClient (client);
+ xCompositeQueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
+
+ REQUEST(xCompositeQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
+ if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ } else {
+ rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
+ }
+ pCompositeClient->major_version = rep.majorVersion;
+ pCompositeClient->minor_version = rep.minorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
+ return Success;
+}
+
+/* Unsupported by current architecture and porting is too much effort. */
+#if 0
+#define VERIFY_WINDOW(pWindow, wid, client, mode) \
+ do { \
+ int err; \
+ err = dixLookupResourceByType((void **) &pWindow, wid, \
+ RT_WINDOW, client, mode); \
+ if (err != Success) { \
+ client->errorValue = wid; \
+ return err; \
+ } \
+ } while (0)
+#endif /* 0 */
+
+static int
+ProcCompositeRedirectWindow (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeRedirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess | DixManageAccess | DixBlendAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ return compRedirectWindow (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeRedirectSubwindows (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess | DixManageAccess | DixBlendAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ return compRedirectSubwindows (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeUnredirectWindow (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess | DixManageAccess | DixBlendAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ return compUnredirectWindow (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeUnredirectSubwindows (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess | DixManageAccess | DixBlendAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ return compUnredirectSubwindows (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ RegionPtr pBorderClip, pRegion;
+ REQUEST(xCompositeCreateRegionFromBorderClipReq);
+
+ REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ cw = GetCompWindow (pWin);
+ if (cw)
+ pBorderClip = &cw->borderClip;
+ else
+ pBorderClip = &pWin->borderClip;
+ pRegion = XFixesRegionCopy (pBorderClip);
+ if (!pRegion)
+ return BadAlloc;
+ RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
+
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return Success;
+}
+
+static int
+ProcCompositeNameWindowPixmap (ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ PixmapPtr pPixmap;
+ ScreenPtr pScreen;
+ int rc;
+
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->viewable)
+ return BadMatch;
+
+ LEGAL_NEW_RESOURCE (stuff->pixmap, client);
+
+ cw = GetCompWindow (pWin);
+ if (!cw)
+ return BadMatch;
+
+ pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ if (!pPixmap)
+ return BadMatch;
+
+ /* security creation/labeling check */
+ /*
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
+ pPixmap, RT_WINDOW, pWin, DixCreateAccess);
+ */
+ rc = Success;
+ if (rc != Success)
+ return rc;
+
+ ++pPixmap->refcnt;
+
+ if (!AddResource (stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
+ return BadAlloc;
+
+ /* Unsupported by current architecture. */
+ /*
+ if (pScreen->NameWindowPixmap) {
+ rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap);
+ if (rc != Success) {
+ FreeResource(stuff->pixmap, RT_NONE);
+ return rc;
+ }
+ }
+ */
+
+ return Success;
+}
+
+static int
+ProcCompositeGetOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeGetOverlayWindowReq);
+ xCompositeGetOverlayWindowReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompScreenPtr cs;
+ CompOverlayClientPtr pOc;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Create an OverlayClient structure to mark this client's
+ * interest in the overlay window
+ */
+ pOc = compCreateOverlayClient(pScreen, client);
+ if (pOc == NULL)
+ return BadAlloc;
+
+ /*
+ * Make sure the overlay window exists
+ */
+ cs = GetCompScreen(pScreen);
+ if (cs->pOverlayWin == NULL)
+ if (!compCreateOverlayWindow(pScreen)) {
+ FreeResource(pOc->resource, RT_NONE);
+ return BadAlloc;
+ }
+
+ /*
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
+ RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
+ */
+ rc = Success;
+ if (rc != Success) {
+ FreeResource(pOc->resource, RT_NONE);
+ return rc;
+ }
+
+ rep = (xCompositeGetOverlayWindowReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .overlayWin = cs->pOverlayWin->drawable.id
+ };
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.overlayWin);
+ }
+ WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
+
+ return Success;
+}
+
+static int
+ProcCompositeReleaseOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+ WindowPtr pWin;
+ CompOverlayClientPtr pOc;
+
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+ /* Unsupported by current architecture and porting is too much effort. */
+ /*
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ */
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+
+ /*
+ * Has client queried a reference to the overlay window
+ * on this screen? If not, generate an error.
+ */
+ pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
+ if (pOc == NULL)
+ return BadMatch;
+
+ /* The delete function will free the client structure */
+ FreeResource(pOc->resource, RT_NONE);
+
+ return Success;
+}
+
+static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
+ ProcCompositeQueryVersion,
+ ProcCompositeRedirectWindow,
+ ProcCompositeRedirectSubwindows,
+ ProcCompositeUnredirectWindow,
+ ProcCompositeUnredirectSubwindows,
+ ProcCompositeCreateRegionFromBorderClip,
+ ProcCompositeNameWindowPixmap,
+ ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,
+};
+
+static int
+ProcCompositeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < CompositeNumberRequests)
+ return (*ProcCompositeVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+static int
+SProcCompositeQueryVersion (ClientPtr client)
+{
+ REQUEST(xCompositeQueryVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
+ swapl(&stuff->majorVersion);
+ swapl(&stuff->minorVersion);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeRedirectWindow (ClientPtr client)
+{
+ REQUEST(xCompositeRedirectWindowReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+ swapl (&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeRedirectSubwindows (ClientPtr client)
+{
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+ swapl (&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeUnredirectWindow (ClientPtr client)
+{
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+ swapl (&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeUnredirectSubwindows (ClientPtr client)
+{
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+ swapl (&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
+{
+ REQUEST(xCompositeCreateRegionFromBorderClipReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
+ swapl (&stuff->region);
+ swapl (&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeNameWindowPixmap (ClientPtr client)
+{
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+ swapl (&stuff->window);
+ swapl (&stuff->pixmap);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeGetOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeGetOverlayWindowReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+ swapl(&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeReleaseOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+ swapl(&stuff->window);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
+ SProcCompositeQueryVersion,
+ SProcCompositeRedirectWindow,
+ SProcCompositeRedirectSubwindows,
+ SProcCompositeUnredirectWindow,
+ SProcCompositeUnredirectSubwindows,
+ SProcCompositeCreateRegionFromBorderClip,
+ SProcCompositeNameWindowPixmap,
+ SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow,
+};
+
+static int
+SProcCompositeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < CompositeNumberRequests)
+ return (*SProcCompositeVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+/* Both unused and incompatible due to architecture, disabled. */
+#if 0
+/** @see GetDefaultBytes */
+static void
+GetCompositeClientWindowBytes(void *value, XID id, ResourceSizePtr size)
+{
+ WindowPtr window = value;
+
+ /* Currently only pixmap bytes are reported to clients. */
+ size->resourceSize = 0;
+
+ /* Calculate pixmap reference sizes. */
+ size->pixmapRefSize = 0;
+ if (window->redirectDraw != RedirectDrawNone)
+ {
+ SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
+ ResourceSizeRec pixmapSize = { 0, 0 };
+ ScreenPtr screen = window->drawable.pScreen;
+ PixmapPtr pixmap = screen->GetWindowPixmap(window);
+ pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
+ size->pixmapRefSize += pixmapSize.pixmapRefSize;
+ }
+}
+#endif /* 0 */
+
+void
+CompositeExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+ int s;
+
+ /* Assume initialization is going to fail */
+ noCompositeExtension = TRUE;
+
+ fprintf(stderr, "COMPOSITE: trying to initialize extension.\n");
+
+ for (s = 0; s < screenInfo.numScreens; s++) {
+ ScreenPtr pScreen = screenInfo.screens[s];
+ VisualPtr vis;
+
+ /* Composite on 8bpp pseudocolor root windows appears to fail, so
+ * just disable it on anything pseudocolor for safety.
+ */
+ for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
+ if ((vis->class | DynamicClass) == PseudoColor)
+ return;
+
+ /* Ensure that Render is initialized, which is required for automatic
+ * compositing.
+ */
+ if (GetPictureScreenIfSet(pScreen) == NULL)
+ return;
+ }
+#ifdef PANORAMIX
+ /* Xinerama's rewriting of window drawing before Composite gets to it
+ * breaks Composite.
+ */
+ if (!noPanoramiXExtension)
+ return;
+#endif
+
+ CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow);
+ if (!CompositeClientWindowType)
+ return;
+
+ /* SetResourceTypeSizeFunc(CompositeClientWindowType,
+ GetCompositeClientWindowBytes);
+ */
+
+ CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows);
+ if (!CompositeClientSubwindowsType)
+ return;
+
+ CompositeClientOverlayType = CreateNewResourceType
+ (FreeCompositeClientOverlay);
+ if (!CompositeClientOverlayType)
+ return;
+
+#ifndef NXAGENT_SERVER
+ if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
+ sizeof (CompositeClientRec)))
+ return;
+#else /* !defined(NXAGENT_SERVER) */
+ if ((CompositeClientPrivIndex = AllocateClientPrivateIndex()) < 0)
+ return;
+ if (!AllocateClientPrivate(CompositeClientPrivIndex, sizeof (CompositeClientRec)))
+ return;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
+ return;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ if (!compScreenInit (screenInfo.screens[s])) {
+ fprintf (stderr, "COMPOSITE: could not initialize via compScreenInit() for screen %d\n", s);
+ return;
+ }
+
+ extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
+ ProcCompositeDispatch, SProcCompositeDispatch,
+ CompositeResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+ CompositeReqCode = (CARD8) extEntry->base;
+
+ /* Initialization succeeded */
+ noCompositeExtension = FALSE;
+}
+
+/*
+ * This code requires features the current infrastructure does not provide
+ * and will thus be disabled.
+ */
+#if 0
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+
+int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
+
+static int
+PanoramiXCompositeRedirectWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+
+ REQUEST(xCompositeRedirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success)
+ break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeRedirectSubwindows(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success)
+ break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeUnredirectWindow(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success)
+ break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
+{
+ PanoramiXRes *win;
+ int rc = 0, j;
+
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->window = win->info[j].id;
+ rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
+ if (rc != Success)
+ break;
+ }
+
+ return rc;
+}
+
+static int
+PanoramiXCompositeNameWindowPixmap(ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ PixmapPtr pPixmap;
+ int rc;
+ PanoramiXRes *win, *newPix;
+ int i;
+
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ LEGAL_NEW_RESOURCE(stuff->pixmap, client);
+
+ if (!(newPix = malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newPix->type = XRT_PIXMAP;
+ newPix->u.pix.shared = FALSE;
+ panoramix_setup_ids(newPix, client, stuff->pixmap);
+
+ FOR_NSCREENS(i) {
+ rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
+ RT_WINDOW, client, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->window;
+ free(newPix);
+ return rc;
+ }
+
+ if (!pWin->viewable) {
+ free(newPix);
+ return BadMatch;
+ }
+
+ cw = GetCompWindow(pWin);
+ if (!cw) {
+ free(newPix);
+ return BadMatch;
+ }
+
+ pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ if (!pPixmap) {
+ free(newPix);
+ return BadMatch;
+ }
+
+ if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap))
+ return BadAlloc;
+
+ ++pPixmap->refcnt;
+ }
+
+ if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix))
+ return BadAlloc;
+
+ return Success;
+}
+
+static int
+PanoramiXCompositeGetOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeGetOverlayWindowReq);
+ xCompositeGetOverlayWindowReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompScreenPtr cs;
+ CompOverlayClientPtr pOc;
+ int rc;
+ PanoramiXRes *win, *overlayWin = NULL;
+ int i;
+
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ cs = GetCompScreen(screenInfo.screens[0]);
+ if (!cs->pOverlayWin) {
+ if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ overlayWin->type = XRT_WINDOW;
+ overlayWin->u.win.root = FALSE;
+ }
+
+ FOR_NSCREENS_BACKWARD(i) {
+ rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
+ RT_WINDOW, client, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->window;
+ free(overlayWin);
+ return rc;
+ }
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Create an OverlayClient structure to mark this client's
+ * interest in the overlay window
+ */
+ pOc = compCreateOverlayClient(pScreen, client);
+ if (pOc == NULL) {
+ free(overlayWin);
+ return BadAlloc;
+ }
+
+ /*
+ * Make sure the overlay window exists
+ */
+ cs = GetCompScreen(pScreen);
+ if (cs->pOverlayWin == NULL)
+ if (!compCreateOverlayWindow(pScreen)) {
+ FreeResource(pOc->resource, RT_NONE);
+ free(overlayWin);
+ return BadAlloc;
+ }
+
+ /*
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client,
+ cs->pOverlayWin->drawable.id,
+ RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
+ DixGetAttrAccess);
+ */
+ rc = Success;
+ if (rc != Success) {
+ FreeResource(pOc->resource, RT_NONE);
+ free(overlayWin);
+ return rc;
+ }
+ }
+
+ if (overlayWin) {
+ FOR_NSCREENS(i) {
+ cs = GetCompScreen(screenInfo.screens[i]);
+ overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
+ }
+
+ AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
+ }
+
+ cs = GetCompScreen(screenInfo.screens[0]);
+
+ rep = (xCompositeGetOverlayWindowReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .overlayWin = cs->pOverlayWin->drawable.id
+ };
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.overlayWin);
+ }
+ WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
+
+ return Success;
+}
+
+static int
+PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
+{
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+ WindowPtr pWin;
+ CompOverlayClientPtr pOc;
+ PanoramiXRes *win;
+ int i, rc;
+
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+
+ if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
+ client, DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ FOR_NSCREENS_BACKWARD(i) {
+ if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
+ XRT_WINDOW, client,
+ DixUnknownAccess))) {
+ client->errorValue = stuff->window;
+ return rc;
+ }
+
+ /*
+ * Has client queried a reference to the overlay window
+ * on this screen? If not, generate an error.
+ */
+ pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
+ if (pOc == NULL)
+ return BadMatch;
+
+ /* The delete function will free the client structure */
+ FreeResource(pOc->resource, RT_NONE);
+ }
+
+ return Success;
+}
+
+void
+PanoramiXCompositeInit(void)
+{
+ int i;
+
+ for (i = 0; i < CompositeNumberRequests; i++)
+ PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcCompositeVector[X_CompositeRedirectWindow] =
+ PanoramiXCompositeRedirectWindow;
+ ProcCompositeVector[X_CompositeRedirectSubwindows] =
+ PanoramiXCompositeRedirectSubwindows;
+ ProcCompositeVector[X_CompositeUnredirectWindow] =
+ PanoramiXCompositeUnredirectWindow;
+ ProcCompositeVector[X_CompositeUnredirectSubwindows] =
+ PanoramiXCompositeUnredirectSubwindows;
+ ProcCompositeVector[X_CompositeNameWindowPixmap] =
+ PanoramiXCompositeNameWindowPixmap;
+ ProcCompositeVector[X_CompositeGetOverlayWindow] =
+ PanoramiXCompositeGetOverlayWindow;
+ ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
+ PanoramiXCompositeReleaseOverlayWindow;
+}
+
+void
+PanoramiXCompositeReset(void)
+{
+ int i;
+
+ for (i = 0; i < CompositeNumberRequests; i++)
+ ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
+}
+
+#endif
+
+#endif /* 0 */
diff --git a/nx-X11/programs/Xserver/composite/compinit.c b/nx-X11/programs/Xserver/composite/compinit.c
new file mode 100644
index 000000000..ff2137887
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compinit.c
@@ -0,0 +1,492 @@
+/*
+ * $Id: compinit.c,v 1.9 2005/07/03 07:37:34 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "compint.h"
+#include "compositeext.h"
+
+#ifndef NXAGENT_SERVER
+DevPrivateKeyRec CompScreenPrivateKeyRec;
+DevPrivateKeyRec CompWindowPrivateKeyRec;
+DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
+#else /* !defined(NXAGENT_SERVER) */
+int CompScreenPrivIndex = -1;
+int CompWindowPrivIndex = -1;
+int CompSubwindowsPrivIndex = -1;
+#endif
+
+static Bool
+compCloseScreen (ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret;
+
+ free(cs->alternateVisuals);
+
+ pScreen->CloseScreen = cs->CloseScreen;
+ pScreen->InstallColormap = cs->InstallColormap;
+ pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
+ pScreen->ReparentWindow = cs->ReparentWindow;
+
+ /*
+ * Unsupported by our old Xserver infrastructure, replaced with direct calls to
+ * compReallocPixmap().
+ */
+ /*
+ pScreen->ConfigNotify = cs->ConfigNotify;
+ */
+
+ pScreen->MoveWindow = cs->MoveWindow;
+ pScreen->ResizeWindow = cs->ResizeWindow;
+ pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
+
+ pScreen->ClipNotify = cs->ClipNotify;
+ pScreen->UnrealizeWindow = cs->UnrealizeWindow;
+ pScreen->RealizeWindow = cs->RealizeWindow;
+ pScreen->DestroyWindow = cs->DestroyWindow;
+ pScreen->CreateWindow = cs->CreateWindow;
+ pScreen->CopyWindow = cs->CopyWindow;
+ pScreen->PositionWindow = cs->PositionWindow;
+
+ pScreen->GetImage = cs->GetImage;
+ pScreen->GetSpans = cs->GetSpans;
+ pScreen->SourceValidate = cs->SourceValidate;
+
+ free (cs);
+ FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, NULL);
+ ret = (*pScreen->CloseScreen) (pScreen);
+ return ret;
+}
+
+static void
+compInstallColormap (ColormapPtr pColormap)
+{
+ VisualPtr pVisual = pColormap->pVisual;
+ ScreenPtr pScreen = pColormap->pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ int a;
+
+ for (a = 0; a < cs->numAlternateVisuals; a++)
+ if (pVisual->vid == cs->alternateVisuals[a])
+ return;
+ pScreen->InstallColormap = cs->InstallColormap;
+ (*pScreen->InstallColormap) (pColormap);
+ cs->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = compInstallColormap;
+}
+
+/* Unsupported by current architecture, drop for now. */
+#if 0
+static void
+compCheckBackingStore(WindowPtr pWin)
+{
+ if (pWin->backingStore != NotUseful && !pWin->backStorage) {
+ compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
+ pWin->backStorage = TRUE;
+ }
+ else if (pWin->backingStore == NotUseful && pWin->backStorage) {
+ compUnredirectWindow(serverClient, pWin,
+ CompositeRedirectAutomatic);
+ pWin->backStorage = FALSE;
+ }
+}
+
+/* Fake backing store via automatic redirection */
+static Bool
+compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ Bool ret;
+
+ pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
+ ret = pScreen->ChangeWindowAttributes(pWin, mask);
+
+ if (ret && (mask & CWBackingStore) &&
+ pScreen->backingStoreSupport != NotUseful)
+ compCheckBackingStore(pWin);
+
+ pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
+
+ return ret;
+}
+#endif /* 0 */
+
+static void
+compGetImage(DrawablePtr pDrawable,
+ int sx, int sy,
+ int w, int h,
+ unsigned int format, unsigned long planemask, char *pdstLine)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ pScreen->GetImage = cs->GetImage;
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
+ cs->GetImage = pScreen->GetImage;
+ pScreen->GetImage = compGetImage;
+}
+
+static void
+compGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
+ int nspans, char *pdstStart)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ pScreen->GetSpans = cs->GetSpans;
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ cs->GetSpans = pScreen->GetSpans;
+ pScreen->GetSpans = compGetSpans;
+}
+
+static void
+compSourceValidate(DrawablePtr pDrawable,
+ int x, int y,
+ int width, int height /* , unsigned int subWindowMode */ /* unsupported */)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ pScreen->SourceValidate = cs->SourceValidate;
+ if (pDrawable->type == DRAWABLE_WINDOW /* && subWindowMode == IncludeInferiors */ /* unsupported */)
+ compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height /*,
+ subWindowMode */ /* unsupported */);
+ cs->SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = compSourceValidate;
+}
+
+/*
+ * Add alternate visuals -- always expose an ARGB32 and RGB24 visual
+ */
+
+static DepthPtr
+compFindVisuallessDepth (ScreenPtr pScreen, int d)
+{
+ int i;
+
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ DepthPtr depth = &pScreen->allowedDepths[i];
+ if (depth->depth == d)
+ {
+ /*
+ * Make sure it doesn't have visuals already
+ */
+ if (depth->numVids)
+ return 0;
+ /*
+ * looks fine
+ */
+ return depth;
+ }
+ }
+ /*
+ * If there isn't one, then it's gonna be hard to have
+ * an associated visual
+ */
+ return 0;
+}
+
+/*
+ * Add a list of visual IDs to the list of visuals to implicitly redirect.
+ */
+static Bool
+compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals)
+{
+ VisualID *p;
+
+ p = reallocarray(cs->alternateVisuals,
+ cs->numAlternateVisuals + nVisuals, sizeof(VisualID));
+ if (p == NULL)
+ return FALSE;
+
+ memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
+
+ cs->alternateVisuals = p;
+ cs->numAlternateVisuals += nVisuals;
+
+ return TRUE;
+}
+
+Bool
+CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
+ int nVisuals)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ return compRegisterAlternateVisuals(cs, vids, nVisuals);
+}
+
+Bool
+CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
+ VisualID parentVisual,
+ VisualID winVisual)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompImplicitRedirectException *p;
+
+ p = reallocarray(cs->implicitRedirectExceptions,
+ cs->numImplicitRedirectExceptions + 1, sizeof(p[0]));
+ if (p == NULL)
+ return FALSE;
+
+ p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
+ p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
+
+ cs->implicitRedirectExceptions = p;
+ cs->numImplicitRedirectExceptions++;
+
+ return TRUE;
+}
+
+typedef struct _alternateVisual {
+ int depth;
+ CARD32 format;
+} CompAlternateVisual;
+
+static CompAlternateVisual altVisuals[] = {
+#if COMP_INCLUDE_RGB24_VISUAL
+ { 24, PICT_r8g8b8 },
+#endif
+ { 32, PICT_a8r8g8b8 },
+};
+
+static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
+ sizeof(CompAlternateVisual);
+
+static Bool
+compAddAlternateVisual (ScreenPtr pScreen, CompScreenPtr cs,
+ CompAlternateVisual * alt)
+{
+ VisualPtr visual;
+ DepthPtr depth;
+ PictFormatPtr pPictFormat;
+ unsigned long alphaMask;
+
+ /*
+ * The ARGB32 visual is always available. Other alternate depth visuals
+ * are only provided if their depth is less than the root window depth.
+ * There's no deep reason for this.
+ */
+ if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
+ return FALSE;
+
+ depth = compFindVisuallessDepth(pScreen, alt->depth);
+ if (!depth)
+ /* alt->depth doesn't exist or already has alternate visuals. */
+ return TRUE;
+
+ pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format);
+ if (!pPictFormat)
+ return FALSE;
+
+ if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
+ return FALSE;
+ }
+
+ visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */
+
+ /* Initialize the visual */
+ visual->bitsPerRGBValue = 8;
+ if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
+ visual->class = PseudoColor;
+ visual->nplanes = PICT_FORMAT_BPP(alt->format);
+ visual->ColormapEntries = 1 << visual->nplanes;
+ }
+ else {
+ DirectFormatRec *direct = &pPictFormat->direct;
+
+ visual->class = TrueColor;
+ visual->redMask = ((unsigned long) direct->redMask) << direct->red;
+ visual->greenMask =
+ ((unsigned long) direct->greenMask) << direct->green;
+ visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue;
+ alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha;
+ visual->offsetRed = direct->red;
+ visual->offsetGreen = direct->green;
+ visual->offsetBlue = direct->blue;
+ /*
+ * Include A bits in this (unlike GLX which includes only RGB)
+ * This lets DIX compute suitable masks for colormap allocations
+ */
+ visual->nplanes = Ones(visual->redMask |
+ visual->greenMask |
+ visual->blueMask | alphaMask);
+ /* find widest component */
+ visual->ColormapEntries = (1 << max(Ones(visual->redMask),
+ max(Ones(visual->greenMask),
+ Ones(visual->blueMask))));
+ }
+
+ /* remember the visual ID to detect auto-update windows */
+ compRegisterAlternateVisuals(cs, &visual->vid, 1);
+
+ return TRUE;
+}
+
+static Bool
+compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs)
+{
+ int alt, ret = 0;
+
+ for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
+ ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
+
+ return ! !ret;
+}
+
+Bool
+compScreenInit (ScreenPtr pScreen)
+{
+ CompScreenPtr cs;
+
+#ifndef NXAGENT_SERVER
+ if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+#else /* !defined(NXAGENT_SERVER) */
+ if ((CompScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ if ((CompWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
+ return FALSE;
+ if ((CompSubwindowsPrivIndex = AllocateWindowPrivateIndex()) < 0)
+ return FALSE;
+
+ if (!AllocateWindowPrivate (pScreen, CompWindowPrivIndex, 0))
+ return FALSE;
+
+ if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivIndex, 0))
+ return FALSE;
+#endif
+
+ if (GetCompScreen (pScreen))
+ return TRUE;
+ cs = (CompScreenPtr) malloc (sizeof (CompScreenRec));
+ if (!cs)
+ return FALSE;
+
+ cs->damaged = FALSE;
+
+ cs->overlayWid = FakeClientID(0);
+ cs->pOverlayWin = NULL;
+ cs->pOverlayClients = NULL;
+
+ cs->numAlternateVisuals = 0;
+ cs->alternateVisuals = NULL;
+ cs->numImplicitRedirectExceptions = 0;
+ cs->implicitRedirectExceptions = NULL;
+
+ if (!compAddAlternateVisuals (pScreen, cs))
+ {
+ free (cs);
+ return FALSE;
+ }
+
+ if (!disableBackingStore)
+ pScreen->backingStoreSupport = WhenMapped;
+
+ cs->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = compPositionWindow;
+
+ cs->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = compCopyWindow;
+
+ cs->CreateWindow = pScreen->CreateWindow;
+ pScreen->CreateWindow = compCreateWindow;
+
+ cs->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = compDestroyWindow;
+
+ cs->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = compRealizeWindow;
+
+ cs->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = compUnrealizeWindow;
+
+ cs->ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = compClipNotify;
+
+ /*
+ * Unsupported by our old Xserver infrastructure, replaced with direct calls to
+ * compReallocPixmap().
+ */
+ /*
+ cs->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = compConfigNotify;
+ */
+
+ cs->MoveWindow = pScreen->MoveWindow;
+ pScreen->MoveWindow = compMoveWindow;
+
+ cs->ResizeWindow = pScreen->ResizeWindow;
+ pScreen->ResizeWindow = compResizeWindow;
+
+ cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
+ pScreen->ChangeBorderWidth = compChangeBorderWidth;
+
+ cs->ReparentWindow = pScreen->ReparentWindow;
+ pScreen->ReparentWindow = compReparentWindow;
+
+ cs->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = compInstallColormap;
+
+ /* Unsupported by our current architecture, drop for now. */
+ /*
+ cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
+ */
+
+ cs->BlockHandler = NULL;
+
+ cs->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = compCloseScreen;
+
+ cs->GetImage = pScreen->GetImage;
+ pScreen->GetImage = compGetImage;
+
+ cs->GetSpans = pScreen->GetSpans;
+ pScreen->GetSpans = compGetSpans;
+
+ cs->SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = compSourceValidate;
+
+ FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, cs);
+
+ RegisterRealChildHeadProc(CompositeRealChildHead);
+
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/composite/compint.h b/nx-X11/programs/Xserver/composite/compint.h
new file mode 100644
index 000000000..62d5fd868
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compint.h
@@ -0,0 +1,360 @@
+/*
+ * $Id: compint.h,v 1.8 2005/07/03 08:53:37 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _COMPINT_H_
+#define _COMPINT_H_
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "dixevents.h"
+#include "globals.h"
+#include "picturestr.h"
+#include "extnsionst.h"
+#include "mi.h"
+#include "damage.h"
+#include "damageextint.h"
+#include "xfixes.h"
+#include <nx-X11/extensions/compositeproto.h>
+#include "compositeext.h"
+#include <assert.h>
+
+/*
+ * enable this for debugging
+#define COMPOSITE_DEBUG
+ */
+
+typedef struct _CompClientWindow {
+ struct _CompClientWindow *next;
+ XID id;
+ int update;
+} CompClientWindowRec, *CompClientWindowPtr;
+
+typedef struct _CompWindow {
+ RegionRec borderClip;
+ DamagePtr damage; /* for automatic update mode */
+ Bool damageRegistered;
+ Bool damaged;
+ int update;
+ CompClientWindowPtr clients;
+ int oldx;
+ int oldy;
+ PixmapPtr pOldPixmap;
+ int borderClipX, borderClipY;
+} CompWindowRec, *CompWindowPtr;
+
+#define COMP_ORIGIN_INVALID 0x80000000
+
+typedef struct _CompSubwindows {
+ int update;
+ CompClientWindowPtr clients;
+} CompSubwindowsRec, *CompSubwindowsPtr;
+
+#ifndef COMP_INCLUDE_RGB24_VISUAL
+#define COMP_INCLUDE_RGB24_VISUAL 0
+#endif
+
+typedef struct _CompOverlayClientRec *CompOverlayClientPtr;
+
+typedef struct _CompOverlayClientRec {
+ CompOverlayClientPtr pNext;
+ ClientPtr pClient;
+ ScreenPtr pScreen;
+ XID resource;
+} CompOverlayClientRec;
+
+typedef struct _CompImplicitRedirectException {
+ XID parentVisual;
+ XID winVisual;
+} CompImplicitRedirectException;
+
+typedef struct _CompScreen {
+ PositionWindowProcPtr PositionWindow;
+ CopyWindowProcPtr CopyWindow;
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ClipNotifyProcPtr ClipNotify;
+ /*
+ * Called from ConfigureWindow, these
+ * three track changes to the offscreen storage
+ * geometry
+ */
+
+ /*
+ * Unsupported by our old Xserver infrastructure, replaced with direct calls to
+ * compReallocPixmap().
+ */
+ /*
+ ConfigNotifyProcPtr ConfigNotify;
+ */
+
+ MoveWindowProcPtr MoveWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ ChangeBorderWidthProcPtr ChangeBorderWidth;
+ /*
+ * Reparenting has an effect on Subwindows redirect
+ */
+ ReparentWindowProcPtr ReparentWindow;
+
+ /*
+ * Colormaps for new visuals better not get installed
+ */
+ InstallColormapProcPtr InstallColormap;
+
+ /*
+ * Fake backing store via automatic redirection
+ */
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+ CloseScreenProcPtr CloseScreen;
+ Bool damaged;
+ int numAlternateVisuals;
+ VisualID *alternateVisuals;
+ int numImplicitRedirectExceptions;
+ CompImplicitRedirectException *implicitRedirectExceptions;
+
+ WindowPtr pOverlayWin;
+ Window overlayWid;
+ CompOverlayClientPtr pOverlayClients;
+
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ SourceValidateProcPtr SourceValidate;
+} CompScreenRec, *CompScreenPtr;
+
+#ifndef NXAGENT_SERVER
+extern DevPrivateKeyRec CompScreenPrivateKeyRec;
+
+#define CompScreenPrivateKey (&CompScreenPrivateKeyRec)
+
+extern DevPrivateKeyRec CompWindowPrivateKeyRec;
+
+#define CompWindowPrivateKey (&CompWindowPrivateKeyRec)
+
+extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
+
+#define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec)
+
+#define GetCompScreen(s) ((CompScreenPtr) \
+ dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey))
+#define GetCompWindow(w) ((CompWindowPtr) \
+ dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey))
+#define GetCompSubwindows(w) ((CompSubwindowsPtr) \
+ dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey))
+#else /* !defined(NXAGENT_SERVER) */
+extern int CompScreenPrivIndex;
+extern int CompWindowPrivIndex;
+extern int CompSubwindowsPrivIndex;
+
+#define GetCompScreen(s) ((CompScreenPtr) (s)->devPrivates[CompScreenPrivIndex].ptr)
+#define GetCompWindow(w) ((CompWindowPtr) (w)->devPrivates[CompWindowPrivIndex].ptr)
+#define GetCompSubwindows(w) ((CompSubwindowsPtr) (w)->devPrivates[CompSubwindowsPrivIndex].ptr)
+#endif /* !defined(NXAGENT_SERVER) */
+
+extern RESTYPE CompositeClientSubwindowsType;
+extern RESTYPE CompositeClientOverlayType;
+
+/* Shim for less ifdefs within the actual code. */
+#ifndef NXAGENT_SERVER
+#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privateKey, ptr_val) do { dixSetPrivate(&(obj)->devPrivates, privateKey, ptr_val); } while (0)
+
+#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivateKey, ptr_val)
+#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivateKey, ptr_val)
+#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivateKey, ptr_val)
+#else /* !defined(NXAGENT_SERVER) */
+#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privIndex, ptr_val) do { (obj)->devPrivates[privIndex].ptr = (void *) (ptr_val); } while (0)
+
+#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivIndex, ptr_val)
+#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivIndex, ptr_val)
+#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivIndex, ptr_val)
+#endif /* !defined(NXAGENT_SERVER) */
+
+/*
+ * compalloc.c
+ */
+
+Bool
+compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
+
+void
+compFreeClientWindow (WindowPtr pWin, XID id);
+
+int
+compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
+
+int
+compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
+
+void
+compFreeClientSubwindows (WindowPtr pWin, XID id);
+
+int
+compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
+
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
+
+Bool
+compAllocPixmap (WindowPtr pWin);
+
+void
+ compSetParentPixmap(WindowPtr pWin);
+
+void
+ compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap);
+
+Bool
+compReallocPixmap (WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, int bw);
+
+/*
+ * compinit.c
+ */
+
+Bool
+ compScreenInit(ScreenPtr pScreen);
+
+/*
+ * compoverlay.c
+ */
+
+void
+ compFreeOverlayClient(CompOverlayClientPtr pOcToDel);
+
+CompOverlayClientPtr
+compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
+
+CompOverlayClientPtr
+compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
+
+Bool
+ compCreateOverlayWindow(ScreenPtr pScreen);
+
+void
+ compDestroyOverlayWindow(ScreenPtr pScreen);
+
+/*
+ * compwindow.c
+ */
+
+#ifdef COMPOSITE_DEBUG
+void
+compCheckTree (ScreenPtr pScreen);
+#else
+#define compCheckTree(s)
+#endif
+
+PictFormatPtr
+compWindowFormat (WindowPtr pWin);
+
+void
+compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
+
+Bool
+compCheckRedirect (WindowPtr pWin);
+
+Bool
+compPositionWindow (WindowPtr pWin, int x, int y);
+
+Bool
+compRealizeWindow (WindowPtr pWin);
+
+Bool
+compUnrealizeWindow (WindowPtr pWin);
+
+
+void
+compClipNotify (WindowPtr pWin, int dx, int dy);
+
+void
+compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
+
+void
+compResizeWindow (WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib);
+
+void
+compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
+
+void
+compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
+
+Bool
+compCreateWindow (WindowPtr pWin);
+
+Bool
+compDestroyWindow (WindowPtr pWin);
+
+void
+compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
+
+RegionPtr
+compGetRedirectBorderClip (WindowPtr pWin);
+
+void
+compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+void
+ compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin);
+
+WindowPtr
+ CompositeRealChildHead(WindowPtr pWin);
+
+int
+ DeleteWindowNoInputDevices(void *value, XID wid);
+
+/*
+ * Unsupported by our old Xserver infrastructure, replaced with direct calls to
+ * compReallocPixmap().
+ */
+/*
+int
+compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
+ int bw, WindowPtr pSib);
+*/
+
+void PanoramiXCompositeInit(void);
+void PanoramiXCompositeReset(void);
+
+#endif /* _COMPINT_H_ */
diff --git a/nx-X11/programs/Xserver/composite/compositeext.h b/nx-X11/programs/Xserver/composite/compositeext.h
new file mode 100644
index 000000000..b96cb1d68
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compositeext.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2009 NVIDIA Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _COMPOSITEEXT_H_
+#define _COMPOSITEEXT_H_
+
+#include "misc.h"
+#include "scrnintstr.h"
+
+extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen,
+ VisualID * vids,
+ int nVisuals);
+
+extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
+ VisualID parentVisual,
+ VisualID winVisual);
+
+extern _X_EXPORT RESTYPE CompositeClientWindowType;
+
+#endif /* _COMPOSITEEXT_H_ */
diff --git a/nx-X11/programs/Xserver/composite/compoverlay.c b/nx-X11/programs/Xserver/composite/compoverlay.c
new file mode 100644
index 000000000..226bbcb6a
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compoverlay.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "compint.h"
+#ifndef NXAGENT_SERVER
+#include "xace.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ * Delete the given overlay client list element from its screen list.
+ */
+void
+compFreeOverlayClient(CompOverlayClientPtr pOcToDel)
+{
+ ScreenPtr pScreen = pOcToDel->pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr *pPrev, pOc;
+
+ for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) {
+ if (pOc == pOcToDel) {
+ *pPrev = pOc->pNext;
+ free(pOc);
+ break;
+ }
+ }
+
+ /* Destroy overlay window when there are no more clients using it */
+ if (cs->pOverlayClients == NULL)
+ compDestroyOverlayWindow(pScreen);
+}
+
+/*
+ * Return the client's first overlay client rec from the given screen
+ */
+CompOverlayClientPtr
+compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
+ if (pOc->pClient == pClient)
+ return pOc;
+
+ return NULL;
+}
+
+/*
+ * Create an overlay client object for the given client
+ */
+CompOverlayClientPtr
+compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ pOc = (CompOverlayClientPtr) malloc(sizeof(CompOverlayClientRec));
+ if (pOc == NULL)
+ return NULL;
+
+ pOc->pClient = pClient;
+ pOc->pScreen = pScreen;
+ pOc->resource = FakeClientID(pClient->index);
+ pOc->pNext = cs->pOverlayClients;
+ cs->pOverlayClients = pOc;
+
+ /*
+ * Create a resource for this element so it can be deleted
+ * when the client goes away.
+ */
+ if (!AddResource(pOc->resource, CompositeClientOverlayType, (void *) pOc))
+ return NULL;
+
+ return pOc;
+}
+
+/*
+ * Create the overlay window and map it
+ */
+Bool
+compCreateOverlayWindow(ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ WindowPtr pRoot = pScreen->root;
+ WindowPtr pWin;
+ XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
+ int result;
+ int w = pScreen->width;
+ int h = pScreen->height;
+ int x = 0, y = 0;
+
+ /* Unsupported by current architecture, disabled. */
+#if 0
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ x = -pScreen->x;
+ y = -pScreen->y;
+ w = PanoramiXPixWidth;
+ h = PanoramiXPixHeight;
+ }
+#endif
+#endif
+
+ pWin = cs->pOverlayWin =
+ CreateWindow(cs->overlayWid, pRoot, x, y, w, h, 0,
+ InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
+ pRoot->drawable.depth,
+ serverClient, pScreen->rootVisual, &result);
+ if (pWin == NULL)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
+ return FALSE;
+
+ MapWindow(pWin, serverClient);
+
+ return TRUE;
+}
+
+/*
+ * Destroy the overlay window
+ */
+void
+compDestroyOverlayWindow(ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ cs->pOverlayWin = NullWindow;
+ FreeResource(cs->overlayWid, RT_NONE);
+}
diff --git a/nx-X11/programs/Xserver/composite/compwindow.c b/nx-X11/programs/Xserver/composite/compwindow.c
new file mode 100644
index 000000000..e9bb39827
--- /dev/null
+++ b/nx-X11/programs/Xserver/composite/compwindow.c
@@ -0,0 +1,909 @@
+/*
+ * $Id: compwindow.c,v 1.11 2005/07/03 07:37:34 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "compint.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+#ifdef COMPOSITE_DEBUG
+static int
+compCheckWindow (WindowPtr pWin, void * data)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
+ PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+
+ if (!pWin->parent)
+ {
+ assert (pWin->redirectDraw == RedriectDrawNone);
+ assert (pWinPixmap == pScreenPixmap);
+ }
+ else if (pWin->redirectDraw != RedirectDrawNone)
+ {
+ assert (pWinPixmap != pParentPixmap);
+ assert (pWinPixmap != pScreenPixmap);
+ }
+ else
+ {
+ assert (pWinPixmap == pParentPixmap);
+ }
+ assert (0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
+ assert (0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
+ if (pParentPixmap)
+ assert (0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
+ return WT_WALKCHILDREN;
+}
+
+void
+compCheckTree (ScreenPtr pScreen)
+{
+ WalkTree (pScreen, compCheckWindow, 0);
+}
+#endif
+
+typedef struct _compPixmapVisit {
+ WindowPtr pWindow;
+ PixmapPtr pPixmap;
+} CompPixmapVisitRec, *CompPixmapVisitPtr;
+
+static Bool
+compRepaintBorder (ClientPtr pClient, void * closure)
+{
+ WindowPtr pWindow;
+#ifndef NXAGENT_SERVER
+ int rc =
+ dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient,
+ DixWriteAccess);
+#else
+ pWindow = SecurityLookupWindow((XID) (intptr_t) closure, pClient, DixWriteAccess);
+ int rc = pWindow ? Success : BadWindow;
+#endif
+
+ if (rc == Success)
+ {
+ RegionRec exposed;
+
+ RegionNull(&exposed);
+ RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
+#ifndef NXAGENT_SERVER
+ pWindow->drawable.pScreen->PaintWindowBorder(pWindow, &exposed, PW_BORDER);
+#else
+ (*pWindow->drawable.pScreen->PaintWindowBorder)(pWindow, &exposed, PW_BORDER);
+#endif
+ RegionUninit(&exposed);
+ }
+ return TRUE;
+}
+
+static int
+compSetPixmapVisitWindow (WindowPtr pWindow, void * data)
+{
+ CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+
+ if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
+ return WT_DONTWALKCHILDREN;
+ (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
+ /*
+ * Recompute winSize and borderSize. This is duplicate effort
+ * when resizing pixmaps, but necessary when changing redirection.
+ * Might be nice to fix this.
+ */
+ SetWinSize (pWindow);
+ SetBorderSize (pWindow);
+ if (HasBorder (pWindow))
+ QueueWorkProc (compRepaintBorder, serverClient,
+ (void *) (intptr_t) pWindow->drawable.id);
+ return WT_WALKCHILDREN;
+}
+
+void
+compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ CompPixmapVisitRec visitRec;
+
+ visitRec.pWindow = pWindow;
+ visitRec.pPixmap = pPixmap;
+ TraverseTree (pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
+ compCheckTree (pWindow->drawable.pScreen);
+}
+
+Bool
+compCheckRedirect (WindowPtr pWin)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+ Bool should;
+
+ should = pWin->realized && (pWin->drawable.class != InputOnly) &&
+ (cw != NULL) && (pWin->parent != NULL);
+
+ /* Never redirect the overlay window */
+ if (cs->pOverlayWin != NULL) {
+ if (pWin == cs->pOverlayWin) {
+ should = FALSE;
+ }
+ }
+
+ if (should != (pWin->redirectDraw != RedirectDrawNone))
+ {
+ if (should)
+ return compAllocPixmap (pWin);
+ else {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+
+ compSetParentPixmap(pWin);
+ compRestoreWindow(pWin, pPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ }
+ }
+ else if (should) {
+ if (cw->update == CompositeRedirectAutomatic)
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ else
+ pWin->redirectDraw = RedirectDrawManual;
+ }
+ return TRUE;
+}
+
+static int
+updateOverlayWindow(ScreenPtr pScreen)
+{
+ CompScreenPtr cs;
+ WindowPtr pWin; /* overlay window */
+ XID vlist[2];
+ int w = pScreen->width;
+ int h = pScreen->height;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ w = PanoramiXPixWidth;
+ h = PanoramiXPixHeight;
+ }
+#endif
+
+ cs = GetCompScreen(pScreen);
+ if ((pWin = cs->pOverlayWin) != NULL) {
+ if ((pWin->drawable.width == w) && (pWin->drawable.height == h))
+ return Success;
+
+ /* Let's resize the overlay window. */
+ vlist[0] = w;
+ vlist[1] = h;
+ return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
+ }
+
+ /* Let's be on the safe side and not assume an overlay window is
+ always allocated. */
+ return Success;
+}
+
+Bool
+compPositionWindow (WindowPtr pWin, int x, int y)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret = TRUE;
+
+ pScreen->PositionWindow = cs->PositionWindow;
+ /*
+ * "Shouldn't need this as all possible places should be wrapped
+ *
+ compCheckRedirect (pWin);
+ */
+#ifdef COMPOSITE_DEBUG
+ if ((pWin->redirectDraw != RedirectDrawNone) !=
+ (pWin->viewable && (GetCompWindow(pWin) != NULL)))
+ abort ();
+#endif
+ if (pWin->redirectDraw != RedirectDrawNone)
+ {
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ int bw = wBorderWidth (pWin);
+ int nx = pWin->drawable.x - bw;
+ int ny = pWin->drawable.y - bw;
+
+ if (pPixmap->screen_x != nx || pPixmap->screen_y != ny)
+ {
+ pPixmap->screen_x = nx;
+ pPixmap->screen_y = ny;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+
+ if (!(*pScreen->PositionWindow) (pWin, x, y))
+ ret = FALSE;
+ cs->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = compPositionWindow;
+ compCheckTree (pWin->drawable.pScreen);
+ if (updateOverlayWindow(pScreen) != Success)
+ ret = FALSE;
+ return ret;
+}
+
+Bool
+compRealizeWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret = TRUE;
+
+ pScreen->RealizeWindow = cs->RealizeWindow;
+ compCheckRedirect (pWin);
+ if (!(*pScreen->RealizeWindow) (pWin))
+ ret = FALSE;
+ cs->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = compRealizeWindow;
+ compCheckTree (pWin->drawable.pScreen);
+ return ret;
+}
+
+Bool
+compUnrealizeWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret = TRUE;
+
+ pScreen->UnrealizeWindow = cs->UnrealizeWindow;
+ compCheckRedirect (pWin);
+ if (!(*pScreen->UnrealizeWindow) (pWin))
+ ret = FALSE;
+ cs->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = compUnrealizeWindow;
+ compCheckTree (pWin->drawable.pScreen);
+ return ret;
+}
+
+/*
+ * Called after the borderClip for the window has settled down
+ * We use this to make sure our extra borderClip has the right origin
+ */
+
+void
+compClipNotify (WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (cw)
+ {
+ if (cw->borderClipX != pWin->drawable.x ||
+ cw->borderClipY != pWin->drawable.y)
+ {
+ RegionTranslate(&cw->borderClip,
+ pWin->drawable.x - cw->borderClipX,
+ pWin->drawable.y - cw->borderClipY);
+ cw->borderClipX = pWin->drawable.x;
+ cw->borderClipY = pWin->drawable.y;
+ }
+ }
+ if (cs->ClipNotify)
+ {
+ pScreen->ClipNotify = cs->ClipNotify;
+ (*pScreen->ClipNotify) (pWin, dx, dy);
+ cs->ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = compClipNotify;
+ }
+}
+
+/*
+ * Returns TRUE if the window needs server-provided automatic redirect,
+ * which is true if the child and parent aren't both regular or ARGB visuals
+ */
+
+static Bool
+compIsAlternateVisual (ScreenPtr pScreen,
+ XID visual)
+{
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ int i;
+
+ for (i = 0; i < cs->numAlternateVisuals; i++)
+ if (cs->alternateVisuals[i] == visual)
+ return TRUE;
+ return FALSE;
+}
+
+static Bool
+compIsImplicitRedirectException(ScreenPtr pScreen,
+ XID parentVisual, XID winVisual)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ int i;
+
+ for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
+ if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
+ cs->implicitRedirectExceptions[i].winVisual == winVisual)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
+{
+ if (pParent)
+ {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XID winVisual = wVisual (pWin);
+ XID parentVisual = wVisual (pParent);
+
+ if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
+ return FALSE;
+
+ if (winVisual != parentVisual &&
+ (compIsAlternateVisual (pScreen, winVisual) ||
+ compIsAlternateVisual (pScreen, parentVisual)))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+compFreeOldPixmap(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ CompWindowPtr cw = GetCompWindow(pWin);
+
+ if (cw->pOldPixmap) {
+ (*pScreen->DestroyPixmap) (cw->pOldPixmap);
+ cw->pOldPixmap = NullPixmap;
+ }
+ }
+}
+
+void
+compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+
+ compCheckTree (pScreen);
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ WindowPtr pParent;
+ int draw_x, draw_y;
+ unsigned int w, h, bw;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return;
+
+ bw = wBorderWidth (pWin);
+ draw_x = pParent->drawable.x + x + (int)bw;
+ draw_y = pParent->drawable.y + y + (int)bw;
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
+ }
+ compCheckTree (pScreen);
+
+ pScreen->MoveWindow = cs->MoveWindow;
+ (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
+ cs->MoveWindow = pScreen->MoveWindow;
+ pScreen->MoveWindow = compMoveWindow;
+
+ compFreeOldPixmap(pWin);
+ compCheckTree (pScreen);
+}
+
+void
+compResizeWindow (WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+
+ compCheckTree (pScreen);
+ if (pWin->redirectDraw != RedirectDrawNone)
+ {
+ WindowPtr pParent;
+ int draw_x, draw_y;
+ unsigned int bw;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return;
+
+ bw = wBorderWidth (pWin);
+ draw_x = pParent->drawable.x + x + (int)bw;
+ draw_y = pParent->drawable.y + y + (int)bw;
+ compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
+ }
+ compCheckTree (pScreen);
+
+ pScreen->ResizeWindow = cs->ResizeWindow;
+ (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
+ cs->ResizeWindow = pScreen->ResizeWindow;
+ pScreen->ResizeWindow = compResizeWindow;
+
+ compFreeOldPixmap(pWin);
+ compCheckTree (pWin->drawable.pScreen);
+}
+
+void
+compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+
+ compCheckTree (pScreen);
+ if (pWin->redirectDraw != RedirectDrawNone)
+ {
+ WindowPtr pParent;
+ int draw_x, draw_y;
+ unsigned int w, h;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return;
+
+ draw_x = pWin->drawable.x;
+ draw_y = pWin->drawable.y;
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
+ }
+
+ compCheckTree (pScreen);
+ pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
+ (*pScreen->ChangeBorderWidth) (pWin, bw);
+ cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
+ pScreen->ChangeBorderWidth = compChangeBorderWidth;
+
+ compFreeOldPixmap(pWin);
+ compCheckTree (pWin->drawable.pScreen);
+}
+
+void
+compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+
+ pScreen->ReparentWindow = cs->ReparentWindow;
+ /*
+ * Remove any implicit redirect due to synthesized visual
+ */
+ if (compImplicitRedirect (pWin, pPriorParent))
+ compUnredirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
+ /*
+ * Handle subwindows redirection
+ */
+ compUnredirectOneSubwindow (pPriorParent, pWin);
+ compRedirectOneSubwindow (pWin->parent, pWin);
+ /*
+ * Add any implict redirect due to synthesized visual
+ */
+ if (compImplicitRedirect (pWin, pWin->parent))
+ compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
+
+ /*
+ * Allocate any necessary redirect pixmap
+ * (this actually should never be true; pWin is always unmapped)
+ */
+ compCheckRedirect (pWin);
+
+ /*
+ * Reset pixmap pointers as appropriate
+ */
+ if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
+ compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
+ /*
+ * Call down to next function
+ */
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow) (pWin, pPriorParent);
+ cs->ReparentWindow = pScreen->ReparentWindow;
+ pScreen->ReparentWindow = compReparentWindow;
+ compCheckTree (pWin->drawable.pScreen);
+}
+
+void
+compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ int dx = 0, dy = 0;
+
+ if (pWin->redirectDraw != RedirectDrawNone)
+ {
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ assert (cw->oldx != COMP_ORIGIN_INVALID);
+ assert (cw->oldy != COMP_ORIGIN_INVALID);
+ if (cw->pOldPixmap)
+ {
+ /*
+ * Ok, the old bits are available in pOldPixmap and
+ * need to be copied to pNewPixmap.
+ */
+ RegionRec rgnDst;
+ GCPtr pGC;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ RegionTranslate(prgnSrc, -dx, -dy);
+
+ RegionNull(&rgnDst);
+
+ RegionIntersect(&rgnDst,
+ &pWin->borderClip, prgnSrc);
+
+ RegionTranslate(&rgnDst,
+ -pPixmap->screen_x, -pPixmap->screen_y);
+
+ dx = dx + pPixmap->screen_x - cw->oldx;
+ dy = dy + pPixmap->screen_y - cw->oldy;
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ if (pGC)
+ {
+ BoxPtr pBox = RegionRects (&rgnDst);
+ int nBox = RegionNumRects (&rgnDst);
+
+ ValidateGC(&pPixmap->drawable, pGC);
+ while (nBox--)
+ {
+ (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
+ &pPixmap->drawable,
+ pGC,
+ pBox->x1 + dx, pBox->y1 + dy,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ pBox->x1, pBox->y1);
+ pBox++;
+ }
+ FreeScratchGC (pGC);
+ }
+ RegionUninit (&rgnDst);
+ return;
+ }
+ dx = pPixmap->screen_x - cw->oldx;
+ dy = pPixmap->screen_y - cw->oldy;
+ ptOldOrg.x += dx;
+ ptOldOrg.y += dy;
+ }
+
+ pScreen->CopyWindow = cs->CopyWindow;
+ if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y)
+ {
+ if (dx || dy)
+ RegionTranslate(prgnSrc, dx, dy);
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ if (dx || dy)
+ RegionTranslate(prgnSrc, -dx, -dy);
+ }
+ else
+ {
+ ptOldOrg.x -= dx;
+ ptOldOrg.y -= dy;
+ RegionTranslate(prgnSrc,
+ pWin->drawable.x - ptOldOrg.x,
+ pWin->drawable.y - ptOldOrg.y);
+ DamageDamageRegion (&pWin->drawable, prgnSrc);
+ }
+ cs->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = compCopyWindow;
+ compCheckTree (pWin->drawable.pScreen);
+}
+
+Bool
+compCreateWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret;
+
+ pScreen->CreateWindow = cs->CreateWindow;
+ ret = (*pScreen->CreateWindow) (pWin);
+ if (pWin->parent && ret)
+ {
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin->parent);
+ CompClientWindowPtr ccw;
+ PixmapPtr parent_pixmap = (*pScreen->GetWindowPixmap)(pWin->parent);
+ PixmapPtr window_pixmap = (*pScreen->GetWindowPixmap)(pWin);
+
+ if (window_pixmap != parent_pixmap)
+ (*pScreen->SetWindowPixmap) (pWin, parent_pixmap);
+ if (csw)
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ compRedirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (compImplicitRedirect (pWin, pWin->parent))
+ compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
+ }
+ cs->CreateWindow = pScreen->CreateWindow;
+ pScreen->CreateWindow = compCreateWindow;
+ compCheckTree (pWin->drawable.pScreen);
+ return ret;
+}
+
+Bool
+compDestroyWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompWindowPtr cw;
+ CompSubwindowsPtr csw;
+ Bool ret;
+
+ pScreen->DestroyWindow = cs->DestroyWindow;
+ while ((cw = GetCompWindow (pWin)))
+ FreeResource (cw->clients->id, RT_NONE);
+ while ((csw = GetCompSubwindows (pWin)))
+ FreeResource (csw->clients->id, RT_NONE);
+
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+
+ compSetParentPixmap (pWin);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ }
+ ret = (*pScreen->DestroyWindow) (pWin);
+ cs->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = compDestroyWindow;
+/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
+ return ret;
+}
+
+void
+compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ RegionRec damage;
+
+ RegionNull(&damage);
+ /*
+ * Align old border clip with new border clip
+ */
+ RegionTranslate(&cw->borderClip,
+ pWin->drawable.x - cw->borderClipX,
+ pWin->drawable.y - cw->borderClipY);
+ /*
+ * Compute newly visible portion of window for repaint
+ */
+ RegionSubtract(&damage, pRegion, &cw->borderClip);
+ /*
+ * Report that as damaged so it will be redrawn
+ */
+ DamageDamageRegion (&pWin->drawable, &damage);
+ RegionUninit(&damage);
+ /*
+ * Save the new border clip region
+ */
+ RegionCopy(&cw->borderClip, pRegion);
+ cw->borderClipX = pWin->drawable.x;
+ cw->borderClipY = pWin->drawable.y;
+}
+
+RegionPtr
+compGetRedirectBorderClip (WindowPtr pWin)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ return &cw->borderClip;
+}
+
+static VisualPtr
+compGetWindowVisual (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VisualID vid = wVisual (pWin);
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == vid)
+ return &pScreen->visuals[i];
+ return 0;
+}
+
+PictFormatPtr
+compWindowFormat (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return PictureMatchVisual (pScreen, pWin->drawable.depth,
+ compGetWindowVisual (pWin));
+}
+
+static void
+compWindowUpdateAutomatic (WindowPtr pWin)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+ PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ PictFormatPtr pSrcFormat = compWindowFormat (pWin);
+ PictFormatPtr pDstFormat = compWindowFormat (pWin->parent);
+ int error;
+ RegionPtr pRegion = DamageRegion (cw->damage);
+ PicturePtr pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
+ pSrcFormat,
+ 0, 0,
+ serverClient,
+ &error);
+ XID subwindowMode = IncludeInferiors;
+ PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable,
+ pDstFormat,
+ CPSubwindowMode,
+ &subwindowMode,
+ serverClient,
+ &error);
+
+ /*
+ * First move the region from window to screen coordinates
+ */
+ RegionTranslate(pRegion,
+ pWin->drawable.x, pWin->drawable.y);
+
+ /*
+ * Clip against the "real" border clip
+ */
+ RegionIntersect(pRegion, pRegion, &cw->borderClip);
+
+ /*
+ * Now translate from screen to dest coordinates
+ */
+ RegionTranslate(pRegion,
+ -pParent->drawable.x, -pParent->drawable.y);
+
+ /*
+ * Clip the picture
+ */
+ SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
+
+ /*
+ * And paint
+ */
+ CompositePicture (PictOpSrc,
+ pSrcPicture,
+ 0,
+ pDstPicture,
+ 0, 0, /* src_x, src_y */
+ 0, 0, /* msk_x, msk_y */
+ pSrcPixmap->screen_x - pParent->drawable.x,
+ pSrcPixmap->screen_y - pParent->drawable.y,
+ pSrcPixmap->drawable.width,
+ pSrcPixmap->drawable.height);
+ FreePicture (pSrcPicture, 0);
+ FreePicture (pDstPicture, 0);
+ /*
+ * Empty the damage region. This has the nice effect of
+ * rendering the translations above harmless
+ */
+ DamageEmpty (cw->damage);
+}
+
+static void
+compPaintWindowToParent(WindowPtr pWin)
+{
+ compPaintChildrenToWindow(pWin->drawable.pScreen, pWin);
+
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ CompWindowPtr cw = GetCompWindow(pWin);
+
+ if (cw->damaged) {
+ compWindowUpdateAutomatic(pWin);
+ cw->damaged = FALSE;
+ }
+ }
+}
+
+void
+compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin)
+{
+ WindowPtr pChild;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ if (!cs->damaged)
+ return;
+
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ compPaintWindowToParent(pChild);
+
+ cs->damaged = FALSE;
+}
+
+WindowPtr
+CompositeRealChildHead(WindowPtr pWin)
+{
+ WindowPtr pChild, pChildBefore;
+ CompScreenPtr cs;
+
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow(pWin->drawable.pScreen->myNum))) {
+
+ /* First child is the screen saver; see if next child is the overlay */
+ pChildBefore = pWin->firstChild;
+ pChild = pChildBefore->nextSib;
+
+ }
+ else {
+ pChildBefore = NullWindow;
+ pChild = pWin->firstChild;
+ }
+
+ if (!pChild) {
+ return NullWindow;
+ }
+
+ cs = GetCompScreen(pWin->drawable.pScreen);
+ if (pChild == cs->pOverlayWin) {
+ return pChild;
+ }
+ else {
+ return pChildBefore;
+ }
+}
+
+/* ConfigNotify not implemented... replace with the old pixmap reallocation algorithm... */
+/*
+int
+compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
+ int bw, WindowPtr pSib)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ Bool ret = 0;
+ WindowPtr pParent = pWin->parent;
+ int draw_x, draw_y;
+ Bool alloc_ret;
+
+ if (cs->ConfigNotify) {
+ pScreen->ConfigNotify = cs->ConfigNotify;
+ ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib);
+ cs->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = compConfigNotify;
+
+ if (ret)
+ return ret;
+ }
+
+ if (pWin->redirectDraw == RedirectDrawNone)
+ return Success;
+
+ compCheckTree(pScreen);
+
+ draw_x = pParent->drawable.x + x + bw;
+ draw_y = pParent->drawable.y + y + bw;
+ alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw);
+
+ if (alloc_ret == FALSE)
+ return BadAlloc;
+ return Success;
+}
+*/
diff --git a/nx-X11/programs/Xserver/damageext/Imakefile b/nx-X11/programs/Xserver/damageext/Imakefile
new file mode 100644
index 000000000..d8cc1bfa4
--- /dev/null
+++ b/nx-X11/programs/Xserver/damageext/Imakefile
@@ -0,0 +1,28 @@
+#include <Server.tmpl>
+
+ NULL =
+
+ SRCS = damageext.c
+
+ OBJS = damageext.o
+
+ INCLUDES = -I../include -I../Xext -I../render -I../xfixes -I../miext/damage \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ `pkg-config --cflags-only-I pixman-1`
+
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ DEFINES = \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryTarget(damage,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(damage,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/damageext/damageext.c b/nx-X11/programs/Xserver/damageext/damageext.c
new file mode 100644
index 000000000..b5e5d0b00
--- /dev/null
+++ b/nx-X11/programs/Xserver/damageext/damageext.c
@@ -0,0 +1,475 @@
+/*
+ * $Id: damageext.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "damageextint.h"
+#include "protocol-versions.h"
+
+unsigned char DamageReqCode;
+int DamageEventBase;
+int DamageErrorBase;
+int DamageClientPrivateIndex;
+RESTYPE DamageExtType;
+RESTYPE DamageExtWinType;
+
+#define prScreen screenInfo.screens[0]
+
+static void
+DamageExtNotify (DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes)
+{
+ ClientPtr pClient = pDamageExt->pClient;
+ DamageClientPtr pDamageClient = GetDamageClient (pClient);
+ DrawablePtr pDrawable = pDamageExt->pDrawable;
+ xDamageNotifyEvent ev;
+ int i;
+
+ UpdateCurrentTimeIf ();
+ ev.type = DamageEventBase + XDamageNotify;
+ ev.level = pDamageExt->level;
+ ev.sequenceNumber = pClient->sequence;
+ ev.drawable = pDrawable->id;
+ ev.damage = pDamageExt->id;
+ ev.timestamp = currentTime.milliseconds;
+ ev.geometry.x = pDrawable->x;
+ ev.geometry.y = pDrawable->y;
+ ev.geometry.width = pDrawable->width;
+ ev.geometry.height = pDrawable->height;
+ if (pBoxes)
+ {
+ for (i = 0; i < nBoxes; i++)
+ {
+ ev.level = pDamageExt->level;
+ if (i < nBoxes - 1)
+ ev.level |= DamageNotifyMore;
+ ev.area.x = pBoxes[i].x1;
+ ev.area.y = pBoxes[i].y1;
+ ev.area.width = pBoxes[i].x2 - pBoxes[i].x1;
+ ev.area.height = pBoxes[i].y2 - pBoxes[i].y1;
+ WriteEventsToClient (pClient, 1, (xEvent *) &ev);
+ }
+ }
+ else
+ {
+ ev.area.x = 0;
+ ev.area.y = 0;
+ ev.area.width = pDrawable->width;
+ ev.area.height = pDrawable->height;
+ WriteEventsToClient (pClient, 1, (xEvent *) &ev);
+ }
+ /* Composite extension marks clients with manual Subwindows as critical */
+ if (pDamageClient->critical > 0)
+ {
+ SetCriticalOutputPending ();
+ pClient->smart_priority = SMART_MAX_PRIORITY;
+ }
+}
+
+static void
+DamageExtReport (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ DamageExtPtr pDamageExt = closure;
+
+ switch (pDamageExt->level) {
+ case DamageReportRawRegion:
+ case DamageReportDeltaRegion:
+ DamageExtNotify (pDamageExt, RegionRects(pRegion), RegionNumRects(pRegion));
+ break;
+ case DamageReportBoundingBox:
+ DamageExtNotify (pDamageExt, RegionExtents(pRegion), 1);
+ break;
+ case DamageReportNonEmpty:
+ DamageExtNotify (pDamageExt, NullBox, 0);
+ break;
+ case DamageReportNone:
+ break;
+ }
+}
+
+static void
+DamageExtDestroy (DamagePtr pDamage, void *closure)
+{
+ DamageExtPtr pDamageExt = closure;
+
+ pDamageExt->pDamage = 0;
+ if (pDamageExt->id)
+ FreeResource (pDamageExt->id, RT_NONE);
+}
+
+void
+DamageExtSetCritical (ClientPtr pClient, Bool critical)
+{
+ DamageClientPtr pDamageClient = GetDamageClient (pClient);
+
+ if (pDamageClient)
+ pDamageClient->critical += critical ? 1 : -1;
+}
+
+static int
+ProcDamageQueryVersion(ClientPtr client)
+{
+ DamageClientPtr pDamageClient = GetDamageClient (client);
+ xDamageQueryVersionReply rep;
+ REQUEST(xDamageQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
+
+ memset(&rep, 0, sizeof(xDamageQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ } else {
+ rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION;
+ if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION &&
+ stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION)
+ rep.minorVersion = stuff->minorVersion;
+ else
+ rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION;
+ }
+ pDamageClient->major_version = rep.majorVersion;
+ pDamageClient->minor_version = rep.minorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xDamageQueryVersionReply), &rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDamageCreate (ClientPtr client)
+{
+ DrawablePtr pDrawable;
+ DamageExtPtr pDamageExt;
+ DamageReportLevel level;
+ RegionPtr pRegion;
+
+ REQUEST(xDamageCreateReq);
+
+ REQUEST_SIZE_MATCH(xDamageCreateReq);
+ LEGAL_NEW_RESOURCE(stuff->damage, client);
+ SECURITY_VERIFY_DRAWABLE (pDrawable, stuff->drawable, client,
+ DixReadAccess);
+ switch (stuff->level) {
+ case XDamageReportRawRectangles:
+ level = DamageReportRawRegion;
+ break;
+ case XDamageReportDeltaRectangles:
+ level = DamageReportDeltaRegion;
+ break;
+ case XDamageReportBoundingBox:
+ level = DamageReportBoundingBox;
+ break;
+ case XDamageReportNonEmpty:
+ level = DamageReportNonEmpty;
+ break;
+ default:
+ client->errorValue = stuff->level;
+ return BadValue;
+ }
+
+ pDamageExt = malloc (sizeof (DamageExtRec));
+ if (!pDamageExt)
+ return BadAlloc;
+ pDamageExt->id = stuff->damage;
+ pDamageExt->pDrawable = pDrawable;
+ pDamageExt->level = level;
+ pDamageExt->pClient = client;
+ pDamageExt->pDamage = DamageCreate (DamageExtReport,
+ DamageExtDestroy,
+ level,
+ FALSE,
+ pDrawable->pScreen,
+ pDamageExt);
+ if (!pDamageExt->pDamage)
+ {
+ free (pDamageExt);
+ return BadAlloc;
+ }
+ if (!AddResource (stuff->damage, DamageExtType, (void *) pDamageExt))
+ return BadAlloc;
+
+ DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pRegion = &((WindowPtr) pDrawable)->borderClip;
+ DamageDamageRegion (pDrawable, pRegion);
+ }
+
+ return (client->noClientException);
+}
+
+static int
+ProcDamageDestroy (ClientPtr client)
+{
+ REQUEST(xDamageDestroyReq);
+ DamageExtPtr pDamageExt;
+
+ REQUEST_SIZE_MATCH(xDamageDestroyReq);
+ VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess);
+ FreeResource (stuff->damage, RT_NONE);
+ return (client->noClientException);
+}
+
+static int
+ProcDamageSubtract (ClientPtr client)
+{
+ REQUEST(xDamageSubtractReq);
+ DamageExtPtr pDamageExt;
+ RegionPtr pRepair;
+ RegionPtr pParts;
+
+ REQUEST_SIZE_MATCH(xDamageSubtractReq);
+ VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess);
+ VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess);
+ VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess);
+
+ if (pDamageExt->level != DamageReportRawRegion)
+ {
+ DamagePtr pDamage = pDamageExt->pDamage;
+ if (pRepair)
+ {
+ if (pParts)
+ RegionIntersect(pParts, DamageRegion (pDamage), pRepair);
+ if (DamageSubtract (pDamage, pRepair))
+ DamageExtReport (pDamage, DamageRegion (pDamage), (void *) pDamageExt);
+ }
+ else
+ {
+ if (pParts)
+ RegionCopy(pParts, DamageRegion (pDamage));
+ DamageEmpty (pDamage);
+ }
+ }
+ return (client->noClientException);
+}
+
+/* Major version controls available requests */
+static const int version_requests[] = {
+ X_DamageQueryVersion, /* before client sends QueryVersion */
+ X_DamageSubtract, /* Version 1 */
+};
+
+#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
+
+int (*ProcDamageVector[XDamageNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ ProcDamageQueryVersion,
+ ProcDamageCreate,
+ ProcDamageDestroy,
+ ProcDamageSubtract,
+};
+
+
+static int
+ProcDamageDispatch (ClientPtr client)
+{
+ REQUEST(xDamageReq);
+ DamageClientPtr pDamageClient = GetDamageClient (client);
+
+ if (pDamageClient->major_version > NUM_VERSION_REQUESTS)
+ return BadRequest;
+ if (stuff->damageReqType > version_requests[pDamageClient->major_version])
+ return BadRequest;
+ return (*ProcDamageVector[stuff->damageReqType]) (client);
+}
+
+static int
+SProcDamageQueryVersion(ClientPtr client)
+{
+ REQUEST(xDamageQueryVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDamageQueryVersionReq);
+ swapl(&stuff->majorVersion);
+ swapl(&stuff->minorVersion);
+ return (*ProcDamageVector[stuff->damageReqType]) (client);
+}
+
+static int
+SProcDamageCreate (ClientPtr client)
+{
+ REQUEST(xDamageCreateReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xDamageCreateReq);
+ swapl (&stuff->damage);
+ swapl (&stuff->drawable);
+ return (*ProcDamageVector[stuff->damageReqType]) (client);
+}
+
+static int
+SProcDamageDestroy (ClientPtr client)
+{
+ REQUEST(xDamageDestroyReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xDamageDestroyReq);
+ swapl (&stuff->damage);
+ return (*ProcDamageVector[stuff->damageReqType]) (client);
+}
+
+static int
+SProcDamageSubtract (ClientPtr client)
+{
+ REQUEST(xDamageSubtractReq);
+
+ swaps (&stuff->length);
+ REQUEST_SIZE_MATCH(xDamageSubtractReq);
+ swapl (&stuff->damage);
+ swapl (&stuff->repair);
+ swapl (&stuff->parts);
+ return (*ProcDamageVector[stuff->damageReqType]) (client);
+}
+
+int (*SProcDamageVector[XDamageNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ SProcDamageQueryVersion,
+ SProcDamageCreate,
+ SProcDamageDestroy,
+ SProcDamageSubtract,
+};
+
+static int
+SProcDamageDispatch (ClientPtr client)
+{
+ REQUEST(xDamageReq);
+ if (stuff->damageReqType >= XDamageNumberRequests)
+ return BadRequest;
+ return (*SProcDamageVector[stuff->damageReqType]) (client);
+}
+
+static void
+DamageClientCallback (CallbackListPtr *list,
+ void * closure,
+ void * data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ DamageClientPtr pDamageClient = GetDamageClient (pClient);
+
+ pDamageClient->critical = 0;
+ pDamageClient->major_version = 0;
+ pDamageClient->minor_version = 0;
+}
+
+/*ARGSUSED*/
+static void
+DamageResetProc (ExtensionEntry *extEntry)
+{
+ DeleteCallback (&ClientStateCallback, DamageClientCallback, 0);
+}
+
+static int
+FreeDamageExt (void * value, XID did)
+{
+ DamageExtPtr pDamageExt = (DamageExtPtr) value;
+
+ /*
+ * Get rid of the resource table entry hanging from the window id
+ */
+ pDamageExt->id = 0;
+ if (WindowDrawable(pDamageExt->pDrawable->type))
+ FreeResourceByType (pDamageExt->pDrawable->id, DamageExtWinType, TRUE);
+ if (pDamageExt->pDamage)
+ {
+ DamageUnregister (pDamageExt->pDrawable, pDamageExt->pDamage);
+ DamageDestroy (pDamageExt->pDamage);
+ }
+ free (pDamageExt);
+ return Success;
+}
+
+static int
+FreeDamageExtWin (void * value, XID wid)
+{
+ DamageExtPtr pDamageExt = (DamageExtPtr) value;
+
+ if (pDamageExt->id)
+ FreeResource (pDamageExt->id, RT_NONE);
+ return Success;
+}
+
+void
+SDamageNotifyEvent (xDamageNotifyEvent *from,
+ xDamageNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->drawable, to->drawable);
+ cpswapl (from->damage, to->damage);
+ cpswaps (from->area.x, to->area.x);
+ cpswaps (from->area.y, to->area.y);
+ cpswaps (from->area.width, to->area.width);
+ cpswaps (from->area.height, to->area.height);
+ cpswaps (from->geometry.x, to->geometry.x);
+ cpswaps (from->geometry.y, to->geometry.y);
+ cpswaps (from->geometry.width, to->geometry.width);
+ cpswaps (from->geometry.height, to->geometry.height);
+}
+
+void
+DamageExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ DamageSetup (screenInfo.screens[s]);
+
+ DamageExtType = CreateNewResourceType (FreeDamageExt);
+ if (!DamageExtType)
+ return;
+
+ DamageExtWinType = CreateNewResourceType (FreeDamageExtWin);
+ if (!DamageExtWinType)
+ return;
+
+ DamageClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (DamageClientPrivateIndex,
+ sizeof (DamageClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, DamageClientCallback, 0))
+ return;
+
+ if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents,
+ XDamageNumberErrors,
+ ProcDamageDispatch, SProcDamageDispatch,
+ DamageResetProc, StandardMinorOpcode)) != 0)
+ {
+ DamageReqCode = (unsigned char)extEntry->base;
+ DamageEventBase = extEntry->eventBase;
+ DamageErrorBase = extEntry->errorBase;
+ EventSwapVector[DamageEventBase + XDamageNotify] =
+ (EventSwapPtr) SDamageNotifyEvent;
+ }
+}
diff --git a/nx-X11/programs/Xserver/damageext/damageext.h b/nx-X11/programs/Xserver/damageext/damageext.h
new file mode 100644
index 000000000..3d748eedf
--- /dev/null
+++ b/nx-X11/programs/Xserver/damageext/damageext.h
@@ -0,0 +1,35 @@
+/*
+ * $Id: damageext.h,v 1.5 2005/07/03 07:01:17 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DAMAGEEXT_H_
+#define _DAMAGEEXT_H_
+
+void
+DamageExtensionInit(void);
+
+#endif /* _DAMAGEEXT_H_ */
diff --git a/nx-X11/programs/Xserver/damageext/damageextint.h b/nx-X11/programs/Xserver/damageext/damageextint.h
new file mode 100644
index 000000000..ba9212eba
--- /dev/null
+++ b/nx-X11/programs/Xserver/damageext/damageextint.h
@@ -0,0 +1,87 @@
+/*
+ * $Id: damageextint.h,v 1.6 2005/07/03 08:53:38 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DAMAGEEXTINT_H_
+#define _DAMAGEEXTINT_H_
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <nx-X11/extensions/damageproto.h>
+#include "windowstr.h"
+#include "selection.h"
+#include "scrnintstr.h"
+#include "damageext.h"
+#include "damage.h"
+#include "xfixes.h"
+
+extern unsigned char DamageReqCode;
+extern int DamageEventBase;
+extern int DamageErrorBase;
+extern int DamageClientPrivateIndex;
+extern RESTYPE DamageExtType;
+extern RESTYPE DamageExtWinType;
+
+typedef struct _DamageClient {
+ CARD32 major_version;
+ CARD32 minor_version;
+ int critical;
+} DamageClientRec, *DamageClientPtr;
+
+#define GetDamageClient(pClient) ((DamageClientPtr) (pClient)->devPrivates[DamageClientPrivateIndex].ptr)
+
+typedef struct _DamageExt {
+ DamagePtr pDamage;
+ DrawablePtr pDrawable;
+ DamageReportLevel level;
+ ClientPtr pClient;
+ XID id;
+} DamageExtRec, *DamageExtPtr;
+
+extern int (*ProcDamageVector[/*XDamageNumberRequests*/])(ClientPtr);
+extern int (*SProcDamageVector[/*XDamageNumberRequests*/])(ClientPtr);
+
+#define VERIFY_DAMAGEEXT(pDamageExt, rid, client, mode) { \
+ pDamageExt = SecurityLookupIDByType (client, rid, DamageExtType, mode); \
+ if (!pDamageExt) { \
+ client->errorValue = rid; \
+ return DamageErrorBase + BadDamage; \
+ } \
+}
+
+void
+SDamageNotifyEvent (xDamageNotifyEvent *from,
+ xDamageNotifyEvent *to);
+
+void
+DamageExtSetCritical (ClientPtr pClient, Bool critical);
+
+#endif /* _DAMAGEEXTINT_H_ */
diff --git a/nx-X11/programs/Xserver/dbe/Imakefile b/nx-X11/programs/Xserver/dbe/Imakefile
new file mode 100644
index 000000000..54ce471c5
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/Imakefile
@@ -0,0 +1,18 @@
+#include <Server.tmpl>
+
+
+ SRCS = dbe.c midbe.c
+ OBJS = dbe.o midbe.o
+ INCLUDES = -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC) $(EXTRAINCLUDES) `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+NormalLibraryObjectRule()
+
+NormalLibraryTarget(dbe,$(OBJS))
+
+LintLibraryTarget(dbe,$(SRCS))
+NormalLintTarget($(SRCS))
+
+
+DependTarget()
+
diff --git a/nx-X11/programs/Xserver/dbe/dbe.c b/nx-X11/programs/Xserver/dbe/dbe.c
new file mode 100644
index 000000000..85a22219f
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/dbe.c
@@ -0,0 +1,1986 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * 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 HEWLETT-PACKARD COMPANY 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 Hewlett-Packard
+ * Company 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 Hewlett-Packard Company.
+ *
+ * DIX DBE code
+ *
+ *****************************************************************************/
+
+
+/* INCLUDES */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "scrnintstr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#define NEED_DBE_PROTOCOL
+#include "dbestruct.h"
+#include "midbe.h"
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+/* GLOBALS */
+
+/* Per-screen initialization functions [init'ed by DbeRegisterFunction()] */
+static Bool (* DbeInitFunct[MAXSCREENS])(); /* pScreen, pDbeScreenPriv */
+
+/* These are static globals copied to DBE's screen private for use by DDX */
+static int dbeScreenPrivIndex;
+static int dbeWindowPrivIndex;
+
+/* These are static globals copied to DBE's screen private for use by DDX */
+static RESTYPE dbeDrawableResType;
+static RESTYPE dbeWindowPrivResType;
+
+/* This global is used by DbeAllocWinPrivPrivIndex() */
+static int winPrivPrivCount = 0;
+
+/* Used to generate DBE's BadBuffer error. */
+static int dbeErrorBase;
+
+/* Used by DbeRegisterFunction() to initialize the initialization function
+ * table only once per server lifetime.
+ */
+static Bool firstRegistrationPass = TRUE;
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeValidateBuffer
+ *
+ * Description:
+ *
+ * This function is called from VALIDATE_DRAWABLE_AND_GC and from
+ * various places in dispatch.c if the server has been compiled with
+ * the flags -DNEED_DBE_BUF_BITS and -DNEED_DBE_BUF_VALIDATE.
+ * When pWin->dstBuffer changes, this function will be called with pWin
+ * as the first argument, the drawable ID that was specified as the
+ * second argument (could be a back buffer id), and True for the third
+ * argument.
+ * When pWin->srcBuffer changes, the third argument will be False, and
+ * the first two arguments are as described for dstBuffer.
+ *
+ * This function should prepare the hardware to access the specified
+ * buffer for reads (if dstbuf is False) or writes (if dstbuf is True).
+ *
+ *****************************************************************************/
+
+void
+DbeValidateBuffer(pWin, drawID, dstbuf)
+ WindowPtr pWin;
+ XID drawID;
+ Bool dstbuf;
+{
+ DbeScreenPrivPtr pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
+ if (pDbeScreenPriv->ValidateBuffer)
+ (*pDbeScreenPriv->ValidateBuffer)(pWin, drawID, dstbuf);
+}
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeRegisterFunction
+ *
+ * Description:
+ *
+ * This function registers the DBE init function for the specified screen.
+ *
+ *****************************************************************************/
+
+void
+DbeRegisterFunction(pScreen, funct)
+ ScreenPtr pScreen;
+ Bool (*funct)();
+{
+ int i;
+
+ /* Initialize the initialization function table if it has not been
+ * initialized already.
+ */
+ if (firstRegistrationPass)
+ {
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ DbeInitFunct[i] = NULL;
+ }
+
+ firstRegistrationPass = FALSE;
+ }
+
+ DbeInitFunct[pScreen->myNum] = funct;
+
+} /* DbeRegisterFunction() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeAllocWinPriv
+ *
+ * Description:
+ *
+ * This function was cloned from AllocateWindow() in window.c.
+ * This function allocates a window priv structure to be associated
+ * with a double-buffered window.
+ *
+ *****************************************************************************/
+static DbeWindowPrivPtr
+DbeAllocWinPriv(pScreen)
+ ScreenPtr pScreen;
+{
+ DbeWindowPrivPtr pDbeWindowPriv;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned int *sizes;
+ register unsigned int size;
+ register int i;
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+ pDbeWindowPriv = (DbeWindowPrivPtr)malloc(pDbeScreenPriv->totalWinPrivSize);
+
+ if (pDbeWindowPriv)
+ {
+ ppriv = (DevUnion *)(pDbeWindowPriv + 1);
+ pDbeWindowPriv->devPrivates = ppriv;
+ sizes = pDbeScreenPriv->winPrivPrivSizes;
+ ptr = (char *)(ppriv + pDbeScreenPriv->winPrivPrivLen);
+ for (i = pDbeScreenPriv->winPrivPrivLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ((size = *sizes))
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+ }
+
+ return(pDbeWindowPriv);
+
+} /* DbeAllocWinPriv() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeFallbackAllocWinPriv
+ *
+ * Description:
+ *
+ * This is a fallback function for AllocWinPriv().
+ *
+ *****************************************************************************/
+
+#if 0 /* NOT USED */
+static DbeWindowPrivPtr
+DbeFallbackAllocWinPriv(pScreen)
+ ScreenPtr pScreen;
+{
+ return (NULL);
+} /* DbeFallbackAllocWinPriv() */
+#endif
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeAllocWinPrivPrivIndex
+ *
+ * Description:
+ *
+ * This function was cloned from AllocateWindowPrivateIndex() in window.c.
+ * This function allocates a new window priv priv index by simply returning
+ * an incremented private counter.
+ *
+ *****************************************************************************/
+
+static int
+DbeAllocWinPrivPrivIndex()
+{
+ return winPrivPrivCount++;
+
+} /* DbeAllocWinPrivPrivIndex() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeAllocWinPrivPriv
+ *
+ * Description:
+ *
+ * This function was cloned from AllocateWindowPrivate() in privates.c.
+ * This function allocates a private structure to be hung off
+ * a window private.
+ *
+ *****************************************************************************/
+
+static Bool
+DbeAllocWinPrivPriv(pScreen, index, amount)
+ register ScreenPtr pScreen;
+ int index;
+ unsigned int amount;
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ unsigned int oldamount;
+
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (index >= pDbeScreenPriv->winPrivPrivLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)realloc(pDbeScreenPriv->winPrivPrivSizes,
+ (index + 1) * sizeof(unsigned));
+ if (!nsizes)
+ {
+ return(FALSE);
+ }
+
+ while (pDbeScreenPriv->winPrivPrivLen <= index)
+ {
+ nsizes[pDbeScreenPriv->winPrivPrivLen++] = 0;
+ pDbeScreenPriv->totalWinPrivSize += sizeof(DevUnion);
+ }
+
+ pDbeScreenPriv->winPrivPrivSizes = nsizes;
+ }
+
+ oldamount = pDbeScreenPriv->winPrivPrivSizes[index];
+
+ if (amount > oldamount)
+ {
+ pDbeScreenPriv->winPrivPrivSizes[index] = amount;
+ pDbeScreenPriv->totalWinPrivSize += (amount - oldamount);
+ }
+ return(TRUE);
+
+} /* DbeAllocWinPrivPriv() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeStubScreen
+ *
+ * Description:
+ *
+ * This is function stubs the function pointers in the given DBE screen
+ * private and increments the number of stubbed screens.
+ *
+ *****************************************************************************/
+
+static void
+DbeStubScreen(pDbeScreenPriv, nStubbedScreens)
+ DbeScreenPrivPtr pDbeScreenPriv;
+ int *nStubbedScreens;
+{
+ /* Stub DIX. */
+ pDbeScreenPriv->SetupBackgroundPainter = NULL;
+ pDbeScreenPriv->AllocWinPriv = NULL;
+ pDbeScreenPriv->AllocWinPrivPrivIndex = NULL;
+ pDbeScreenPriv->AllocWinPrivPriv = NULL;
+
+ /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX
+ * initialization function failed, we assume that it did not wrap
+ * PositionWindow. Also, DestroyWindow is only wrapped if the DDX
+ * initialization function succeeded.
+ */
+
+ /* Stub DDX. */
+ pDbeScreenPriv->GetVisualInfo = NULL;
+ pDbeScreenPriv->AllocBackBufferName = NULL;
+ pDbeScreenPriv->SwapBuffers = NULL;
+ pDbeScreenPriv->BeginIdiom = NULL;
+ pDbeScreenPriv->EndIdiom = NULL;
+ pDbeScreenPriv->WinPrivDelete = NULL;
+ pDbeScreenPriv->ResetProc = NULL;
+ pDbeScreenPriv->ValidateBuffer = NULL;
+
+ (*nStubbedScreens)++;
+
+} /* DbeStubScreen() */
+
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetVersion
+ *
+ * Description:
+ *
+ * This function is for processing a DbeGetVersion request.
+ * This request returns the major and minor version numbers of this
+ * extension.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetVersion(client)
+ ClientPtr client;
+{
+ /* REQUEST(xDbeGetVersionReq); */
+ xDbeGetVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xDbeGetVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = DBE_MAJOR_VERSION;
+ rep.minorVersion = DBE_MINOR_VERSION;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ }
+
+ WriteToClient(client, sizeof(xDbeGetVersionReply), &rep);
+
+ return(client->noClientException);
+
+} /* ProcDbeGetVersion() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeAllocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeAllocateBackBufferName request.
+ * This request allocates a drawable ID used to refer to the back buffer
+ * of a window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - server can not allocate resources
+ * BadIDChoice - id is out of range for client; id is already in use
+ * BadMatch - window is not an InputOutput window;
+ * visual of window is not on list returned by
+ * DBEGetVisualInfo;
+ * BadValue - invalid swap action is specified
+ * BadWindow - window is not a valid window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeAllocateBackBufferName(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeAllocateBackBufferNameReq);
+ WindowPtr pWin;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ XdbeScreenVisualInfo scrVisInfo;
+ register int i;
+ Bool visualMatched = FALSE;
+ xDbeSwapAction swapAction;
+ VisualID visual;
+ int status;
+
+
+ REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
+
+ /* The window must be valid. */
+ if (!(pWin = SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess)))
+ {
+ return(BadWindow);
+ }
+
+ /* The window must be InputOutput. */
+ if (pWin->drawable.class != InputOutput)
+ {
+ return(BadMatch);
+ }
+
+ /* The swap action must be valid. */
+ swapAction = stuff->swapAction; /* use local var for performance. */
+ if ((swapAction != XdbeUndefined ) &&
+ (swapAction != XdbeBackground) &&
+ (swapAction != XdbeUntouched ) &&
+ (swapAction != XdbeCopied ))
+ {
+ return(BadValue);
+ }
+
+ /* The id must be in range and not already in use. */
+ LEGAL_NEW_RESOURCE(stuff->buffer, client);
+
+ /* The visual of the window must be in the list returned by
+ * GetVisualInfo.
+ */
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
+ if (!pDbeScreenPriv->GetVisualInfo)
+ return(BadMatch); /* screen doesn't support double buffering */
+
+ if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
+ {
+ /* GetVisualInfo() failed to allocate visual info data. */
+ return(BadAlloc);
+ }
+
+ /* See if the window's visual is on the list. */
+ visual = wVisual(pWin);
+ for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
+ {
+ if (scrVisInfo.visinfo[i].visual == visual)
+ {
+ visualMatched = TRUE;
+ }
+ }
+
+ /* Free what was allocated by the GetVisualInfo() call above. */
+ free(scrVisInfo.visinfo);
+
+ if (!visualMatched)
+ {
+ return(BadMatch);
+ }
+
+ if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
+ {
+ /* There is no buffer associated with the window.
+ * Allocate a window priv.
+ */
+
+ if (!(pDbeWindowPriv =
+ (*pDbeScreenPriv->AllocWinPriv)(pWin->drawable.pScreen)))
+ {
+ return(BadAlloc);
+ }
+
+ /* Make the window priv a DBE window priv resource. */
+ if (!AddResource(stuff->buffer, dbeWindowPrivResType,
+ (void *)pDbeWindowPriv))
+ {
+ free(pDbeWindowPriv);
+ return(BadAlloc);
+ }
+
+ /* Fill out window priv information. */
+ pDbeWindowPriv->pWindow = pWin;
+ pDbeWindowPriv->width = pWin->drawable.width;
+ pDbeWindowPriv->height = pWin->drawable.height;
+ pDbeWindowPriv->x = pWin->drawable.x;
+ pDbeWindowPriv->y = pWin->drawable.y;
+ pDbeWindowPriv->nBufferIDs = 0;
+
+ /* Set the buffer ID array pointer to the initial (static) array). */
+ pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
+
+ /* Initialize the buffer ID list. */
+ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
+ pDbeWindowPriv->IDs[0] = stuff->buffer;
+ for (i = 1; i < DBE_INIT_MAX_IDS; i++)
+ {
+ pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
+ }
+
+
+ /* Actually connect the window priv to the window. */
+ pWin->devPrivates[dbeWindowPrivIndex].ptr = (void *)pDbeWindowPriv;
+
+ } /* if -- There is no buffer associated with the window. */
+
+ else
+ {
+ /* A buffer is already associated with the window.
+ * Add the new buffer ID to the array, reallocating the array memory
+ * if necessary.
+ */
+
+ /* Determine if there is a free element in the ID array. */
+ for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
+ {
+ if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
+ {
+ /* There is still room in the ID array. */
+ break;
+ }
+ }
+
+ if (i == pDbeWindowPriv->maxAvailableIDs)
+ {
+ /* No more room in the ID array -- reallocate another array. */
+ XID *pIDs;
+
+
+ /* Setup an array pointer for the realloc operation below. */
+ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
+ {
+ /* We will malloc a new array. */
+ pIDs = NULL;
+ }
+ else
+ {
+ /* We will realloc a new array. */
+ pIDs = pDbeWindowPriv->IDs;
+ }
+
+ /* malloc/realloc a new array and initialize all elements to 0. */
+ pDbeWindowPriv->IDs = (XID *)realloc(pIDs,
+ (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
+ if (!pDbeWindowPriv->IDs)
+ {
+ return(BadAlloc);
+ }
+ memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
+ (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
+ pDbeWindowPriv->nBufferIDs) * sizeof(XID));
+
+ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
+ {
+ /* We just went from using the initial (static) array to a
+ * newly allocated array. Copy the IDs from the initial array
+ * to the new array.
+ */
+ memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
+ DBE_INIT_MAX_IDS * sizeof(XID));
+ }
+
+ pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
+ }
+
+ /* Finally, record the buffer ID in the array. */
+ pDbeWindowPriv->IDs[i] = stuff->buffer;
+
+ /* Associate the new ID with an existing window priv. */
+ if (!AddResource(stuff->buffer, dbeWindowPrivResType,
+ (void *)pDbeWindowPriv))
+ {
+ pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
+ return(BadAlloc);
+ }
+
+ } /* else -- A buffer is already associated with the window. */
+
+
+ /* Call the DDX routine to allocate the back buffer. */
+ status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
+ stuff->swapAction);
+
+ if ((status != Success) && (pDbeWindowPriv->nBufferIDs == 0))
+ {
+ /* The DDX buffer allocation routine failed for the first buffer of
+ * this window.
+ */
+ free(pDbeWindowPriv);
+ return(status);
+ }
+
+ /* Increment the number of buffers (XIDs) associated with this window. */
+ pDbeWindowPriv->nBufferIDs++;
+
+ /* Set swap action on all calls. */
+ pDbeWindowPriv->swapAction = stuff->swapAction;
+
+
+ return(status);
+
+} /* ProcDbeAllocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeDeallocateBackBufferName request.
+ * This request frees a drawable ID that was obtained by a
+ * DbeAllocateBackBufferName request.
+ *
+ * Return Values:
+ *
+ * BadBuffer - buffer to deallocate is not associated with a window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeDeallocateBackBufferName(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeDeallocateBackBufferNameReq);
+ DbeWindowPrivPtr pDbeWindowPriv;
+ int i;
+
+
+ REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
+
+ /* Buffer name must be valid */
+ if (!(pDbeWindowPriv = (DbeWindowPrivPtr)SecurityLookupIDByType(client,
+ stuff->buffer, dbeWindowPrivResType, DixDestroyAccess)) ||
+ !(SecurityLookupIDByType(client, stuff->buffer, dbeDrawableResType,
+ DixDestroyAccess)))
+ {
+ client->errorValue = stuff->buffer;
+ return(dbeErrorBase + DbeBadBuffer);
+ }
+
+ /* Make sure that the id is valid for the window.
+ * This is paranoid code since we already looked up the ID by type
+ * above.
+ */
+
+ for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
+ {
+ /* Loop through the ID list to find the ID. */
+ if (pDbeWindowPriv->IDs[i] == stuff->buffer)
+ {
+ break;
+ }
+ }
+
+ if (i == pDbeWindowPriv->nBufferIDs)
+ {
+ /* We did not find the ID in the ID list. */
+ client->errorValue = stuff->buffer;
+ return(dbeErrorBase + DbeBadBuffer);
+ }
+
+ FreeResource(stuff->buffer, RT_NONE);
+
+ return(Success);
+
+} /* ProcDbeDeallocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This function is for processing a DbeSwapBuffers request.
+ * This request swaps the buffers for all windows listed, applying the
+ * appropriate swap action for each window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - local allocation failed; this return value is not defined
+ * by the protocol
+ * BadMatch - a window in request is not double-buffered; a window in
+ * request is listed more than once
+ * BadValue - invalid swap action is specified; no swap action is
+ * specified
+ * BadWindow - a window in request is not valid
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeSwapBuffers(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeSwapBuffersReq);
+ WindowPtr pWin;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeSwapInfoPtr swapInfo;
+ xDbeSwapInfo *dbeSwapInfo;
+ int error;
+ unsigned int i, j;
+ unsigned int nStuff;
+ int nStuff_i; /* DDX API requires int for nStuff */
+
+ REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+ nStuff = stuff->n; /* use local variable for performance. */
+
+ if (nStuff == 0)
+ {
+ REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
+ return(Success);
+ }
+
+ if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
+ return BadAlloc;
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
+
+ /* Get to the swap info appended to the end of the request. */
+ dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
+
+ /* Allocate array to record swap information. */
+ swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
+ if (swapInfo == NULL)
+ {
+ return(BadAlloc);
+ }
+
+
+ for (i = 0; i < nStuff; i++)
+ {
+ /* Check all windows to swap. */
+
+ /* Each window must be a valid window - BadWindow. */
+ if (!(pWin = SecurityLookupWindow(dbeSwapInfo[i].window, client,
+ DixWriteAccess)))
+ {
+ free(swapInfo);
+ return(BadWindow);
+ }
+
+ /* Each window must be double-buffered - BadMatch. */
+ if (DBE_WINDOW_PRIV(pWin) == NULL)
+ {
+ free(swapInfo);
+ return(BadMatch);
+ }
+
+ /* Each window must only be specified once - BadMatch. */
+ for (j = i + 1; j < nStuff; j++)
+ {
+ if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
+ {
+ free(swapInfo);
+ return(BadMatch);
+ }
+ }
+
+ /* Each swap action must be valid - BadValue. */
+ if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
+ (dbeSwapInfo[i].swapAction != XdbeBackground) &&
+ (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
+ (dbeSwapInfo[i].swapAction != XdbeCopied ))
+ {
+ free(swapInfo);
+ return(BadValue);
+ }
+
+ /* Everything checks out OK. Fill in the swap info array. */
+ swapInfo[i].pWindow = pWin;
+ swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
+
+ } /* for (i = 0; i < nStuff; i++) */
+
+
+ /* Call the DDX routine to perform the swap(s). The DDX routine should
+ * scan the swap list (swap info), swap any buffers that it knows how to
+ * handle, delete them from the list, and update nStuff to indicate how
+ * many windows it did not handle.
+ *
+ * This scheme allows a range of sophistication in the DDX SwapBuffers()
+ * implementation. Naive implementations could just swap the first buffer
+ * in the list, move the last buffer to the front, decrement nStuff, and
+ * return. The next level of sophistication could be to scan the whole
+ * list for windows on the same screen. Up another level, the DDX routine
+ * could deal with cross-screen synchronization.
+ */
+
+ nStuff_i = nStuff;
+ while (nStuff_i > 0)
+ {
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
+ error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff_i, swapInfo);
+ if (error != Success)
+ {
+ free(swapInfo);
+ return(error);
+ }
+ }
+
+ free(swapInfo);
+ return(Success);
+
+} /* ProcDbeSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeBeginIdiom
+ *
+ * Description:
+ *
+ * This function is for processing a DbeBeginIdiom request.
+ * This request informs the server that a complex swap will immediately
+ * follow this request.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeBeginIdiom(client)
+ ClientPtr client;
+{
+ /* REQUEST(xDbeBeginIdiomReq); */
+ DbeScreenPrivPtr pDbeScreenPriv;
+ register int i;
+
+
+ REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
+
+ /* Call the DDX begin idiom procedure if there is one. */
+ if (pDbeScreenPriv->BeginIdiom)
+ {
+ (*pDbeScreenPriv->BeginIdiom)(client);
+ }
+ }
+
+ return(Success);
+
+} /* ProcDbeBeginIdiom() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetVisualInfo request.
+ * This request returns information about which visuals support
+ * double buffering.
+ *
+ * Return Values:
+ *
+ * BadDrawable - value in screen specifiers is not a valid drawable
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetVisualInfo(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeGetVisualInfoReq);
+ DbeScreenPrivPtr pDbeScreenPriv;
+ xDbeGetVisualInfoReply rep;
+ Drawable *drawables;
+ DrawablePtr *pDrawables = NULL;
+ register int i, j;
+ register int count; /* number of visual infos in reply */
+ register int length; /* length of reply */
+ ScreenPtr pScreen;
+ XdbeScreenVisualInfo *pScrVisInfo;
+
+
+ REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
+
+ if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
+ return BadAlloc;
+ /* Make sure any specified drawables are valid. */
+ if (stuff->n != 0)
+ {
+ if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
+ sizeof(DrawablePtr))))
+ {
+ return(BadAlloc);
+ }
+
+ drawables = (Drawable *)&stuff[1];
+
+ for (i = 0; i < stuff->n; i++)
+ {
+ if (!(pDrawables[i] = (DrawablePtr)SecurityLookupDrawable(
+ drawables[i], client, DixReadAccess)))
+ {
+ free(pDrawables);
+ return(BadDrawable);
+ }
+ }
+ }
+
+ count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
+ if (!(pScrVisInfo = (XdbeScreenVisualInfo *)malloc(count *
+ sizeof(XdbeScreenVisualInfo))))
+ {
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return(BadAlloc);
+ }
+
+ length = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
+ pDrawables[i]->pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
+ {
+ /* We failed to alloc pScrVisInfo[i].visinfo. */
+
+ /* Free visinfos that we allocated for previous screen infos.*/
+ for (j = 0; j < i; j++)
+ {
+ free(pScrVisInfo[j].visinfo);
+ }
+
+ /* Free pDrawables if we needed to allocate it above. */
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return(BadAlloc);
+ }
+
+ /* Account for n, number of xDbeVisInfo items in list. */
+ length += sizeof(CARD32);
+
+ /* Account for n xDbeVisInfo items */
+ length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = length >> 2;
+ rep.m = count;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.m);
+ }
+
+ /* Send off reply. */
+ WriteToClient(client, sizeof(xDbeGetVisualInfoReply), &rep);
+
+ for (i = 0; i < count; i++)
+ {
+ CARD32 data32;
+
+ /* For each screen in the reply, send off the visual info */
+
+ /* Send off number of visuals. */
+ data32 = (CARD32)pScrVisInfo[i].count;
+
+ if (client->swapped)
+ {
+ swapl(&data32);
+ }
+
+ WriteToClient(client, sizeof(CARD32), &data32);
+
+ /* Now send off visual info items. */
+ for (j = 0; j < pScrVisInfo[i].count; j++)
+ {
+ xDbeVisInfo visInfo;
+
+ /* Copy the data in the client data structure to a protocol
+ * data structure. We will send data to the client from the
+ * protocol data structure.
+ */
+
+ visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual;
+ visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth;
+ visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
+
+ if (client->swapped)
+ {
+ swapl(&visInfo.visualID);
+
+ /* We do not need to swap depth and perfLevel since they are
+ * already 1 byte quantities.
+ */
+ }
+
+ /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
+ WriteToClient(client, 2*sizeof(CARD32), &visInfo.visualID);
+ }
+ }
+
+ /* Clean up memory. */
+ for (i = 0; i < count; i++)
+ {
+ free(pScrVisInfo[i].visinfo);
+ }
+ free(pScrVisInfo);
+
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return(client->noClientException);
+
+} /* ProcDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetbackBufferAttributes
+ * request. This request returns information about a back buffer.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetBackBufferAttributes(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeGetBackBufferAttributesReq);
+ xDbeGetBackBufferAttributesReply rep;
+ DbeWindowPrivPtr pDbeWindowPriv;
+
+ REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
+
+ if (!(pDbeWindowPriv = (DbeWindowPrivPtr)SecurityLookupIDByType(client,
+ stuff->buffer, dbeWindowPrivResType, DixReadAccess)))
+ {
+ rep.attributes = None;
+ }
+ else
+ {
+ rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.attributes);
+ }
+
+ WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
+ &rep);
+ return(client->noClientException);
+
+} /* ProcDbeGetbackBufferAttributes() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeDispatch
+ *
+ * Description:
+ *
+ * This function dispatches DBE requests.
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+
+ switch (stuff->data)
+ {
+ case X_DbeGetVersion:
+ return(ProcDbeGetVersion(client));
+
+ case X_DbeAllocateBackBufferName:
+ return(ProcDbeAllocateBackBufferName(client));
+
+ case X_DbeDeallocateBackBufferName:
+ return(ProcDbeDeallocateBackBufferName(client));
+
+ case X_DbeSwapBuffers:
+ return(ProcDbeSwapBuffers(client));
+
+ case X_DbeBeginIdiom:
+ return(ProcDbeBeginIdiom(client));
+
+ case X_DbeEndIdiom:
+ return(Success);
+
+ case X_DbeGetVisualInfo:
+ return(ProcDbeGetVisualInfo(client));
+
+ case X_DbeGetBackBufferAttributes:
+ return(ProcDbeGetBackBufferAttributes(client));
+
+ default:
+ return(BadRequest);
+ }
+
+} /* ProcDbeDispatch() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetVersion
+ *
+ * Description:
+ *
+ * This function is for processing a DbeGetVersion request on a swapped
+ * server. This request returns the major and minor version numbers of
+ * this extension.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeGetVersionReq);
+
+ swaps(&stuff->length);
+ return(ProcDbeGetVersion(client));
+
+} /* SProcDbeGetVersion() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeAllocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeAllocateBackBufferName request on
+ * a swapped server. This request allocates a drawable ID used to refer
+ * to the back buffer of a window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - server can not allocate resources
+ * BadIDChoice - id is out of range for client; id is already in use
+ * BadMatch - window is not an InputOutput window;
+ * visual of window is not on list returned by
+ * DBEGetVisualInfo;
+ * BadValue - invalid swap action is specified
+ * BadWindow - window is not a valid window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeAllocateBackBufferName(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeAllocateBackBufferNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
+
+ swapl(&stuff->window);
+ swapl(&stuff->buffer);
+ /* stuff->swapAction is a byte. We do not need to swap this field. */
+
+ return(ProcDbeAllocateBackBufferName(client));
+
+} /* SProcDbeAllocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeDeallocateBackBufferName request
+ * on a swapped server. This request frees a drawable ID that was
+ * obtained by a DbeAllocateBackBufferName request.
+ *
+ * Return Values:
+ *
+ * BadBuffer - buffer to deallocate is not associated with a window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeDeallocateBackBufferName(client)
+ ClientPtr client;
+{
+ REQUEST (xDbeDeallocateBackBufferNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
+
+ swapl(&stuff->buffer);
+
+ return(ProcDbeDeallocateBackBufferName(client));
+
+} /* SProcDbeDeallocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This function is for processing a DbeSwapBuffers request on a swapped
+ * server. This request swaps the buffers for all windows listed,
+ * applying the appropriate swap action for each window.
+ *
+ * Return Values:
+ *
+ * BadMatch - a window in request is not double-buffered; a window in
+ * request is listed more than once; all windows in request do
+ * not have the same root
+ * BadValue - invalid swap action is specified
+ * BadWindow - a window in request is not valid
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeSwapBuffers(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeSwapBuffersReq);
+ unsigned int i;
+ xDbeSwapInfo *pSwapInfo;
+
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+
+ swapl(&stuff->n);
+ if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
+ return BadAlloc;
+ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
+
+ if (stuff->n != 0)
+ {
+ pSwapInfo = (xDbeSwapInfo *)stuff+1;
+
+ /* The swap info following the fix part of this request is a window(32)
+ * followed by a 1 byte swap action and then 3 pad bytes. We only need
+ * to swap the window information.
+ */
+ for (i = 0; i < stuff->n; i++)
+ {
+ swapl(&pSwapInfo->window);
+ }
+ }
+
+ return(ProcDbeSwapBuffers(client));
+
+} /* SProcDbeSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeBeginIdiom
+ *
+ * Description:
+ *
+ * This function is for processing a DbeBeginIdiom request on a swapped
+ * server. This request informs the server that a complex swap will
+ * immediately follow this request.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeBeginIdiom(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeBeginIdiomReq);
+
+ swaps(&stuff->length);
+ return(ProcDbeBeginIdiom(client));
+
+} /* SProcDbeBeginIdiom() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetVisualInfo request on a
+ * swapped server. This request returns information about which visuals
+ * support double buffering.
+ *
+ * Return Values:
+ *
+ * BadDrawable - value in screen specifiers is not a valid drawable
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetVisualInfo(client)
+ ClientPtr client;
+{
+ REQUEST(xDbeGetVisualInfoReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
+
+ swapl(&stuff->n);
+ SwapRestL(stuff);
+
+ return(ProcDbeGetVisualInfo(client));
+
+} /* SProcDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetbackBufferAttributes
+ * request on a swapped server. This request returns information about a
+ * back buffer.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetBackBufferAttributes(client)
+ ClientPtr client;
+{
+ REQUEST (xDbeGetBackBufferAttributesReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
+
+ swapl(&stuff->buffer);
+
+ return(ProcDbeGetBackBufferAttributes(client));
+
+} /* SProcDbeGetBackBufferAttributes() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeDispatch
+ *
+ * Description:
+ *
+ * This function dispatches DBE requests on a swapped server.
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+
+ switch (stuff->data)
+ {
+ case X_DbeGetVersion:
+ return(SProcDbeGetVersion(client));
+
+ case X_DbeAllocateBackBufferName:
+ return(SProcDbeAllocateBackBufferName(client));
+
+ case X_DbeDeallocateBackBufferName:
+ return(SProcDbeDeallocateBackBufferName(client));
+
+ case X_DbeSwapBuffers:
+ return(SProcDbeSwapBuffers(client));
+
+ case X_DbeBeginIdiom:
+ return(SProcDbeBeginIdiom(client));
+
+ case X_DbeEndIdiom:
+ return(Success);
+
+ case X_DbeGetVisualInfo:
+ return(SProcDbeGetVisualInfo(client));
+
+ case X_DbeGetBackBufferAttributes:
+ return(SProcDbeGetBackBufferAttributes(client));
+
+ default:
+ return (BadRequest);
+ }
+
+} /* SProcDbeDispatch() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeSetupBackgroundPainter
+ *
+ * Description:
+ *
+ * This function sets up pGC to clear pixmaps.
+ *
+ * Return Values:
+ *
+ * TRUE - setup was successful
+ * FALSE - the window's background state is NONE
+ *
+ *****************************************************************************/
+
+static Bool
+DbeSetupBackgroundPainter(pWin, pGC)
+ WindowPtr pWin;
+ GCPtr pGC;
+{
+ void *gcvalues[4];
+ int ts_x_origin, ts_y_origin;
+ PixUnion background;
+ int backgroundState;
+ Mask gcmask;
+
+
+ /* First take care of any ParentRelative stuff by altering the
+ * tile/stipple origin to match the coordinates of the upper-left
+ * corner of the first ancestor without a ParentRelative background.
+ * This coordinate is, of course, negative.
+ */
+ ts_x_origin = ts_y_origin = 0;
+ while (pWin->backgroundState == ParentRelative)
+ {
+ ts_x_origin -= pWin->origin.x;
+ ts_y_origin -= pWin->origin.y;
+
+ pWin = pWin->parent;
+ }
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ switch (backgroundState)
+ {
+ case BackgroundPixel:
+ gcvalues[0] = (void *)background.pixel;
+ gcvalues[1] = (void *)FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ break;
+
+ case BackgroundPixmap:
+ gcvalues[0] = (void *)FillTiled;
+ gcvalues[1] = (void *)background.pixmap;
+ gcvalues[2] = (void *)(long)ts_x_origin;
+ gcvalues[3] = (void *)(long)ts_y_origin;
+ gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
+ break;
+
+ default:
+ /* pWin->backgroundState == None */
+ return(FALSE);
+ }
+
+ if (DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE) != 0)
+ {
+ return(FALSE);
+ }
+
+ return(TRUE);
+
+} /* DbeSetupBackgroundPainter() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeDrawableDelete
+ *
+ * Description:
+ *
+ * This is the resource delete function for dbeDrawableResType.
+ * It is registered when the drawable resource type is created in
+ * DbeExtensionInit().
+ *
+ * To make resource deletion simple, we do not do anything in this function
+ * and leave all resource deleteion to DbeWindowPrivDelete(), which will
+ * eventually be called or already has been called. Deletion functions are
+ * not guaranteed to be called in any particular order.
+ *
+ *****************************************************************************/
+static int
+DbeDrawableDelete(pDrawable, id)
+ void *pDrawable;
+ XID id;
+{
+ return(Success);
+
+} /* DbeDrawableDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeWindowPrivDelete
+ *
+ * Description:
+ *
+ * This is the resource delete function for dbeWindowPrivResType.
+ * It is registered when the drawable resource type is created in
+ * DbeExtensionInit().
+ *
+ *****************************************************************************/
+static int
+DbeWindowPrivDelete(pDbeWinPriv, id)
+ void *pDbeWinPriv;
+ XID id;
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
+ int i;
+
+
+ /*
+ **************************************************************************
+ ** Remove the buffer ID from the ID array.
+ **************************************************************************
+ */
+
+ /* Find the ID in the ID array. */
+ i = 0;
+ while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
+ {
+ i++;
+ }
+
+ if (i == pDbeWindowPriv->nBufferIDs)
+ {
+ /* We did not find the ID in the array. We should never get here. */
+ return(BadValue);
+ }
+
+ /* Remove the ID from the array. */
+
+ if (i < (pDbeWindowPriv->nBufferIDs - 1))
+ {
+ /* Compress the buffer ID array, overwriting the ID in the process. */
+ memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
+ (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
+ }
+ else
+ {
+ /* We are removing the last ID in the array, in which case, the
+ * assignement below is all that we need to do.
+ */
+ }
+ pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
+
+ pDbeWindowPriv->nBufferIDs--;
+
+ /* If an extended array was allocated, then check to see if the remaining
+ * buffer IDs will fit in the static array.
+ */
+
+ if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
+ (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS))
+ {
+ /* Copy the IDs back into the static array. */
+ memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
+ DBE_INIT_MAX_IDS * sizeof(XID));
+
+ /* Free the extended array; use the static array. */
+ free(pDbeWindowPriv->IDs);
+ pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
+ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
+ }
+
+
+ /*
+ **************************************************************************
+ ** Perform DDX level tasks.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
+ (DbeWindowPrivPtr)pDbeWindowPriv);
+ (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
+
+
+ /*
+ **************************************************************************
+ ** Perform miscellaneous tasks if this is the last buffer associated
+ ** with the window.
+ **************************************************************************
+ */
+
+ if (pDbeWindowPriv->nBufferIDs == 0)
+ {
+ /* Reset the DBE window priv pointer. */
+ pDbeWindowPriv->pWindow->devPrivates[dbeWindowPrivIndex].ptr =
+ (void *)NULL;
+
+ /* We are done with the window priv. */
+ free(pDbeWindowPriv);
+ }
+
+ return(Success);
+
+} /* DbeWindowPrivDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeResetProc
+ *
+ * Description:
+ *
+ * This routine is called at the end of every server generation.
+ * It deallocates any memory reserved for the extension and performs any
+ * other tasks related to shutting down the extension.
+ *
+ *****************************************************************************/
+static void
+DbeResetProc(extEntry)
+ ExtensionEntry *extEntry;
+{
+ int i;
+ ScreenPtr pScreen;
+ DbeScreenPrivPtr pDbeScreenPriv;
+
+
+ if (dbeScreenPrivIndex < 0)
+ {
+ return;
+ }
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (pDbeScreenPriv)
+ {
+ /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
+ pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
+
+ if (pDbeScreenPriv->ResetProc)
+ (*pDbeScreenPriv->ResetProc)(pScreen);
+
+ if (pDbeScreenPriv->winPrivPrivSizes)
+ {
+ free(pDbeScreenPriv->winPrivPrivSizes);
+ }
+
+ free(pDbeScreenPriv);
+ }
+ }
+
+ /* We want to init the initialization function table after every server
+ * reset in DbeRegisterFunction().
+ */
+ firstRegistrationPass = TRUE;
+
+} /* DbeResetProc() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeDestroyWindow
+ *
+ * Description:
+ *
+ * This is the wrapper for pScreen->DestroyWindow.
+ * This function frees buffer resources for a window before it is
+ * destroyed.
+ *
+ *****************************************************************************/
+
+static Bool
+DbeDestroyWindow(pWin)
+ WindowPtr pWin;
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ ScreenPtr pScreen;
+ Bool ret;
+
+
+ /*
+ **************************************************************************
+ ** 1. Unwrap the member routine.
+ **************************************************************************
+ */
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+ pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
+
+ /*
+ **************************************************************************
+ ** 2. Do any work necessary before the member routine is called.
+ **
+ ** Call the window priv delete function for all buffer IDs associated
+ ** with this window.
+ **************************************************************************
+ */
+
+ if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
+ {
+ while (pDbeWindowPriv)
+ {
+ /* *DbeWinPrivDelete() will free the window private and set it to
+ * NULL if there are no more buffer IDs associated with this
+ * window.
+ */
+ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+ }
+ }
+
+ /*
+ **************************************************************************
+ ** 3. Call the member routine, saving its result if necessary.
+ **************************************************************************
+ */
+
+ ret = (*pScreen->DestroyWindow)(pWin);
+
+ /*
+ **************************************************************************
+ ** 4. Rewrap the member routine, restoring the wrapper value first in case
+ ** the wrapper (or something that it wrapped) change this value.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DbeDestroyWindow;
+
+ /*
+ **************************************************************************
+ ** 5. Do any work necessary after the member routine has been called.
+ **
+ ** In this case we do not need to do anything.
+ **************************************************************************
+ */
+
+ return(ret);
+
+} /* DbeDestroyWindow() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeExtensionInit
+ *
+ * Description:
+ *
+ * Called from InitExtensions in main()
+ *
+ *****************************************************************************/
+
+void
+DbeExtensionInit()
+{
+ ExtensionEntry *extEntry;
+ register int i, j;
+ ScreenPtr pScreen = NULL;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ int nStubbedScreens = 0;
+ Bool ddxInitSuccess;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) return;
+#endif
+
+ /* Allocate private pointers in windows and screens. */
+
+ if ((dbeScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ {
+ return;
+ }
+
+ if ((dbeWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
+ {
+ return;
+ }
+
+ /* Initialize the priv priv counts between server generations. */
+ winPrivPrivCount = 0;
+
+ /* Create the resource types. */
+ dbeDrawableResType =
+ CreateNewResourceType(DbeDrawableDelete) | RC_DRAWABLE;
+ dbeWindowPrivResType =
+ CreateNewResourceType(DbeWindowPrivDelete);
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ /* For each screen, set up DBE screen privates and init DIX and DDX
+ * interface.
+ */
+
+ pScreen = screenInfo.screens[i];
+
+ if (!AllocateWindowPrivate(pScreen, dbeWindowPrivIndex, 0) ||
+ !(pDbeScreenPriv =
+ (DbeScreenPrivPtr)calloc(1, sizeof(DbeScreenPrivRec))))
+ {
+ /* If we can not alloc a window or screen private,
+ * then free any privates that we already alloc'ed and return
+ */
+
+ for (j = 0; j < i; j++)
+ {
+ free(screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].ptr);
+ screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].ptr = NULL;
+ }
+ return;
+ }
+
+ pScreen->devPrivates[dbeScreenPrivIndex].ptr = (void *)pDbeScreenPriv;
+
+ /* Store the DBE priv priv size info for later use when allocating
+ * priv privs at the driver level.
+ */
+ pDbeScreenPriv->winPrivPrivLen = 0;
+ pDbeScreenPriv->winPrivPrivSizes = (unsigned *)NULL;
+ pDbeScreenPriv->totalWinPrivSize = sizeof(DbeWindowPrivRec);
+
+ /* Copy the resource types */
+ pDbeScreenPriv->dbeDrawableResType = dbeDrawableResType;
+ pDbeScreenPriv->dbeWindowPrivResType = dbeWindowPrivResType;
+
+ /* Copy the private indices */
+ pDbeScreenPriv->dbeScreenPrivIndex = dbeScreenPrivIndex;
+ pDbeScreenPriv->dbeWindowPrivIndex = dbeWindowPrivIndex;
+
+ if(DbeInitFunct[i])
+ {
+ /* This screen supports DBE. */
+
+ /* Setup DIX. */
+ pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
+ pDbeScreenPriv->AllocWinPriv = DbeAllocWinPriv;
+ pDbeScreenPriv->AllocWinPrivPrivIndex = DbeAllocWinPrivPrivIndex;
+ pDbeScreenPriv->AllocWinPrivPriv = DbeAllocWinPrivPriv;
+
+ /* Setup DDX. */
+ ddxInitSuccess = (*DbeInitFunct[i])(pScreen, pDbeScreenPriv);
+
+ /* DDX DBE initialization may have the side affect of
+ * reallocating pDbeScreenPriv, so we need to update it.
+ */
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (ddxInitSuccess)
+ {
+ /* Wrap DestroyWindow. The DDX initialization function
+ * already wrapped PositionWindow for us.
+ */
+
+ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DbeDestroyWindow;
+ }
+ else
+ {
+ /* DDX initialization failed. Stub the screen. */
+ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
+ }
+ }
+ else
+ {
+ /* This screen does not support DBE. */
+
+#ifndef DISABLE_MI_DBE_BY_DEFAULT
+ /* Setup DIX. */
+ pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
+ pDbeScreenPriv->AllocWinPriv = DbeAllocWinPriv;
+ pDbeScreenPriv->AllocWinPrivPrivIndex = DbeAllocWinPrivPrivIndex;
+ pDbeScreenPriv->AllocWinPrivPriv = DbeAllocWinPrivPriv;
+
+ /* Setup DDX. */
+ ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
+
+ /* DDX DBE initialization may have the side affect of
+ * reallocating pDbeScreenPriv, so we need to update it.
+ */
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (ddxInitSuccess)
+ {
+ /* Wrap DestroyWindow. The DDX initialization function
+ * already wrapped PositionWindow for us.
+ */
+
+ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DbeDestroyWindow;
+ }
+ else
+ {
+ /* DDX initialization failed. Stub the screen. */
+ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
+ }
+#else
+ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
+#endif
+
+ } /* else -- this screen does not support DBE. */
+
+ } /* for (i = 0; i < screenInfo.numScreens; i++) */
+
+
+ if (nStubbedScreens == screenInfo.numScreens)
+ {
+ /* All screens stubbed. Clean up and return. */
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ free(screenInfo.screens[i]->devPrivates[dbeScreenPrivIndex].ptr);
+ pScreen->devPrivates[dbeScreenPrivIndex].ptr = NULL;
+ }
+ return;
+ }
+
+
+ /* Now add the extension. */
+ extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
+ DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
+ DbeResetProc, StandardMinorOpcode);
+
+ dbeErrorBase = extEntry->errorBase;
+
+} /* DbeExtensionInit() */
+
diff --git a/nx-X11/programs/Xserver/dbe/dbestruct.h b/nx-X11/programs/Xserver/dbe/dbestruct.h
new file mode 100644
index 000000000..17690d5a3
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/dbestruct.h
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * 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 HEWLETT-PACKARD COMPANY 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 Hewlett-Packard
+ * Company 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 Hewlett-Packard Company.
+ *
+ * Header file for DIX-related DBE
+ *
+ *****************************************************************************/
+
+#ifndef DBE_STRUCT_H
+#define DBE_STRUCT_H
+
+
+/* INCLUDES */
+
+#define NEED_DBE_PROTOCOL
+#include <nx-X11/extensions/Xdbeproto.h>
+#include "windowstr.h"
+
+
+/* DEFINES */
+
+#define DBE_SCREEN_PRIV(pScreen) \
+ ((dbeScreenPrivIndex < 0) ? \
+ NULL : \
+ ((DbeScreenPrivPtr)((pScreen)->devPrivates[dbeScreenPrivIndex].ptr)))
+
+#define DBE_SCREEN_PRIV_FROM_DRAWABLE(pDrawable) \
+ DBE_SCREEN_PRIV((pDrawable)->pScreen)
+
+#define DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(pDbeWindowPriv) \
+ DBE_SCREEN_PRIV((pDbeWindowPriv)->pWindow->drawable.pScreen)
+
+#define DBE_SCREEN_PRIV_FROM_WINDOW(pWindow) \
+ DBE_SCREEN_PRIV((pWindow)->drawable.pScreen)
+
+#define DBE_SCREEN_PRIV_FROM_PIXMAP(pPixmap) \
+ DBE_SCREEN_PRIV((pPixmap)->drawable.pScreen)
+
+#define DBE_SCREEN_PRIV_FROM_GC(pGC)\
+ DBE_SCREEN_PRIV((pGC)->pScreen)
+
+#define DBE_WINDOW_PRIV(pWindow)\
+ ((dbeWindowPrivIndex < 0) ? \
+ NULL : \
+ ((DbeWindowPrivPtr)(pWindow->devPrivates[dbeWindowPrivIndex].ptr)))
+
+/* Initial size of the buffer ID array in the window priv. */
+#define DBE_INIT_MAX_IDS 2
+
+/* Reallocation increment for the buffer ID array. */
+#define DBE_INCR_MAX_IDS 4
+
+/* Marker for free elements in the buffer ID array. */
+#define DBE_FREE_ID_ELEMENT 0
+
+
+/* TYPEDEFS */
+
+/* Record used to pass swap information between DIX and DDX swapping
+ * procedures.
+ */
+typedef struct _DbeSwapInfoRec
+{
+ WindowPtr pWindow;
+ unsigned char swapAction;
+
+} DbeSwapInfoRec, *DbeSwapInfoPtr;
+
+/*
+ ******************************************************************************
+ ** Per-window data
+ ******************************************************************************
+ */
+
+typedef struct _DbeWindowPrivRec
+{
+ /* A pointer to the window with which the DBE window private (buffer) is
+ * associated.
+ */
+ WindowPtr pWindow;
+
+ /* Last known swap action for this buffer. Legal values for this field
+ * are XdbeUndefined, XdbeBackground, XdbeUntouched, and XdbeCopied.
+ */
+ unsigned char swapAction;
+
+ /* Last known buffer size.
+ */
+ unsigned short width, height;
+
+ /* Coordinates used for static gravity when the window is positioned.
+ */
+ short x, y;
+
+ /* Number of XIDs associated with this buffer.
+ */
+ int nBufferIDs;
+
+ /* Capacity of the current buffer ID array, IDs. */
+ int maxAvailableIDs;
+
+ /* Pointer to the array of buffer IDs. This initially points to initIDs.
+ * When the static limit of the initIDs array is reached, the array is
+ * reallocated and this pointer is set to the new array instead of initIDs.
+ */
+ XID *IDs;
+
+ /* Initial array of buffer IDs. We are defining the XID array within the
+ * window priv to optimize for data locality. In most cases, only one
+ * buffer will be associated with a window. Having the array declared
+ * here can prevent us from accessing the data in another memory page,
+ * possibly resulting in a page swap and loss of performance. Initially we
+ * will use this array to store buffer IDs. For situations where we have
+ * more IDs than can fit in this static array, we will allocate a larger
+ * array to use, possibly suffering a performance loss.
+ */
+ XID initIDs[DBE_INIT_MAX_IDS];
+
+ /* Device-specific private information.
+ */
+ DevUnion *devPrivates;
+
+} DbeWindowPrivRec, *DbeWindowPrivPtr;
+
+
+/*
+ ******************************************************************************
+ ** Per-screen data
+ ******************************************************************************
+ */
+
+typedef struct _DbeScreenPrivRec
+{
+ /* Info for creating window privs */
+ int winPrivPrivLen; /* Length of privs in DbeWindowPrivRec */
+ unsigned int *winPrivPrivSizes; /* Array of private record sizes */
+ unsigned int totalWinPrivSize; /* PrivRec + size of all priv priv ptrs */
+
+ /* Resources created by DIX to be used by DDX */
+ RESTYPE dbeDrawableResType;
+ RESTYPE dbeWindowPrivResType;
+
+ /* Private indices created by DIX to be used by DDX */
+ int dbeScreenPrivIndex;
+ int dbeWindowPrivIndex;
+
+ /* Wrapped functions
+ * It is the responsibilty of the DDX layer to wrap PositionWindow().
+ * DbeExtensionInit wraps DestroyWindow().
+ */
+ PositionWindowProcPtr PositionWindow;
+ DestroyWindowProcPtr DestroyWindow;
+
+ /* Per-screen DIX routines */
+ Bool (*SetupBackgroundPainter)(
+ WindowPtr /*pWin*/,
+ GCPtr /*pGC*/
+);
+ DbeWindowPrivPtr (*AllocWinPriv)(
+ ScreenPtr /*pScreen*/
+);
+ int (*AllocWinPrivPrivIndex)(
+ void
+);
+ Bool (*AllocWinPrivPriv)(
+ ScreenPtr /*pScreen*/,
+ int /*index*/,
+ unsigned /*amount*/
+);
+
+ /* Per-screen DDX routines */
+ Bool (*GetVisualInfo)(
+ ScreenPtr /*pScreen*/,
+ XdbeScreenVisualInfo * /*pVisInfo*/
+);
+ int (*AllocBackBufferName)(
+ WindowPtr /*pWin*/,
+ XID /*bufId*/,
+ int /*swapAction*/
+);
+ int (*SwapBuffers)(
+ ClientPtr /*client*/,
+ int * /*pNumWindows*/,
+ DbeSwapInfoPtr /*swapInfo*/
+);
+ void (*BeginIdiom)(
+ ClientPtr /*client*/
+);
+ void (*EndIdiom)(
+ ClientPtr /*client*/
+);
+ void (*WinPrivDelete)(
+ DbeWindowPrivPtr /*pDbeWindowPriv*/,
+ XID /*bufId*/
+);
+ void (*ResetProc)(
+ ScreenPtr /*pScreen*/
+);
+ void (*ValidateBuffer)(
+ WindowPtr /*pWin*/,
+ XID /*bufId*/,
+ Bool /*dstbuffer*/
+);
+
+ /* Device-specific private information.
+ */
+ DevUnion *devPrivates;
+
+} DbeScreenPrivRec, *DbeScreenPrivPtr;
+
+#endif /* DBE_STRUCT_H */
diff --git a/nx-X11/programs/Xserver/dbe/midbe.c b/nx-X11/programs/Xserver/dbe/midbe.c
new file mode 100644
index 000000000..e241e5f28
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/midbe.c
@@ -0,0 +1,847 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * 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 HEWLETT-PACKARD COMPANY 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 Hewlett-Packard
+ * Company 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 Hewlett-Packard Company.
+ *
+ * Machine-independent DBE code
+ *
+ *****************************************************************************/
+
+
+/* INCLUDES */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include "dbestruct.h"
+#include "midbestr.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "inputstr.h"
+
+#include <stdio.h>
+
+/* DEFINES */
+
+
+/* TYPEDEFS */
+
+
+/* GLOBALS */
+
+static int miDbePrivPrivGeneration = 0;
+static int miDbeWindowPrivPrivIndex = -1;
+RESTYPE dbeDrawableResType;
+RESTYPE dbeWindowPrivResType;
+int dbeScreenPrivIndex = -1;
+int dbeWindowPrivIndex = -1;
+
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeGetVisualInfo request. This function
+ * is called through pDbeScreenPriv->GetVisualInfo. This function is also
+ * called for the DbeAllocateBackBufferName request at the extension level;
+ * it is called by ProcDbeAllocateBackBufferName() in dbe.c.
+ *
+ * If memory allocation fails or we can not get the visual info, this
+ * function returns FALSE. Otherwise, it returns TRUE for success.
+ *
+ *****************************************************************************/
+
+static Bool
+miDbeGetVisualInfo(pScreen, pScrVisInfo)
+ ScreenPtr pScreen;
+ XdbeScreenVisualInfo *pScrVisInfo;
+{
+ register int i, j, k;
+ register int count;
+ DepthPtr pDepth;
+ XdbeVisualInfo *visInfo;
+
+
+ /* Determine number of visuals for this screen. */
+ for (i = 0, count = 0; i < pScreen->numDepths; i++)
+ {
+ count += pScreen->allowedDepths[i].numVids;
+ }
+
+ /* Allocate an array of XdbeVisualInfo items. */
+ if (!(visInfo = (XdbeVisualInfo *)malloc(count * sizeof(XdbeVisualInfo))))
+ {
+ return(FALSE); /* memory alloc failure */
+ }
+
+ for (i = 0, k = 0; i < pScreen->numDepths; i++)
+ {
+ /* For each depth of this screen, get visual information. */
+
+ pDepth = &pScreen->allowedDepths[i];
+
+ for (j = 0; j < pDepth->numVids; j++)
+ {
+ /* For each visual for this depth of this screen, get visual ID
+ * and visual depth. Since this is MI code, we will always return
+ * the same performance level for all visuals (0). A higher
+ * performance level value indicates higher performance.
+ */
+ visInfo[k].visual = pDepth->vids[j];
+ visInfo[k].depth = pDepth->depth;
+ visInfo[k].perflevel = 0;
+ k++;
+ }
+ }
+
+ /* Record the number of visuals and point visual_depth to
+ * the array of visual info.
+ */
+ pScrVisInfo->count = count;
+ pScrVisInfo->visinfo = visInfo;
+
+ return(TRUE); /* success */
+
+} /* miDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miAllocBackBufferName
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeAllocateBackBufferName request.
+ *
+ *****************************************************************************/
+
+static int
+miDbeAllocBackBufferName(pWin, bufId, swapAction)
+ WindowPtr pWin;
+ XID bufId;
+ int swapAction;
+{
+ ScreenPtr pScreen;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ GCPtr pGC;
+ xRectangle clearRect;
+
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+
+ if (pDbeWindowPriv->nBufferIDs == 0)
+ {
+ /* There is no buffer associated with the window.
+ * We have to create the window priv priv. Remember, the window
+ * priv was created at the DIX level, so all we need to do is
+ * create the priv priv and attach it to the priv.
+ */
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ /* Setup the window priv priv. */
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
+
+ /* Get a front pixmap. */
+ if (!(pDbeWindowPrivPriv->pFrontBuffer =
+ (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
+ pDbeWindowPriv->height,
+ pWin->drawable.depth, 0)))
+ {
+ return(BadAlloc);
+ }
+
+ /* Get a back pixmap. */
+ if (!(pDbeWindowPrivPriv->pBackBuffer =
+ (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
+ pDbeWindowPriv->height,
+ pWin->drawable.depth, 0)))
+ {
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
+ return(BadAlloc);
+ }
+
+
+ /* Make the back pixmap a DBE drawable resource. */
+ if (!AddResource(bufId, dbeDrawableResType,
+ (void *)pDbeWindowPrivPriv->pBackBuffer))
+ {
+ /* free the buffer and the drawable resource */
+ FreeResource(bufId, RT_NONE);
+ return(BadAlloc);
+ }
+
+
+ /* Attach the priv priv to the priv. */
+ pDbeWindowPriv->devPrivates[miDbeWindowPrivPrivIndex].ptr =
+ (void *)pDbeWindowPrivPriv;
+
+
+ /* Clear the back buffer. */
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
+ clearRect.x = clearRect.y = 0;
+ clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
+ clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
+ (*pGC->ops->PolyFillRect)(
+ (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1,
+ &clearRect);
+ }
+ FreeScratchGC(pGC);
+
+ } /* if no buffer associated with the window */
+
+ else
+ {
+ /* A buffer is already associated with the window.
+ * Place the new buffer ID information at the head of the ID list.
+ */
+
+ /* Associate the new ID with an existing pixmap. */
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ if (!AddResource(bufId, dbeDrawableResType,
+ (void *)pDbeWindowPrivPriv->pBackBuffer))
+ {
+ return(BadAlloc);
+ }
+
+ }
+
+ return(Success);
+
+} /* miDbeAllocBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeAliasBuffers
+ *
+ * Description:
+ *
+ * This function associates all XIDs of a buffer with the back pixmap
+ * stored in the window priv.
+ *
+ *****************************************************************************/
+
+static void
+miDbeAliasBuffers(pDbeWindowPriv)
+ DbeWindowPrivPtr pDbeWindowPriv;
+{
+ int i;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv =
+ MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+
+ for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
+ {
+ ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
+ (void *)pDbeWindowPrivPriv->pBackBuffer);
+ }
+
+} /* miDbeAliasBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeSwapBuffers request.
+ *
+ *****************************************************************************/
+
+static int
+miDbeSwapBuffers(client, pNumWindows, swapInfo)
+ ClientPtr client;
+ int *pNumWindows;
+ DbeSwapInfoPtr swapInfo;
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ GCPtr pGC;
+ WindowPtr pWin;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+ PixmapPtr pTmpBuffer;
+ xRectangle clearRect;
+
+
+ pWin = swapInfo[0].pWindow;
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+
+ /*
+ **********************************************************************
+ ** Setup before swap.
+ **********************************************************************
+ */
+
+ switch(swapInfo[0].swapAction)
+ {
+ case XdbeUndefined:
+ break;
+
+ case XdbeBackground:
+ break;
+
+ case XdbeUntouched:
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pWin,
+ (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
+ pGC, 0, 0, pWin->drawable.width,
+ pWin->drawable.height, 0, 0);
+ break;
+
+ case XdbeCopied:
+ break;
+
+ }
+
+ /*
+ **********************************************************************
+ ** Swap.
+ **********************************************************************
+ */
+
+ ValidateGC((DrawablePtr)pWin, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ (DrawablePtr)pWin, pGC, 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+
+ /*
+ **********************************************************************
+ ** Tasks after swap.
+ **********************************************************************
+ */
+
+ switch(swapInfo[0].swapAction)
+ {
+ case XdbeUndefined:
+ break;
+
+ case XdbeBackground:
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width =
+ pDbeWindowPrivPriv->pBackBuffer->drawable.width;
+ clearRect.height =
+ pDbeWindowPrivPriv->pBackBuffer->drawable.height;
+ (*pGC->ops->PolyFillRect)(
+ (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ pGC, 1, &clearRect);
+ }
+ break;
+
+ case XdbeUntouched:
+ /* Swap pixmap pointers. */
+ pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
+ pDbeWindowPrivPriv->pBackBuffer =
+ pDbeWindowPrivPriv->pFrontBuffer;
+ pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
+
+ miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
+
+ break;
+
+ case XdbeCopied:
+ break;
+
+ }
+
+ /* Remove the swapped window from the swap information array and decrement
+ * pNumWindows to indicate to the DIX level how many windows were actually
+ * swapped.
+ */
+
+ if (*pNumWindows > 1)
+ {
+ /* We were told to swap more than one window, but we only swapped the
+ * first one. Remove the first window in the list by moving the last
+ * window to the beginning.
+ */
+ swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
+ swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
+
+ /* Clear the last window information just to be safe. */
+ swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL;
+ swapInfo[*pNumWindows - 1].swapAction = 0;
+ }
+ else
+ {
+ /* Clear the window information just to be safe. */
+ swapInfo[0].pWindow = (WindowPtr)NULL;
+ swapInfo[0].swapAction = 0;
+ }
+
+ (*pNumWindows)--;
+
+ FreeScratchGC(pGC);
+
+ return(Success);
+
+} /* miSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeWinPrivDelete
+ *
+ * Description:
+ *
+ * This is the MI function for deleting the dbeWindowPrivResType resource.
+ * This function is invoked indirectly by calling FreeResource() to free
+ * the resources associated with a DBE buffer ID. There are 5 ways that
+ * miDbeWinPrivDelete() can be called by FreeResource(). They are:
+ *
+ * - A DBE window is destroyed, in which case the DbeDestroyWindow()
+ * wrapper is invoked. The wrapper calls FreeResource() for all DBE
+ * buffer IDs.
+ *
+ * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
+ * after a buffer allocation failure.
+ *
+ * - The PositionWindow wrapper, miDbePositionWindow(), calls
+ * FreeResource() when it fails to create buffers of the new size.
+ * FreeResource() is called for all DBE buffer IDs.
+ *
+ * - FreeClientResources() calls FreeResource() when a client dies or the
+ * the server resets.
+ *
+ * When FreeResource() is called for a DBE buffer ID, the delete function
+ * for the only other type of DBE resource, dbeDrawableResType, is also
+ * invoked. This delete function (DbeDrawableDelete) is a NOOP to make
+ * resource deletion easier. It is not guaranteed which delete function is
+ * called first. Hence, we will let miDbeWinPrivDelete() free all DBE
+ * resources.
+ *
+ * This function deletes/frees the following stuff associated with
+ * the window private:
+ *
+ * - the ID node in the ID list representing the passed in ID.
+ *
+ * In addition, pDbeWindowPriv->nBufferIDs is decremented.
+ *
+ * If this function is called for the last/only buffer ID for a window,
+ * these are additionally deleted/freed:
+ *
+ * - the front and back pixmaps
+ * - the window priv itself
+ *
+ *****************************************************************************/
+
+static void
+miDbeWinPrivDelete(pDbeWindowPriv, bufId)
+ DbeWindowPrivPtr pDbeWindowPriv;
+ XID bufId;
+{
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+
+
+ if (pDbeWindowPriv->nBufferIDs != 0)
+ {
+ /* We still have at least one more buffer ID associated with this
+ * window.
+ */
+ return;
+ }
+
+
+ /* We have no more buffer IDs associated with this window. We need to
+ * free some stuff.
+ */
+
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+
+ /* Destroy the front and back pixmaps. */
+ if (pDbeWindowPrivPriv->pFrontBuffer)
+ {
+ (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
+ pDbeWindowPrivPriv->pFrontBuffer);
+ }
+ if (pDbeWindowPrivPriv->pBackBuffer)
+ {
+ (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
+ pDbeWindowPrivPriv->pBackBuffer);
+ }
+
+} /* miDbeWinPrivDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbePositionWindow
+ *
+ * Description:
+ *
+ * This function was cloned from miMbxPositionWindow() in mimultibuf.c.
+ * This function resizes the buffer when the window is resized.
+ *
+ *****************************************************************************/
+
+static Bool
+miDbePositionWindow(pWin, x, y)
+ WindowPtr pWin;
+ int x;
+ int y;
+{
+ ScreenPtr pScreen;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ int width, height;
+ int dx, dy, dw, dh;
+ int sourcex, sourcey;
+ int destx, desty;
+ int savewidth, saveheight;
+ PixmapPtr pFrontBuffer;
+ PixmapPtr pBackBuffer;
+ Bool clear;
+ GCPtr pGC;
+ xRectangle clearRect;
+ Bool ret;
+
+
+ /*
+ **************************************************************************
+ ** 1. Unwrap the member routine.
+ **************************************************************************
+ */
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+ pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
+
+ /*
+ **************************************************************************
+ ** 2. Do any work necessary before the member routine is called.
+ **
+ ** In this case we do not need to do anything.
+ **************************************************************************
+ */
+
+ /*
+ **************************************************************************
+ ** 3. Call the member routine, saving its result if necessary.
+ **************************************************************************
+ */
+
+ ret = (*pScreen->PositionWindow)(pWin, x, y);
+
+ /*
+ **************************************************************************
+ ** 4. Rewrap the member routine, restoring the wrapper value first in case
+ ** the wrapper (or something that it wrapped) change this value.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = miDbePositionWindow;
+
+ /*
+ **************************************************************************
+ ** 5. Do any work necessary after the member routine has been called.
+ **************************************************************************
+ */
+
+ if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
+ {
+ return(ret);
+ }
+
+ if (pDbeWindowPriv->width == pWin->drawable.width &&
+ pDbeWindowPriv->height == pWin->drawable.height)
+ {
+ return(ret);
+ }
+
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+
+ dx = pWin->drawable.x - pDbeWindowPriv->x;
+ dy = pWin->drawable.y - pDbeWindowPriv->y;
+ dw = width - pDbeWindowPriv->width;
+ dh = height - pDbeWindowPriv->height;
+
+ GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
+
+ clear = ((pDbeWindowPriv->width < (unsigned short)width ) ||
+ (pDbeWindowPriv->height < (unsigned short)height) ||
+ (pWin->bitGravity == ForgetGravity));
+
+ sourcex = 0;
+ sourcey = 0;
+ savewidth = pDbeWindowPriv->width;
+ saveheight = pDbeWindowPriv->height;
+
+ /* Clip rectangle to source and destination. */
+ if (destx < 0)
+ {
+ savewidth += destx;
+ sourcex -= destx;
+ destx = 0;
+ }
+
+ if (destx + savewidth > width)
+ {
+ savewidth = width - destx;
+ }
+
+ if (desty < 0)
+ {
+ saveheight += desty;
+ sourcey -= desty;
+ desty = 0;
+ }
+
+ if (desty + saveheight > height)
+ {
+ saveheight = height - desty;
+ }
+
+ pDbeWindowPriv->width = width;
+ pDbeWindowPriv->height = height;
+ pDbeWindowPriv->x = pWin->drawable.x;
+ pDbeWindowPriv->y = pWin->drawable.y;
+
+ pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ if (clear)
+ {
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width = width;
+ clearRect.height = height;
+ }
+ else
+ {
+ clear = FALSE;
+ }
+ }
+
+ /* Create DBE buffer pixmaps equal to size of resized window. */
+ pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
+ pWin->drawable.depth, 0);
+
+ pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
+ pWin->drawable.depth, 0);
+
+ if (!pFrontBuffer || !pBackBuffer)
+ {
+ /* We failed at creating 1 or 2 of the pixmaps. */
+
+ if (pFrontBuffer)
+ {
+ (*pScreen->DestroyPixmap)(pFrontBuffer);
+ }
+
+ if (pBackBuffer)
+ {
+ (*pScreen->DestroyPixmap)(pBackBuffer);
+ }
+
+ /* Destroy all buffers for this window. */
+ while (pDbeWindowPriv)
+ {
+ /* DbeWindowPrivDelete() will free the window private if there no
+ * more buffer IDs associated with this window.
+ */
+ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+ }
+
+ FreeScratchGC(pGC);
+ return(FALSE);
+ }
+
+ else
+ {
+ /* Clear out the new DBE buffer pixmaps. */
+
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+
+
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ ValidateGC((DrawablePtr)pFrontBuffer, pGC);
+
+ /* I suppose this could avoid quite a bit of work if
+ * it computed the minimal area required.
+ */
+ if (clear)
+ {
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1,
+ &clearRect);
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1,
+ &clearRect);
+ }
+
+ /* Copy the contents of the old DBE pixmaps to the new pixmaps. */
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
+ (DrawablePtr)pFrontBuffer, pGC, sourcex,
+ sourcey, savewidth, saveheight, destx, desty);
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ (DrawablePtr)pBackBuffer, pGC, sourcex,
+ sourcey, savewidth, saveheight, destx, desty);
+ }
+
+ /* Destroy the old pixmaps, and point the DBE window priv to the new
+ * pixmaps.
+ */
+
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
+
+ pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
+ pDbeWindowPrivPriv->pBackBuffer = pBackBuffer;
+
+ /* Make sure all XID are associated with the new back pixmap. */
+ miDbeAliasBuffers(pDbeWindowPriv);
+
+ FreeScratchGC(pGC);
+ }
+
+ return(ret);
+
+} /* miDbePositionWindow() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeResetProc
+ *
+ * Description:
+ *
+ * This function is called from DbeResetProc(), which is called at the end
+ * of every server generation. This function peforms any MI-specific
+ * shutdown tasks.
+ *
+ *****************************************************************************/
+
+static void
+miDbeResetProc(pScreen)
+ ScreenPtr pScreen;
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ /* Unwrap wrappers */
+ pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
+
+} /* miDbeResetProc() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeInit
+ *
+ * Description:
+ *
+ * This is the MI initialization function called by DbeExtensionInit().
+ *
+ *****************************************************************************/
+
+Bool
+miDbeInit(pScreen, pDbeScreenPriv)
+ ScreenPtr pScreen;
+ DbeScreenPrivPtr pDbeScreenPriv;
+{
+ /* Copy resource types created by DIX */
+ dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType;
+ dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
+
+ /* Copy private indices created by DIX */
+ dbeScreenPrivIndex = pDbeScreenPriv->dbeScreenPrivIndex;
+ dbeWindowPrivIndex = pDbeScreenPriv->dbeWindowPrivIndex;
+
+ /* Reset the window priv privs if generations do not match. */
+ if (miDbePrivPrivGeneration != serverGeneration)
+ {
+ /*
+ **********************************************************************
+ ** Allocate the window priv priv.
+ **********************************************************************
+ */
+
+ miDbeWindowPrivPrivIndex = (*pDbeScreenPriv->AllocWinPrivPrivIndex)();
+
+ /* Make sure we only do this code once. */
+ miDbePrivPrivGeneration = serverGeneration;
+
+ } /* if -- Reset priv privs. */
+
+ if (!(*pDbeScreenPriv->AllocWinPrivPriv)(pScreen,
+ miDbeWindowPrivPrivIndex, sizeof(MiDbeWindowPrivPrivRec)))
+ {
+ return(FALSE);
+ }
+
+ /* Wrap functions. */
+ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = miDbePositionWindow;
+
+ /* Initialize the per-screen DBE function pointers. */
+ pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo;
+ pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName;
+ pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers;
+ pDbeScreenPriv->BeginIdiom = 0;
+ pDbeScreenPriv->EndIdiom = 0;
+ pDbeScreenPriv->ResetProc = miDbeResetProc;
+ pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete;
+
+ /* The mi implementation doesn't need buffer validation. */
+ pDbeScreenPriv->ValidateBuffer = (void (*)())NoopDDA;
+
+ return(TRUE);
+
+} /* miDbeInit() */
diff --git a/nx-X11/programs/Xserver/dbe/midbe.h b/nx-X11/programs/Xserver/dbe/midbe.h
new file mode 100644
index 000000000..a21af12bb
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/midbe.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * 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 HEWLETT-PACKARD COMPANY 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 Hewlett-Packard
+ * Company 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 Hewlett-Packard Company.
+ *
+ * Header file for users of machine-independent DBE code
+ *
+ *****************************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef MIDBE_H
+#define MIDBE_H
+
+/* EXTERNS */
+
+extern Bool miDbeInit(
+ ScreenPtr pScreen,
+ DbeScreenPrivPtr pDbeScreenPriv
+);
+
+#endif /* MIDBE_H */
+
diff --git a/nx-X11/programs/Xserver/dbe/midbestr.h b/nx-X11/programs/Xserver/dbe/midbestr.h
new file mode 100644
index 000000000..1ad0104aa
--- /dev/null
+++ b/nx-X11/programs/Xserver/dbe/midbestr.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * 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 HEWLETT-PACKARD COMPANY 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 Hewlett-Packard
+ * Company 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 Hewlett-Packard Company.
+ *
+ * Header file for users of machine-independent DBE code
+ *
+ *****************************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef MIDBE_STRUCT_H
+#define MIDBE_STRUCT_H
+
+
+/* DEFINES */
+
+#define MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv) \
+ (((miDbeWindowPrivPrivIndex < 0) || (!pDbeWindowPriv)) ? \
+ NULL : \
+ ((MiDbeWindowPrivPrivPtr) \
+ ((pDbeWindowPriv)->devPrivates[miDbeWindowPrivPrivIndex].ptr)))
+
+#define MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin)\
+ MI_DBE_WINDOW_PRIV_PRIV(DBE_WINDOW_PRIV(pWin))
+
+#define MI_DBE_SCREEN_PRIV_PRIV(pDbeScreenPriv) \
+ (((miDbeScreenPrivPrivIndex < 0) || (!pDbeScreenPriv)) ? \
+ NULL : \
+ ((MiDbeScreenPrivPrivPtr) \
+ ((pDbeScreenPriv)->devPrivates[miDbeScreenPrivPrivIndex].ptr)))
+
+
+/* TYPEDEFS */
+
+typedef struct _MiDbeWindowPrivPrivRec
+{
+ /* Place machine-specific fields in here.
+ * Since this is mi code, we do not really have machine-specific fields.
+ */
+
+ /* Pointer to a drawable that contains the contents of the back buffer.
+ */
+ PixmapPtr pBackBuffer;
+
+ /* Pointer to a drawable that contains the contents of the front buffer.
+ * This pointer is only used for the XdbeUntouched swap action. For that
+ * swap action, we need to copy the front buffer (window) contents into
+ * this drawable, copy the contents of current back buffer drawable (the
+ * back buffer) into the window, swap the front and back drawable pointers,
+ * and then swap the drawable/resource associations in the resource
+ * database.
+ */
+ PixmapPtr pFrontBuffer;
+
+ /* Pointer back to our window private with which we are associated. */
+ DbeWindowPrivPtr pDbeWindowPriv;
+
+} MiDbeWindowPrivPrivRec, *MiDbeWindowPrivPrivPtr;
+
+typedef struct _MiDbeScreenPrivPrivRec
+{
+ /* Place machine-specific fields in here.
+ * Since this is mi code, we do not really have machine-specific fields.
+ */
+
+ /* Pointer back to our screen private with which we are associated. */
+ DbeScreenPrivPtr pDbeScreenPriv;
+
+} MiDbeScreenPrivPrivRec, *MiDbeScreenPrivPrivPtr;
+
+#endif /* MIDBE_STRUCT_H */
+
diff --git a/nx-X11/programs/Xserver/dix/Imakefile b/nx-X11/programs/Xserver/dix/Imakefile
new file mode 100644
index 000000000..1024de965
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/Imakefile
@@ -0,0 +1,143 @@
+NULL =
+
+#include <Server.tmpl>
+
+XPSRC = xpstubs.c
+XPOBJ = xpstubs.o
+
+#if !HasFfs
+FFS_SRC = ffs.c
+FFS_OBJ = ffs.o
+#endif
+
+#if (!(defined(NXAgentServer) && NXAgentServer))
+NXAGENT_SKIP_SRCS = \
+ dispatch.c \
+ dixfonts.c \
+ events.c \
+ extension.c \
+ glyphcurs.c \
+ property.c \
+ resource.c \
+ window.c \
+ $(NULL)
+NXAGENT_SKIP_OBJS = \
+ dispatch.o \
+ dixfonts.o \
+ events.o \
+ extension.o \
+ glyphcurs.o \
+ property.o \
+ resource.o \
+ window.o \
+ $(NULL)
+#endif
+
+
+SRCS = \
+ atom.c \
+ colormap.c \
+ cursor.c \
+ devices.c \
+ dixutils.c \
+ gc.c \
+ globals.c \
+ grabs.c \
+ main.c \
+ region.c \
+ swaprep.c \
+ swapreq.c \
+ tables.c \
+ initatoms.c \
+ privates.c \
+ pixmap.c \
+ $(NXAGENT_SKIP_SRCS) \
+ $(FFS_SRC) \
+ $(NULL)
+
+OBJS = \
+ atom.o \
+ colormap.o \
+ cursor.o \
+ devices.o \
+ dixutils.o \
+ gc.o \
+ globals.o \
+ grabs.o \
+ main.o \
+ region.o \
+ swaprep.o \
+ swapreq.o \
+ tables.o \
+ initatoms.o \
+ privates.o \
+ pixmap.o \
+ $(NXAGENT_SKIP_OBJS) \
+ $(FFS_OBJ) \
+ $(NULL)
+
+ INCLUDES = -I../include \
+ -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/lbx \
+ `pkg-config --cflags-only-I pixman-1` \
+ $(NULL)
+
+ LINTLIBS = ../os/llib-los.ln
+
+/*
+ * The following configuration parameters may be set in the appropriate
+ * .macros files or site.def in the directory util/imake.includes/:
+ *
+ * DefaultFontPath COMPILEDDEFAULTFONTPATH
+ *
+ * The sample util/imake.includes/Imake.tmpl will provide generic defaults.
+ * The values in site.h are simply a last line of defense and should not be
+ * changed.
+ */
+
+#ifdef DefaultFontPath
+DEFAULTFONTPATH = DefaultFontPath
+SITE_FONT_PATH = -DCOMPILEDDEFAULTFONTPATH=\"$(DEFAULTFONTPATH)\"
+#endif
+
+#ifdef DefaultDisplayClass
+DEFAULTDISPLAYCLASS = DefaultDisplayClass
+ SITE_DISPLAY_CLASS = -DCOMPILEDDISPLAYCLASS=\"$(DEFAULTDISPLAYCLASS)\"
+#endif
+
+#ifdef XVendorString
+VENDORSTRING = XVendorString
+ VENDOR_STRING = -DVENDOR_STRING=\"$(VENDORSTRING)\"
+#endif
+
+#ifdef XVendorRelease
+VENDORRELEASE = XVendorRelease
+ VENDOR_RELEASE = -DVENDOR_RELEASE="$(VENDORRELEASE)"
+#endif
+
+#ifdef DarwinArchitecture
+#if DarwinQuartzSupport
+ QUARTZ_DEFINES = -DDARWIN_WITH_QUARTZ
+#endif
+#endif
+
+SITE_DEFINES = $(SITE_FONT_PATH) $(SITE_DISPLAY_CLASS)
+
+VENDOR_DEFINES = $(VENDOR_STRING) $(VENDOR_RELEASE) $(QUARTZ_DEFINES)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(dix,$(OBJS))
+LintLibraryTarget(dix,$(SRCS) $(XPSRC))
+NormalLintTarget($(SRCS) $(XPSRC))
+
+SpecialCObjectRule(globals,$(ICONFIGFILES),$(SITE_DEFINES))
+SpecialCObjectRule(main,$(ICONFIGFILES),$(VENDOR_DEFINES))
+SpecialCObjectRule(pixmap,$(ICONFIGFILES),$(_NOOP_))
+SpecialCObjectRule(privates,$(ICONFIGFILES),$(_NOOP_))
+SpecialCObjectRule(window,$(ICONFIGFILES),$(QUARTZ_DEFINES))
+
+NormalLibraryTarget(xpstubs,$(XPOBJ))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/dix/atom.c b/nx-X11/programs/Xserver/dix/atom.c
new file mode 100644
index 000000000..d569c2314
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/atom.c
@@ -0,0 +1,210 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xatom.h>
+#include "misc.h"
+#include "resource.h"
+#include "dix.h"
+
+#define InitialTableSize 100
+
+typedef struct _Node {
+ struct _Node *left, *right;
+ Atom a;
+ unsigned int fingerPrint;
+ const char *string;
+} NodeRec, *NodePtr;
+
+static Atom lastAtom = None;
+static NodePtr atomRoot = (NodePtr)NULL;
+static unsigned long tableLength;
+static NodePtr *nodeTable;
+
+void FreeAtom(NodePtr patom);
+
+Atom
+MakeAtom(const char *string, unsigned len, Bool makeit)
+{
+ register NodePtr * np;
+ unsigned i;
+ int comp;
+ register unsigned int fp = 0;
+
+ np = &atomRoot;
+ for (i = 0; i < (len+1)/2; i++)
+ {
+ fp = fp * 27 + string[i];
+ fp = fp * 27 + string[len - 1 - i];
+ }
+ while (*np != (NodePtr) NULL)
+ {
+ if (fp < (*np)->fingerPrint)
+ np = &((*np)->left);
+ else if (fp > (*np)->fingerPrint)
+ np = &((*np)->right);
+ else
+ { /* now start testing the strings */
+ comp = strncmp(string, (*np)->string, (int)len);
+ if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
+ np = &((*np)->left);
+ else if (comp > 0)
+ np = &((*np)->right);
+ else
+ return(*np)->a;
+ }
+ }
+ if (makeit)
+ {
+ register NodePtr nd;
+
+ nd = (NodePtr) malloc(sizeof(NodeRec));
+ if (!nd)
+ return BAD_RESOURCE;
+ if (lastAtom < XA_LAST_PREDEFINED)
+ {
+ nd->string = string;
+ }
+ else
+ {
+ nd->string = strndup(string, len);
+ if (!nd->string) {
+ free(nd);
+ return BAD_RESOURCE;
+ }
+ }
+ if ((lastAtom + 1) >= tableLength) {
+ NodePtr *table;
+
+ table = (NodePtr *) realloc(nodeTable,
+ tableLength * (2 * sizeof(NodePtr)));
+ if (!table) {
+ if (nd->string != string)
+ /* nd->string has been strdup'ed */
+ free((char *)nd->string);
+ free(nd);
+ return BAD_RESOURCE;
+ }
+ tableLength <<= 1;
+ nodeTable = table;
+ }
+ *np = nd;
+ nd->left = nd->right = (NodePtr) NULL;
+ nd->fingerPrint = fp;
+ nd->a = (++lastAtom);
+ *(nodeTable+lastAtom) = nd;
+ return nd->a;
+ }
+ else
+ return None;
+}
+
+Bool
+ValidAtom(Atom atom)
+{
+ return (atom != None) && (atom <= lastAtom);
+}
+
+const char *
+NameForAtom(Atom atom)
+{
+ NodePtr node;
+ if (atom > lastAtom) return 0;
+ if ((node = nodeTable[atom]) == (NodePtr)NULL) return 0;
+ return node->string;
+}
+
+void
+AtomError()
+{
+ FatalError("initializing atoms");
+}
+
+void
+FreeAtom(NodePtr patom)
+{
+ if(patom->left)
+ FreeAtom(patom->left);
+ if(patom->right)
+ FreeAtom(patom->right);
+ if (patom->a > XA_LAST_PREDEFINED)
+ free((char *)patom->string);
+ free(patom);
+}
+
+void
+FreeAllAtoms()
+{
+ if(atomRoot == (NodePtr)NULL)
+ return;
+ FreeAtom(atomRoot);
+ atomRoot = (NodePtr)NULL;
+ free(nodeTable);
+ nodeTable = (NodePtr *)NULL;
+ lastAtom = None;
+}
+
+void
+InitAtoms()
+{
+ FreeAllAtoms();
+ tableLength = InitialTableSize;
+ nodeTable = (NodePtr *)malloc(InitialTableSize*sizeof(NodePtr));
+ if (!nodeTable)
+ AtomError();
+ nodeTable[None] = (NodePtr)NULL;
+ MakePredeclaredAtoms();
+ if (lastAtom != XA_LAST_PREDEFINED)
+ AtomError ();
+}
+
+
diff --git a/nx-X11/programs/Xserver/dix/buildatoms b/nx-X11/programs/Xserver/dix/buildatoms
new file mode 100644
index 000000000..dfbbca8a9
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/buildatoms
@@ -0,0 +1,43 @@
+#!/bin/sh
+hfile=../../../include/Xatom.h
+cfile=initatoms.c
+rm -f $hfile $cfile
+umask 222
+awk '
+BEGIN {
+ hfile = "'$hfile'";
+ cfile = "'$cfile'";
+ hformat = "#define XA_%s ((Atom) %d)\n";
+ printf("#ifndef XATOM_H\n") > hfile;
+ printf("#define XATOM_H 1\n\n") > hfile;
+ printf("/* THIS IS A GENERATED FILE\n") > hfile;
+ printf(" *\n") > hfile;
+ printf(" * Do not change! Changing this file implies a protocol change!\n") > hfile;
+ printf(" */\n\n") > hfile;
+
+ printf("/* THIS IS A GENERATED FILE\n") > cfile;
+ printf(" *\n") > cfile;
+ printf(" * Do not change! Changing this file implies a protocol change!\n") > cfile;
+ printf(" */\n\n") > cfile;
+ printf("#include \"X.h\"\n") > cfile;
+ printf("#include \"Xatom.h\"\n") > cfile;
+ printf("#include \"misc.h\"\n") > cfile;
+ printf("#include \"dix.h\"\n") > cfile;
+ printf("void MakePredeclaredAtoms()\n") > cfile;
+ printf("{\n") > cfile;
+
+ }
+
+NF == 2 && $2 == "@" {
+ printf(hformat, $1, ++atomno) > hfile ;
+ printf(" if (MakeAtom(\"%s\", %d, 1) != XA_%s) AtomError();\n", $1, length($1), $1) > cfile ;
+ }
+
+END {
+ printf("\n") > hfile;
+ printf(hformat, "LAST_PREDEFINED", atomno) > hfile ;
+ printf("#endif /* XATOM_H */\n") > hfile;
+ printf("}\n") > cfile ;
+ }
+' BuiltInAtoms
+exit 0
diff --git a/nx-X11/programs/Xserver/dix/colormap.c b/nx-X11/programs/Xserver/dix/colormap.c
new file mode 100644
index 000000000..7fcde71f3
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/colormap.c
@@ -0,0 +1,2755 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "dix.h"
+#include "colormapst.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "windowstr.h"
+
+extern XID clientErrorValue;
+extern int colormapPrivateCount;
+
+static Pixel FindBestPixel(
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb * /*prgb*/,
+ int /*channel*/
+);
+
+static int AllComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int RedComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int GreenComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int BlueComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static void FreePixels(
+ register ColormapPtr /*pmap*/,
+ register int /*client*/
+);
+
+static void CopyFree(
+ int /*channel*/,
+ int /*client*/,
+ ColormapPtr /*pmapSrc*/,
+ ColormapPtr /*pmapDst*/
+);
+
+static void FreeCell(
+ ColormapPtr /*pmap*/,
+ Pixel /*i*/,
+ int /*channel*/
+);
+
+static void UpdateColors(
+ ColormapPtr /*pmap*/
+);
+
+static int AllocDirect(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*prmask*/,
+ Pixel * /*pgmask*/,
+ Pixel * /*pbmask*/
+);
+
+static int AllocPseudo(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pmask*/,
+ Pixel ** /*pppixFirst*/
+);
+
+static Bool AllocCP(
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*count*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pMask*/
+);
+
+static Bool AllocShared(
+ ColormapPtr /*pmap*/,
+ Pixel * /*ppix*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Pixel /*rmask*/,
+ Pixel /*gmask*/,
+ Pixel /*bmask*/,
+ Pixel * /*ppixFirst*/
+);
+
+static int FreeCo(
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*color*/,
+ int /*npixIn*/,
+ Pixel * /*ppixIn*/,
+ Pixel /*mask*/
+);
+
+static int TellNoMap(
+ WindowPtr /*pwin*/,
+ Colormap * /*pmid*/
+);
+
+static void FindColorInRootCmap (
+ ColormapPtr /* pmap */,
+ EntryPtr /* pentFirst */,
+ int /* size */,
+ xrgb* /* prgb */,
+ Pixel* /* pPixel */,
+ int /* channel */,
+ ColorCompareProcPtr /* comp */
+);
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+#if COMPOSITE
+#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \
+ (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
+#else
+#define ALPHAMASK(vis) 0
+#endif
+
+#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
+
+/* GetNextBitsOrBreak(bits, mask, base) --
+ * (Suggestion: First read the macro, then read this explanation.
+ *
+ * Either generate the next value to OR in to a pixel or break out of this
+ * while loop
+ *
+ * This macro is used when we're trying to generate all 2^n combinations of
+ * bits in mask. What we're doing here is counting in binary, except that
+ * the bits we use to count may not be contiguous. This macro will be
+ * called 2^n times, returning a different value in bits each time. Then
+ * it will cause us to break out of a surrounding loop. (It will always be
+ * called from within a while loop.)
+ * On call: mask is the value we want to find all the combinations for
+ * base has 1 bit set where the least significant bit of mask is set
+ *
+ * For example,if mask is 01010, base should be 0010 and we count like this:
+ * 00010 (see this isn't so hard),
+ * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
+ * we add that to bits getting (0100 + 0100) =
+ * 01000 for our next value.
+ * then we add 0010 to get
+ * 01010 and we're done (easy as 1, 2, 3)
+ */
+#define GetNextBitsOrBreak(bits, mask, base) \
+ if((bits) == (mask)) \
+ break; \
+ (bits) += (base); \
+ while((bits) & ~(mask)) \
+ (bits) += ((bits) & ~(mask));
+/* ID of server as client */
+#define SERVER_ID 0
+
+typedef struct _colorResource
+{
+ Colormap mid;
+ int client;
+} colorResource;
+
+/* Invariants:
+ * refcnt == 0 means entry is empty
+ * refcnt > 0 means entry is useable by many clients, so it can't be changed
+ * refcnt == AllocPrivate means entry owned by one client only
+ * fShared should only be set if refcnt == AllocPrivate, and only in red map
+ */
+
+
+/**
+ * Create and initialize the color map
+ *
+ * \param mid resource to use for this colormap
+ * \param alloc 1 iff all entries are allocated writable
+ */
+int
+CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
+ ColormapPtr *ppcmap, int alloc, int client)
+{
+ int class, size;
+ unsigned long sizebytes;
+ ColormapPtr pmap;
+ register EntryPtr pent;
+ int i;
+ register Pixel *ppix, **pptr;
+
+ class = pVisual->class;
+ if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
+ return (BadMatch);
+
+ size = pVisual->ColormapEntries;
+ sizebytes = (size * sizeof(Entry)) +
+ (MAXCLIENTS * sizeof(Pixel *)) +
+ (MAXCLIENTS * sizeof(int));
+ if ((class | DynamicClass) == DirectColor)
+ sizebytes *= 3;
+ sizebytes += sizeof(ColormapRec);
+ pmap = (ColormapPtr) malloc(sizebytes);
+ if (!pmap)
+ return (BadAlloc);
+ pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
+ sizebytes = size * sizeof(Entry);
+ pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
+ pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->mid = mid;
+ pmap->flags = 0; /* start out with all flags clear */
+ if(mid == pScreen->defColormap)
+ pmap->flags |= IsDefault;
+ pmap->pScreen = pScreen;
+ pmap->pVisual = pVisual;
+ pmap->class = class;
+ if ((class | DynamicClass) == DirectColor)
+ size = NUMRED(pVisual);
+ pmap->freeRed = size;
+ bzero ((char *) pmap->red, (int)sizebytes);
+ bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
+ for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
+ *pptr = (Pixel *)NULL;
+ if (alloc == AllocAll)
+ {
+ if (class & DynamicClass)
+ pmap->flags |= AllAllocated;
+ for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeRed = 0;
+ ppix = (Pixel *)malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap);
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsRed[client] = size;
+ }
+
+ if ((class | DynamicClass) == DirectColor)
+ {
+ pmap->freeGreen = NUMGREEN(pVisual);
+ pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
+ pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->freeBlue = NUMBLUE(pVisual);
+ pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
+ pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
+ (MAXCLIENTS * sizeof(Pixel *)));
+
+ bzero ((char *) pmap->green, (int)sizebytes);
+ bzero ((char *) pmap->blue, (int)sizebytes);
+
+ memmove((char *) pmap->clientPixelsGreen,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ memmove((char *) pmap->clientPixelsBlue,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
+ bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
+
+ /* If every cell is allocated, mark its refcnt */
+ if (alloc == AllocAll)
+ {
+ size = pmap->freeGreen;
+ for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeGreen = 0;
+ ppix = (Pixel *) malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap->clientPixelsRed[client]);
+ free(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsGreen[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsGreen[client] = size;
+
+ size = pmap->freeBlue;
+ for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeBlue = 0;
+ ppix = (Pixel *) malloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ free(pmap->clientPixelsGreen[client]);
+ free(pmap->clientPixelsRed[client]);
+ free(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsBlue[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsBlue[client] = size;
+ }
+ }
+ if (!AddResource(mid, RT_COLORMAP, (void *)pmap))
+ return (BadAlloc);
+ /* If the device wants a chance to initialize the colormap in any way,
+ * this is it. In specific, if this is a Static colormap, this is the
+ * time to fill in the colormap's values */
+ pmap->flags |= BeingCreated;
+
+
+ /*
+ * Allocate the array of devPrivate's for this colormap.
+ */
+
+ if (colormapPrivateCount == 0)
+ pmap->devPrivates = NULL;
+ else
+ {
+ pmap->devPrivates = (DevUnion *) calloc (
+ sizeof(DevUnion), colormapPrivateCount);
+ if (!pmap->devPrivates)
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ }
+
+ if (!(*pScreen->CreateColormap)(pmap))
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ pmap->flags &= ~BeingCreated;
+ *ppcmap = pmap;
+ return (Success);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeColormap (void * value, XID mid)
+{
+ int i;
+ register EntryPtr pent;
+ ColormapPtr pmap = (ColormapPtr)value;
+
+ if(CLIENT_ID(mid) != SERVER_ID)
+ {
+ (*pmap->pScreen->UninstallColormap) (pmap);
+ WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (void *) &mid);
+ }
+
+ /* This is the device's chance to undo anything it needs to, especially
+ * to free any storage it allocated */
+ (*pmap->pScreen->DestroyColormap)(pmap);
+
+ if(pmap->clientPixelsRed)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ free(pmap->clientPixelsRed[i]);
+ }
+
+ if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
+ {
+ for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
+ pent >= pmap->red;
+ pent--)
+ {
+ if(pent->fShared)
+ {
+ if (--pent->co.shco.red->refcnt == 0)
+ free(pent->co.shco.red);
+ if (--pent->co.shco.green->refcnt == 0)
+ free(pent->co.shco.green);
+ if (--pent->co.shco.blue->refcnt == 0)
+ free(pent->co.shco.blue);
+ }
+ }
+ }
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ {
+ free(pmap->clientPixelsGreen[i]);
+ free(pmap->clientPixelsBlue[i]);
+ }
+ }
+
+ if (pmap->devPrivates)
+ free(pmap->devPrivates);
+
+ free(pmap);
+ return(Success);
+}
+
+/* Tell window that pmid has disappeared */
+static int
+TellNoMap (WindowPtr pwin, Colormap *pmid)
+{
+ xEvent xE;
+
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = None;
+ xE.u.colormap.new = TRUE;
+ xE.u.colormap.state = ColormapUninstalled;
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
+#endif
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ if (pwin->optional) {
+ pwin->optional->colormap = None;
+ CheckWindowOptionalNeed (pwin);
+ }
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got uninstalled */
+int
+TellLostMap (WindowPtr pwin, void * value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapUninstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got installed */
+int
+TellGainedMap (WindowPtr pwin, void * value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap (pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapInstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+
+int
+CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
+{
+ ColormapPtr pmap = (ColormapPtr) NULL;
+ int result, alloc, size;
+ Colormap midSrc;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+
+ pScreen = pSrc->pScreen;
+ pVisual = pSrc->pVisual;
+ midSrc = pSrc->mid;
+ alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
+ AllocAll : AllocNone;
+ size = pVisual->ColormapEntries;
+
+ /* If the create returns non-0, it failed */
+ result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
+ if(result != Success)
+ return(result);
+ if(alloc == AllocAll)
+ {
+ memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
+ memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
+ }
+ pSrc->flags &= ~AllAllocated;
+ FreePixels(pSrc, client);
+ UpdateColors(pmap);
+ return(Success);
+ }
+
+ CopyFree(REDMAP, client, pSrc, pmap);
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ CopyFree(GREENMAP, client, pSrc, pmap);
+ CopyFree(BLUEMAP, client, pSrc, pmap);
+ }
+ if (pmap->class & DynamicClass)
+ UpdateColors(pmap);
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return(Success);
+}
+
+/* Helper routine for freeing large numbers of cells from a map */
+static void
+CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
+{
+ int z, npix;
+ EntryPtr pentSrcFirst, pentDstFirst;
+ EntryPtr pentSrc, pentDst;
+ Pixel *ppix;
+ int nalloc;
+
+ switch(channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case REDMAP:
+ ppix = (pmapSrc->clientPixelsRed)[client];
+ npix = (pmapSrc->numPixelsRed)[client];
+ pentSrcFirst = pmapSrc->red;
+ pentDstFirst = pmapDst->red;
+ break;
+ case GREENMAP:
+ ppix = (pmapSrc->clientPixelsGreen)[client];
+ npix = (pmapSrc->numPixelsGreen)[client];
+ pentSrcFirst = pmapSrc->green;
+ pentDstFirst = pmapDst->green;
+ break;
+ case BLUEMAP:
+ ppix = (pmapSrc->clientPixelsBlue)[client];
+ npix = (pmapSrc->numPixelsBlue)[client];
+ pentSrcFirst = pmapSrc->blue;
+ pentDstFirst = pmapDst->blue;
+ break;
+ }
+ nalloc = 0;
+ if (pmapSrc->class & DynamicClass)
+ {
+ for(z = npix; --z >= 0; ppix++)
+ {
+ /* Copy entries */
+ pentSrc = pentSrcFirst + *ppix;
+ pentDst = pentDstFirst + *ppix;
+ if (pentDst->refcnt > 0)
+ {
+ pentDst->refcnt++;
+ }
+ else
+ {
+ *pentDst = *pentSrc;
+ nalloc++;
+ if (pentSrc->refcnt > 0)
+ pentDst->refcnt = 1;
+ else
+ pentSrc->fShared = FALSE;
+ }
+ FreeCell(pmapSrc, *ppix, channel);
+ }
+ }
+
+ /* Note that FreeCell has already fixed pmapSrc->free{Color} */
+ switch(channel)
+ {
+ case REDMAP:
+ pmapDst->freeRed -= nalloc;
+ (pmapDst->clientPixelsRed)[client] =
+ (pmapSrc->clientPixelsRed)[client];
+ (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
+ (pmapSrc->numPixelsRed)[client] = 0;
+ break;
+ case GREENMAP:
+ pmapDst->freeGreen -= nalloc;
+ (pmapDst->clientPixelsGreen)[client] =
+ (pmapSrc->clientPixelsGreen)[client];
+ (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
+ (pmapSrc->numPixelsGreen)[client] = 0;
+ break;
+ case BLUEMAP:
+ pmapDst->freeBlue -= nalloc;
+ pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
+ pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
+ pmapSrc->numPixelsBlue[client] = 0;
+ break;
+ }
+}
+
+/* Free the ith entry in a color map. Must handle freeing of
+ * colors allocated through AllocColorPlanes */
+static void
+FreeCell (ColormapPtr pmap, Pixel i, int channel)
+{
+ EntryPtr pent;
+ int *pCount;
+
+
+ switch (channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ case REDMAP:
+ pent = (EntryPtr) &pmap->red[i];
+ pCount = &pmap->freeRed;
+ break;
+ case GREENMAP:
+ pent = (EntryPtr) &pmap->green[i];
+ pCount = &pmap->freeGreen;
+ break;
+ case BLUEMAP:
+ pent = (EntryPtr) &pmap->blue[i];
+ pCount = &pmap->freeBlue;
+ break;
+ }
+ /* If it's not privately allocated and it's not time to free it, just
+ * decrement the count */
+ if (pent->refcnt > 1)
+ pent->refcnt--;
+ else
+ {
+ /* If the color type is shared, find the sharedcolor. If decremented
+ * refcnt is 0, free the shared cell. */
+ if (pent->fShared)
+ {
+ if(--pent->co.shco.red->refcnt == 0)
+ free(pent->co.shco.red);
+ if(--pent->co.shco.green->refcnt == 0)
+ free(pent->co.shco.green);
+ if(--pent->co.shco.blue->refcnt == 0)
+ free(pent->co.shco.blue);
+ pent->fShared = FALSE;
+ }
+ pent->refcnt = 0;
+ *pCount += 1;
+ }
+}
+
+static void
+UpdateColors (ColormapPtr pmap)
+{
+ xColorItem *defs;
+ register xColorItem *pdef;
+ register EntryPtr pent;
+ register VisualPtr pVisual;
+ int i, n, size;
+
+ pVisual = pmap->pVisual;
+ size = pVisual->ColormapEntries;
+ defs = (xColorItem *)malloc(size * sizeof(xColorItem));
+ if (!defs)
+ return;
+ n = 0;
+ pdef = defs;
+ if (pmap->class == DirectColor)
+ {
+ for (i = 0; i < size; i++)
+ {
+ if (!pmap->red[i].refcnt &&
+ !pmap->green[i].refcnt &&
+ !pmap->blue[i].refcnt)
+ continue;
+ pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
+ ((Pixel)i << pVisual->offsetGreen) |
+ ((Pixel)i << pVisual->offsetBlue);
+ pdef->red = pmap->red[i].co.local.red;
+ pdef->green = pmap->green[i].co.local.green;
+ pdef->blue = pmap->blue[i].co.local.blue;
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ else
+ {
+ for (i = 0, pent = pmap->red; i < size; i++, pent++)
+ {
+ if (!pent->refcnt)
+ continue;
+ pdef->pixel = i;
+ if(pent->fShared)
+ {
+ pdef->red = pent->co.shco.red->color;
+ pdef->green = pent->co.shco.green->color;
+ pdef->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ pdef->red = pent->co.local.red;
+ pdef->green = pent->co.local.green;
+ pdef->blue = pent->co.local.blue;
+ }
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ if (n)
+ (*pmap->pScreen->StoreColors)(pmap, n, defs);
+ free(defs);
+}
+
+/* Get a read-only color from a ColorMap (probably slow for large maps)
+ * Returns by changing the value in pred, pgreen, pblue and pPix
+ */
+int
+AllocColor (ColormapPtr pmap,
+ unsigned short *pred, unsigned short *pgreen, unsigned short *pblue,
+ Pixel *pPix, int client)
+{
+ Pixel pixR, pixG, pixB;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+ int npix;
+ Pixel *ppix;
+
+ pVisual = pmap->pVisual;
+ (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
+ rgb.red = *pred;
+ rgb.green = *pgreen;
+ rgb.blue = *pblue;
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ /* If the colormap is being created, then we want to be able to change
+ * the colormap, even if it's a static type. Otherwise, we'd never be
+ * able to initialize static colormaps
+ */
+ if(pmap->flags & BeingCreated)
+ class |= DynamicClass;
+
+ /* If this is one of the static storage classes, and we're not initializing
+ * it, the best we can do is to find the closest color entry to the
+ * requested one and return that.
+ */
+ switch (class) {
+ case StaticColor:
+ case StaticGray:
+ /* Look up all three components in the same pmap */
+ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->red[pixR].co.local.green;
+ *pblue = pmap->red[pixR].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ *pPix = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue) |
+ ALPHAMASK(pVisual);
+
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->green[pixG].co.local.green;
+ *pblue = pmap->blue[pixB].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ npix = pmap->numPixelsGreen[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixG;
+ pmap->clientPixelsGreen[client] = ppix;
+ npix = pmap->numPixelsBlue[client];
+ ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixB;
+ pmap->clientPixelsBlue[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ pmap->numPixelsGreen[client]++;
+ pmap->numPixelsBlue[client]++;
+ break;
+
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap = (ColormapPtr)
+ SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
+ RT_COLORMAP, DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ pPix, PSEUDOMAP, AllComp);
+ }
+ if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
+ client, AllComp) != Success)
+ return (BadAlloc);
+ break;
+
+ case DirectColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap = (ColormapPtr)
+ SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
+ RT_COLORMAP, DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ {
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ &pixR, REDMAP, RedComp);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
+ &pixG, GREENMAP, GreenComp);
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
+ &pixB, BLUEMAP, BlueComp);
+ *pPix = pixR | pixG | pixB;
+ }
+ }
+
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ client, RedComp) != Success)
+ return (BadAlloc);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, client, GreenComp) != Success)
+ {
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ client, BlueComp) != Success)
+ {
+ (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
+
+ break;
+ }
+
+ /* if this is the client's first pixel in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((pmap->numPixelsRed[client] == 1) &&
+ (CLIENT_ID(pmap->mid) != client) &&
+ !(pmap->flags & BeingCreated))
+ {
+ colorResource *pcr;
+
+ pcr = (colorResource *) malloc(sizeof(colorResource));
+ if (!pcr)
+ {
+ (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
+ return (BadAlloc);
+ }
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *)pcr))
+ return (BadAlloc);
+ }
+ return (Success);
+}
+
+/*
+ * FakeAllocColor -- fake an AllocColor request by
+ * returning a free pixel if availible, otherwise returning
+ * the closest matching pixel. This is used by the mi
+ * software sprite code to recolor cursors. A nice side-effect
+ * is that this routine will never return failure.
+ */
+
+void
+FakeAllocColor (register ColormapPtr pmap, register xColorItem *item)
+{
+ Pixel pixR, pixG, pixB;
+ Pixel temp;
+ int entries;
+ xrgb rgb;
+ int class;
+ register VisualPtr pVisual;
+
+ pVisual = pmap->pVisual;
+ rgb.red = item->red;
+ rgb.green = item->green;
+ rgb.blue = item->blue;
+ (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ switch (class) {
+ case GrayScale:
+ case PseudoColor:
+ item->pixel = 0;
+ if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
+ -1, AllComp) == Success) {
+ item->pixel = temp;
+ break;
+ }
+ /* fall through ... */
+ case StaticColor:
+ case StaticGray:
+ item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ break;
+
+ case DirectColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ -1, RedComp) != Success)
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
+ << pVisual->offsetRed;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, -1, GreenComp) != Success)
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
+ GREENMAP) << pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ -1, BlueComp) != Success)
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
+ << pVisual->offsetBlue;
+ item->pixel = pixR | pixG | pixB;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ item->pixel = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue);
+ break;
+ }
+}
+
+/* free a pixel value obtained from FakeAllocColor */
+void
+FakeFreeColor(register ColormapPtr pmap, Pixel pixel)
+{
+ register VisualPtr pVisual;
+ Pixel pixR, pixG, pixB;
+
+ switch (pmap->class) {
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->red[pixel].refcnt == AllocTemporary)
+ pmap->red[pixel].refcnt = 0;
+ break;
+ case DirectColor:
+ pVisual = pmap->pVisual;
+ pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pmap->red[pixR].refcnt == AllocTemporary)
+ pmap->red[pixR].refcnt = 0;
+ if (pmap->green[pixG].refcnt == AllocTemporary)
+ pmap->green[pixG].refcnt = 0;
+ if (pmap->blue[pixB].refcnt == AllocTemporary)
+ pmap->blue[pixB].refcnt = 0;
+ break;
+ }
+}
+
+typedef unsigned short BigNumUpper;
+typedef unsigned long BigNumLower;
+
+#define BIGNUMLOWERBITS 24
+#define BIGNUMUPPERBITS 16
+#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
+#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
+#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
+#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
+
+typedef struct _bignum {
+ BigNumUpper upper;
+ BigNumLower lower;
+} BigNumRec, *BigNumPtr;
+
+#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
+ ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
+
+#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
+ ((r)->lower = LOWERPART(u)))
+
+#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
+ ((r)->lower = BIGNUMLOWER-1))
+
+static void
+BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
+{
+ BigNumLower lower, carry = 0;
+
+ lower = x->lower + y->lower;
+ if (lower >= BIGNUMLOWER) {
+ lower -= BIGNUMLOWER;
+ carry = 1;
+ }
+ r->lower = lower;
+ r->upper = x->upper + y->upper + carry;
+}
+
+static Pixel
+FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
+{
+ EntryPtr pent;
+ Pixel pixel, final;
+ long dr, dg, db;
+ unsigned long sq;
+ BigNumRec minval, sum, temp;
+
+ final = 0;
+ MaxBigNum(&minval);
+ /* look for the minimal difference */
+ for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
+ {
+ dr = dg = db = 0;
+ switch(channel)
+ {
+ case PSEUDOMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ db = (long) pent->co.local.blue - prgb->blue;
+ case REDMAP:
+ dr = (long) pent->co.local.red - prgb->red;
+ break;
+ case GREENMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ break;
+ case BLUEMAP:
+ db = (long) pent->co.local.blue - prgb->blue;
+ break;
+ }
+ sq = dr * dr;
+ UnsignedToBigNum (sq, &sum);
+ sq = dg * dg;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ sq = db * db;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ if (BigNumGreater (&minval, &sum))
+ {
+ final = pixel;
+ minval = sum;
+ }
+ }
+ return(final);
+}
+
+static void
+FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size,
+ xrgb *prgb, Pixel *pPixel, int channel,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Pixel pixel;
+ int count;
+
+ if ((pixel = *pPixel) >= size)
+ pixel = 0;
+ for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
+ {
+ if (pent->refcnt > 0 && (*comp) (pent, prgb))
+ {
+ switch (channel)
+ {
+ case REDMAP:
+ pixel <<= pmap->pVisual->offsetRed;
+ break;
+ case GREENMAP:
+ pixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ pixel <<= pmap->pVisual->offsetBlue;
+ break;
+ default: /* PSEUDOMAP */
+ break;
+ }
+ *pPixel = pixel;
+ }
+ }
+}
+
+/* Tries to find a color in pmap that exactly matches the one requested in prgb
+ * if it can't it allocates one.
+ * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
+ * load *pPixel with that value, otherwise set it to 0
+ */
+int
+FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb,
+ Pixel *pPixel, int channel, int client,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Bool foundFree;
+ Pixel pixel, Free = 0;
+ int npix, count, *nump = NULL;
+ Pixel **pixp = NULL, *ppix;
+ xColorItem def;
+
+ foundFree = FALSE;
+
+ if((pixel = *pPixel) >= size)
+ pixel = 0;
+ /* see if there is a match, and also look for a free entry */
+ for (pent = pentFirst + pixel, count = size; --count >= 0; )
+ {
+ if (pent->refcnt > 0)
+ {
+ if ((*comp) (pent, prgb))
+ {
+ if (client >= 0)
+ pent->refcnt++;
+ *pPixel = pixel;
+ switch(channel)
+ {
+ case REDMAP:
+ *pPixel <<= pmap->pVisual->offsetRed;
+ case PSEUDOMAP:
+ break;
+ case GREENMAP:
+ *pPixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ *pPixel <<= pmap->pVisual->offsetBlue;
+ break;
+ }
+ goto gotit;
+ }
+ }
+ else if (!foundFree && pent->refcnt == 0)
+ {
+ Free = pixel;
+ foundFree = TRUE;
+ /* If we're initializing the colormap, then we are looking for
+ * the first free cell we can find, not to minimize the number
+ * of entries we use. So don't look any further. */
+ if(pmap->flags & BeingCreated)
+ break;
+ }
+ pixel++;
+ if(pixel >= size)
+ {
+ pent = pentFirst;
+ pixel = 0;
+ }
+ else
+ pent++;
+ }
+
+ /* If we got here, we didn't find a match. If we also didn't find
+ * a free entry, we're out of luck. Otherwise, we'll usurp a free
+ * entry and fill it in */
+ if (!foundFree)
+ return (BadAlloc);
+ pent = pentFirst + Free;
+ pent->fShared = FALSE;
+ pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
+
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ pent->co.local.red = prgb->red;
+ pent->co.local.green = prgb->green;
+ pent->co.local.blue = prgb->blue;
+ def.red = prgb->red;
+ def.green = prgb->green;
+ def.blue = prgb->blue;
+ def.flags = (DoRed|DoGreen|DoBlue);
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free;
+ break;
+
+ case REDMAP:
+ pent->co.local.red = prgb->red;
+ def.red = prgb->red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoRed;
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free << pmap->pVisual->offsetRed;
+ break;
+
+ case GREENMAP:
+ pent->co.local.green = prgb->green;
+ def.red = pmap->red[0].co.local.red;
+ def.green = prgb->green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoGreen;
+ if (client >= 0)
+ pmap->freeGreen--;
+ def.pixel = Free << pmap->pVisual->offsetGreen;
+ break;
+
+ case BLUEMAP:
+ pent->co.local.blue = prgb->blue;
+ def.red = pmap->red[0].co.local.red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = prgb->blue;
+ def.flags = DoBlue;
+ if (client >= 0)
+ pmap->freeBlue--;
+ def.pixel = Free << pmap->pVisual->offsetBlue;
+ break;
+ }
+ (*pmap->pScreen->StoreColors) (pmap, 1, &def);
+ pixel = Free;
+ *pPixel = def.pixel;
+
+gotit:
+ if (pmap->flags & BeingCreated || client == -1)
+ return(Success);
+ /* Now remember the pixel, for freeing later */
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ nump = pmap->numPixelsRed;
+ pixp = pmap->clientPixelsRed;
+ break;
+
+ case GREENMAP:
+ nump = pmap->numPixelsGreen;
+ pixp = pmap->clientPixelsGreen;
+ break;
+
+ case BLUEMAP:
+ nump = pmap->numPixelsBlue;
+ pixp = pmap->clientPixelsBlue;
+ break;
+ }
+ npix = nump[client];
+ ppix = (Pixel *) realloc (pixp[client], (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ {
+ pent->refcnt--;
+ if (!pent->fShared)
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->freeRed++;
+ break;
+ case GREENMAP:
+ pmap->freeGreen++;
+ break;
+ case BLUEMAP:
+ pmap->freeBlue++;
+ break;
+ }
+ return(BadAlloc);
+ }
+ ppix[npix] = pixel;
+ pixp[client] = ppix;
+ nump[client]++;
+
+ return(Success);
+}
+
+/* Comparison functions -- passed to FindColor to determine if an
+ * entry is already the color we're looking for or not */
+static int
+AllComp (EntryPtr pent, xrgb *prgb)
+{
+ if((pent->co.local.red == prgb->red) &&
+ (pent->co.local.green == prgb->green) &&
+ (pent->co.local.blue == prgb->blue) )
+ return (1);
+ return (0);
+}
+
+static int
+RedComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.red == prgb->red)
+ return (1);
+ return (0);
+}
+
+static int
+GreenComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.green == prgb->green)
+ return (1);
+ return (0);
+}
+
+static int
+BlueComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.blue == prgb->blue)
+ return (1);
+ return (0);
+}
+
+
+/* Read the color value of a cell */
+
+int
+QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList)
+{
+ Pixel *ppix, pixel;
+ xrgb *prgb;
+ VisualPtr pVisual;
+ EntryPtr pent;
+ Pixel i;
+ int errVal = Success;
+
+ pVisual = pmap->pVisual;
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel & rgbbad) {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (i >= numred)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->red = pmap->red[i].co.local.red;
+ i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (i >= numgreen)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->green = pmap->green[i].co.local.green;
+ i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (i >= numblue)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->blue = pmap->blue[i].co.local.blue;
+ }
+ }
+ else
+ {
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ }
+ else
+ {
+ pent = (EntryPtr)&pmap->red[pixel];
+ if (pent->fShared)
+ {
+ prgb->red = pent->co.shco.red->color;
+ prgb->green = pent->co.shco.green->color;
+ prgb->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ prgb->red = pent->co.local.red;
+ prgb->green = pent->co.local.green;
+ prgb->blue = pent->co.local.blue;
+ }
+ }
+ }
+ }
+ return (errVal);
+}
+
+static void
+FreePixels(register ColormapPtr pmap, register int client)
+{
+ register Pixel *ppix, *ppixStart;
+ register int n;
+ int class;
+
+ class = pmap->class;
+ ppixStart = pmap->clientPixelsRed[client];
+ if (class & DynamicClass)
+ {
+ n = pmap->numPixelsRed[client];
+ for (ppix = ppixStart; --n >= 0; )
+ {
+ FreeCell(pmap, *ppix, REDMAP);
+ ppix++;
+ }
+ }
+
+ free(ppixStart);
+ pmap->clientPixelsRed[client] = (Pixel *) NULL;
+ pmap->numPixelsRed[client] = 0;
+ if ((class | DynamicClass) == DirectColor)
+ {
+ ppixStart = pmap->clientPixelsGreen[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
+ FreeCell(pmap, *ppix++, GREENMAP);
+ free(ppixStart);
+ pmap->clientPixelsGreen[client] = (Pixel *) NULL;
+ pmap->numPixelsGreen[client] = 0;
+
+ ppixStart = pmap->clientPixelsBlue[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
+ FreeCell(pmap, *ppix++, BLUEMAP);
+ free(ppixStart);
+ pmap->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmap->numPixelsBlue[client] = 0;
+ }
+}
+
+/**
+ * Frees all of a client's colors and cells.
+ *
+ * \param value must conform to DeleteType
+ * \unused fakeid
+ */
+int
+FreeClientPixels (void * value, XID fakeid)
+{
+ ColormapPtr pmap;
+ colorResource *pcr = (colorResource *)value;
+
+ pmap = (ColormapPtr) LookupIDByType(pcr->mid, RT_COLORMAP);
+ if (pmap)
+ FreePixels(pmap, pcr->client);
+ free(pcr);
+ return Success;
+}
+
+int
+AllocColorCells (int client, ColormapPtr pmap, int colors, int planes,
+ Bool contig, Pixel *ppix, Pixel *masks)
+{
+ Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
+ int n, class;
+ int ok;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (pmap->class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = (colorResource *) malloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (pmap->class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, planes, planes, planes,
+ contig, ppix, &rmask, &gmask, &bmask);
+ if(ok == Success)
+ {
+ for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
+ {
+ while(!(rmask & r))
+ r += r;
+ while(!(gmask & g))
+ g += g;
+ while(!(bmask & b))
+ b += b;
+ *masks++ = r | g | b;
+ }
+ }
+ }
+ else
+ {
+ ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
+ &ppixFirst);
+ if(ok == Success)
+ {
+ for (r = 1, n = planes; --n >= 0; r += r)
+ {
+ while(!(rmask & r))
+ r += r;
+ *masks++ = r;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ free(pcr);
+
+ return (ok);
+}
+
+
+int
+AllocColorPlanes (int client, ColormapPtr pmap, int colors,
+ int r, int g, int b, Bool contig, Pixel *pixels,
+ Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ int ok;
+ Pixel mask, *ppixFirst;
+ register Pixel shift;
+ register int i;
+ int class;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = (colorResource *) malloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
+ prmask, pgmask, pbmask);
+ }
+ else
+ {
+ /* Allocate the proper pixels */
+ /* XXX This is sort of bad, because of contig is set, we force all
+ * r + g + b bits to be contiguous. Should only force contiguity
+ * per mask
+ */
+ ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
+ &mask, &ppixFirst);
+
+ if(ok == Success)
+ {
+ /* now split that mask into three */
+ *prmask = *pgmask = *pbmask = 0;
+ shift = 1;
+ for (i = r; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *prmask |= shift;
+ }
+ for (i = g; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pgmask |= shift;
+ }
+ for (i = b; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pbmask |= shift;
+ }
+
+ /* set up the shared color cells */
+ if (!AllocShared(pmap, pixels, colors, r, g, b,
+ *prmask, *pgmask, *pbmask, ppixFirst))
+ {
+ (void)FreeColors(pmap, client, colors, pixels, mask);
+ ok = BadAlloc;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (void *)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ free(pcr);
+
+ return (ok);
+}
+
+static int
+AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig,
+ Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ Pixel *ppixRed, *ppixGreen, *ppixBlue;
+ Pixel *ppix, *pDst, *p;
+ int npix, npixR, npixG, npixB;
+ Bool okR, okG, okB;
+ Pixel *rpix = 0, *gpix = 0, *bpix = 0;
+
+ npixR = c << r;
+ npixG = c << g;
+ npixB = c << b;
+ if ((r >= 32) || (g >= 32) || (b >= 32) ||
+ (npixR > pmap->freeRed) || (npixR < c) ||
+ (npixG > pmap->freeGreen) || (npixG < c) ||
+ (npixB > pmap->freeBlue) || (npixB < c))
+ return BadAlloc;
+
+ /* start out with empty pixels */
+ for(p = pixels; p < pixels + c; p++)
+ *p = 0;
+
+ ppixRed = (Pixel *)malloc(npixR * sizeof(Pixel));
+ ppixGreen = (Pixel *)malloc(npixG * sizeof(Pixel));
+ ppixBlue = (Pixel *)malloc(npixB * sizeof(Pixel));
+ if (!ppixRed || !ppixGreen || !ppixBlue)
+ {
+ if (ppixBlue) free(ppixBlue);
+ if (ppixGreen) free(ppixGreen);
+ if (ppixRed) free(ppixRed);
+ return(BadAlloc);
+ }
+
+ okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
+ okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
+ okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
+
+ if (okR && okG && okB)
+ {
+ rpix = (Pixel *) realloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + (c << r)) *
+ sizeof(Pixel));
+ if (rpix)
+ pmap->clientPixelsRed[client] = rpix;
+ gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client],
+ (pmap->numPixelsGreen[client] + (c << g)) *
+ sizeof(Pixel));
+ if (gpix)
+ pmap->clientPixelsGreen[client] = gpix;
+ bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client],
+ (pmap->numPixelsBlue[client] + (c << b)) *
+ sizeof(Pixel));
+ if (bpix)
+ pmap->clientPixelsBlue[client] = bpix;
+ }
+
+ if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
+ {
+ if (okR)
+ for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
+ pmap->red[*ppix].refcnt = 0;
+ if (okG)
+ for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
+ pmap->green[*ppix].refcnt = 0;
+ if (okB)
+ for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
+ pmap->blue[*ppix].refcnt = 0;
+ free(ppixBlue);
+ free(ppixGreen);
+ free(ppixRed);
+ return(BadAlloc);
+ }
+
+ *prmask <<= pmap->pVisual->offsetRed;
+ *pgmask <<= pmap->pVisual->offsetGreen;
+ *pbmask <<= pmap->pVisual->offsetBlue;
+
+ ppix = rpix + pmap->numPixelsRed[client];
+ for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixRed + c)
+ *pDst++ |= *p << pmap->pVisual->offsetRed;
+ }
+ pmap->numPixelsRed[client] += npixR;
+ pmap->freeRed -= npixR;
+
+ ppix = gpix + pmap->numPixelsGreen[client];
+ for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixGreen + c)
+ *pDst++ |= *p << pmap->pVisual->offsetGreen;
+ }
+ pmap->numPixelsGreen[client] += npixG;
+ pmap->freeGreen -= npixG;
+
+ ppix = bpix + pmap->numPixelsBlue[client];
+ for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixBlue + c)
+ *pDst++ |= *p << pmap->pVisual->offsetBlue;
+ }
+ pmap->numPixelsBlue[client] += npixB;
+ pmap->freeBlue -= npixB;
+
+
+ for (pDst = pixels; pDst < pixels + c; pDst++)
+ *pDst |= ALPHAMASK(pmap->pVisual);
+
+ free(ppixBlue);
+ free(ppixGreen);
+ free(ppixRed);
+
+ return (Success);
+}
+
+static int
+AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig,
+ Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
+{
+ Pixel *ppix, *p, *pDst, *ppixTemp;
+ int npix;
+ Bool ok;
+
+ npix = c << r;
+ if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
+ return(BadAlloc);
+ if(!(ppixTemp = (Pixel *)malloc(npix * sizeof(Pixel))))
+ return(BadAlloc);
+ ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
+
+ if (ok)
+ {
+
+ /* all the allocated pixels are added to the client pixel list,
+ * but only the unique ones are returned to the client */
+ ppix = (Pixel *)realloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
+ if (!ppix)
+ {
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ pmap->red[*p].refcnt = 0;
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ ppix += pmap->numPixelsRed[client];
+ *pppixFirst = ppix;
+ pDst = pixels;
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixTemp + c)
+ *pDst++ = *p;
+ }
+ pmap->numPixelsRed[client] += npix;
+ pmap->freeRed -= npix;
+ }
+ free(ppixTemp);
+ return (ok ? Success : BadAlloc);
+}
+
+/* Allocates count << planes pixels from colormap pmap for client. If
+ * contig, then the plane mask is made of consecutive bits. Returns
+ * all count << pixels in the array pixels. The first count of those
+ * pixels are the unique pixels. *pMask has the mask to Or with the
+ * unique pixels to get the rest of them.
+ *
+ * Returns True iff all pixels could be allocated
+ * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
+ * (see AllocShared for why we care)
+ */
+static Bool
+AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes,
+ Bool contig, Pixel *pixels, Pixel *pMask)
+{
+ EntryPtr ent;
+ Pixel pixel, base, entries, maxp, save;
+ int dplanes, found;
+ Pixel *ppix;
+ Pixel mask;
+ Pixel finalmask;
+
+ dplanes = pmap->pVisual->nplanes;
+
+ /* Easy case. Allocate pixels only */
+ if (planes == 0)
+ {
+ /* allocate writable entries */
+ ppix = pixels;
+ ent = pentFirst;
+ pixel = 0;
+ while (--count >= 0)
+ {
+ /* Just find count unallocated cells */
+ while (ent->refcnt)
+ {
+ ent++;
+ pixel++;
+ }
+ ent->refcnt = AllocPrivate;
+ *ppix++ = pixel;
+ ent->fShared = FALSE;
+ }
+ *pMask = 0;
+ return (TRUE);
+ }
+ else if (planes > dplanes)
+ {
+ return (FALSE);
+ }
+
+ /* General case count pixels * 2 ^ planes cells to be allocated */
+
+ /* make room for new pixels */
+ ent = pentFirst;
+
+ /* first try for contiguous planes, since it's fastest */
+ for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
+ --dplanes >= 0;
+ mask += mask, base += base)
+ {
+ ppix = pixels;
+ found = 0;
+ pixel = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ while (pixel < entries)
+ {
+ save = pixel;
+ maxp = pixel + mask + base;
+ /* check if all are free */
+ while (pixel != maxp && ent[pixel].refcnt == 0)
+ pixel += base;
+ if (pixel == maxp)
+ {
+ /* this one works */
+ *ppix++ = save;
+ found++;
+ if (found == count)
+ {
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = pixels[count];
+ maxp = pixel + mask;
+ while (1)
+ {
+ ent[pixel].refcnt = AllocPrivate;
+ ent[pixel].fShared = FALSE;
+ if (pixel == maxp)
+ break;
+ pixel += base;
+ *ppix++ = pixel;
+ }
+ }
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ pixel = save + 1;
+ if (pixel & mask)
+ pixel += mask;
+ }
+ }
+
+ dplanes = pmap->pVisual->nplanes;
+ if (contig || planes == 1 || dplanes < 3)
+ return (FALSE);
+
+ /* this will be very slow for large maps, need a better algorithm */
+
+ /*
+ we can generate the smallest and largest numbers that fits in dplanes
+ bits and contain exactly planes bits set as follows. First, we need to
+ check that it is possible to generate such a mask at all.
+ (Non-contiguous masks need one more bit than contiguous masks). Then
+ the smallest such mask consists of the rightmost planes-1 bits set, then
+ a zero, then a one in position planes + 1. The formula is
+ (3 << (planes-1)) -1
+ The largest such masks consists of the leftmost planes-1 bits set, then
+ a zero, then a one bit in position dplanes-planes-1. If dplanes is
+ smaller than 32 (the number of bits in a word) then the formula is:
+ (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
+ If dplanes = 32, then we can't calculate (1<<dplanes) and we have
+ to use:
+ ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
+
+ << Thank you, Loretta>>>
+
+ */
+
+ finalmask =
+ (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
+ (((Pixel)1)<<(dplanes-planes-1));
+ for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
+ {
+ /* next 3 magic statements count number of ones (HAKMEM #169) */
+ pixel = (mask >> 1) & 033333333333;
+ pixel = mask - pixel - ((pixel >> 1) & 033333333333);
+ if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
+ continue;
+ ppix = pixels;
+ found = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ base = lowbit (mask);
+ for (pixel = 0; pixel < entries; pixel++)
+ {
+ if (pixel & mask)
+ continue;
+ maxp = 0;
+ /* check if all are free */
+ while (ent[pixel + maxp].refcnt == 0)
+ {
+ GetNextBitsOrBreak(maxp, mask, base);
+ }
+ if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
+ continue;
+ /* this one works */
+ *ppix++ = pixel;
+ found++;
+ if (found < count)
+ continue;
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = (pixels)[count];
+ maxp = 0;
+ while (1)
+ {
+ ent[pixel + maxp].refcnt = AllocPrivate;
+ ent[pixel + maxp].fShared = FALSE;
+ GetNextBitsOrBreak(maxp, mask, base);
+ *ppix++ = pixel + maxp;
+ }
+ }
+
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+}
+
+/**
+ *
+ * \param ppixFirst First of the client's new pixels
+ */
+static Bool
+AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b,
+ Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
+{
+ Pixel *pptr, *cptr;
+ int npix, z, npixClientNew, npixShared;
+ Pixel basemask, base, bits, common;
+ SHAREDCOLOR *pshared, **ppshared, **psharedList;
+
+ npixClientNew = c << (r + g + b);
+ npixShared = (c << r) + (c << g) + (c << b);
+ psharedList = (SHAREDCOLOR **)malloc(npixShared *
+ sizeof(SHAREDCOLOR *));
+ if (!psharedList)
+ return FALSE;
+ ppshared = psharedList;
+ for (z = npixShared; --z >= 0; )
+ {
+ if (!(ppshared[z] = (SHAREDCOLOR *)malloc(sizeof(SHAREDCOLOR))))
+ {
+ for (z++ ; z < npixShared; z++)
+ free(ppshared[z]);
+ return FALSE;
+ }
+ }
+ for(pptr = ppix, npix = c; --npix >= 0; pptr++)
+ {
+ basemask = ~(gmask | bmask);
+ common = *pptr & basemask;
+ if (rmask)
+ {
+ bits = 0;
+ base = lowbit (rmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, rmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | bmask);
+ common = *pptr & basemask;
+ if (gmask)
+ {
+ bits = 0;
+ base = lowbit (gmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, gmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | gmask);
+ common = *pptr & basemask;
+ if (bmask)
+ {
+ bits = 0;
+ base = lowbit (bmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + g);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, bmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ }
+ }
+ free(psharedList);
+ return TRUE;
+}
+
+
+/** FreeColors
+ * Free colors and/or cells (probably slow for large numbers)
+ */
+int
+FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
+{
+ int rval, result, class;
+ Pixel rmask;
+
+ class = pmap->class;
+ if (pmap->flags & AllAllocated)
+ return(BadAccess);
+ if ((class | DynamicClass) == DirectColor)
+ {
+ rmask = mask & RGBMASK(pmap->pVisual);
+ result = FreeCo(pmap, client, REDMAP, count, pixels,
+ mask & pmap->pVisual->redMask);
+ /* If any of the three calls fails, we must report that, if more
+ * than one fails, it's ok that we report the last one */
+ rval = FreeCo(pmap, client, GREENMAP, count, pixels,
+ mask & pmap->pVisual->greenMask);
+ if(rval != Success)
+ result = rval;
+ rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
+ mask & pmap->pVisual->blueMask);
+ if(rval != Success)
+ result = rval;
+ }
+ else
+ {
+ rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
+ result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
+ }
+ if ((mask != rmask) && count)
+ {
+ clientErrorValue = *pixels | mask;
+ result = BadValue;
+ }
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return (result);
+}
+
+/**
+ * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
+ * which the client has allocated in channel colormap cells of pmap.
+ * doesn't change newpixels if it doesn't need to
+ *
+ * \param pmap which colormap head
+ * \param color which sub-map, eg, RED, BLUE, PSEUDO
+ * \param npixIn number of pixels passed in
+ * \param ppixIn number of base pixels
+ * \param mask mask client gave us
+ */
+static int
+FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
+{
+ Pixel *ppixClient, pixTest;
+ int npixClient, npixNew, npix;
+ Pixel bits, base, cmask, rgbbad;
+ Pixel *pptr, *cptr;
+ int n, zapped;
+ int errVal = Success;
+ int offset, numents;
+
+ if (npixIn == 0)
+ return (errVal);
+ bits = 0;
+ zapped = 0;
+ base = lowbit (mask);
+
+ switch(color)
+ {
+ case REDMAP:
+ cmask = pmap->pVisual->redMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetRed;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ case GREENMAP:
+ cmask = pmap->pVisual->greenMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetGreen;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsGreen[client];
+ npixClient = pmap->numPixelsGreen[client];
+ break;
+ case BLUEMAP:
+ cmask = pmap->pVisual->blueMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetBlue;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsBlue[client];
+ npixClient = pmap->numPixelsBlue[client];
+ break;
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ cmask = ~((Pixel)0);
+ rgbbad = 0;
+ offset = 0;
+ numents = pmap->pVisual->ColormapEntries;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ }
+
+ /* zap all pixels which match */
+ while (1)
+ {
+ /* go through pixel list */
+ for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
+ {
+ pixTest = ((*pptr | bits) & cmask) >> offset;
+ if ((pixTest >= numents) || (*pptr & rgbbad))
+ {
+ clientErrorValue = *pptr | bits;
+ errVal = BadValue;
+ continue;
+ }
+
+ /* find match in client list */
+ for (cptr = ppixClient, npix = npixClient;
+ --npix >= 0 && *cptr != pixTest;
+ cptr++) ;
+
+ if (npix >= 0)
+ {
+ if (pmap->class & DynamicClass)
+ {
+ FreeCell(pmap, pixTest, color);
+ }
+ *cptr = ~((Pixel)0);
+ zapped++;
+ }
+ else
+ errVal = BadAccess;
+ }
+ /* generate next bits value */
+ GetNextBitsOrBreak(bits, mask, base);
+ }
+
+ /* delete freed pixels from client pixel list */
+ if (zapped)
+ {
+ npixNew = npixClient - zapped;
+ if (npixNew)
+ {
+ /* Since the list can only get smaller, we can do a copy in
+ * place and then realloc to a smaller size */
+ pptr = cptr = ppixClient;
+
+ /* If we have all the new pixels, we don't have to examine the
+ * rest of the old ones */
+ for(npix = 0; npix < npixNew; cptr++)
+ {
+ if (*cptr != ~((Pixel)0))
+ {
+ *pptr++ = *cptr;
+ npix++;
+ }
+ }
+ pptr = (Pixel *)realloc(ppixClient, npixNew * sizeof(Pixel));
+ if (pptr)
+ ppixClient = pptr;
+ npixClient = npixNew;
+ }
+ else
+ {
+ npixClient = 0;
+ free(ppixClient);
+ ppixClient = (Pixel *)NULL;
+ }
+ switch(color)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->clientPixelsRed[client] = ppixClient;
+ pmap->numPixelsRed[client] = npixClient;
+ break;
+ case GREENMAP:
+ pmap->clientPixelsGreen[client] = ppixClient;
+ pmap->numPixelsGreen[client] = npixClient;
+ break;
+ case BLUEMAP:
+ pmap->clientPixelsBlue[client] = ppixClient;
+ pmap->numPixelsBlue[client] = npixClient;
+ break;
+ }
+ }
+ return (errVal);
+}
+
+
+
+/* Redefine color values */
+int
+StoreColors (ColormapPtr pmap, int count, xColorItem *defs)
+{
+ register Pixel pix;
+ register xColorItem *pdef;
+ register EntryPtr pent, pentT, pentLast;
+ register VisualPtr pVisual;
+ SHAREDCOLOR *pred, *pgreen, *pblue;
+ int n, ChgRed, ChgGreen, ChgBlue, idef;
+ int class, errVal = Success;
+ int ok;
+
+
+ class = pmap->class;
+ if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
+ {
+ return(BadAccess);
+ }
+ pVisual = pmap->pVisual;
+
+ idef = 0;
+ if((class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+ ok = TRUE;
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ if (pdef->pixel & rgbbad)
+ {
+ errVal = BadValue;
+ clientErrorValue = pdef->pixel;
+ continue;
+ }
+ pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (pix >= numred)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoRed)
+ {
+ pmap->red[pix].co.local.red = pdef->red;
+ }
+ else
+ {
+ pdef->red = pmap->red[pix].co.local.red;
+ }
+
+ pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (pix >= numgreen)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->green[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoGreen)
+ {
+ pmap->green[pix].co.local.green = pdef->green;
+ }
+ else
+ {
+ pdef->green = pmap->green[pix].co.local.green;
+ }
+
+ pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pix >= numblue)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->blue[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoBlue)
+ {
+ pmap->blue[pix].co.local.blue = pdef->blue;
+ }
+ else
+ {
+ pdef->blue = pmap->blue[pix].co.local.blue;
+ }
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ } else
+ clientErrorValue = pdef->pixel;
+ }
+ }
+ else
+ {
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+
+ ok = TRUE;
+ if (pdef->pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pdef->pixel;
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ }
+ else
+ continue;
+
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ pent = &pmap->red[pdef->pixel];
+
+ if(pdef->flags & DoRed)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.red->color = pdef->red;
+ if (pent->co.shco.red->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.red = pdef->red;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->red = pent->co.shco.red->color;
+ else
+ pdef->red = pent->co.local.red;
+ }
+ if(pdef->flags & DoGreen)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.green->color = pdef->green;
+ if (pent->co.shco.green->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.green = pdef->green;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->green = pent->co.shco.green->color;
+ else
+ pdef->green = pent->co.local.green;
+ }
+ if(pdef->flags & DoBlue)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.blue->color = pdef->blue;
+ if (pent->co.shco.blue->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.blue = pdef->blue;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->blue = pent->co.shco.blue->color;
+ else
+ pdef->blue = pent->co.local.blue;
+ }
+
+ if(!ok)
+ {
+ /* have to run through the colormap and change anybody who
+ * shares this value */
+ pred = pent->co.shco.red;
+ pgreen = pent->co.shco.green;
+ pblue = pent->co.shco.blue;
+ ChgRed = pdef->flags & DoRed;
+ ChgGreen = pdef->flags & DoGreen;
+ ChgBlue = pdef->flags & DoBlue;
+ pentLast = pmap->red + pVisual->ColormapEntries;
+
+ for(pentT = pmap->red; pentT < pentLast; pentT++)
+ {
+ if(pentT->fShared && (pentT != pent))
+ {
+ xColorItem defChg;
+
+ /* There are, alas, devices in this world too dumb
+ * to read their own hardware colormaps. Sick, but
+ * true. So we're going to be really nice and load
+ * the xColorItem with the proper value for all the
+ * fields. We will only set the flags for those
+ * fields that actually change. Smart devices can
+ * arrange to change only those fields. Dumb devices
+ * can rest assured that we have provided for them,
+ * and can change all three fields */
+
+ defChg.flags = 0;
+ if(ChgRed && pentT->co.shco.red == pred)
+ {
+ defChg.flags |= DoRed;
+ }
+ if(ChgGreen && pentT->co.shco.green == pgreen)
+ {
+ defChg.flags |= DoGreen;
+ }
+ if(ChgBlue && pentT->co.shco.blue == pblue)
+ {
+ defChg.flags |= DoBlue;
+ }
+ if(defChg.flags != 0)
+ {
+ defChg.pixel = pentT - pmap->red;
+ defChg.red = pentT->co.shco.red->color;
+ defChg.green = pentT->co.shco.green->color;
+ defChg.blue = pentT->co.shco.blue->color;
+ (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ /* Note that we use idef, the count of acceptable entries, and not
+ * count, the count of proposed entries */
+ if (idef != 0)
+ ( *pmap->pScreen->StoreColors) (pmap, idef, defs);
+ return (errVal);
+}
+
+int
+IsMapInstalled(Colormap map, WindowPtr pWin)
+{
+ Colormap *pmaps;
+ int imap, nummaps, found;
+
+ pmaps = (Colormap *) malloc(
+ pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap));
+ if(!pmaps)
+ return(FALSE);
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, pmaps);
+ found = FALSE;
+ for(imap = 0; imap < nummaps; imap++)
+ {
+ if(pmaps[imap] == map)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ free(pmaps);
+ return (found);
+}
+
+struct colormap_lookup_data {
+ ScreenPtr pScreen;
+ VisualPtr visuals;
+};
+
+static void
+_colormap_find_resource(void *value, XID id, void *cdata)
+{
+ struct colormap_lookup_data *cmap_data = cdata;
+ VisualPtr visuals = cmap_data->visuals;
+ ScreenPtr pScreen = cmap_data->pScreen;
+ ColormapPtr cmap = value;
+ int j;
+
+ if (pScreen != cmap->pScreen)
+ return;
+
+ j = cmap->pVisual - pScreen->visuals;
+ cmap->pVisual = &visuals[j];
+}
+
+/* something has realloced the visuals, instead of breaking
+ ABI fix it up here - glx and compsite did this wrong */
+Bool
+ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth)
+{
+ struct colormap_lookup_data cdata;
+ int numVisuals;
+ VisualPtr visuals;
+ XID *vids, vid;
+ int first_new_vid, first_new_visual, i;
+
+ first_new_vid = depth->numVids;
+ first_new_visual = pScreen->numVisuals;
+
+ vids = reallocarray(depth->vids, depth->numVids + new_visual_count,
+ sizeof(XID));
+ if (!vids)
+ return FALSE;
+
+ /* its realloced now no going back if we fail the next one */
+ depth->vids = vids;
+
+ numVisuals = pScreen->numVisuals + new_visual_count;
+ visuals = reallocarray(pScreen->visuals, numVisuals, sizeof(VisualRec));
+ if (!visuals) {
+ return FALSE;
+ }
+
+ cdata.visuals = visuals;
+ cdata.pScreen = pScreen;
+ FindClientResourcesByType(serverClient, RT_COLORMAP,
+ _colormap_find_resource, &cdata);
+
+ pScreen->visuals = visuals;
+
+ for (i = 0; i < new_visual_count; i++) {
+ vid = FakeClientID(0);
+ pScreen->visuals[first_new_visual + i].vid = vid;
+ vids[first_new_vid + i] = vid;
+ }
+
+ depth->numVids += new_visual_count;
+ pScreen->numVisuals += new_visual_count;
+
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/dix/cursor.c b/nx-X11/programs/Xserver/dix/cursor.c
new file mode 100644
index 000000000..a1bf6a7ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/cursor.c
@@ -0,0 +1,457 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "dixfontstr.h"
+#include "opaque.h"
+
+typedef struct _GlyphShare {
+ FontPtr font;
+ unsigned short sourceChar;
+ unsigned short maskChar;
+ CursorBitsPtr bits;
+ struct _GlyphShare *next;
+} GlyphShare, *GlyphSharePtr;
+
+static GlyphSharePtr sharedGlyphs = (GlyphSharePtr)NULL;
+
+#ifdef XFIXES
+static CARD32 cursorSerial;
+#endif
+
+static void
+FreeCursorBits(CursorBitsPtr bits)
+{
+ if (--bits->refcnt > 0)
+ return;
+ free(bits->source);
+ free(bits->mask);
+#ifdef ARGB_CURSOR
+ free(bits->argb);
+#endif
+ if (bits->refcnt == 0)
+ {
+ register GlyphSharePtr *prev, this;
+
+ for (prev = &sharedGlyphs;
+ (this = *prev) && (this->bits != bits);
+ prev = &this->next)
+ ;
+ if (this)
+ {
+ *prev = this->next;
+ CloseFont(this->font, (Font)0);
+ free(this);
+ }
+ free(bits);
+ }
+}
+
+/**
+ * To be called indirectly by DeleteResource; must use exactly two args.
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeCursor(void * value, XID cid)
+{
+ int nscr;
+ CursorPtr pCurs = (CursorPtr)value;
+
+ ScreenPtr pscr;
+
+ if ( --pCurs->refcnt > 0)
+ return(Success);
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ (void)( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ free( pCurs);
+ return(Success);
+}
+
+
+/*
+ * We check for empty cursors so that we won't have to display them
+ */
+static void
+CheckForEmptyMask(CursorBitsPtr bits)
+{
+ register unsigned char *msk = bits->mask;
+ int n = BitmapBytePad(bits->width) * bits->height;
+
+ bits->emptyMask = FALSE;
+ while(n--)
+ if(*(msk++) != 0) return;
+#ifdef ARGB_CURSOR
+ if (bits->argb)
+ {
+ CARD32 *argb = bits->argb;
+ int n = bits->width * bits->height;
+ while (n--)
+ if (*argb++ & 0xff000000) return;
+ }
+#endif
+ bits->emptyMask = TRUE;
+}
+
+/**
+ * does nothing about the resource table, just creates the data structure.
+ * does not copy the src and mask bits
+ *
+ * \param psrcbits server-defined padding
+ * \param pmaskbits server-defined padding
+ * \param argb no padding
+ */
+CursorPtr
+AllocCursorARGB(unsigned char *psrcbits, unsigned char *pmaskbits, CARD32 *argb,
+ CursorMetricPtr cm,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue)
+{
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+
+ pCurs = (CursorPtr)malloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (!pCurs)
+ {
+ free(psrcbits);
+ free(pmaskbits);
+ return (CursorPtr)NULL;
+ }
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ bits->source = psrcbits;
+ bits->mask = pmaskbits;
+#ifdef ARGB_CURSOR
+ bits->argb = argb;
+#endif
+ bits->width = cm->width;
+ bits->height = cm->height;
+ bits->xhot = cm->xhot;
+ bits->yhot = cm->yhot;
+ bits->refcnt = -1;
+ CheckForEmptyMask(bits);
+
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+#ifdef XFIXES
+ pCurs->serialNumber = ++cursorSerial;
+ pCurs->name = None;
+#endif
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(bits);
+ free(pCurs);
+ return (CursorPtr)NULL;
+ }
+ }
+ return pCurs;
+}
+
+/**
+ *
+ * \param psrcbits server-defined padding
+ * \param pmaskbits server-defined padding
+ */
+CursorPtr
+AllocCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
+ CursorMetricPtr cm,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue)
+{
+ return AllocCursorARGB (psrcbits, pmaskbits, (CARD32 *) 0, cm,
+ foreRed, foreGreen, foreBlue,
+ backRed, backGreen, backBlue);
+}
+
+int
+AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
+ unsigned foreRed, unsigned foreGreen, unsigned foreBlue,
+ unsigned backRed, unsigned backGreen, unsigned backBlue,
+ CursorPtr *ppCurs, ClientPtr client)
+{
+ FontPtr sourcefont, maskfont;
+ unsigned char *srcbits;
+ unsigned char *mskbits;
+ CursorMetricRec cm;
+ int res;
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+ GlyphSharePtr pShare;
+
+ sourcefont = (FontPtr) SecurityLookupIDByType(client, source, RT_FONT,
+ DixReadAccess);
+ maskfont = (FontPtr) SecurityLookupIDByType(client, mask, RT_FONT,
+ DixReadAccess);
+
+ if (!sourcefont)
+ {
+ client->errorValue = source;
+ return(BadFont);
+ }
+ if (!maskfont && (mask != None))
+ {
+ client->errorValue = mask;
+ return(BadFont);
+ }
+ if (sourcefont != maskfont)
+ pShare = (GlyphSharePtr)NULL;
+ else
+ {
+ for (pShare = sharedGlyphs;
+ pShare &&
+ ((pShare->font != sourcefont) ||
+ (pShare->sourceChar != sourceChar) ||
+ (pShare->maskChar != maskChar));
+ pShare = pShare->next)
+ ;
+ }
+ if (pShare)
+ {
+ pCurs = (CursorPtr)malloc(sizeof(CursorRec));
+ if (!pCurs)
+ return BadAlloc;
+ bits = pShare->bits;
+ bits->refcnt++;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm))
+ {
+ client->errorValue = sourceChar;
+ return BadValue;
+ }
+ if (!maskfont)
+ {
+ register long n;
+ register unsigned char *mskptr;
+
+ n = BitmapBytePad(cm.width)*(long)cm.height;
+ mskptr = mskbits = (unsigned char *)malloc(n);
+ if (!mskptr)
+ return BadAlloc;
+ while (--n >= 0)
+ *mskptr++ = ~0;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm))
+ {
+ client->errorValue = maskChar;
+ return BadValue;
+ }
+ if ((res = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits)) != 0)
+ return res;
+ }
+ if ((res = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits)) != 0)
+ {
+ free(mskbits);
+ return res;
+ }
+ if (sourcefont != maskfont)
+ {
+ pCurs = (CursorPtr)malloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (pCurs)
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ else
+ {
+ pCurs = (CursorPtr)malloc(sizeof(CursorRec));
+ if (pCurs)
+ bits = (CursorBitsPtr)malloc(sizeof(CursorBits));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ if (!bits)
+ {
+ free(pCurs);
+ free(mskbits);
+ free(srcbits);
+ return BadAlloc;
+ }
+ bits->source = srcbits;
+ bits->mask = mskbits;
+#ifdef ARGB_CURSOR
+ bits->argb = 0;
+#endif
+ bits->width = cm.width;
+ bits->height = cm.height;
+ bits->xhot = cm.xhot;
+ bits->yhot = cm.yhot;
+ if (sourcefont != maskfont)
+ bits->refcnt = -1;
+ else
+ {
+ bits->refcnt = 1;
+ pShare = (GlyphSharePtr)malloc(sizeof(GlyphShare));
+ if (!pShare)
+ {
+ FreeCursorBits(bits);
+ return BadAlloc;
+ }
+ pShare->font = sourcefont;
+ sourcefont->refcnt++;
+ pShare->sourceChar = sourceChar;
+ pShare->maskChar = maskChar;
+ pShare->bits = bits;
+ pShare->next = sharedGlyphs;
+ sharedGlyphs = pShare;
+ }
+ }
+ CheckForEmptyMask(bits);
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+#ifdef XFIXES
+ pCurs->serialNumber = ++cursorSerial;
+ pCurs->name = None;
+#endif
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ free(pCurs);
+ return BadAlloc;
+ }
+ }
+ *ppCurs = pCurs;
+ return Success;
+}
+
+/** CreateRootCursor
+ *
+ * look up the name of a font
+ * open the font
+ * add the font to the resource table
+ * make a cursor from the glyphs
+ * add the cursor to the resource table
+ *************************************************************/
+
+CursorPtr
+CreateRootCursor(char *pfilename, unsigned glyph)
+{
+ CursorPtr curs;
+ FontPtr cursorfont;
+ int err;
+ XID fontID;
+
+ fontID = FakeClientID(0);
+ err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync,
+ (unsigned)strlen( pfilename), pfilename);
+ if (err != Success)
+ return NullCursor;
+
+ cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT);
+ if (!cursorfont)
+ return NullCursor;
+ if (AllocGlyphCursor(fontID, glyph, fontID, glyph + 1,
+ 0, 0, 0, ~0, ~0, ~0, &curs, serverClient) != Success)
+ return NullCursor;
+
+ if (!AddResource(FakeClientID(0), RT_CURSOR, (void *)curs))
+ return NullCursor;
+
+ return curs;
+}
diff --git a/nx-X11/programs/Xserver/dix/devices.c b/nx-X11/programs/Xserver/dix/devices.c
new file mode 100644
index 000000000..d649a8657
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/devices.c
@@ -0,0 +1,1646 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <nx-X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "site.h"
+#ifdef XKB
+#include "xkbsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#include "dispatch.h"
+#include "swaprep.h"
+#include "dixevents.h"
+
+DeviceIntPtr
+_AddInputDevice(DeviceProc deviceProc, Bool autoStart)
+{
+ register DeviceIntPtr dev;
+
+ if (inputInfo.numDevices >= MAX_DEVICES)
+ return (DeviceIntPtr)NULL;
+ dev = (DeviceIntPtr) calloc(1, sizeof(DeviceIntRec));
+ if (!dev)
+ return (DeviceIntPtr)NULL;
+ dev->name = (char *)NULL;
+ dev->type = 0;
+ dev->id = inputInfo.numDevices;
+ inputInfo.numDevices++;
+ dev->public.on = FALSE;
+ dev->public.processInputProc = (ProcessInputProc)NoopDDA;
+ dev->public.realInputProc = (ProcessInputProc)NoopDDA;
+ dev->public.enqueueInputProc = EnqueueEvent;
+ dev->deviceProc = deviceProc;
+ dev->startup = autoStart;
+ dev->sync.frozen = FALSE;
+ dev->sync.other = NullGrab;
+ dev->sync.state = NOT_GRABBED;
+ dev->sync.event = (xEvent *) NULL;
+ dev->sync.evcount = 0;
+ dev->grab = NullGrab;
+ dev->grabTime = currentTime;
+ dev->fromPassiveGrab = FALSE;
+ dev->key = (KeyClassPtr)NULL;
+ dev->valuator = (ValuatorClassPtr)NULL;
+ dev->button = (ButtonClassPtr)NULL;
+ dev->focus = (FocusClassPtr)NULL;
+ dev->proximity = (ProximityClassPtr)NULL;
+ dev->kbdfeed = (KbdFeedbackPtr)NULL;
+ dev->ptrfeed = (PtrFeedbackPtr)NULL;
+ dev->intfeed = (IntegerFeedbackPtr)NULL;
+ dev->stringfeed = (StringFeedbackPtr)NULL;
+ dev->bell = (BellFeedbackPtr)NULL;
+ dev->leds = (LedFeedbackPtr)NULL;
+ dev->next = inputInfo.off_devices;
+#ifdef XKB
+ dev->xkb_interest= NULL;
+#endif
+ dev->nPrivates = 0;
+ dev->devPrivates = NULL;
+ dev->unwrapProc = NULL;
+ inputInfo.off_devices = dev;
+ return dev;
+}
+
+Bool
+EnableDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr *prev;
+
+ for (prev = &inputInfo.off_devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+ if ((*prev != dev) || !dev->inited ||
+ ((*dev->deviceProc)(dev, DEVICE_ON) != Success))
+ return FALSE;
+ *prev = dev->next;
+ dev->next = inputInfo.devices;
+ inputInfo.devices = dev;
+ return TRUE;
+}
+
+Bool
+DisableDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr *prev;
+
+ for (prev = &inputInfo.devices;
+ *prev && (*prev != dev);
+ prev = &(*prev)->next)
+ ;
+ if (*prev != dev)
+ return FALSE;
+ (void)(*dev->deviceProc)(dev, DEVICE_OFF);
+ *prev = dev->next;
+ dev->next = inputInfo.off_devices;
+ inputInfo.off_devices = dev;
+ return TRUE;
+}
+
+int
+InitAndStartDevices()
+{
+ register DeviceIntPtr dev, next;
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next)
+ dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
+ for (dev = inputInfo.off_devices; dev; dev = next)
+ {
+ next = dev->next;
+ if (dev->inited && dev->startup)
+ (void)EnableDevice(dev);
+ }
+ for (dev = inputInfo.devices;
+ dev && (dev != inputInfo.keyboard);
+ dev = dev->next)
+ ;
+ if (!dev || (dev != inputInfo.keyboard)) {
+ ErrorF("No core keyboard\n");
+ return BadImplementation;
+ }
+ for (dev = inputInfo.devices;
+ dev && (dev != inputInfo.pointer);
+ dev = dev->next)
+ ;
+ if (!dev || (dev != inputInfo.pointer)) {
+ ErrorF("No core pointer\n");
+ return BadImplementation;
+ }
+ return Success;
+}
+
+static void
+CloseDevice(register DeviceIntPtr dev)
+{
+ KbdFeedbackPtr k, knext;
+ PtrFeedbackPtr p, pnext;
+ IntegerFeedbackPtr i, inext;
+ StringFeedbackPtr s, snext;
+ BellFeedbackPtr b, bnext;
+ LedFeedbackPtr l, lnext;
+
+ if (dev->inited)
+ (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
+ free(dev->name);
+ if (dev->key)
+ {
+#ifdef XKB
+ if (dev->key->xkbInfo)
+ XkbFreeInfo(dev->key->xkbInfo);
+#endif
+ free(dev->key->curKeySyms.map);
+ free(dev->key->modifierKeyMap);
+ free(dev->key);
+ }
+ free(dev->valuator);
+#ifdef XKB
+ if ((dev->button)&&(dev->button->xkb_acts))
+ free(dev->button->xkb_acts);
+#endif
+ free(dev->button);
+ if (dev->focus)
+ {
+ free(dev->focus->trace);
+ free(dev->focus);
+ }
+ free(dev->proximity);
+ for (k=dev->kbdfeed; k; k=knext)
+ {
+ knext = k->next;
+#ifdef XKB
+ if (k->xkb_sli)
+ XkbFreeSrvLedInfo(k->xkb_sli);
+#endif
+ free(k);
+ }
+ for (p=dev->ptrfeed; p; p=pnext)
+ {
+ pnext = p->next;
+ free(p);
+ }
+ for (i=dev->intfeed; i; i=inext)
+ {
+ inext = i->next;
+ free(i);
+ }
+ for (s=dev->stringfeed; s; s=snext)
+ {
+ snext = s->next;
+ free(s->ctrl.symbols_supported);
+ free(s->ctrl.symbols_displayed);
+ free(s);
+ }
+ for (b=dev->bell; b; b=bnext)
+ {
+ bnext = b->next;
+ free(b);
+ }
+ for (l=dev->leds; l; l=lnext)
+ {
+ lnext = l->next;
+#ifdef XKB
+ if (l->xkb_sli)
+ XkbFreeSrvLedInfo(l->xkb_sli);
+#endif
+ free(l);
+ }
+#ifdef XKB
+ while (dev->xkb_interest) {
+ XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
+ }
+#endif
+ free(dev->sync.event);
+ free(dev);
+}
+
+void
+CloseDownDevices()
+{
+ register DeviceIntPtr dev, next;
+
+ for (dev = inputInfo.devices; dev; dev = next)
+ {
+ next = dev->next;
+ CloseDevice(dev);
+ }
+ for (dev = inputInfo.off_devices; dev; dev = next)
+ {
+ next = dev->next;
+ CloseDevice(dev);
+ }
+ inputInfo.devices = NULL;
+ inputInfo.off_devices = NULL;
+ inputInfo.keyboard = NULL;
+ inputInfo.pointer = NULL;
+}
+
+void
+RemoveDevice(register DeviceIntPtr dev)
+{
+ register DeviceIntPtr prev,tmp,next;
+
+ prev= NULL;
+ for (tmp= inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp==dev) {
+ CloseDevice(tmp);
+ if (prev==NULL)
+ inputInfo.devices = next;
+ else
+ prev->next = next;
+ inputInfo.numDevices--;
+ if (inputInfo.keyboard == tmp)
+ inputInfo.keyboard = NULL;
+ else if (inputInfo.pointer == tmp)
+ inputInfo.pointer = NULL;
+ return;
+ }
+ }
+
+ prev= NULL;
+ for (tmp= inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
+ next = tmp->next;
+ if (tmp==dev) {
+ CloseDevice(tmp);
+ if (prev==NULL)
+ inputInfo.off_devices = next;
+ else
+ prev->next = next;
+ inputInfo.numDevices--;
+ if (inputInfo.keyboard == tmp)
+ inputInfo.keyboard = NULL;
+ else if (inputInfo.pointer == tmp)
+ inputInfo.pointer = NULL;
+ return;
+ }
+ }
+ ErrorF("Internal Error! Attempt to remove a non-existent device\n");
+ return;
+}
+
+int
+NumMotionEvents()
+{
+ return inputInfo.pointer->valuator->numMotionEvents;
+}
+
+void
+_RegisterPointerDevice(DeviceIntPtr device)
+{
+ inputInfo.pointer = device;
+#ifdef XKB
+ device->public.processInputProc = CoreProcessPointerEvent;
+ device->public.realInputProc = CoreProcessPointerEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessPointerEvent);
+#else
+ device->public.processInputProc = ProcessPointerEvent;
+ device->public.realInputProc = ProcessPointerEvent;
+#endif
+ device->ActivateGrab = ActivatePointerGrab;
+ device->DeactivateGrab = DeactivatePointerGrab;
+ if (!device->name)
+ {
+ char *p = "pointer";
+ device->name = (char *)malloc(strlen(p) + 1);
+ strcpy(device->name, p);
+ }
+}
+
+void
+_RegisterKeyboardDevice(DeviceIntPtr device)
+{
+ inputInfo.keyboard = device;
+#ifdef XKB
+ device->public.processInputProc = CoreProcessKeyboardEvent;
+ device->public.realInputProc = CoreProcessKeyboardEvent;
+ if (!noXkbExtension)
+ XkbSetExtension(device,ProcessKeyboardEvent);
+#else
+ device->public.processInputProc = ProcessKeyboardEvent;
+ device->public.realInputProc = ProcessKeyboardEvent;
+#endif
+ device->ActivateGrab = ActivateKeyboardGrab;
+ device->DeactivateGrab = DeactivateKeyboardGrab;
+ if (!device->name)
+ {
+ char *k = "keyboard";
+ device->name = (char *)malloc(strlen(k) + 1);
+ strcpy(device->name, k);
+ }
+}
+
+DevicePtr
+LookupKeyboardDevice()
+{
+ return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
+}
+
+DevicePtr
+LookupPointerDevice()
+{
+ return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
+}
+
+DevicePtr
+LookupDevice(int id)
+{
+ DeviceIntPtr dev;
+
+ for (dev=inputInfo.devices; dev; dev=dev->next) {
+ if (dev->id == (CARD8)id)
+ return (DevicePtr)dev;
+ }
+ for (dev=inputInfo.off_devices; dev; dev=dev->next) {
+ if (dev->id == (CARD8)id)
+ return (DevicePtr)dev;
+ }
+ return NULL;
+}
+
+void
+QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
+{
+ if (inputInfo.keyboard) {
+ *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
+ *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
+ }
+}
+
+Bool
+SetKeySymsMap(register KeySymsPtr dst, register KeySymsPtr src)
+{
+ int i, j;
+ int rowDif = src->minKeyCode - dst->minKeyCode;
+ /* if keysym map size changes, grow map first */
+
+ if (src->mapWidth < dst->mapWidth)
+ {
+ for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
+ {
+#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
+#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
+ for (j = 0; j < src->mapWidth; j++)
+ dst->map[DI(i, j)] = src->map[SI(i, j)];
+ for (j = src->mapWidth; j < dst->mapWidth; j++)
+ dst->map[DI(i, j)] = NoSymbol;
+#undef SI
+#undef DI
+ }
+ return TRUE;
+ }
+ else if (src->mapWidth > dst->mapWidth)
+ {
+ KeySym *map;
+ int bytes = sizeof(KeySym) * src->mapWidth *
+ (dst->maxKeyCode - dst->minKeyCode + 1);
+ map = (KeySym *)malloc(bytes);
+ if (!map)
+ return FALSE;
+ bzero((char *)map, bytes);
+ if (dst->map)
+ {
+ for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
+ memmove((char *)&map[i*src->mapWidth],
+ (char *)&dst->map[i*dst->mapWidth],
+ dst->mapWidth * sizeof(KeySym));
+ free(dst->map);
+ }
+ dst->mapWidth = src->mapWidth;
+ dst->map = map;
+ }
+ memmove((char *)&dst->map[rowDif * dst->mapWidth],
+ (char *)src->map,
+ (int)(src->maxKeyCode - src->minKeyCode + 1) *
+ dst->mapWidth * sizeof(KeySym));
+ return TRUE;
+}
+
+static Bool
+InitModMap(register KeyClassPtr keyc)
+{
+ int i, j;
+ CARD8 keysPerModifier[8];
+ CARD8 mask;
+
+ keyc->maxKeysPerModifier = 0;
+ for (i = 0; i < 8; i++)
+ keysPerModifier[i] = 0;
+ for (i = 8; i < MAP_LENGTH; i++)
+ {
+ for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+ {
+ if (mask & keyc->modifierMap[i])
+ {
+ if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
+ keyc->maxKeysPerModifier = keysPerModifier[j];
+ }
+ }
+ }
+ keyc->modifierKeyMap = (KeyCode *)calloc(8, keyc->maxKeysPerModifier);
+ if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
+ return (FALSE);
+ for (i = 0; i < 8; i++)
+ keysPerModifier[i] = 0;
+ for (i = 8; i < MAP_LENGTH; i++)
+ {
+ for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
+ {
+ if (mask & keyc->modifierMap[i])
+ {
+ keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
+ keysPerModifier[j]] = i;
+ keysPerModifier[j]++;
+ }
+ }
+ }
+ return TRUE;
+}
+
+Bool
+InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
+{
+ int i;
+ register KeyClassPtr keyc;
+
+ keyc = (KeyClassPtr)calloc(1, sizeof(KeyClassRec));
+ if (!keyc)
+ return FALSE;
+ keyc->curKeySyms.map = (KeySym *)NULL;
+ keyc->curKeySyms.mapWidth = 0;
+ keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
+ keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
+ keyc->modifierKeyMap = (KeyCode *)NULL;
+ keyc->state = 0;
+ keyc->prev_state = 0;
+ if (pModifiers)
+ memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
+ else
+ bzero((char *)keyc->modifierMap, MAP_LENGTH);
+ bzero((char *)keyc->down, DOWN_LENGTH);
+ for (i = 0; i < 8; i++)
+ keyc->modifierKeyCount[i] = 0;
+ if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
+ {
+ free(keyc->curKeySyms.map);
+ free(keyc->modifierKeyMap);
+ free(keyc);
+ return FALSE;
+ }
+ dev->key = keyc;
+#ifdef XKB
+ dev->key->xkbInfo= NULL;
+ if (!noXkbExtension) XkbInitDevice(dev);
+#endif
+ return TRUE;
+}
+
+Bool
+InitButtonClassDeviceStruct(register DeviceIntPtr dev, int numButtons,
+ CARD8 *map)
+{
+ register ButtonClassPtr butc;
+ int i;
+
+ butc = (ButtonClassPtr)calloc(1, sizeof(ButtonClassRec));
+ if (!butc)
+ return FALSE;
+ butc->numButtons = numButtons;
+ for (i = 1; i <= numButtons; i++)
+ butc->map[i] = map[i];
+ butc->buttonsDown = 0;
+ butc->state = 0;
+ butc->motionMask = 0;
+ bzero((char *)butc->down, DOWN_LENGTH);
+#ifdef XKB
+ butc->xkb_acts= NULL;
+#endif
+ dev->button = butc;
+ return TRUE;
+}
+
+Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
+ ValuatorMotionProcPtr motionProc,
+ int numMotionEvents, int mode)
+{
+ int i;
+ register ValuatorClassPtr valc;
+
+ valc = (ValuatorClassPtr)calloc(1, sizeof(ValuatorClassRec) +
+ numAxes * sizeof(AxisInfo) +
+ numAxes * sizeof(unsigned int));
+ if (!valc)
+ return FALSE;
+ valc->GetMotionProc = motionProc;
+ valc->numMotionEvents = numMotionEvents;
+ valc->motionHintWindow = NullWindow;
+ valc->numAxes = numAxes;
+ valc->mode = mode;
+ valc->axes = (AxisInfoPtr)(valc + 1);
+ valc->axisVal = (int *)(valc->axes + numAxes);
+ for (i=0; i<numAxes; i++)
+ valc->axisVal[i]=0;
+ dev->valuator = valc;
+ return TRUE;
+}
+
+Bool
+InitFocusClassDeviceStruct(DeviceIntPtr dev)
+{
+ register FocusClassPtr focc;
+
+ focc = (FocusClassPtr)calloc(1, sizeof(FocusClassRec));
+ if (!focc)
+ return FALSE;
+ focc->win = PointerRootWin;
+ focc->revert = None;
+ focc->time = currentTime;
+ focc->trace = (WindowPtr *)NULL;
+ focc->traceSize = 0;
+ focc->traceGood = 0;
+ dev->focus = focc;
+ return TRUE;
+}
+
+Bool
+InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
+ KbdCtrlProcPtr controlProc)
+{
+ register KbdFeedbackPtr feedc;
+
+ feedc = (KbdFeedbackPtr)calloc(1, sizeof(KbdFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->BellProc = bellProc;
+ feedc->CtrlProc = controlProc;
+#ifdef XKB
+ defaultKeyboardControl.autoRepeat = TRUE;
+#endif
+ feedc->ctrl = defaultKeyboardControl;
+ feedc->ctrl.id = 0;
+ if ((feedc->next = dev->kbdfeed) != 0)
+ feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
+ dev->kbdfeed = feedc;
+#ifdef XKB
+ feedc->xkb_sli= NULL;
+ if (!noXkbExtension)
+ XkbFinishDeviceInit(dev);
+#endif
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ return TRUE;
+}
+
+Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
+{
+ register PtrFeedbackPtr feedc;
+
+ feedc = (PtrFeedbackPtr)calloc(1, sizeof(PtrFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultPointerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->ptrfeed) )
+ feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
+ dev->ptrfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+
+LedCtrl defaultLedControl = {
+ DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
+
+BellCtrl defaultBellControl = {
+ DEFAULT_BELL,
+ DEFAULT_BELL_PITCH,
+ DEFAULT_BELL_DURATION,
+ 0};
+
+IntegerCtrl defaultIntegerControl = {
+ DEFAULT_INT_RESOLUTION,
+ DEFAULT_INT_MIN_VALUE,
+ DEFAULT_INT_MAX_VALUE,
+ DEFAULT_INT_DISPLAYED,
+ 0};
+
+Bool
+InitStringFeedbackClassDeviceStruct (
+ DeviceIntPtr dev, StringCtrlProcPtr controlProc,
+ int max_symbols, int num_symbols_supported, KeySym *symbols)
+{
+ int i;
+ register StringFeedbackPtr feedc;
+
+ feedc = (StringFeedbackPtr)calloc(1, sizeof(StringFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl.num_symbols_supported = num_symbols_supported;
+ feedc->ctrl.num_symbols_displayed = 0;
+ feedc->ctrl.max_symbols = max_symbols;
+ feedc->ctrl.symbols_supported = (KeySym *)
+ calloc (num_symbols_supported, sizeof (KeySym));
+ feedc->ctrl.symbols_displayed = (KeySym *)
+ calloc (max_symbols, sizeof (KeySym));
+ if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
+ {
+ if (feedc->ctrl.symbols_supported)
+ free(feedc->ctrl.symbols_supported);
+ if (feedc->ctrl.symbols_displayed)
+ free(feedc->ctrl.symbols_displayed);
+ free(feedc);
+ return FALSE;
+ }
+ for (i=0; i<num_symbols_supported; i++)
+ *(feedc->ctrl.symbols_supported+i) = *symbols++;
+ for (i=0; i<max_symbols; i++)
+ *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->stringfeed) )
+ feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
+ dev->stringfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
+ BellCtrlProcPtr controlProc)
+{
+ register BellFeedbackPtr feedc;
+
+ feedc = (BellFeedbackPtr)calloc(1, sizeof(BellFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->BellProc = bellProc;
+ feedc->ctrl = defaultBellControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->bell) )
+ feedc->ctrl.id = dev->bell->ctrl.id + 1;
+ dev->bell = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
+{
+ register LedFeedbackPtr feedc;
+
+ feedc = (LedFeedbackPtr)calloc(1, sizeof(LedFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultLedControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->leds) )
+ feedc->ctrl.id = dev->leds->ctrl.id + 1;
+#ifdef XKB
+ feedc->xkb_sli= NULL;
+#endif
+ dev->leds = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
+{
+ register IntegerFeedbackPtr feedc;
+
+ feedc = (IntegerFeedbackPtr)calloc(1, sizeof(IntegerFeedbackClassRec));
+ if (!feedc)
+ return FALSE;
+ feedc->CtrlProc = controlProc;
+ feedc->ctrl = defaultIntegerControl;
+ feedc->ctrl.id = 0;
+ if ( (feedc->next = dev->intfeed) )
+ feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
+ dev->intfeed = feedc;
+ (*controlProc)(dev, &feedc->ctrl);
+ return TRUE;
+}
+
+Bool
+InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
+ ValuatorMotionProcPtr motionProc,
+ PtrCtrlProcPtr controlProc, int numMotionEvents)
+{
+ DeviceIntPtr dev = (DeviceIntPtr)device;
+
+ return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
+ InitValuatorClassDeviceStruct(dev, 2, motionProc,
+ numMotionEvents, 0) &&
+ InitPtrFeedbackClassDeviceStruct(dev, controlProc));
+}
+
+Bool
+InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
+ CARD8 pModifiers[], BellProcPtr bellProc,
+ KbdCtrlProcPtr controlProc)
+{
+ DeviceIntPtr dev = (DeviceIntPtr)device;
+
+ return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
+ InitFocusClassDeviceStruct(dev) &&
+ InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
+}
+
+void
+SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
+ ClientPtr client)
+{
+ int i;
+ xEvent event;
+
+ event.u.u.type = MappingNotify;
+ event.u.mappingNotify.request = request;
+ if (request == MappingKeyboard)
+ {
+ event.u.mappingNotify.firstKeyCode = firstKeyCode;
+ event.u.mappingNotify.count = count;
+ }
+#ifdef XKB
+ if (!noXkbExtension &&
+ ((request == MappingKeyboard) || (request == MappingModifier))) {
+ XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
+ client);
+ }
+#endif
+
+ /* 0 is the server client */
+ for (i=1; i<currentMaxClients; i++)
+ {
+ if (clients[i] && clients[i]->clientState == ClientStateRunning)
+ {
+#ifdef XKB
+ if (!noXkbExtension &&
+ (request == MappingKeyboard) &&
+ (clients[i]->xkbClientFlags != 0) &&
+ (clients[i]->mapNotifyMask&XkbKeySymsMask))
+ continue;
+#endif
+ event.u.u.sequenceNumber = clients[i]->sequence;
+ WriteEventsToClient(clients[i], 1, &event);
+ }
+ }
+}
+
+/*
+ * n-squared algorithm. n < 255 and don't want to copy the whole thing and
+ * sort it to do the checking. How often is it called? Just being lazy?
+ */
+Bool
+BadDeviceMap(register BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
+{
+ register int i, j;
+
+ for (i = 0; i < length; i++)
+ if (buff[i]) /* only check non-zero elements */
+ {
+ if ((low > buff[i]) || (high < buff[i]))
+ {
+ *errval = buff[i];
+ return TRUE;
+ }
+ for (j = i + 1; j < length; j++)
+ if (buff[i] == buff[j])
+ {
+ *errval = buff[i];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+Bool
+AllModifierKeysAreUp(dev, map1, per1, map2, per2)
+ register DeviceIntPtr dev;
+ register CARD8 *map1, *map2;
+ int per1, per2;
+{
+ register int i, j, k;
+ register CARD8 *down = dev->key->down;
+
+ for (i = 8; --i >= 0; map2 += per2)
+ {
+ for (j = per1; --j >= 0; map1++)
+ {
+ if (*map1 && BitIsOn(down, *map1))
+ {
+ for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
+ ;
+ if (k < 0)
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+int
+ProcSetModifierMapping(ClientPtr client)
+{
+ xSetModifierMappingReply rep;
+ REQUEST(xSetModifierMappingReq);
+ KeyCode *inputMap;
+ int inputMapLen;
+ register int i;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ register KeyClassPtr keyc = keybd->key;
+
+ REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
+
+ if (client->req_len != ((stuff->numKeyPerModifier<<1) +
+ (sizeof (xSetModifierMappingReq)>>2)))
+ return BadLength;
+
+ inputMapLen = 8*stuff->numKeyPerModifier;
+ inputMap = (KeyCode *)&stuff[1];
+
+ /*
+ * Now enforce the restriction that "all of the non-zero keycodes must be
+ * in the range specified by min-keycode and max-keycode in the
+ * connection setup (else a Value error)"
+ */
+ i = inputMapLen;
+ while (i--)
+ {
+ if (inputMap[i]
+ && (inputMap[i] < keyc->curKeySyms.minKeyCode
+ || inputMap[i] > keyc->curKeySyms.maxKeyCode))
+ {
+ client->errorValue = inputMap[i];
+ return BadValue;
+ }
+ }
+
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+ return BadAccess;
+#endif
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = MappingSuccess;
+
+ /*
+ * Now enforce the restriction that none of the old or new
+ * modifier keys may be down while we change the mapping, and
+ * that the DDX layer likes the choice.
+ */
+ if (!AllModifierKeysAreUp(keybd, keyc->modifierKeyMap,
+ (int)keyc->maxKeysPerModifier,
+ inputMap, (int)stuff->numKeyPerModifier)
+ ||
+ !AllModifierKeysAreUp(keybd, inputMap, (int)stuff->numKeyPerModifier,
+ keyc->modifierKeyMap,
+ (int)keyc->maxKeysPerModifier))
+ {
+ rep.success = MappingBusy;
+ }
+ else
+ {
+ for (i = 0; i < inputMapLen; i++)
+ {
+ if (inputMap[i] && !LegalModifier(inputMap[i], (DevicePtr)keybd))
+ {
+ rep.success = MappingFailed;
+ break;
+ }
+ }
+ }
+
+ if (rep.success == MappingSuccess)
+ {
+ KeyCode *map;
+ /*
+ * Now build the keyboard's modifier bitmap from the
+ * list of keycodes.
+ */
+ map = (KeyCode *)malloc(inputMapLen);
+ if (!map && inputMapLen)
+ return BadAlloc;
+ if (keyc->modifierKeyMap)
+ free(keyc->modifierKeyMap);
+ keyc->modifierKeyMap = map;
+ memmove((char *)map, (char *)inputMap, inputMapLen);
+
+ keyc->maxKeysPerModifier = stuff->numKeyPerModifier;
+ for (i = 0; i < MAP_LENGTH; i++)
+ keyc->modifierMap[i] = 0;
+ for (i = 0; i < inputMapLen; i++)
+ {
+ if (inputMap[i])
+ keyc->modifierMap[inputMap[i]] |=
+ (1<<(((unsigned int)i)/keyc->maxKeysPerModifier));
+ }
+ }
+
+ if (rep.success == MappingSuccess)
+ SendMappingNotify(MappingModifier, 0, 0, client);
+
+ WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
+
+ return(client->noClientException);
+}
+
+int
+ProcGetModifierMapping(ClientPtr client)
+{
+ xGetModifierMappingReply rep;
+ register KeyClassPtr keyc = inputInfo.keyboard->key;
+
+ REQUEST_SIZE_MATCH(xReq);
+ memset(&rep, 0, sizeof(xGetModifierMappingReply));
+ rep.type = X_Reply;
+ rep.numKeyPerModifier = keyc->maxKeysPerModifier;
+ rep.sequenceNumber = client->sequence;
+ /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
+ rep.length = keyc->maxKeysPerModifier << 1;
+
+ WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
+
+ /* Use the (modified by DDX) map that SetModifierMapping passed in */
+ WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
+ (char *)keyc->modifierKeyMap);
+ return client->noClientException;
+}
+
+int
+ProcChangeKeyboardMapping(ClientPtr client)
+{
+ REQUEST(xChangeKeyboardMappingReq);
+ unsigned len;
+ KeySymsRec keysyms;
+ register KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+
+ len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
+ if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
+ return BadLength;
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+ {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if ( ((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
+ curKeySyms->maxKeyCode) ||
+ (stuff->keySymsPerKeyCode == 0))
+ {
+ client->errorValue = stuff->keySymsPerKeyCode;
+ return BadValue;
+ }
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard,
+ TRUE))
+ return BadAccess;
+#endif
+ keysyms.minKeyCode = stuff->firstKeyCode;
+ keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
+ keysyms.mapWidth = stuff->keySymsPerKeyCode;
+ keysyms.map = (KeySym *)&stuff[1];
+ if (!SetKeySymsMap(curKeySyms, &keysyms))
+ return BadAlloc;
+ SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
+ client);
+ return client->noClientException;
+
+}
+
+int
+ProcSetPointerMapping(ClientPtr client)
+{
+ REQUEST(xSetPointerMappingReq);
+ BYTE *map;
+ xSetPointerMappingReply rep;
+ register unsigned int i;
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
+ if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
+ return BadLength;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = MappingSuccess;
+ map = (BYTE *)&stuff[1];
+ if (stuff->nElts != mouse->button->numButtons)
+ {
+ client->errorValue = stuff->nElts;
+ return BadValue;
+ }
+ if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
+ return BadValue;
+ for (i=0; i < stuff->nElts; i++)
+ if ((mouse->button->map[i + 1] != map[i]) &&
+ BitIsOn(mouse->button->down, i + 1))
+ {
+ rep.success = MappingBusy;
+ WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+ return Success;
+ }
+ for (i = 0; i < stuff->nElts; i++)
+ mouse->button->map[i + 1] = map[i];
+ SendMappingNotify(MappingPointer, 0, 0, client);
+ WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+ return Success;
+}
+
+int
+ProcGetKeyboardMapping(ClientPtr client)
+{
+ xGetKeyboardMappingReply rep;
+ REQUEST(xGetKeyboardMappingReq);
+ KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+
+ REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
+
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode))
+ {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if (stuff->firstKeyCode + stuff->count >
+ (unsigned)(curKeySyms->maxKeyCode + 1))
+ {
+ client->errorValue = stuff->count;
+ return BadValue;
+ }
+
+ memset(&rep, 0, sizeof(xGetKeyboardMappingReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.keySymsPerKeyCode = curKeySyms->mapWidth;
+ /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+ rep.length = (curKeySyms->mapWidth * stuff->count);
+ WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+ WriteSwappedDataToClient(
+ client,
+ curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
+ &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
+ curKeySyms->mapWidth]);
+
+ return client->noClientException;
+}
+
+int
+ProcGetPointerMapping(ClientPtr client)
+{
+ xGetPointerMappingReply rep;
+ ButtonClassPtr butc = inputInfo.pointer->button;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.nElts = butc->numButtons;
+ rep.length = ((unsigned)rep.nElts + (4-1))/4;
+ WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
+ WriteToClient(client, (int)rep.nElts, &butc->map[1]);
+ return Success;
+}
+
+void
+NoteLedState(DeviceIntPtr keybd, int led, Bool on)
+{
+ KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
+ if (on)
+ ctrl->leds |= ((Leds)1 << (led - 1));
+ else
+ ctrl->leds &= ~((Leds)1 << (led - 1));
+}
+
+int
+Ones(unsigned long mask) /* HACKMEM 169 */
+{
+ register unsigned long y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+int
+ProcChangeKeyboardControl (ClientPtr client)
+{
+#define DO_ALL (-1)
+ KeybdCtrl ctrl;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ XID *vlist;
+ int t;
+ int led = DO_ALL;
+ int key = DO_ALL;
+ BITS32 vmask, index2;
+ int mask, i;
+ REQUEST(xChangeKeyboardControlReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+ vmask = stuff->mask;
+ if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
+ return BadLength;
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, keybd, TRUE))
+ return BadAccess;
+#endif
+ vlist = (XID *)&stuff[1]; /* first word of values */
+ ctrl = keybd->kbdfeed->ctrl;
+ while (vmask)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ switch (index2)
+ {
+ case KBKeyClickPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.click;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.click = t;
+ break;
+ case KBBellPercent:
+ t = (INT8)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell;
+ else if (t < 0 || t > 100)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell = t;
+ break;
+ case KBBellPitch:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_pitch;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_pitch = t;
+ break;
+ case KBBellDuration:
+ t = (INT16)*vlist;
+ vlist++;
+ if (t == -1)
+ t = defaultKeyboardControl.bell_duration;
+ else if (t < 0)
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ ctrl.bell_duration = t;
+ break;
+ case KBLed:
+ led = (CARD8)*vlist;
+ vlist++;
+ if (led < 1 || led > 32)
+ {
+ client->errorValue = led;
+ return BadValue;
+ }
+ if (!(stuff->mask & KBLedMode))
+ return BadMatch;
+ break;
+ case KBLedMode:
+ t = (CARD8)*vlist;
+ vlist++;
+ if (t == LedModeOff)
+ {
+ if (led == DO_ALL)
+ ctrl.leds = 0x0;
+ else
+ ctrl.leds &= ~(((Leds)(1)) << (led - 1));
+ }
+ else if (t == LedModeOn)
+ {
+ if (led == DO_ALL)
+ ctrl.leds = ~0L;
+ else
+ ctrl.leds |= (((Leds)(1)) << (led - 1));
+ }
+ else
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+#ifdef XKB
+ if (!noXkbExtension) {
+ XkbEventCauseRec cause;
+ XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
+ XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
+ ctrl.leds, &cause);
+ ctrl.leds = keybd->kbdfeed->ctrl.leds;
+ }
+#endif
+ break;
+ case KBKey:
+ key = (KeyCode)*vlist;
+ vlist++;
+ if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
+ (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode)
+ {
+ client->errorValue = key;
+ return BadValue;
+ }
+ if (!(stuff->mask & KBAutoRepeatMode))
+ return BadMatch;
+ break;
+ case KBAutoRepeatMode:
+ i = (key >> 3);
+ mask = (1 << (key & 7));
+ t = (CARD8)*vlist;
+ vlist++;
+#ifdef XKB
+ if (!noXkbExtension && key != DO_ALL)
+ XkbDisableComputedAutoRepeats(keybd,key);
+#endif
+ if (t == AutoRepeatModeOff)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = FALSE;
+ else
+ ctrl.autoRepeats[i] &= ~mask;
+ }
+ else if (t == AutoRepeatModeOn)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = TRUE;
+ else
+ ctrl.autoRepeats[i] |= mask;
+ }
+ else if (t == AutoRepeatModeDefault)
+ {
+ if (key == DO_ALL)
+ ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+ else
+ ctrl.autoRepeats[i] =
+ (ctrl.autoRepeats[i] & ~mask) |
+ (defaultKeyboardControl.autoRepeats[i] & mask);
+ }
+ else
+ {
+ client->errorValue = t;
+ return BadValue;
+ }
+ break;
+ default:
+ client->errorValue = stuff->mask;
+ return BadValue;
+ }
+ }
+ keybd->kbdfeed->ctrl = ctrl;
+#ifdef XKB
+ /* The XKB RepeatKeys control and core protocol global autorepeat */
+ /* value are linked */
+ if (!noXkbExtension) {
+ XkbSetRepeatKeys(keybd,key,keybd->kbdfeed->ctrl.autoRepeat);
+ }
+ else
+#endif
+ (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
+ return Success;
+#undef DO_ALL
+}
+
+int
+ProcGetKeyboardControl (ClientPtr client)
+{
+ int i;
+ register KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
+ xGetKeyboardControlReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 5;
+ rep.sequenceNumber = client->sequence;
+ rep.globalAutoRepeat = ctrl->autoRepeat;
+ rep.keyClickPercent = ctrl->click;
+ rep.bellPercent = ctrl->bell;
+ rep.bellPitch = ctrl->bell_pitch;
+ rep.bellDuration = ctrl->bell_duration;
+ rep.ledMask = ctrl->leds;
+ for (i = 0; i < 32; i++)
+ rep.map[i] = ctrl->autoRepeats[i];
+ WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
+ return Success;
+}
+
+int
+ProcBell(ClientPtr client)
+{
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ int base = keybd->kbdfeed->ctrl.bell;
+ int newpercent;
+ REQUEST(xBellReq);
+ REQUEST_SIZE_MATCH(xBellReq);
+ if (stuff->percent < -100 || stuff->percent > 100)
+ {
+ client->errorValue = stuff->percent;
+ return BadValue;
+ }
+ newpercent = (base * stuff->percent) / 100;
+ if (stuff->percent < 0)
+ newpercent = base + newpercent;
+ else
+ newpercent = base - newpercent + stuff->percent;
+#ifdef XKB
+ if (!noXkbExtension)
+ XkbHandleBell(FALSE,FALSE, keybd, newpercent, &keybd->kbdfeed->ctrl, 0,
+ None, NULL, client);
+ else
+#endif
+ (*keybd->kbdfeed->BellProc)(newpercent, keybd,
+ (void *) &keybd->kbdfeed->ctrl, 0);
+ return Success;
+}
+
+int
+ProcChangePointerControl(ClientPtr client)
+{
+ DeviceIntPtr mouse = inputInfo.pointer;
+ PtrCtrl ctrl; /* might get BadValue part way through */
+ REQUEST(xChangePointerControlReq);
+
+ REQUEST_SIZE_MATCH(xChangePointerControlReq);
+ ctrl = mouse->ptrfeed->ctrl;
+ if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse))
+ {
+ client->errorValue = stuff->doAccel;
+ return(BadValue);
+ }
+ if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse))
+ {
+ client->errorValue = stuff->doThresh;
+ return(BadValue);
+ }
+ if (stuff->doAccel)
+ {
+ if (stuff->accelNum == -1)
+ ctrl.num = defaultPointerControl.num;
+ else if (stuff->accelNum < 0)
+ {
+ client->errorValue = stuff->accelNum;
+ return BadValue;
+ }
+ else ctrl.num = stuff->accelNum;
+ if (stuff->accelDenum == -1)
+ ctrl.den = defaultPointerControl.den;
+ else if (stuff->accelDenum <= 0)
+ {
+ client->errorValue = stuff->accelDenum;
+ return BadValue;
+ }
+ else ctrl.den = stuff->accelDenum;
+ }
+ if (stuff->doThresh)
+ {
+ if (stuff->threshold == -1)
+ ctrl.threshold = defaultPointerControl.threshold;
+ else if (stuff->threshold < 0)
+ {
+ client->errorValue = stuff->threshold;
+ return BadValue;
+ }
+ else ctrl.threshold = stuff->threshold;
+ }
+ mouse->ptrfeed->ctrl = ctrl;
+ (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
+ return Success;
+}
+
+int
+ProcGetPointerControl(ClientPtr client)
+{
+ register PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
+ xGetPointerControlReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.threshold = ctrl->threshold;
+ rep.accelNumerator = ctrl->num;
+ rep.accelDenominator = ctrl->den;
+ WriteReplyToClient(client, sizeof(xGenericReply), &rep);
+ return Success;
+}
+
+void
+MaybeStopHint(register DeviceIntPtr dev, ClientPtr client)
+{
+ GrabPtr grab = dev->grab;
+
+ if ((grab && SameClient(grab, client) &&
+ ((grab->eventMask & PointerMotionHintMask) ||
+ (grab->ownerEvents &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))) ||
+ (!grab &&
+ (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+ PointerMotionHintMask)))
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+ProcGetMotionEvents(ClientPtr client)
+{
+ WindowPtr pWin;
+ xTimecoord * coords = (xTimecoord *) NULL;
+ xGetMotionEventsReply rep;
+ int i, count, xmin, xmax, ymin, ymax;
+ unsigned long nEvents;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ TimeStamp start, stop;
+ REQUEST(xGetMotionEventsReq);
+
+ REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+ pWin = SecurityLookupWindow(stuff->window, client, TRUE);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ nEvents = 0;
+ start = ClientTimeToServerTime(stuff->start);
+ stop = ClientTimeToServerTime(stuff->stop);
+ if ((CompareTimeStamps(start, stop) != LATER) &&
+ (CompareTimeStamps(start, currentTime) != LATER) &&
+ mouse->valuator->numMotionEvents)
+ {
+ if (CompareTimeStamps(stop, currentTime) == LATER)
+ stop = currentTime;
+ coords = (xTimecoord *)malloc(mouse->valuator->numMotionEvents
+ * sizeof(xTimecoord));
+ if (!coords)
+ return BadAlloc;
+ count = (*mouse->valuator->GetMotionProc) (mouse, coords,
+ start.milliseconds,
+ stop.milliseconds,
+ pWin->drawable.pScreen);
+ xmin = pWin->drawable.x - wBorderWidth (pWin);
+ xmax = pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin);
+ ymin = pWin->drawable.y - wBorderWidth (pWin);
+ ymax = pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin);
+ for (i = 0; i < count; i++)
+ if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
+ (ymin <= coords[i].y) && (coords[i].y < ymax))
+ {
+ coords[nEvents].time = coords[i].time;
+ coords[nEvents].x = coords[i].x - pWin->drawable.x;
+ coords[nEvents].y = coords[i].y - pWin->drawable.y;
+ nEvents++;
+ }
+ }
+ rep.length = nEvents * (sizeof(xTimecoord) >> 2);
+ rep.nEvents = nEvents;
+ WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
+ if (nEvents)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
+ WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
+ (char *)coords);
+ }
+ if (coords)
+ free(coords);
+ return Success;
+}
+
+int
+ProcQueryKeymap(ClientPtr client)
+{
+ xQueryKeymapReply rep;
+ int i;
+ CARD8 *down = inputInfo.keyboard->key->down;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 2;
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ {
+ bzero((char *)&rep.map[0], 32);
+ }
+ else
+#endif
+ for (i = 0; i<32; i++)
+ rep.map[i] = down[i];
+ WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+ return Success;
+}
+
+/******************************************************************************
+ * The following entrypoints are provided for binary compatibility with
+ * previous versions (they make casts, where the current version changes types
+ * for more stringent prototype checking).
+ ******************************************************************************/
+#ifdef AddInputDevice
+#undef AddInputDevice
+
+DevicePtr
+AddInputDevice(DeviceProc deviceProc, Bool autoStart)
+{
+ return (DevicePtr)_AddInputDevice(deviceProc, autoStart);
+}
+#endif /* AddInputDevice */
+
+#ifdef RegisterPointerDevice
+#undef RegisterPointerDevice
+
+void
+RegisterPointerDevice(DevicePtr device)
+{
+ _RegisterPointerDevice((DeviceIntPtr)device);
+}
+#endif /* RegisterPointerDevice */
+
+#ifdef RegisterKeyboardDevice
+#undef RegisterKeyboardDevice
+
+void
+RegisterKeyboardDevice(DevicePtr device)
+{
+ _RegisterKeyboardDevice((DeviceIntPtr)device);
+}
+#endif /* RegisterKeyboardDevice */
diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c
new file mode 100644
index 000000000..c9ce8981c
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/dispatch.c
@@ -0,0 +1,4201 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS_XFONT2 */
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "../Xext/panoramiX.h"
+#include "../Xext/panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+#ifdef XKB
+#include "inputstr.h"
+#include "xkbsrv.h"
+#endif
+#include "client.h"
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+extern int screenPrivateCount;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+#ifndef NXAGENT_SERVER
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ free(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+}
+#endif /* NXAGENT_SERVER */
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+#ifdef HAVE_SETITIMER
+#define SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE HAVE_SETITIMER
+Bool SmartScheduleSignalEnable = SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE;
+#endif
+
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+ClientPtr SmartLastClient;
+int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ int i;
+ int client;
+ ClientPtr pClient, best = NULL;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index -
+ SmartLastIndex[pClient->smart_priority -
+ SMART_MIN_PRIORITY]) & 0xff;
+
+ /* pick the best client */
+ if (!best ||
+ pClient->priority > best->priority ||
+ (pClient->priority == best->priority &&
+ (pClient->smart_priority > best->smart_priority ||
+ (pClient->smart_priority == best->smart_priority && robin > bestRobin))))
+ {
+ best = pClient;
+ bestRobin = robin;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best->index;
+}
+
+#ifndef NXAGENT_SERVER
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+ long start_tick;
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ clientReady = (int *) malloc(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ nready = WaitForSomething(clientReady);
+
+ if (nready)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+ start_tick = SmartScheduleTime;
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+ if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+ /* now, finally, deal with client requests */
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+
+ client->sequence++;
+#ifdef DEBUG
+ if (client->requestLogIndex == MAX_REQUEST_LOG)
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+ result = (* client->requestVector[MAJOROP])(client);
+
+ if (!SmartScheduleSignalEnable)
+ SmartScheduleTime = GetTimeInMillis();
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ KillAllClients();
+ free(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+#endif /* NXAGENT_SERVER */
+
+int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ DixWriteAccess)))
+ return BadWindow;
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &result);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (void *)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ memset(&wa, 0, sizeof(xGetWindowAttributesReply));
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->parent)
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixDestroyAccess);
+ if (!pWin)
+ return(BadWindow);
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ DixWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, DixReadAccess);
+ memset(rep, 0, sizeof(xGetGeometryReply));
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = pDraw->pScreen->root->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+
+#ifndef NXAGENT_SERVER
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ memset(&reply, 0, sizeof(xQueryTreeReply));
+ reply.type = X_Reply;
+ reply.root = pWin->drawable.pScreen->root->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ numChildren++;
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) malloc(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ free(childIDs);
+ }
+
+ return(client->noClientException);
+}
+#endif /* NXAGENT_SERVER */
+
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ memset(&reply, 0, sizeof(xInternAtomReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+ const char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ memset(&reply, 0, sizeof(xGetAtomNameReply));
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)malloc(sizeof(Selection));
+ else
+ newsels = (Selection *)realloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (ValidAtom(stuff->id))
+ {
+ int i;
+ xGetSelectionOwnerReply reply;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
+ memset(&reply, 0, sizeof(xGetSelectionOwnerReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ if (i < NumCurrentSelections)
+ reply.owner = CurrentSelections[i].window;
+ else
+ reply.owner = None;
+ WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None)
+#ifdef XCSECURITY
+ && (!client->CheckAccess ||
+ (* client->CheckAccess)(client, CurrentSelections[i].window,
+ RT_WINDOW, DixReadAccess,
+ CurrentSelections[i].pWin))
+#endif
+ )
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ OnlyListenToOneClient(client);
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (void *)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (void *)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ register WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+ DixReadAccess);
+ if (!pDst)
+ return(BadWindow);
+ memset(&rep, 0, sizeof(xTranslateCoordsReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+#ifdef SHAPE
+ BoxRec box;
+#endif
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ RegionContainsPoint(
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ DixDestroyAccess);
+ if ( pFont != (FontPtr)NULL) /* id was valid */
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ client->errorValue = stuff->id; /* EITHER font or gc */
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ DixReadAccess);
+ if (!pFont)
+ {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+ DixReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->id;
+ return(BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+
+ reply = (xQueryFontReply *)malloc(rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ memset(reply, 0, rlength);
+ reply->type = X_Reply;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ free(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+ REQUEST(xQueryTextExtentsReq);
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ DixReadAccess);
+ if (!pFont)
+ {
+ pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ DixReadAccess);
+ if (!pGC)
+ {
+ client->errorValue = stuff->fid;
+ return(BadFont);
+ }
+ pFont = pGC->font;
+ }
+ length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+#ifdef HAS_XFONT2
+ if (!xfont2_query_text_extents(pFont, length, (unsigned char *)&stuff[1], &info))
+#else
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+#endif /* HAS_XFONT2 */
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcListFonts(register ClientPtr client)
+{
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+#endif /* NXAGENT_SERVER */
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(void * value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ register int i;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ DixReadAccess);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ return BadAlloc;
+ }
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+CreatePmap:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth, 0);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (void *)pMap))
+ return(client->noClientException);
+ }
+ return (BadAlloc);
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ DixDestroyAccess);
+ if (pMap)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+ int error;
+ GC *pGC;
+ register DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+ DixReadAccess);
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask,
+ (XID *) &stuff[1], &error);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (void *)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result;
+ unsigned len;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, DixWriteAccess);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+ register GC *dstGC;
+ register GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, DixReadAccess);
+ SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, DixWriteAccess);
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+ register GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, DixWriteAccess);
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+ int nr;
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ SECURITY_VERIFY_GC(pGC,stuff->gc, client, DixWriteAccess);
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ SECURITY_VERIFY_GC(pGC, stuff->id, client, DixDestroyAccess);
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+ register DrawablePtr pDst;
+ register DrawablePtr pSrc;
+ register GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+ DixReadAccess);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ RegionDestroy(pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+ register DrawablePtr psrcDraw, pdstDraw;
+ register GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+ DixReadAccess);
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+ (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+ {
+ client->errorValue = stuff->bitPlane;
+ return(BadValue);
+ }
+
+ pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY, stuff->bitPlane);
+ if (pGC->graphicsExposures)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ RegionDestroy(pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+ int npoint;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 1)
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+ int nsegs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+ int nrects;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (things)
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+ int things;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+ int narcs;
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+ if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height))
+ return BadLength;
+
+ if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
+ (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int linesDone;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+#ifdef XCSECURITY
+ RegionPtr pVisibleRegion = NULL;
+#endif
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, DixReadAccess);
+
+ memset(&xgi, 0, sizeof(xGetImageReply));
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + x < 0 ||
+ pDraw->x + x + width > pDraw->pScreen->width ||
+ pDraw->y + y < 0 ||
+ pDraw->y + y + height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ }
+ else
+ {
+ if(x < 0 ||
+ x+width > (int)pDraw->width ||
+ y < 0 ||
+ y+height > (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+
+ SET_DBE_SRCBUF(pDraw, drawable);
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = (char *)calloc(1, sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = (xgi.length + 3) >> 2;
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) malloc(length)))
+ return (BadAlloc);
+ memset(pBuf, 0, length);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+#ifdef XCSECURITY
+ if (client->trustLevel != XSecurityClientTrusted &&
+ pDraw->type == DRAWABLE_WINDOW)
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ RegionTranslate(pVisibleRegion, -pDraw->x, -pDraw->y);
+ }
+ }
+#endif
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (void *) pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (void *)pBuf);
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ SecurityCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+#endif
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+#ifdef XCSECURITY
+ if (pVisibleRegion)
+ RegionDestroy(pVisibleRegion);
+#endif
+ if (!im_return)
+ free(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+ int err;
+ register DrawablePtr pDraw;
+ register GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+ DixDestroyAccess);
+ if (pmap)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client, stuff->srcCmap,
+ RT_COLORMAP, DixReadAccess|DixWriteAccess)) )
+ {
+ result = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return(BadColor);
+ }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, DixReadAccess);
+ if (pcmp)
+ {
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_COLORMAP, DixReadAccess);
+ if (pcmp)
+ {
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadColor);
+ }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+
+ if (!pWin)
+ return(BadWindow);
+
+ preply = (xListInstalledColormapsReply *)
+ malloc(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ free(preply);
+ return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+ ColormapPtr pmap;
+ int retval;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pmap)
+ {
+ memset(&acr, 0, sizeof(xAllocColorReply));
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return (retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ int retval;
+
+ xAllocNamedColorReply ancr;
+
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (retval = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks, retval;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = (Pixel *)malloc(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ free(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = length >> 2;
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ free(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels, retval;
+ long length;
+ Pixel *ppixels;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = (Pixel *)malloc(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ free(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ acpr.length = length >> 2;
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ free(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ retval = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ int count;
+ int retval;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(retval);
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixWriteAccess);
+ if (pcmp)
+ {
+ xColorItem def;
+ int retval;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ retval = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(retval);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixReadAccess);
+ if (pcmp)
+ {
+ int count, retval;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+ prgbs = (xrgb *)malloc(count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ memset(prgbs, 0, count * sizeof(xrgb));
+ if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) free(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return (retval);
+ }
+ }
+
+ memset(&qcr, 0, sizeof(xQueryColorsReply));
+ qcr.type = X_Reply;
+ qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) free(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP, DixReadAccess);
+ if (pcmp)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+
+ register PixmapPtr src;
+ register PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+ RT_PIXMAP, DixReadAccess);
+ msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+ RT_PIXMAP, DixReadAccess);
+ if ( src == (PixmapPtr)NULL)
+ {
+ client->errorValue = stuff->source;
+ return (BadPixmap);
+ }
+ if ( msk == (PixmapPtr)NULL)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (BadPixmap);
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = (unsigned char *)malloc(n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = (unsigned char *)malloc(n);
+ if (!mskbits)
+ {
+ free(srcbits);
+ return (BadAlloc);
+ }
+
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)srcbits, n);
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (void *)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ register unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (void *)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursor( srcbits, mskbits, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (void *)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (void *)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+ CursorPtr pCursor;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+ RT_CURSOR, DixDestroyAccess);
+ if (pCursor)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadCursor);
+ }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ register DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ REQUEST(xQueryBestSizeReq);
+
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+ SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+ DixReadAccess);
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ memset(&reply, 0, sizeof(xQueryBestSizeReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+#ifndef NXAGENT_SERVER
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ if (blankingOption == DefaultBlanking)
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ else
+ ScreenSaverBlanking = blankingOption;
+ if (exposureOption == DefaultExposures)
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ else
+ ScreenSaverAllowExposures = exposureOption;
+
+ if (stuff->timeout >= 0)
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ else
+ ScreenSaverTime = defaultScreenSaverTime;
+ if (stuff->interval >= 0)
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ else
+ ScreenSaverInterval = defaultScreenSaverInterval;
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+
+ REQUEST_SIZE_MATCH(xReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (void *)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (void *)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ void * pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+ /* untrusted clients can't list hosts */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to list hosts\n", client->index);
+ return BadAccess;
+ }
+#endif
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = len >> 2;
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ free(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ if ((killclient = LookupClient(stuff->id, client)))
+ {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadValue);
+ }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ bufferStart = GetFontPath(&numpaths, &stringLens);
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ WriteToClient(client, stringLens + numpaths, bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+ REQUEST(xSetCloseDownModeReq);
+
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+#ifndef NXAGENT_SERVER
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+int ProcNoOperation(register ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+#ifndef NXAGENT_SERVER
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ FreeClientResources(client);
+ /* Disable client ID tracking. This must be done after
+ * ClientStateCallback. */
+ ReleaseClientIds(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+ SmartLastClient = NullClient;
+ free(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+static void
+KillAllClients()
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+void InitClient(ClientPtr client, int i, void * ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->clientGone = FALSE;
+ client->closeDownMode = i ? DestroyAll : RetainPermanent;
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+ client->noClientException = Success;
+#ifdef DEBUG
+ client->requestLogIndex = 0;
+#endif
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+ client->big_requests = FALSE;
+ client->priority = 0;
+ client->clientState = ClientStateInitial;
+#ifdef XKB
+ if (!noXkbExtension) {
+ client->xkbClientFlags = 0;
+ client->mapNotifyMask = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ }
+#endif
+ client->replyBytesRemaining = 0;
+#ifdef XCSECURITY
+ client->trustLevel = XSecurityClientTrusted;
+ client->CheckAccess = NULL;
+ client->authId = 0;
+#endif
+ client->fontResFunc = NULL;
+ client->smart_priority = 0;
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+ client->clientIds = NULL;
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+#ifndef NXAGENT_SERVER
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)malloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+ return 1;
+}
+#endif /* NXAGENT_SERVER */
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(void * ospriv)
+{
+ register int i;
+ register ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = (ClientPtr)malloc(totalClientSize);
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ InitClientPrivates(client);
+ if (!InitClientResources(client))
+ {
+ free(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ free(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+
+ /* Enable client ID tracking. This must be done before
+ * ClientStateCallback. */
+ ReserveClientIds(client);
+
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+ REQUEST(xReq);
+ register xConnClientPrefix *prefix;
+ int whichbyte = 1;
+ char order;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ order = prefix->byteOrder;
+ if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ if (client->swapped)
+ {
+ swaps(&stuff->length);
+ }
+ if (order == 'r' || order == 'R')
+ {
+ client->local = FALSE;
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+ register xWindowRoot *root;
+ register int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ memset(&csp, 0, sizeof(xConnSetupPrefix));
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ WriteToClient(client, sz_xConnSetupPrefix, &csp);
+ WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ register unsigned int j;
+ register xDepth *pDepth;
+
+ root->currentInputMask = screenInfo.screens[i]->root->eventMask |
+ wOtherEventMasks (screenInfo.screens[i]->root);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ memset(&rep, 0, sizeof(xError));
+ rep.type = X_Error;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].pWin == pWin)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+ register int i;
+
+ for (i = 0; i< NumCurrentSelections; i++)
+ if (CurrentSelections[i].client == client)
+ {
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind = SelectionWindowDestroy;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ CurrentSelections[i].pWin = (WindowPtr)NULL;
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].client = NullClient;
+ }
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
+
+/*
+ * This array encodes the answer to the question "what is the log base 2
+ * of the number of pixels that fit in a scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int answer[6][4] = {
+ /* pad pad pad pad*/
+ /* 8 16 32 64 */
+
+ { 3, 4, 5 , 6 }, /* 1 bit per pixel */
+ { 1, 2, 3 , 4 }, /* 4 bits per pixel */
+ { 0, 1, 2 , 3 }, /* 8 bits per pixel */
+ { ~0, 0, 1 , 2 }, /* 16 bits per pixel */
+ { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */
+ { ~0, ~0, 0 , 1 } /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the bytesperPixel value for cases where the number
+ * of bits per pixel is a multiple of 8 but not a power of 2.
+ */
+static int answerBytesPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 0, ~0, ~0, ~0, /* 4 bits per pixel */
+ 0, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the first index for
+ * the answer array above given the number of bits per pixel?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForBitsPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 1, ~0, ~0, ~0, /* 4 bits per pixel */
+ 2, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 4, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 5 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the second index for
+ * the answer array above given the number of bits per scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForScanlinePad[ 65 ] = {
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 3 /* 64 bits per scanline pad unit */
+};
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+static int init_screen(ScreenPtr pScreen, int i)
+{
+ int scanlinepad, format, depth, bitsPerPixel, j, k;
+#ifdef DEBUG
+ void (**jNI) ();
+#endif /* DEBUG */
+
+ pScreen->myNum = i;
+ pScreen->WindowPrivateLen = 0;
+ pScreen->WindowPrivateSizes = (unsigned *)NULL;
+ pScreen->totalWindowSize =
+ ((sizeof(WindowRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+ pScreen->GCPrivateLen = 0;
+ pScreen->GCPrivateSizes = (unsigned *)NULL;
+ pScreen->totalGCSize =
+ ((sizeof(GC) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+#ifdef PIXPRIV
+ pScreen->PixmapPrivateLen = 0;
+ pScreen->PixmapPrivateSizes = (unsigned *)NULL;
+ pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
+#endif
+ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
+ pScreen->CreateScreenResources = 0;
+
+#ifdef DEBUG
+ for (jNI = &pScreen->QueryBestSize;
+ jNI < (void (**) ()) &pScreen->SendGraphicsExpose;
+ jNI++)
+ *jNI = NotImplemented;
+#endif /* DEBUG */
+
+ /*
+ * This loop gets run once for every Screen that gets added,
+ * but thats ok. If the ddx layer initializes the formats
+ * one at a time calling AddScreen() after each, then each
+ * iteration will make it a little more accurate. Worst case
+ * we do this loop N * numPixmapFormats where N is # of screens.
+ * Anyway, this must be called after InitOutput and before the
+ * screen init routine is called.
+ */
+ for (format=0; format<screenInfo.numPixmapFormats; format++)
+ {
+ depth = screenInfo.formats[format].depth;
+ bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
+ scanlinepad = screenInfo.formats[format].scanlinePad;
+ j = indexForBitsPerPixel[ bitsPerPixel ];
+ k = indexForScanlinePad[ scanlinepad ];
+ PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].padRoundUp =
+ (scanlinepad/bitsPerPixel) - 1;
+ j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
+ PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
+ if (answerBytesPerPixel[bitsPerPixel])
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
+ PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
+ answerBytesPerPixel[bitsPerPixel];
+ }
+ else
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
+ }
+ }
+ return 0;
+}
+
+void FreeScreen(ScreenPtr);
+
+/*
+ grow the array of screenRecs if necessary.
+ call the device-supplied initialization procedure
+ with its screen number, a pointer to its ScreenRec, argc, and argv.
+ return the number of successfully installed screens.
+*/
+
+int
+AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
+ int /*argc */ ,
+ char ** /*argv */
+ ), int argc, char **argv)
+{
+
+ int i;
+ ScreenPtr pScreen;
+ Bool ret;
+
+ i = screenInfo.numScreens;
+ if (i == MAXSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ pScreen->devPrivates = (DevUnion *)calloc(sizeof(DevUnion),
+ screenPrivateCount);
+ if (!pScreen->devPrivates && screenPrivateCount)
+ return -1;
+
+ ret = init_screen(pScreen, i);
+ if (ret != 0) {
+ free(pScreen);
+ return ret;
+ }
+ /* This is where screen specific stuff gets initialized. Load the
+ screen structure, call the hardware, whatever.
+ This is also where the default colormap should be allocated and
+ also pixel values for blackPixel, whitePixel, and the cursor
+ Note that InitScreen is NOT allowed to modify argc, argv, or
+ any of the strings pointed to by argv. They may be passed to
+ multiple screens.
+ */
+ pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
+ screenInfo.screens[i] = pScreen;
+ screenInfo.numScreens++;
+ if (!(*pfnInit)(pScreen, argc, argv))
+ {
+ FreeScreen(pScreen);
+ screenInfo.numScreens--;
+ return -1;
+ }
+ return i;
+}
+
+void
+FreeScreen(ScreenPtr pScreen)
+{
+ pScreen->root = NullWindow;
+ free(pScreen->WindowPrivateSizes);
+ free(pScreen->GCPrivateSizes);
+#ifdef PIXPRIV
+ free(pScreen->PixmapPrivateSizes);
+#endif
+ free(pScreen->devPrivates);
+ free(pScreen);
+}
diff --git a/nx-X11/programs/Xserver/dix/dispatch.h b/nx-X11/programs/Xserver/dix/dispatch.h
new file mode 100644
index 000000000..dd07096af
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/dispatch.h
@@ -0,0 +1,146 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/*
+ * This prototypes the dispatch.c module (except for functions declared in
+ * global headers), plus related dispatch procedures from devices.c, events.c,
+ * extension.c, property.c.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef DISPATCH_H
+#define DISPATCH_H 1
+
+DISPATCH_PROC(InitClientPrivates);
+DISPATCH_PROC(ProcAllocColor);
+DISPATCH_PROC(ProcAllocColorCells);
+DISPATCH_PROC(ProcAllocColorPlanes);
+DISPATCH_PROC(ProcAllocNamedColor);
+DISPATCH_PROC(ProcBell);
+DISPATCH_PROC(ProcChangeAccessControl);
+DISPATCH_PROC(ProcChangeCloseDownMode);
+DISPATCH_PROC(ProcChangeGC);
+DISPATCH_PROC(ProcChangeHosts);
+DISPATCH_PROC(ProcChangeKeyboardControl);
+DISPATCH_PROC(ProcChangeKeyboardMapping);
+DISPATCH_PROC(ProcChangePointerControl);
+DISPATCH_PROC(ProcChangeProperty);
+DISPATCH_PROC(ProcChangeSaveSet);
+DISPATCH_PROC(ProcChangeWindowAttributes);
+DISPATCH_PROC(ProcCirculateWindow);
+DISPATCH_PROC(ProcClearToBackground);
+DISPATCH_PROC(ProcCloseFont);
+DISPATCH_PROC(ProcConfigureWindow);
+DISPATCH_PROC(ProcConvertSelection);
+DISPATCH_PROC(ProcCopyArea);
+DISPATCH_PROC(ProcCopyColormapAndFree);
+DISPATCH_PROC(ProcCopyGC);
+DISPATCH_PROC(ProcCopyPlane);
+DISPATCH_PROC(ProcCreateColormap);
+DISPATCH_PROC(ProcCreateCursor);
+DISPATCH_PROC(ProcCreateGC);
+DISPATCH_PROC(ProcCreateGlyphCursor);
+DISPATCH_PROC(ProcCreatePixmap);
+DISPATCH_PROC(ProcCreateWindow);
+DISPATCH_PROC(ProcDeleteProperty);
+DISPATCH_PROC(ProcDestroySubwindows);
+DISPATCH_PROC(ProcDestroyWindow);
+DISPATCH_PROC(ProcEstablishConnection);
+DISPATCH_PROC(ProcFillPoly);
+DISPATCH_PROC(ProcForceScreenSaver);
+DISPATCH_PROC(ProcFreeColormap);
+DISPATCH_PROC(ProcFreeColors);
+DISPATCH_PROC(ProcFreeCursor);
+DISPATCH_PROC(ProcFreeGC);
+DISPATCH_PROC(ProcFreePixmap);
+DISPATCH_PROC(ProcGetAtomName);
+DISPATCH_PROC(ProcGetFontPath);
+DISPATCH_PROC(ProcGetGeometry);
+DISPATCH_PROC(ProcGetImage);
+DISPATCH_PROC(ProcGetKeyboardControl);
+DISPATCH_PROC(ProcGetKeyboardMapping);
+DISPATCH_PROC(ProcGetModifierMapping);
+DISPATCH_PROC(ProcGetMotionEvents);
+DISPATCH_PROC(ProcGetPointerControl);
+DISPATCH_PROC(ProcGetPointerMapping);
+DISPATCH_PROC(ProcGetProperty);
+DISPATCH_PROC(ProcGetScreenSaver);
+DISPATCH_PROC(ProcGetSelectionOwner);
+DISPATCH_PROC(ProcGetWindowAttributes);
+DISPATCH_PROC(ProcGrabServer);
+DISPATCH_PROC(ProcImageText16);
+DISPATCH_PROC(ProcImageText8);
+DISPATCH_PROC(ProcInitialConnection);
+DISPATCH_PROC(ProcInstallColormap);
+DISPATCH_PROC(ProcInternAtom);
+DISPATCH_PROC(ProcKillClient);
+DISPATCH_PROC(ProcListExtensions);
+DISPATCH_PROC(ProcListFonts);
+DISPATCH_PROC(ProcListFontsWithInfo);
+DISPATCH_PROC(ProcListHosts);
+DISPATCH_PROC(ProcListInstalledColormaps);
+DISPATCH_PROC(ProcListProperties);
+DISPATCH_PROC(ProcLookupColor);
+DISPATCH_PROC(ProcMapSubwindows);
+DISPATCH_PROC(ProcMapWindow);
+DISPATCH_PROC(ProcNoOperation);
+DISPATCH_PROC(ProcOpenFont);
+DISPATCH_PROC(ProcPolyArc);
+DISPATCH_PROC(ProcPolyFillArc);
+DISPATCH_PROC(ProcPolyFillRectangle);
+DISPATCH_PROC(ProcPolyLine);
+DISPATCH_PROC(ProcPolyPoint);
+DISPATCH_PROC(ProcPolyRectangle);
+DISPATCH_PROC(ProcPolySegment);
+DISPATCH_PROC(ProcPolyText);
+DISPATCH_PROC(ProcPutImage);
+DISPATCH_PROC(ProcQueryBestSize);
+DISPATCH_PROC(ProcQueryColors);
+DISPATCH_PROC(ProcQueryExtension);
+DISPATCH_PROC(ProcQueryFont);
+DISPATCH_PROC(ProcQueryKeymap);
+DISPATCH_PROC(ProcQueryTextExtents);
+DISPATCH_PROC(ProcQueryTree);
+DISPATCH_PROC(ProcReparentWindow);
+DISPATCH_PROC(ProcRotateProperties);
+DISPATCH_PROC(ProcSetClipRectangles);
+DISPATCH_PROC(ProcSetDashes);
+DISPATCH_PROC(ProcSetFontPath);
+DISPATCH_PROC(ProcSetModifierMapping);
+DISPATCH_PROC(ProcSetPointerMapping);
+DISPATCH_PROC(ProcSetScreenSaver);
+DISPATCH_PROC(ProcSetSelectionOwner);
+DISPATCH_PROC(ProcStoreColors);
+DISPATCH_PROC(ProcStoreNamedColor);
+DISPATCH_PROC(ProcTranslateCoords);
+DISPATCH_PROC(ProcUngrabServer);
+DISPATCH_PROC(ProcUninstallColormap);
+DISPATCH_PROC(ProcUnmapSubwindows);
+DISPATCH_PROC(ProcUnmapWindow);
+
+#endif /* DISPATCH_H */
diff --git a/nx-X11/programs/Xserver/dix/dixfonts.c b/nx-X11/programs/Xserver/dix/dixfonts.c
new file mode 100644
index 000000000..98d2a6439
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/dixfonts.c
@@ -0,0 +1,2553 @@
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "list.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#endif /* HAS_XFONT2 */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <nx-X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+#ifndef HAS_XFONT2
+extern void register_fpe_functions(void);
+#endif
+
+extern void * fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+#ifdef HAS_XFONT2
+xfont2_fpe_funcs_rec const **fpe_functions;
+#else
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+#endif
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+#ifdef HAS_XFONT2
+xfont2_pattern_cache_ptr patternCache;
+#else
+static FontPatternCachePtr patternCache;
+#endif /* HAS_FONT2 */
+
+int
+FontToXError(err)
+ int err;
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+ if (pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ realloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(void * data, int count, void * LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->wakeup_fpe) (fpe);
+#else
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+#endif /* HAS_XFONT2 */
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->free_fpe) (fpe);
+#else
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+#endif
+ free(fpe->name);
+ free(fpe);
+ }
+}
+
+#ifndef NXAGENT_SERVER
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->open_font)
+#else
+ err = (*fpe_functions[fpe->type].open_font)
+#endif /* HAS_XFONT2 */
+ ((void *) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) realloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (void *) c);
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ /* check values for firstCol, lastCol, firstRow, and lastRow */
+ if (pfont->info.firstCol > pfont->info.lastCol ||
+ pfont->info.firstRow > pfont->info.lastRow ||
+ pfont->info.lastCol - pfont->info.firstCol > 255) {
+ err = AllocError;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+ if (!(*pScr->RealizeFont) (pScr, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (void *) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+#ifdef HAS_XFONT2
+ xfont2_cache_font_pattern(patternCache, c->origFontName, c->origFontNameLen,
+#else
+ CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+#endif /* HAS_XFONT2 */
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ ClientWakeup(c->client);
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ free(c->fpe_list);
+ free(c->fontname);
+ free(c);
+ return TRUE;
+}
+#endif /* NXAGENT_SERVER */
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)malloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ free(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+#ifdef HAS_XFONT2
+ cached = xfont2_find_cached_font_pattern(patternCache, pfontname, lenfname);
+#else
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+#endif /* HAS_XFONT2 */
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (void *) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = (OFclosurePtr) malloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = (char *) malloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ free(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ free(c->fontname);
+ free(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+int
+CloseFont(void * value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+#ifdef HAS_XFONT2
+ xfont2_remove_cached_font_pattern(patternCache, pfont);
+#else
+ RemoveCachedFontPattern (patternCache, pfont);
+#endif /* HAS_XFONT2 */
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef XF86BIGFONT
+ XF86BigfontFreeFontShm(pfont);
+#endif
+ fpe = pfont->fpe;
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->close_font) (fpe, pfont);
+#else
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+#endif
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+#ifndef NXAGENT_SERVER
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+#ifdef HAS_XFONT2
+ if (!fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_fonts)
+#else
+ err = (*fpe_functions[fpe->type].list_fonts)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) free(resolved);
+ resolved = (char *) malloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+#ifdef HAS_XFONT2
+ (void)xfont2_add_font_names_name(c->names, c->savedName,
+#else
+ (void)AddFontNamesName(c->names, c->savedName,
+#endif /* HAS_XFONT2 */
+ c->savedNameLen);
+ }
+ else
+#ifdef HAS_XFONT2
+ (void)xfont2_add_font_names_name(c->names, name, namelen);
+#else
+ (void)AddFontNamesName(c->names, name, namelen);
+#endif /* HAS_XFONT2 */
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ free(c->savedName);
+ c->savedName = (char *)malloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ memset(&reply, 0, sizeof(xListFontsReply));
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) malloc(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ WriteToClient(client, stringLens + nnames, bufferStart);
+ free(bufferStart);
+
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ if (c->savedName) free(c->savedName);
+#ifdef HAS_XFONT2
+ xfont2_free_font_names(names);
+#else
+ FreeFontNames(names);
+#endif /* HAS_XFONT2 */
+ free(c);
+ if (resolved) free(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) malloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ free(c);
+ return BadAlloc;
+ }
+#ifdef HAS_XFONT2
+ c->names = xfont2_make_font_names_record(max_names < 100 ? max_names : 100);
+#else
+ c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+#endif /* HAS_XFONT2 */
+ if (!c->names)
+ {
+ free(c->fpe_list);
+ free(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->start_list_fonts_with_info)
+#else
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_next_font_with_info)
+#else
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->list_next_font_with_info)
+#else
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ free(c->savedName);
+ c->savedName = (char *)malloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) realloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ memset(reply + c->length, 0, length - c->length);
+ c->reply = reply;
+ c->length = length;
+ }
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ free(fontInfo.props);
+ free(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->reply);
+ free(c->fpe_list);
+ if (c->savedName) free(c->savedName);
+ free(c);
+ return TRUE;
+}
+#endif /* NXAGENT_SERVER */
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFWIclosurePtr) malloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ free(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+ register FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, DixWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ c->pDraw = (DrawablePtr)0;
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+ DixReadAccess);
+ if (!pFont)
+ {
+ client->errorValue = fid;
+ err = BadFont;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = (PTclosurePtr) malloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = (unsigned char *)malloc(len);
+ if (!c->data)
+ {
+ free(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ free(c->data);
+ free(c);
+ err = BadAlloc;
+ goto bail;
+ }
+
+#ifdef NXAGENT_SERVER
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+#endif
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ free(c->data);
+ free(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (void *) c);
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ free(c->data);
+ free(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept &&
+ c->pDraw &&
+ c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+ RC_DRAWABLE, DixWriteAccess))
+ {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ err = Success;
+ goto bail;
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+ ITclosurePtr old_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = (ITclosurePtr) malloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ old_closure = c;
+ *new_closure = *c;
+ c = new_closure;
+
+ data = (unsigned char *)malloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ free(c);
+ c = old_closure;
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ free(c->data);
+ free(c);
+ c = old_closure;
+ err = BadAlloc;
+ goto bail;
+ }
+
+#ifdef NXAGENT_SERVER
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+#endif
+
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ free(c->data);
+ free(c);
+ c = old_closure;
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (void *) c);
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ free(c->data);
+ free(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+#ifdef HAS_XFONT2
+ if ((*fpe_functions[i]->name_check) (pathname))
+#else
+ if ((*fpe_functions[i].name_check) (pathname))
+#endif /* HAS_XFONT2 */
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+ list[i]->name_length, list[i]->name,
+ list[i]->refcount, found);
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ free((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+#ifdef HAS_XFONT2
+ if (fpe_functions[i]->set_path_hook)
+ (*fpe_functions[i]->set_path_hook) ();
+#else
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+#endif /* HAS_XFONT2 */
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF ("Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->reset_fpe) (fpe);
+#else
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+#endif /* HAS_XFONT2 */
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = (FontPathElementPtr) malloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = (char *) malloc(len + 1);
+ if (!fpe->name)
+ {
+ free(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->init_fpe) (fpe);
+#else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+#endif /* HAS_XFONT2 */
+ if (err != Successful)
+ {
+#ifndef NXAGENT_SERVER
+ if (persist)
+ {
+ ErrorF("Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+#endif /* NXAGENT_SERVER */
+ free (fpe->name);
+ free (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+#ifdef HAS_XFONT2
+ xfont2_empty_font_pattern_cache(patternCache);
+#else
+ EmptyFontPatternCache(patternCache);
+#endif /* HAS_XFONT2 */
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ free(fplist);
+ return FontToXError(err);
+}
+
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths)
+{
+ int err = Success;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ int bad;
+ err = SetFontPathElements(npaths, paths, &bad, FALSE);
+ client->errorValue = bad;
+ }
+ return err;
+}
+
+#ifndef NXAGENT_SERVER
+int
+SetDefaultFontPath(char *path)
+{
+ char *temp_path,
+ *start,
+ *end;
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* ensure temp_path contains "built-ins" */
+ start = path;
+ while (1) {
+ start = strstr(start, "built-ins");
+ if (start == NULL)
+ break;
+ end = start + strlen("built-ins");
+ if ((start == path || start[-1] == ',') && (!*end || *end == ','))
+ break;
+ start = end;
+ }
+ if (!start) {
+ if (asprintf(&temp_path, "%s%sbuilt-ins", path, *path ? "," : "")
+ == -1)
+ temp_path = NULL;
+ }
+ else {
+ temp_path = strdup(path);
+ }
+ if (!temp_path)
+ return BadAlloc;
+
+ /* get enough for string, plus values -- use up commas */
+ len = strlen(temp_path) + 1;
+ nump = cp = newpath = (unsigned char *) malloc(len);
+ if (!newpath) {
+ free(temp_path);
+ return BadAlloc;
+ }
+ pp = (unsigned char *) temp_path;
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ free(newpath);
+ free(temp_path);
+
+ return err;
+}
+#endif /* NXAGENT_SERVER */
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ c = realloc(font_path_string, len);
+ if (c == NULL) {
+ free(font_path_string);
+ font_path_string = NULL;
+ return NULL;
+ }
+
+ font_path_string = c;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+#ifdef HAS_XFONT2
+ if (fpe_functions[pfont->fpe->type]->load_glyphs)
+ return (*fpe_functions[pfont->fpe->type]->load_glyphs)
+#else
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+#endif
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+void
+#ifdef HAS_XFONT2
+GetGlyphs(FontPtr font, unsigned long count, unsigned char *chars,
+ FontEncoding fontEncoding,
+ unsigned long *glyphcount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+#else
+dixGetGlyphs(FontPtr font, unsigned long count, unsigned char *chars,
+ FontEncoding fontEncoding,
+ unsigned long *glyphcount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+#endif /* HAS_XFONT2 */
+ {
+ (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs);
+ }
+
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+#ifdef HAS_XFONT2
+ if (fpe_functions[fpe->type]->client_died)
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+}
+
+#ifdef HAS_XFONT2
+static int
+register_fpe_funcs(const xfont2_fpe_funcs_rec *funcs)
+{
+ xfont2_fpe_funcs_rec const **new;
+
+ /* grow the list */
+ new = reallocarray(fpe_functions, num_fpe_types + 1, sizeof(xfont2_fpe_funcs_ptr));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types] = funcs;
+
+ return num_fpe_types++;
+}
+#else
+void
+InitFonts ()
+{
+ patternCache = MakeFontPatternCache();
+
+ ResetFontPrivateIndex();
+
+ register_fpe_functions();
+}
+#endif /* HAS_XFONT2 */
+
+#ifdef HAS_XFONT2
+static unsigned long
+get_server_generation(void)
+{
+ return serverGeneration;
+}
+
+static void *
+get_server_client(void)
+{
+ return serverClient;
+}
+
+static int
+get_default_point_size(void)
+#else
+int
+GetDefaultPointSize ()
+#endif /* HAS_XFONT2 */
+{
+ return 120;
+}
+
+#ifdef HAS_XFONT2
+static FontResolutionPtr
+get_client_resolutions(int *num)
+#else
+FontResolutionPtr
+GetClientResolutions (int *num)
+#endif /* HAS_XFONT2 */
+{
+ if (requestingClient && requestingClient->fontResFunc != NULL &&
+ !requestingClient->clientGone)
+ {
+ return (*requestingClient->fontResFunc)(requestingClient, num);
+ }
+ else {
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+ }
+}
+
+#ifndef HAS_XFONT2
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) realloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+#endif /* !HAS_XFONT2 */
+
+void
+FreeFonts()
+{
+ if (patternCache) {
+#ifdef HAS_XFONT2
+ xfont2_free_font_pattern_cache(patternCache);
+#else
+ FreeFontPatternCache(patternCache);
+#endif /* HAS_XFONT2 */
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ free(fpe_functions);
+ num_fpe_types = 0;
+#ifdef HAS_XFONT2
+ fpe_functions = NULL;
+#else
+ fpe_functions = (FPEFunctions *) 0;
+#endif /* HAS_XFONT2 */
+}
+
+/* convenience functions for FS interface */
+
+#ifdef HAS_XFONT2
+static
+#endif /* HAS_XFONT2 */
+FontPtr
+find_old_font(XID id)
+{
+ return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+ DixUnknownAccess);
+}
+
+#ifdef HAS_XFONT2
+static Font
+get_new_font_client_id(void)
+#else
+Font
+GetNewFontClientID()
+#endif /* HAS_XFONT2 */
+{
+ return FakeClientID(0);
+}
+
+#ifdef HAS_XFONT2
+static int
+store_font_Client_font(FontPtr pfont, Font id)
+#else
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+#endif /* HAS_XFONT2 */
+{
+ return AddResource(id, RT_NONE, (void *) pfont);
+}
+
+#ifdef HAS_XFONT2
+static void
+delete_font_client_id(Font id)
+#else
+void
+DeleteFontClientID(Font id)
+#endif /* HAS_XFONT2 */
+{
+ FreeResource(id, RT_NONE);
+}
+
+#ifdef HAS_XFONT2
+static int
+_client_auth_generation(ClientPtr client)
+#else
+int
+client_auth_generation(ClientPtr client)
+#endif /* HAS_XFONT2 */
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+#ifdef HAS_XFONT2
+static void
+fs_block_handler(void *blockData, OSTimePtr timeout, void *readmask)
+{
+ FontBlockHandlerProcPtr block_handler = blockData;
+
+ (*block_handler)(timeout);
+}
+
+struct fs_fd_entry {
+ struct xorg_list entry;
+ int fd;
+ void *data;
+ FontFdHandlerProcPtr handler;
+};
+
+static void
+fs_fd_handler(int fd, int ready, void *data)
+{
+ struct fs_fd_entry *entry = data;
+
+ entry->handler(fd, entry->data);
+}
+
+static struct xorg_list fs_fd_list;
+
+static int
+add_fs_fd(int fd, FontFdHandlerProcPtr handler, void *data)
+{
+ struct fs_fd_entry *entry = calloc(1, sizeof (struct fs_fd_entry));
+
+ if (!entry)
+ return FALSE;
+
+ entry->fd = fd;
+ entry->data = data;
+ entry->handler = handler;
+ if (!SetNotifyFd(fd, fs_fd_handler, X_NOTIFY_READ, entry)) {
+ free(entry);
+ return FALSE;
+ }
+ xorg_list_add(&entry->entry, &fs_fd_list);
+ return TRUE;
+}
+
+static void
+remove_fs_fd(int fd)
+{
+ struct fs_fd_entry *entry, *temp;
+
+ xorg_list_for_each_entry_safe(entry, temp, &fs_fd_list, entry) {
+ if (entry->fd == fd) {
+ xorg_list_del(&entry->entry);
+ free(entry);
+ break;
+ }
+ }
+ RemoveNotifyFd(fd);
+}
+
+static void
+adjust_fs_wait_for_delay(void *wt, unsigned long newdelay)
+{
+ AdjustWaitForDelay(wt, newdelay);
+}
+
+static int
+_init_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler)
+#else
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+#endif /* HAS_XFONT2 */
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+#ifdef HAS_XFONT2
+ if (!RegisterBlockAndWakeupHandlers(fs_block_handler,
+ FontWakeup, (void *) block_handler))
+#else
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (void *) 0))
+#endif /* HAS_XFONT2 */
+ return AllocError;
+#ifdef HAS_XFONT2
+ xorg_list_init(&fs_fd_list);
+#endif /* HAS_XFONT2 */
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+#ifdef HAS_XFONT2
+static void
+_remove_fs_handlers(FontPathElementPtr fpe, FontBlockHandlerProcPtr block_handler, Bool all)
+#else
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+#endif /* HAS_XFONT2 */
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+#ifdef HAS_XFONT2
+ RemoveBlockAndWakeupHandlers(fs_block_handler, FontWakeup,
+ (void *) block_handler);
+#else
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (void *) 0);
+#endif /* HAS_XFONT2 */
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+#ifdef HAS_XFONT2
+static const xfont2_client_funcs_rec xfont2_client_funcs = {
+ .version = XFONT2_CLIENT_FUNCS_VERSION,
+ .client_auth_generation = _client_auth_generation,
+ .client_signal = ClientSignal,
+ .delete_font_client_id = delete_font_client_id,
+ .verrorf = VErrorF,
+ .find_old_font = find_old_font,
+ .get_client_resolutions = get_client_resolutions,
+ .get_default_point_size = get_default_point_size,
+ .get_new_font_client_id = get_new_font_client_id,
+ .get_time_in_millis = GetTimeInMillis,
+ .init_fs_handlers = _init_fs_handlers,
+ .register_fpe_funcs = register_fpe_funcs,
+ .remove_fs_handlers = _remove_fs_handlers,
+ .get_server_client = get_server_client,
+ .set_font_authorizations = set_font_authorizations,
+ .store_font_client_font = store_font_Client_font,
+ .make_atom = MakeAtom,
+ .valid_atom = ValidAtom,
+ .name_for_atom = NameForAtom,
+ .get_server_generation = get_server_generation,
+ .add_fs_fd = add_fs_fd,
+ .remove_fs_fd = remove_fs_fd,
+ .adjust_fs_wait_for_delay = adjust_fs_wait_for_delay,
+};
+
+xfont2_pattern_cache_ptr fontPatternCache;
+
+void
+InitFonts(void)
+{
+ if (fontPatternCache)
+ xfont2_free_font_pattern_cache(fontPatternCache);
+ fontPatternCache = xfont2_make_font_pattern_cache();
+ xfont2_init(&xfont2_client_funcs);
+}
+#endif /* HAS_XFONT2 */
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+ int r,
+ l;
+ int bpr;
+ int byte;
+ static unsigned maskTab[] = {
+ (1 << 7), (1 << 6), (1 << 5), (1 << 4),
+ (1 << 3), (1 << 2), (1 << 1), (1 << 0),
+ };
+
+ bpr = GLYPH_SIZE(cip, 4);
+ for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+ void * row = (void *) cip->bits + r * bpr;
+
+ byte = 0;
+ for (l = 0; l <= (cip->metrics.rightSideBearing -
+ cip->metrics.leftSideBearing); l++) {
+ if (maskTab[l & 7] & (((int*)row)[l >> 3]))
+ putchar('X');
+ else
+ putchar('.');
+ }
+ putchar('\n');
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/dix/dixutils.c b/nx-X11/programs/Xserver/dix/dixutils.c
new file mode 100644
index 000000000..3ccc90d71
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/dixutils.c
@@ -0,0 +1,923 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+/*
+
+(c)Copyright 1988,1991 Adobe Systems Incorporated. All rights reserved.
+
+Permission to use, copy, modify, distribute, and sublicense this software and its
+documentation for any purpose and without fee is hereby granted, provided that
+the above copyright notices appear in all copies and that both those copyright
+notices and this permission notice appear in supporting documentation and that
+the name of Adobe Systems Incorporated not be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission. No trademark license to use the Adobe trademarks is hereby
+granted. If the Adobe trademark "Display PostScript"(tm) is used to describe
+this software, its functionality or for any other purpose, such use shall be
+limited to a statement that this software works in conjunction with the Display
+PostScript system. Proper trademark attribution to reflect Adobe's ownership
+of the trademark shall be given whenever any such reference to the Display
+PostScript system is made.
+
+ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
+PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. ADOBE
+DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
+INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
+OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
+LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
+SUPPORT FOR THE SOFTWARE.
+
+Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+Incorporated which may be registered in certain jurisdictions.
+
+Author: Adobe Systems Incorporated
+
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#define XK_LATIN1
+#include <nx-X11/keysymdef.h>
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+/*
+ * CompareTimeStamps returns -1, 0, or +1 depending on if the first
+ * argument is less than, equal to or greater than the second argument.
+ */
+
+int
+CompareTimeStamps(TimeStamp a, TimeStamp b)
+{
+ if (a.months < b.months)
+ return EARLIER;
+ if (a.months > b.months)
+ return LATER;
+ if (a.milliseconds < b.milliseconds)
+ return EARLIER;
+ if (a.milliseconds > b.milliseconds)
+ return LATER;
+ return SAMETIME;
+}
+
+/*
+ * convert client times to server TimeStamps
+ */
+
+#define HALFMONTH ((unsigned long) 1<<31)
+TimeStamp
+ClientTimeToServerTime(CARD32 c)
+{
+ TimeStamp ts;
+ if (c == CurrentTime)
+ return currentTime;
+ ts.months = currentTime.months;
+ ts.milliseconds = c;
+ if (c > currentTime.milliseconds)
+ {
+ if (((unsigned long) c - currentTime.milliseconds) > HALFMONTH)
+ ts.months -= 1;
+ }
+ else if (c < currentTime.milliseconds)
+ {
+ if (((unsigned long)currentTime.milliseconds - c) > HALFMONTH)
+ ts.months += 1;
+ }
+ return ts;
+}
+
+/*
+ * ISO Latin-1 case conversion routine
+ *
+ * this routine always null-terminates the result, so
+ * beware of too-small buffers
+ */
+
+static unsigned char
+ISOLatin1ToLower (unsigned char source)
+{
+ unsigned char dest;
+ if ((source >= XK_A) && (source <= XK_Z))
+ dest = source + (XK_a - XK_A);
+ else if ((source >= XK_Agrave) && (source <= XK_Odiaeresis))
+ dest = source + (XK_agrave - XK_Agrave);
+ else if ((source >= XK_Ooblique) && (source <= XK_Thorn))
+ dest = source + (XK_oslash - XK_Ooblique);
+ else
+ dest = source;
+ return dest;
+}
+
+
+void
+CopyISOLatin1Lowered(char *dest, const char *source, int length)
+{
+ register int i;
+
+ for (i = 0; i < length; i++, source++, dest++)
+ *dest = ISOLatin1ToLower (*source);
+ *dest = '\0';
+}
+
+int
+CompareISOLatin1Lowered(unsigned char *s1, int s1len,
+ unsigned char *s2, int s2len)
+{
+ unsigned char c1, c2;
+
+ for (;;)
+ {
+ /* note -- compare against zero so that -1 ignores len */
+ c1 = s1len-- ? *s1++ : '\0';
+ c2 = s2len-- ? *s2++ : '\0';
+ if (!c1 ||
+ (c1 != c2 &&
+ (c1 = ISOLatin1ToLower (c1)) != (c2 = ISOLatin1ToLower (c2))))
+ break;
+ }
+ return (int) c1 - (int) c2;
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupWindow and SecurityLookupDrawable:
+ * Look up the window/drawable taking into account the client doing
+ * the lookup and the type of access desired. Return the window/drawable
+ * if it exists and the client is allowed access, else return NULL.
+ * Most Proc* functions should be calling these instead of
+ * LookupWindow and LookupDrawable, which do no access checks.
+ */
+
+WindowPtr
+SecurityLookupWindow(XID rid, ClientPtr client, Mask access_mode)
+{
+ client->errorValue = rid;
+ if(rid == INVALID)
+ return NULL;
+ return (WindowPtr)SecurityLookupIDByType(client, rid, RT_WINDOW, access_mode);
+}
+
+
+void *
+SecurityLookupDrawable(XID rid, ClientPtr client, Mask access_mode)
+{
+ register DrawablePtr pDraw;
+
+ if(rid == INVALID)
+ return (void *) NULL;
+ pDraw = (DrawablePtr)SecurityLookupIDByClass(client, rid, RC_DRAWABLE,
+ access_mode);
+ if ((client->trustLevel != XSecurityClientTrusted) || (pDraw && (pDraw->type != UNDRAWABLE_WINDOW)))
+ return (void *)pDraw;
+ return (void *)NULL;
+}
+
+/* We can't replace the LookupWindow and LookupDrawable functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+WindowPtr
+LookupWindow(XID rid, ClientPtr client)
+{
+ return SecurityLookupWindow(rid, client, DixUnknownAccess);
+}
+
+void *
+LookupDrawable(XID rid, ClientPtr client)
+{
+ return SecurityLookupDrawable(rid, client, DixUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+WindowPtr
+LookupWindow(XID rid, ClientPtr client)
+{
+ WindowPtr pWin;
+
+ client->errorValue = rid;
+ if(rid == INVALID)
+ return NULL;
+ return (WindowPtr)LookupIDByType(rid, RT_WINDOW);
+}
+
+
+void *
+LookupDrawable(XID rid, ClientPtr client)
+{
+ register DrawablePtr pDraw;
+
+ if(rid == INVALID)
+ return (void *) NULL;
+ pDraw = (DrawablePtr)LookupIDByClass(rid, RC_DRAWABLE);
+ if (pDraw && (pDraw->type != UNDRAWABLE_WINDOW))
+ return (void *)pDraw;
+ return (void *)NULL;
+}
+
+#endif /* XCSECURITY */
+
+ClientPtr
+LookupClient(XID rid, ClientPtr client)
+{
+ void * pRes = (void *)SecurityLookupIDByClass(client, rid, RC_ANY,
+ DixReadAccess);
+ int clientIndex = CLIENT_ID(rid);
+
+ if (clientIndex && pRes && clients[clientIndex] && !(rid & SERVER_BIT))
+ {
+ return clients[clientIndex];
+ }
+ return (ClientPtr)NULL;
+}
+
+
+int
+AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode,
+ Bool toRoot, Bool remap)
+{
+ int numnow;
+ SaveSetElt *pTmp = NULL;
+ int j;
+
+ numnow = client->numSaved;
+ j = 0;
+ if (numnow)
+ {
+ pTmp = client->saveSet;
+ while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (void *)pWin))
+ j++;
+ }
+ if (mode == SetModeInsert)
+ {
+ if (j < numnow) /* duplicate */
+ return(Success);
+ numnow++;
+ pTmp = (SaveSetElt *)realloc(client->saveSet, sizeof(*pTmp) * numnow);
+ if (!pTmp)
+ return(BadAlloc);
+ client->saveSet = pTmp;
+ client->numSaved = numnow;
+ SaveSetAssignWindow(client->saveSet[numnow - 1], pWin);
+ SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot);
+ SaveSetAssignRemap(client->saveSet[numnow - 1], remap);
+ return(Success);
+ }
+ else if ((mode == SetModeDelete) && (j < numnow))
+ {
+ while (j < numnow-1)
+ {
+ pTmp[j] = pTmp[j+1];
+ j++;
+ }
+ numnow--;
+ if (numnow)
+ {
+ pTmp = (SaveSetElt *)realloc(client->saveSet, sizeof(*pTmp) * numnow);
+ if (pTmp)
+ client->saveSet = pTmp;
+ }
+ else
+ {
+ free(client->saveSet);
+ client->saveSet = (SaveSetElt *)NULL;
+ }
+ client->numSaved = numnow;
+ return(Success);
+ }
+ return(Success);
+}
+
+void
+DeleteWindowFromAnySaveSet(WindowPtr pWin)
+{
+ register int i;
+ register ClientPtr client;
+
+ for (i = 0; i< currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && client->numSaved)
+ (void)AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, TRUE);
+ }
+}
+
+/* No-op Don't Do Anything : sometimes we need to be able to call a procedure
+ * that doesn't do anything. For example, on screen with only static
+ * colormaps, if someone calls install colormap, it's easier to have a dummy
+ * procedure to call than to check if there's a procedure
+ */
+void
+NoopDDA(void)
+{
+}
+
+typedef struct _BlockHandler {
+ BlockHandlerProcPtr BlockHandler;
+ WakeupHandlerProcPtr WakeupHandler;
+ void * blockData;
+ Bool deleted;
+} BlockHandlerRec, *BlockHandlerPtr;
+
+static BlockHandlerPtr handlers;
+static int numHandlers;
+static int sizeHandlers;
+static Bool inHandler;
+static Bool handlerDeleted;
+
+/**
+ *
+ * \param pTimeout DIX doesn't want to know how OS represents time
+ * \param pReadMask nor how it represents the det of descriptors
+ */
+void
+BlockHandler(void * pTimeout, void * pReadmask)
+{
+ register int i, j;
+
+ ++inHandler;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ (* screenInfo.screens[i]->BlockHandler)(i,
+ screenInfo.screens[i]->blockData,
+ pTimeout, pReadmask);
+ for (i = 0; i < numHandlers; i++)
+ (*handlers[i].BlockHandler) (handlers[i].blockData,
+ pTimeout, pReadmask);
+ if (handlerDeleted)
+ {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted)
+ {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j+1];
+ numHandlers--;
+ }
+ else
+ i++;
+ handlerDeleted = FALSE;
+ }
+ --inHandler;
+}
+
+/**
+ *
+ * \param result 32 bits of undefined result from the wait
+ * \param pReadmask the resulting descriptor mask
+ */
+void
+WakeupHandler(int result, void * pReadmask)
+{
+ register int i, j;
+
+ ++inHandler;
+ for (i = numHandlers - 1; i >= 0; i--)
+ (*handlers[i].WakeupHandler) (handlers[i].blockData,
+ result, pReadmask);
+ for (i = 0; i < screenInfo.numScreens; i++)
+ (* screenInfo.screens[i]->WakeupHandler)(i,
+ screenInfo.screens[i]->wakeupData,
+ result, pReadmask);
+ if (handlerDeleted)
+ {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted)
+ {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j+1];
+ numHandlers--;
+ }
+ else
+ i++;
+ handlerDeleted = FALSE;
+ }
+ --inHandler;
+}
+
+/**
+ * Reentrant with BlockHandler and WakeupHandler, except wakeup won't
+ * get called until next time
+ */
+Bool
+RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ void * blockData)
+{
+ BlockHandlerPtr new;
+
+ if (numHandlers >= sizeHandlers)
+ {
+ new = (BlockHandlerPtr) realloc (handlers, (numHandlers + 1) *
+ sizeof (BlockHandlerRec));
+ if (!new)
+ return FALSE;
+ handlers = new;
+ sizeHandlers = numHandlers + 1;
+ }
+ handlers[numHandlers].BlockHandler = blockHandler;
+ handlers[numHandlers].WakeupHandler = wakeupHandler;
+ handlers[numHandlers].blockData = blockData;
+ handlers[numHandlers].deleted = FALSE;
+ numHandlers = numHandlers + 1;
+ return TRUE;
+}
+
+void
+RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+ WakeupHandlerProcPtr wakeupHandler,
+ void * blockData)
+{
+ int i;
+
+ for (i = 0; i < numHandlers; i++)
+ if (handlers[i].BlockHandler == blockHandler &&
+ handlers[i].WakeupHandler == wakeupHandler &&
+ handlers[i].blockData == blockData)
+ {
+ if (inHandler)
+ {
+ handlerDeleted = TRUE;
+ handlers[i].deleted = TRUE;
+ }
+ else
+ {
+ for (; i < numHandlers - 1; i++)
+ handlers[i] = handlers[i+1];
+ numHandlers--;
+ }
+ break;
+ }
+}
+
+void
+InitBlockAndWakeupHandlers ()
+{
+ free (handlers);
+ handlers = (BlockHandlerPtr) 0;
+ numHandlers = 0;
+ sizeHandlers = 0;
+}
+
+/*
+ * A general work queue. Perform some task before the server
+ * sleeps for input.
+ */
+
+WorkQueuePtr workQueue;
+static WorkQueuePtr *workQueueLast = &workQueue;
+
+void
+ProcessWorkQueue(void)
+{
+ WorkQueuePtr q, *p;
+
+ p = &workQueue;
+ /*
+ * Scan the work queue once, calling each function. Those
+ * which return TRUE are removed from the queue, otherwise
+ * they will be called again. This must be reentrant with
+ * QueueWorkProc.
+ */
+ while ((q = *p))
+ {
+ if ((*q->function) (q->client, q->closure))
+ {
+ /* remove q from the list */
+ *p = q->next; /* don't fetch until after func called */
+ free (q);
+ }
+ else
+ {
+ p = &q->next; /* don't fetch until after func called */
+ }
+ }
+ workQueueLast = p;
+}
+
+void
+ProcessWorkQueueZombies(void)
+{
+ WorkQueuePtr q, *p;
+
+ p = &workQueue;
+ while ((q = *p))
+ {
+ if (q->client && q->client->clientGone)
+ {
+ (void) (*q->function) (q->client, q->closure);
+ /* remove q from the list */
+ *p = q->next; /* don't fetch until after func called */
+ free (q);
+ }
+ else
+ {
+ p = &q->next; /* don't fetch until after func called */
+ }
+ }
+ workQueueLast = p;
+}
+
+Bool
+QueueWorkProc (
+ Bool (*function)(ClientPtr /* pClient */, void * /* closure */),
+ ClientPtr client, void * closure)
+{
+ WorkQueuePtr q;
+
+ q = (WorkQueuePtr) malloc (sizeof *q);
+ if (!q)
+ return FALSE;
+ q->function = function;
+ q->client = client;
+ q->closure = closure;
+ q->next = NULL;
+ *workQueueLast = q;
+ workQueueLast = &q->next;
+ return TRUE;
+}
+
+/*
+ * Manage a queue of sleeping clients, awakening them
+ * when requested, by using the OS functions IgnoreClient
+ * and AttendClient. Note that this *ignores* the troubles
+ * with request data interleaving itself with events, but
+ * we'll leave that until a later time.
+ */
+
+typedef struct _SleepQueue {
+ struct _SleepQueue *next;
+ ClientPtr client;
+ ClientSleepProcPtr function;
+ void * closure;
+} SleepQueueRec, *SleepQueuePtr;
+
+static SleepQueuePtr sleepQueue = NULL;
+
+Bool
+ClientSleep (ClientPtr client, ClientSleepProcPtr function, void * closure)
+{
+ SleepQueuePtr q;
+
+ q = (SleepQueuePtr) malloc (sizeof *q);
+ if (!q)
+ return FALSE;
+
+ IgnoreClient (client);
+ q->next = sleepQueue;
+ q->client = client;
+ q->function = function;
+ q->closure = closure;
+ sleepQueue = q;
+ return TRUE;
+}
+
+Bool
+ClientSignal (ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client)
+ {
+ return QueueWorkProc (q->function, q->client, q->closure);
+ }
+ return FALSE;
+}
+
+void
+ClientWakeup (ClientPtr client)
+{
+ SleepQueuePtr q, *prev;
+
+ prev = &sleepQueue;
+ while ( (q = *prev) )
+ {
+ if (q->client == client)
+ {
+ *prev = q->next;
+ free (q);
+ if (client->clientGone)
+ /* Oops -- new zombie cleanup code ensures this only
+ * happens from inside CloseDownClient; don't want to
+ * recurse here...
+ */
+ /* CloseDownClient(client) */;
+ else
+ AttendClient (client);
+ break;
+ }
+ prev = &q->next;
+ }
+}
+
+Bool
+ClientIsAsleep (ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Generic Callback Manager
+ */
+
+/* ===== Private Procedures ===== */
+
+static int numCallbackListsToCleanup = 0;
+static CallbackListPtr **listsToCleanup = NULL;
+
+static Bool
+_AddCallback(
+ CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ void *data)
+{
+ CallbackPtr cbr;
+
+ cbr = (CallbackPtr) malloc(sizeof(CallbackRec));
+ if (!cbr)
+ return FALSE;
+ cbr->proc = callback;
+ cbr->data = data;
+ cbr->next = (*pcbl)->list;
+ cbr->deleted = FALSE;
+ (*pcbl)->list = cbr;
+ return TRUE;
+}
+
+static Bool
+_DeleteCallback(
+ CallbackListPtr *pcbl,
+ CallbackProcPtr callback,
+ void *data)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, pcbr;
+
+ for (pcbr = NULL, cbr = cbl->list;
+ cbr != NULL;
+ pcbr = cbr, cbr = cbr->next)
+ {
+ if ((cbr->proc == callback) && (cbr->data == data))
+ break;
+ }
+ if (cbr != NULL)
+ {
+ if (cbl->inCallback)
+ {
+ ++(cbl->numDeleted);
+ cbr->deleted = TRUE;
+ }
+ else
+ {
+ if (pcbr == NULL)
+ cbl->list = cbr->next;
+ else
+ pcbr->next = cbr->next;
+ free(cbr);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+_CallCallbacks(
+ CallbackListPtr *pcbl,
+ void *call_data)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, pcbr;
+
+ ++(cbl->inCallback);
+ for (cbr = cbl->list; cbr != NULL; cbr = cbr->next)
+ {
+ (*(cbr->proc)) (pcbl, cbr->data, call_data);
+ }
+ --(cbl->inCallback);
+
+ if (cbl->inCallback) return;
+
+ /* Was the entire list marked for deletion? */
+
+ if (cbl->deleted)
+ {
+ DeleteCallbackList(pcbl);
+ return;
+ }
+
+ /* Were some individual callbacks on the list marked for deletion?
+ * If so, do the deletions.
+ */
+
+ if (cbl->numDeleted)
+ {
+ for (pcbr = NULL, cbr = cbl->list; (cbr != NULL) && cbl->numDeleted; )
+ {
+ if (cbr->deleted)
+ {
+ if (pcbr)
+ {
+ cbr = cbr->next;
+ free(pcbr->next);
+ pcbr->next = cbr;
+ } else
+ {
+ cbr = cbr->next;
+ free(cbl->list);
+ cbl->list = cbr;
+ }
+ cbl->numDeleted--;
+ }
+ else /* this one wasn't deleted */
+ {
+ pcbr = cbr;
+ cbr = cbr->next;
+ }
+ }
+ }
+}
+
+static void
+_DeleteCallbackList(
+ CallbackListPtr *pcbl)
+{
+ CallbackListPtr cbl = *pcbl;
+ CallbackPtr cbr, nextcbr;
+ int i;
+
+ if (cbl->inCallback)
+ {
+ cbl->deleted = TRUE;
+ return;
+ }
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ if ((listsToCleanup[i] = pcbl) != 0)
+ {
+ listsToCleanup[i] = NULL;
+ break;
+ }
+ }
+
+ for (cbr = cbl->list; cbr != NULL; cbr = nextcbr)
+ {
+ nextcbr = cbr->next;
+ free(cbr);
+ }
+ free(cbl);
+ *pcbl = NULL;
+}
+
+static CallbackFuncsRec default_cbfuncs =
+{
+ _AddCallback,
+ _DeleteCallback,
+ _CallCallbacks,
+ _DeleteCallbackList
+};
+
+/* ===== Public Procedures ===== */
+
+Bool
+CreateCallbackList(CallbackListPtr *pcbl, CallbackFuncsPtr cbfuncs)
+{
+ CallbackListPtr cbl;
+ int i;
+
+ if (!pcbl) return FALSE;
+ cbl = (CallbackListPtr) malloc(sizeof(CallbackListRec));
+ if (!cbl) return FALSE;
+ cbl->funcs = cbfuncs ? *cbfuncs : default_cbfuncs;
+ cbl->inCallback = 0;
+ cbl->deleted = FALSE;
+ cbl->numDeleted = 0;
+ cbl->list = NULL;
+ *pcbl = cbl;
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ if (!listsToCleanup[i])
+ {
+ listsToCleanup[i] = pcbl;
+ return TRUE;
+ }
+ }
+
+ listsToCleanup = (CallbackListPtr **)xnfrealloc(listsToCleanup,
+ sizeof(CallbackListPtr *) * (numCallbackListsToCleanup+1));
+ listsToCleanup[numCallbackListsToCleanup] = pcbl;
+ numCallbackListsToCleanup++;
+ return TRUE;
+}
+
+Bool
+AddCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void * data)
+{
+ if (!pcbl) return FALSE;
+ if (!*pcbl)
+ { /* list hasn't been created yet; go create it */
+ if (!CreateCallbackList(pcbl, (CallbackFuncsPtr)NULL))
+ return FALSE;
+ }
+ return ((*(*pcbl)->funcs.AddCallback) (pcbl, callback, data));
+}
+
+Bool
+DeleteCallback(CallbackListPtr *pcbl, CallbackProcPtr callback, void * data)
+{
+ if (!pcbl || !*pcbl) return FALSE;
+ return ((*(*pcbl)->funcs.DeleteCallback) (pcbl, callback, data));
+}
+
+void
+CallCallbacks(CallbackListPtr *pcbl, void * call_data)
+{
+ if (!pcbl || !*pcbl) return;
+ (*(*pcbl)->funcs.CallCallbacks) (pcbl, call_data);
+}
+
+void
+DeleteCallbackList(CallbackListPtr *pcbl)
+{
+ if (!pcbl || !*pcbl) return;
+ (*(*pcbl)->funcs.DeleteCallbackList) (pcbl);
+}
+
+void
+InitCallbackManager()
+{
+ int i;
+
+ for (i = 0; i < numCallbackListsToCleanup; i++)
+ {
+ DeleteCallbackList(listsToCleanup[i]);
+ }
+ if (listsToCleanup) free(listsToCleanup);
+
+ numCallbackListsToCleanup = 0;
+ listsToCleanup = NULL;
+}
diff --git a/nx-X11/programs/Xserver/dix/events.c b/nx-X11/programs/Xserver/dix/events.c
new file mode 100644
index 000000000..73187f712
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/events.c
@@ -0,0 +1,4490 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <nx-X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include "xkbsrv.h"
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#include <nx-X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#define EXTENSION_EVENT_BASE 64
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+ (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+ QdEventPtr pending, *pendtail;
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+ WindowPtr replayWin; /* ComputeFreezes */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static struct {
+ CursorPtr current;
+ BoxRec hotLimits; /* logical constraints of hot spot */
+ Bool confined; /* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+ RegionPtr hotShape; /* additional logical shape constraint */
+#endif
+ BoxRec physLimits; /* physical constraints of hot spot */
+ WindowPtr win; /* window of logical position */
+ HotSpot hot; /* logical pointer position */
+ HotSpot hotPhys; /* physical pointer position */
+#ifdef PANORAMIX
+ ScreenPtr screen; /* all others are in Screen 0 coordinates */
+ RegionRec Reg1; /* Region 1 for confining motion */
+ RegionRec Reg2; /* Region 2 for confining virtual motion */
+ WindowPtr windows[MAXSCREENS];
+ WindowPtr confineWin; /* confine window */
+#endif
+} sprite; /* info about the cursor sprite */
+
+static void DoEnterLeaveEvents(
+ WindowPtr fromWin,
+ WindowPtr toWin,
+ int mode
+);
+
+static WindowPtr XYToWindow(
+ int x,
+ int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c /* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = sprite.screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!RegionContainsPoint(&XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(RegionContainsPoint(&XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ sprite.screen = pScreen;
+ sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+ sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+ ScreenPtr pScreen = sprite.screen;
+ BoxRec newBox = sprite.physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents
+){
+ HotSpot new;
+
+ if (!cursor)
+ return;
+
+ new = sprite.hotPhys;
+
+ /* I don't care what the DDX has to say about it */
+ sprite.physLimits = sprite.hotLimits;
+
+ /* constrain the pointer to those limits */
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape) /* more work if the shape is a mess */
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+ if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ XineramaSetCursorPosition (new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+
+ /* Tell DDX what the limits are */
+ XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+ if(pWin == screenInfo.screens[0]->root) {
+ int i;
+ for (i = 0; i < PanoramiXNumScreens; i++)
+ sprite.windows[i] = screenInfo.screens[i]->root;
+ } else {
+ PanoramiXRes *win;
+ int i;
+
+ win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+ if(!win)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+ if(!sprite.windows[i]) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+ QdEventPtr qe,
+ WindowPtr pWin
+){
+
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ int x, y, off_x, off_y, i;
+ BoxRec lims;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ RegionCopy(&sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ RegionTranslate(&sprite.Reg2, x, y);
+
+ RegionUnion(&sprite.Reg2, &sprite.Reg2,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ lims = *RegionExtents(&sprite.Reg2);
+
+ if (sprite.hot.x < lims.x1)
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+ sprite.hot.y = lims.y2 - 1;
+
+ if (RegionNumRects(&sprite.Reg2) > 1)
+ ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ sprite.hot.x = XE_KBPTR.rootX;
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ XineramaSetCursorPosition(
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+ if (syncEvents.playingEvents)
+ {
+ XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ RegionCopy(&sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ RegionTranslate(&sprite.Reg1, x, y);
+
+ RegionUnion(&sprite.Reg1, &sprite.Reg1,
+ &sprite.windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ sprite.hotLimits = *RegionExtents(&sprite.Reg1);
+
+ if(RegionNumRects(&sprite.Reg1) > 1)
+ sprite.hotShape = &sprite.Reg1;
+ else
+ sprite.hotShape = NullRegion;
+
+ sprite.confined = FALSE;
+ sprite.confineWin = (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin;
+
+ XineramaCheckPhysLimits(sprite.current, generateEvents);
+ }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ XineramaCheckPhysLimits(cursor, FALSE);
+ (*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+
+#endif /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+ if ((event < LASTEvent) || (event >= 128))
+ FatalError("SetMaskForEvent: bogus event number");
+ filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+ xEvent xE;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ memset(&xE, 0, sizeof(xEvent));
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ if (syncEvents.playingEvents)
+ xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+ else
+ xE.u.keyButtonPointer.time = currentTime.milliseconds;
+ xE.u.u.type = MotionNotify;
+ (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+
+ if (RegionContainsPoint(shape, x, y, &box))
+ return;
+ box = *RegionExtents(shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!RegionContainsPoint(shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen)
+{
+ HotSpot new;
+
+ if (!cursor)
+ return;
+ new = sprite.hotPhys;
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+ if (new.x < sprite.physLimits.x1)
+ new.x = sprite.physLimits.x1;
+ else
+ if (new.x >= sprite.physLimits.x2)
+ new.x = sprite.physLimits.x2 - 1;
+ if (new.y < sprite.physLimits.y1)
+ new.y = sprite.physLimits.y1;
+ else
+ if (new.y >= sprite.physLimits.y2)
+ new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &new.x, &new.y);
+#endif
+ if ((pScreen != sprite.hotPhys.pScreen) ||
+ (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+ {
+ if (pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys = new;
+ (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+ if (!generateEvents)
+ SyntheticMotion(new.x, new.y);
+ }
+}
+
+static void
+CheckVirtualMotion(
+ register QdEventPtr qe,
+ register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaCheckVirtualMotion(qe, pWin);
+ return;
+ }
+#endif
+ if (qe)
+ {
+ sprite.hot.pScreen = qe->pScreen;
+ sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+ sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+ pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+ NullWindow;
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+ if (sprite.hot.pScreen != pWin->drawable.pScreen)
+ {
+ sprite.hot.pScreen = pWin->drawable.pScreen;
+ sprite.hot.x = sprite.hot.y = 0;
+ }
+ lims = *RegionExtents(&pWin->borderSize);
+ if (sprite.hot.x < lims.x1)
+ sprite.hot.x = lims.x1;
+ else if (sprite.hot.x >= lims.x2)
+ sprite.hot.x = lims.x2 - 1;
+ if (sprite.hot.y < lims.y1)
+ sprite.hot.y = lims.y1;
+ else if (sprite.hot.y >= lims.y2)
+ sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+ if (wBoundingShape(pWin))
+ ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+ if (qe)
+ {
+ qe->pScreen = sprite.hot.pScreen;
+ qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+ qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+ }
+ }
+ ROOT = sprite.hot.pScreen->root;
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pWin, generateEvents);
+ return;
+ }
+#endif
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion((QdEventPtr)NULL, pWin);
+ SyntheticMotion(sprite.hot.x, sprite.hot.y);
+ }
+ else
+ {
+ sprite.hotLimits = *RegionExtents(&pWin->borderSize);
+#ifdef SHAPE
+ sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+#endif
+ CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+ pScreen);
+ }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+ return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaChangeToCursor(cursor);
+ return;
+ }
+#endif
+
+ if (cursor != sprite.current)
+ {
+ if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+ (sprite.current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(cursor, FALSE, sprite.confined,
+ (ScreenPtr)NULL);
+ (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+ cursor);
+ FreeCursor(sprite.current, (Cursor)0);
+ sprite.current = cursor;
+ sprite.current->refcnt++;
+ }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+ register WindowPtr win;
+ register GrabPtr grab = inputInfo.pointer->grab;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, sprite.win))
+ win = sprite.win;
+ else
+ win = grab->window;
+ }
+ else
+ win = sprite.win;
+ for (; win; win = win->parent)
+ if (win->optional && win->optional->cursor != NullCursor)
+ {
+ ChangeToCursor(win->optional->cursor);
+ return;
+ }
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+ return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+ return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+ return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+ *px = sprite.hotPhys.x;
+ *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+ if(!noPanoramiXExtension) {
+ return sprite.screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+ if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+ MonthChangedOrBadTime(xE); \
+ currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+ lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+ register QdEventPtr tail = *syncEvents.pendtail;
+ register QdEventPtr qe;
+ xEvent *qxE;
+
+ NoticeTime(xE);
+
+#ifdef XKB
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ xE->u.u.type == KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ sprite.hotPhys.pScreen->root->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
+ }
+ if (xE->u.u.type == MotionNotify)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ sprite.hotPhys.x = XE_KBPTR.rootX;
+ sprite.hotPhys.y = XE_KBPTR.rootY;
+ /* do motion compression */
+ if (tail &&
+ (tail->event->u.u.type == MotionNotify) &&
+ (tail->pScreen == sprite.hotPhys.pScreen))
+ {
+ tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+ tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+ tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+ qe = (QdEventPtr)calloc(1, sizeof(QdEventRec) + (count * sizeof(xEvent)));
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = sprite.hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (xEvent *)(qe + 1);
+ qe->evcount = count;
+ for (qxE = qe->event; --count >= 0; qxE++, xE++)
+ *qxE = *xE;
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+ register QdEventPtr *prev, qe;
+ register DeviceIntPtr dev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->sync.frozen)
+ {
+ *prev = qe->next;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->u.u.type == MotionNotify)
+ CheckVirtualMotion(qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ qe->event->u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x;
+ qe->event->u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y;
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device,
+ qe->evcount);
+ free(qe);
+ for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+ dev->sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+ register DeviceIntPtr replayDev = syncEvents.replayDev;
+ register int i;
+ WindowPtr w;
+ register xEvent *xE;
+ int count;
+ GrabPtr grab;
+ register DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ xE = replayDev->sync.event;
+ count = replayDev->sync.evcount;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+ for (i = 0; i < spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin == spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+ replayDev, count);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus)
+ DeliverFocusedEvent(replayDev, xE, w, count);
+ else
+ DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ /* the following may have been skipped during replay, so do it now */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
+ TRUE, FALSE);
+ PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
+ TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ register GrabPtr grab = thisDev->grab;
+ register DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->sync.state = THAWED;
+ if (thisDev->sync.other &&
+ (CLIENT_BITS(thisDev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->sync.other = NullGrab;
+ }
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev != thisDev)
+ {
+ if (otherMode == GrabModeSync)
+ dev->sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->sync.other &&
+ (CLIENT_BITS(dev->sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->sync.other = NullGrab;
+ }
+ }
+ }
+ ComputeFreezes();
+}
+
+#ifndef NXAGENT_SERVER
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+}
+#endif /* NXAGENT_SERVER */
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ WindowPtr oldWin;
+
+ if (keybd->grab)
+ oldWin = keybd->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = sprite.win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ keybd->grabTime = syncEvents.time;
+ else
+ keybd->grabTime = time;
+ keybd->activeGrab = *grab;
+ keybd->grab = &keybd->activeGrab;
+ keybd->fromPassiveGrab = passive;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+ register GrabPtr grab = keybd->grab;
+ register DeviceIntPtr dev;
+ register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : sprite.win;
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->grab = NullGrab;
+ keybd->sync.state = NOT_GRABBED;
+ keybd->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ register DeviceIntPtr dev;
+
+ thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = TRUE;
+ grabTime = thisDev->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+ grabTime = dev->grabTime;
+ otherGrabbed = TRUE;
+ if (thisDev->sync.other == dev->grab)
+ thisSynced = TRUE;
+ if (dev->sync.state < FROZEN)
+ othersFrozen = FALSE;
+ }
+ else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+ othersFrozen = FALSE;
+ }
+ if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ thisDev->sync.state = THAWED;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ thisDev->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ thisDev->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = thisDev->grab->window;
+ (*thisDev->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ if (dev->grab && SameClient(dev->grab, client))
+ dev->sync.state = THAWED;
+ if (dev->sync.other && SameClient(dev->sync.other, client))
+ dev->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ register DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->grab && SameClient(dev->grab, client))
+ {
+ (*dev->DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
+ Mask filter, GrabPtr grab)
+{
+ int type;
+
+#ifdef DEBUG
+ if (debug_events) ErrorF(
+ "Event([%d, %d], mask=0x%x), client=%d",
+ pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client))
+ return -1; /* don't send, but notify caller */
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+ fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+#ifdef XINPUT
+ else
+ {
+ if ((type == DeviceMotionNotify) &&
+ MaybeSendDeviceMotionNotifyHint
+ ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+ return 1;
+ }
+#endif
+ if (BitIsOn(criticalEvents, type))
+ {
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+ if (debug_events) ErrorF( " delivered\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef DEBUG
+ if (debug_events) ErrorF("\n");
+#endif
+ return 0;
+ }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
+ Mask filter, GrabPtr grab, int mskidx)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ register InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+ /* CantBeFiltered means only window owner gets the event */
+ if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+ if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+ if (filter != CantBeFiltered)
+ {
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ OtherInputMasks *inputMasks;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[mskidx] & filter))
+ return 0;
+ other = inputMasks->inputClients;
+ }
+ else
+ other = (InputClients *)wOtherClients(pWin);
+ for (; other; other = other->next)
+ {
+ if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+ other->mask[mskidx], filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = other->mask[mskidx];
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ if ((type == ButtonPress) && deliveries && (!grab))
+ {
+ GrabRec tempGrab;
+
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ (*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ currentTime, TRUE);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+ else
+ {
+ if (((type == DeviceMotionNotify)
+#ifdef XKB
+ || (type == DeviceButtonPress)
+#endif
+ ) && deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+#endif
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ register OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ return TryClientEvents(wClient(pWin), pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ return TryClientEvents(rClient(other), pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static void
+FixUpEventFromWindow(
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ if (calcChild)
+ {
+ WindowPtr w=spriteTrace[spriteTraceGood-1];
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == pWin)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == pWin)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ }
+ XE_KBPTR.root = ROOT->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab,
+ register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+ Window child = None;
+ int type = xE->u.u.type;
+ Mask filter = filters[type];
+ int deliveries = 0;
+
+ if (type & EXTENSION_EVENT_BASE)
+ {
+ register OtherInputMasks *inputMasks;
+ int mskidx = dev->id;
+
+ inputMasks = wOtherInputMasks(pWin);
+ if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+ return 0;
+ while (pWin)
+ {
+ if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, mskidx);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (inputMasks &&
+ (filter & inputMasks->dontPropagateMask[mskidx])))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ if (pWin)
+ inputMasks = wOtherInputMasks(pWin);
+ }
+ }
+ else
+ {
+ if (!(filter & pWin->deliverableEvents))
+ return 0;
+ while (pWin)
+ {
+ if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+ {
+ FixUpEventFromWindow(xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+ grab, 0);
+ if (deliveries > 0)
+ return deliveries;
+ }
+ if ((deliveries < 0) ||
+ (pWin == stopAt) ||
+ (filter & wDontPropagateMask(pWin)))
+ return 0;
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+ }
+ return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count,
+ register WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+ filter = filters[xE->u.u.type];
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+ deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+ NullGrab, 0);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab,
+ 0);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(otherParent, xE, count,
+ SubstructureNotifyMask,
+ NullGrab, 0);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if(RegionContainsPoint(&pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(RegionContainsPoint(
+ &sprite.windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+#ifndef NXAGENT_SERVER
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+ pWin = ROOT->firstChild;
+ while (pWin)
+ {
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)realloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+#endif /* NXAGENT_SERVER */
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+ WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaCheckMotion(xE);
+#endif
+
+ if (xE && !syncEvents.playingEvents)
+ {
+ if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+ {
+ sprite.hot.pScreen = sprite.hotPhys.pScreen;
+ ROOT = sprite.hot.pScreen->root;
+ }
+ sprite.hot.x = XE_KBPTR.rootX;
+ sprite.hot.y = XE_KBPTR.rootY;
+ if (sprite.hot.x < sprite.physLimits.x1)
+ sprite.hot.x = sprite.physLimits.x1;
+ else if (sprite.hot.x >= sprite.physLimits.x2)
+ sprite.hot.x = sprite.physLimits.x2 - 1;
+ if (sprite.hot.y < sprite.physLimits.y1)
+ sprite.hot.y = sprite.physLimits.y1;
+ else if (sprite.hot.y >= sprite.physLimits.y2)
+ sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+ sprite.hotPhys = sprite.hot;
+ if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+ (sprite.hotPhys.y != XE_KBPTR.rootY))
+ {
+ (*sprite.hotPhys.pScreen->SetCursorPosition)(
+ sprite.hotPhys.pScreen,
+ sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+ }
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ }
+
+ sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+ if (!(sprite.win->deliverableEvents &
+ Motion_Filter(inputInfo.pointer->button))
+ !syncEvents.playingEvents)
+ {
+ /* XXX Do PointerNonInterestBox here */
+ }
+#endif
+ if (sprite.win != prevSpriteWin)
+ {
+ if (prevSpriteWin != NullWindow) {
+ if (!xE)
+ UpdateCurrentTimeIf();
+ DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+ }
+ PostNewCursor();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+ (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., screenInfo.screens[0]->root) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ GrabPtr grab;
+
+ if (noPanoramiXExtension) return;
+
+ sprite.hot.x -= xoff;
+ sprite.hot.y -= yoff;
+
+ sprite.hotPhys.x -= xoff;
+ sprite.hotPhys.y -= yoff;
+
+ sprite.hotLimits.x1 -= xoff;
+ sprite.hotLimits.y1 -= yoff;
+ sprite.hotLimits.x2 -= xoff;
+ sprite.hotLimits.y2 -= yoff;
+
+ if (RegionNotEmpty(&sprite.Reg1))
+ RegionTranslate(&sprite.Reg1, xoff, yoff);
+ if (RegionNotEmpty(&sprite.Reg2))
+ RegionTranslate(&sprite.Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(sprite.hotPhys.pScreen->root,
+ TRUE, FALSE);
+}
+#endif
+
+#ifndef NXAGENT_SERVER
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ RegionNull(&sprite.Reg1);
+ RegionNull(&sprite.Reg2);
+ }
+#endif
+}
+#endif /* NXAGENT_SERVER */
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+ sprite.hotPhys.x = x;
+ sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != sprite.screen) {
+ sprite.screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(sprite.confineWin)
+ XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(screenInfo.screens[0]->root, TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*sprite.screen->SetCursorPosition)(sprite.screen,
+ sprite.hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[sprite.screen->myNum].x,
+ sprite.hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != sprite.hotPhys.pScreen)
+ ConfineCursorToWindow(newScreen->root, TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (RegionContainsPoint(&pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = sprite.windows[i];
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(RegionContainsPoint(&pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, DixReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, DixReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == screenInfo.screens[0]->root) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == screenInfo.screens[0]->root) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+
+ XineramaSetCursorPosition(x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y;
+ ScreenPtr newScreen;
+
+ REQUEST(xWarpPointerReq);
+
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None)
+ {
+ dest = SecurityLookupWindow(stuff->dstWid, client, DixReadAccess);
+ if (!dest)
+ return BadWindow;
+ }
+ x = sprite.hotPhys.x;
+ y = sprite.hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ source = SecurityLookupWindow(winID, client, DixReadAccess);
+ if (!source) return BadWindow;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = sprite.hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == sprite.hotPhys.pScreen)
+ {
+ if (x < sprite.physLimits.x1)
+ x = sprite.physLimits.x1;
+ else if (x >= sprite.physLimits.x2)
+ x = sprite.physLimits.x2 - 1;
+ if (y < sprite.physLimits.y1)
+ y = sprite.physLimits.y1;
+ else if (y >= sprite.physLimits.y2)
+ y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+ if (sprite.hotShape)
+ ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+ (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen())
+ {
+ NewCurrentScreen(newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+ if(RegionNotEmpty(&pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(RegionNotEmpty(&sprite.windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ register DeviceIntPtr device,
+ register xEvent *xE,
+ int count)
+{
+ register GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ register xEvent *dxE;
+
+ if (!grab)
+ return FALSE;
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.type = xE->u.u.type;
+ tempGrab.detail.exact = xE->u.u.detail;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ for (; grab; grab = grab->next)
+ {
+#ifdef XKB
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi;
+
+ gdev= grab->modifierDevice;
+ xkbi= gdev->key->xkbInfo;
+#endif
+ tempGrab.modifierDevice = grab->modifierDevice;
+ if ((device == grab->modifierDevice) &&
+ ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceKeyPress)
+#endif
+ ))
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->prev_state;
+#endif
+ else
+ tempGrab.modifiersDetail.exact =
+#ifdef XKB
+ (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+ grab->modifierDevice->key->state;
+#endif
+ if (GrabMatchesSecond(&tempGrab, grab) &&
+ (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(grab->confineTo))))
+ {
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+ return FALSE;
+#endif
+#ifdef XKB
+ if (!noXkbExtension) {
+ XE_KBPTR.state &= 0x1f00;
+ XE_KBPTR.state |=
+ tempGrab.modifiersDetail.exact&(~0x1f00);
+ }
+#endif
+ (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+ (void) TryClientEvents(rClient(grab), xE, count,
+ filters[xE->u.u.type],
+ filters[xE->u.u.type], grab);
+
+ if (device->sync.state == FROZEN_NO_EVENT)
+ {
+ if (device->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ device->sync.event = (xEvent *)realloc(device->sync.event,
+ count*
+ sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ device->sync.evcount = count;
+ for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ device->sync.state = FROZEN_WITH_EVENT;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated. If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated. If the focus window itself is reached and
+its descendants contain the pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated. If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE,
+ int checkFirst, int count)
+{
+ register int i;
+ register WindowPtr pWin = NULL;
+ register FocusClassPtr focus = device->focus;
+
+ if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+ || (xE->u.u.type == DeviceButtonPress)
+#endif
+ ) && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= spriteTraceGood) ||
+ ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < spriteTraceGood; i++)
+ {
+ pWin = spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+ WindowPtr focus = keybd->focus->win;
+ int mskidx = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+ return;
+ }
+ /* just deliver it to the focus window */
+ FixUpEventFromWindow(xE, focus, None, FALSE);
+ if (xE->u.u.type & EXTENSION_EVENT_BASE)
+ mskidx = keybd->id;
+ (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+ NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev,
+ Bool deactivateGrab, int count)
+{
+ register GrabPtr grab = thisDev->grab;
+ int deliveries = 0;
+ register DeviceIntPtr dev;
+ register xEvent *dxE;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+ thisDev, count);
+ else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+ deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+ thisDev, count);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+ thisDev, count);
+ }
+ if (!deliveries)
+ {
+ FixUpEventFromWindow(xE, grab->window, None, TRUE);
+ deliveries = TryClientEvents(rClient(grab), xE, count,
+ (Mask)grab->eventMask,
+ filters[xE->u.u.type], grab);
+ if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+ || xE->u.u.type == DeviceMotionNotify
+#endif
+ ))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+ && xE->u.u.type != DeviceMotionNotify
+#endif
+ ))
+ switch (thisDev->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(dev->grab->resource) ==
+ CLIENT_BITS(thisDev->grab->resource)))
+ dev->sync.state = FROZEN_NO_EVENT;
+ else
+ dev->sync.other = thisDev->grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ thisDev->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (thisDev->sync.evcount < count)
+ {
+ Must_have_memory = TRUE; /* XXX */
+ thisDev->sync.event = (xEvent *)realloc(thisDev->sync.event,
+ count*sizeof(xEvent));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ thisDev->sync.evcount = count;
+ for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+ *dxE = *xE;
+ break;
+ }
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+ int key, bit;
+ register BYTE *kptr;
+ register int i;
+ register CARD8 modifiers;
+ register CARD16 mask;
+ GrabPtr grab = keybd->grab;
+ Bool deactivateGrab = FALSE;
+ register KeyClassPtr keyc = keybd->key;
+
+ if (!syncEvents.playingEvents)
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
+ }
+ }
+ XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+ modifiers = keyc->modifierMap[key];
+
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ if (*kptr & bit) /* allow ddx to generate multiple downs */
+ {
+ if (!modifiers)
+ {
+ xE->u.u.type = KeyRelease;
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ xE->u.u.type = KeyPress;
+ /* release can have side effects, don't fall through */
+ (*keybd->public.processInputProc)(xE, keybd, count);
+ }
+ return;
+ }
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers)
+ {
+ /* This key affects modifier "i" */
+ keyc->modifierKeyCount[i]++;
+ keyc->state |= mask;
+ modifiers &= ~mask;
+ }
+ }
+ if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+ {
+ keybd->activatingKey = key;
+ return;
+ }
+ break;
+ case KeyRelease:
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return;
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ keyc->prev_state = keyc->state;
+ for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+ {
+ if (mask & modifiers) {
+ /* This key affects modifier "i" */
+ if (--keyc->modifierKeyCount[i] <= 0) {
+ keyc->state &= ~mask;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ modifiers &= ~mask;
+ }
+ }
+ if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+ if (grab)
+ DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+ else
+ DeliverFocusedEvent(keybd, xE, sprite.win, count);
+ if (deactivateGrab)
+ (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+ int key, bit;
+ register BYTE *kptr;
+ register KeyClassPtr keyc = keybd->key;
+
+ key = xE->u.u.detail;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+ ErrorF("FixKeyState: Key %d %s\n",key,
+ (xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ switch (xE->u.u.type)
+ {
+ case KeyPress:
+ *kptr |= bit;
+ break;
+ case KeyRelease:
+ *kptr &= ~bit;
+ break;
+ default:
+ FatalError("Impossible keyboard event");
+ }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+ register GrabPtr grab = mouse->grab;
+ Bool deactivateGrab = FALSE;
+ register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+ XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+#endif
+
+ if (!syncEvents.playingEvents)
+ NoticeTime(xE)
+ XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+ (noXkbExtension ?
+ inputInfo.keyboard->key->state :
+ xkbi->state.grab_mods)
+#else
+ inputInfo.keyboard->key->state
+#endif
+ ));
+ {
+ NoticeTime(xE);
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (xE->u.u.type == MotionNotify)
+ XE_KBPTR.root =
+ sprite.hotPhys.pScreen->root->drawable.id;
+ eventinfo.events = xE;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (void *)&eventinfo);
+ }
+ }
+ if (xE->u.u.type != MotionNotify)
+ {
+ register int key;
+ register BYTE *kptr;
+ int bit;
+
+ XE_KBPTR.rootX = sprite.hot.x;
+ XE_KBPTR.rootY = sprite.hot.y;
+
+ key = xE->u.u.detail;
+ kptr = &butc->down[key >> 3];
+ bit = 1 << (key & 7);
+ switch (xE->u.u.type)
+ {
+ case ButtonPress:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (!(*kptr & bit))
+ butc->buttonsDown++;
+ butc->motionMask = ButtonMotionMask;
+ *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!grab)
+ if (CheckDeviceGrabs(mouse, xE, 0, count))
+ return;
+ break;
+ case ButtonRelease:
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (*kptr & bit)
+ --butc->buttonsDown;
+ if (!butc->buttonsDown)
+ butc->motionMask = 0;
+ *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+ xE->u.u.detail = butc->map[key];
+#endif
+ if (xE->u.u.detail == 0)
+ return;
+ if (xE->u.u.detail <= 5)
+ butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ filters[MotionNotify] = Motion_Filter(butc);
+ if (!butc->state && mouse->fromPassiveGrab)
+ deactivateGrab = TRUE;
+ break;
+ default:
+ FatalError("bogus pointer event from ddx");
+ }
+ }
+ else if (!CheckMotion(xE))
+ return;
+ if (grab)
+ DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+ else
+ DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ mouse, count);
+ if (deactivateGrab)
+ (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+ register WindowPtr pWin;
+{
+ register OtherClients *others;
+ register WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(void * value, XID id)
+{
+ register OtherClientsPtr other, prev;
+ register WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ free(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+ pWin->eventMask = mask;
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = (OtherClients *) malloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (void *)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+ (mask & PointerMotionHintMask) &&
+ !(check & PointerMotionHintMask) &&
+ !inputInfo.pointer->grab)
+ inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ register int i, free;
+
+ if ((mask & ~PropagateMask) && !permitOldBugs)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+static WindowPtr
+CommonAncestor(
+ register WindowPtr a,
+ register WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (IsParent(b, a)) return b;
+ return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+ int type,
+ int mode,
+ int detail,
+ register WindowPtr pWin,
+ Window child)
+{
+ register DeviceIntPtr keybd = inputInfo.keyboard;
+ WindowPtr focus;
+ register DeviceIntPtr mouse = inputInfo.pointer;
+ register GrabPtr grab = mouse->grab;
+ Mask mask;
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+ if (mask & filters[type])
+ {
+ xEvent event;
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = sprite.hot.x;
+ event.u.enterLeave.rootY = sprite.hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(&event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+#ifdef XKB
+ if (!noXkbExtension) {
+ event.u.enterLeave.state = mouse->button->state & 0x1f00;
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ } else
+#endif
+ event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+ event.u.enterLeave.mode = mode;
+ focus = keybd->focus->win;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), &event, 1, mask,
+ filters[type], grab);
+ else
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+ NullGrab, 0);
+ }
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+
+#ifdef XCSECURITY
+ ClientPtr client = grab ? rClient(grab)
+ : clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+ ke.type = KeymapNotify;
+ if (grab)
+ (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+ KeymapStateMask, grab);
+ else
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+ WindowPtr parent = child->parent;
+
+ if (ancestor == parent)
+ return;
+ EnterNotifies(ancestor, parent, mode, detail);
+ EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+ register WindowPtr pWin;
+
+ if (ancestor == child)
+ return;
+ for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+ {
+ EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+ child = pWin;
+ }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ if (fromWin == toWin)
+ return;
+ if (IsParent(fromWin, toWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+ EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+ }
+ else if (IsParent(toWin, fromWin))
+ {
+ EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+ LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+ }
+ else
+ { /* neither fromWin nor toWin is descendent of the other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+ LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+ EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+ EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+ }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+ xEvent event;
+
+#ifdef XINPUT
+ if (dev != inputInfo.keyboard)
+ {
+ DeviceFocusEvent(dev, type, mode, detail, pWin);
+ return;
+ }
+#endif
+ memset(&event, 0, sizeof(xEvent));
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+ (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+ 0);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+#ifdef XCSECURITY
+ ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+ if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+ {
+ bzero((char *)&ke.map[0], 31);
+ }
+ else
+#endif
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+ ke.type = KeymapNotify;
+ (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab, 0);
+ }
+}
+
+ /*
+ * recursive because it is easier
+ * no-op if child not descended from ancestor
+ */
+static Bool
+FocusInEvents(
+ DeviceIntPtr dev,
+ WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ if (child == NullWindow)
+ return ancestor == NullWindow;
+ if (ancestor == child)
+ {
+ if (doAncestor)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+ doAncestor))
+ {
+ if (child != skipChild)
+ FocusEvent(dev, FocusIn, mode, detail, child);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+ DeviceIntPtr dev,
+ WindowPtr child, WindowPtr ancestor,
+ int mode, int detail,
+ Bool doAncestor)
+{
+ register WindowPtr pWin;
+
+ for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+ FocusEvent(dev, FocusOut, mode, detail, pWin);
+ if (doAncestor)
+ FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+ int out, in; /* for holding details for to/from
+ PointerRoot/None */
+ int i;
+
+ if (fromWin == toWin)
+ return;
+ out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+ if ((toWin == NullWindow) || (toWin == PointerRootWin))
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
+ }
+ else
+ {
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+ FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ /* next call catches the root too, if the screen changed */
+ FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+ NotifyNonlinearVirtual, FALSE);
+ }
+ /* Notify all the roots */
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[0]->root);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusIn, mode, in, screenInfo.screens[i]->root);
+ if (toWin == PointerRootWin)
+ (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+ NotifyPointer, TRUE);
+ }
+ else
+ {
+ if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+ {
+ if (fromWin == PointerRootWin)
+ FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+ TRUE);
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[0]->root);
+ else
+#endif
+ for (i=0; i<screenInfo.numScreens; i++)
+ FocusEvent(dev, FocusOut, mode, out, screenInfo.screens[i]->root);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+ NotifyNonlinearVirtual, TRUE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+ NotifyPointer, FALSE);
+ }
+ else
+ {
+ if (IsParent(toWin, fromWin))
+ {
+ FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+ FocusOutEvents(dev, fromWin->parent, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+ if ((IsParent(toWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(fromWin, sprite.win)) &&
+ (!IsParent(sprite.win, fromWin)))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ else
+ if (IsParent(fromWin, toWin))
+ {
+ if ((IsParent(fromWin, sprite.win)) &&
+ (sprite.win != fromWin) &&
+ (!IsParent(toWin, sprite.win)) &&
+ (!IsParent(sprite.win, toWin)))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+ (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+ NotifyVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+ }
+ else
+ {
+ /* neither fromWin or toWin is child of other */
+ WindowPtr common = CommonAncestor(toWin, fromWin);
+ /* common == NullWindow ==> different screens */
+ if (IsParent(fromWin, sprite.win))
+ FocusOutEvents(dev, sprite.win, fromWin, mode,
+ NotifyPointer, FALSE);
+ FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+ if (fromWin->parent != NullWindow)
+ FocusOutEvents(dev, fromWin->parent, common, mode,
+ NotifyNonlinearVirtual, FALSE);
+ if (toWin->parent != NullWindow)
+ (void)FocusInEvents(dev, common, toWin, toWin, mode,
+ NotifyNonlinearVirtual, FALSE);
+ FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+ if (IsParent(toWin, sprite.win))
+ (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+ mode, NotifyPointer, FALSE);
+ }
+ }
+ }
+}
+
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ register FocusClassPtr focus;
+ register WindowPtr focusWin;
+ int mode;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ focusWin = inputInfo.keyboard->focus->win;
+ else if (!(focusWin = SecurityLookupWindow(focusID, client,
+ DixReadAccess)))
+ return BadWindow;
+ else
+ {
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+ else
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ register WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ Must_have_memory = TRUE; /* XXX */
+ focus->trace = (WindowPtr *)realloc(focus->trace,
+ focus->traceSize *
+ sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+int
+ProcSetInputFocus(client)
+ ClientPtr client;
+{
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ return Success;
+#endif
+ return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ xGetInputFocusReply rep;
+ /* REQUEST(xReq); */
+ FocusClassPtr focus = inputInfo.keyboard->focus;
+
+ REQUEST_SIZE_MATCH(xReq);
+ memset(&rep, 0, sizeof(xGetInputFocusReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor, oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ DixReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, DixReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ /* at this point, some sort of reply is guaranteed. */
+ time = ClientTimeToServerTime(stuff->time);
+ memset(&rep, 0, sizeof(xGrabPointerReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ grab = device->grab;
+ if ((grab) && !SameClient(grab, client))
+ rep.status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+ rep.status = GrabNotViewable;
+ else if (device->sync.frozen &&
+ device->sync.other && !SameClient(device->sync.other, client))
+ rep.status = GrabFrozen;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ rep.status = GrabInvalidTime;
+ else
+ {
+ GrabRec tempGrab;
+
+ oldCursor = NullCursor;
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+ tempGrab.cursor = cursor;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = stuff->ownerEvents;
+ tempGrab.eventMask = stuff->eventMask;
+ tempGrab.confineTo = confineTo;
+ tempGrab.window = pWin;
+ tempGrab.keyboardMode = stuff->keyboardMode;
+ tempGrab.pointerMode = stuff->pointerMode;
+ tempGrab.device = device;
+ (*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ if (oldCursor)
+ FreeCursor (oldCursor, (Cursor)0);
+ rep.status = GrabSuccess;
+ }
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ register GrabPtr grab = device->grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, DixReadAccess);
+ if (!newCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor();
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.pointer;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
+ unsigned this_mode, unsigned other_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+ register WindowPtr pWin;
+ register GrabPtr grab;
+ TimeStamp time;
+
+ UpdateCurrentTime();
+ if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+ {
+ client->errorValue = this_mode;
+ return BadValue;
+ }
+ if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+ {
+ client->errorValue = other_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ time = ClientTimeToServerTime(ctime);
+ grab = dev->grab;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if (!pWin->realized)
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (dev->sync.frozen &&
+ dev->sync.other && !SameClient(dev->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = this_mode;
+ tempGrab.pointerMode = other_mode;
+ tempGrab.eventMask = mask;
+ tempGrab.device = dev;
+ (*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+ memset(&rep, 0, sizeof(xGrabKeyboardReply));
+#ifdef XCSECURITY
+ if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+ {
+ result = Success;
+ rep.status = AlreadyGrabbed;
+ }
+ else
+#endif
+ result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+ stuff->pointerMode, stuff->grabWindow,
+ stuff->ownerEvents, stuff->time,
+ KeyPressMask | KeyReleaseMask, &rep.status);
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = inputInfo.keyboard;
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->grab;
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->DeactivateGrab)(device);
+ return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ REQUEST(xResourceReq);
+ DeviceIntPtr mouse = inputInfo.pointer;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = SecurityLookupWindow(stuff->id, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ memset(&rep, 0, sizeof(xQueryPointerReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+ rep.length = 0;
+ rep.root = (ROOT)->drawable.id;
+ rep.rootX = sprite.hot.x;
+ rep.rootY = sprite.hot.y;
+ rep.child = None;
+ if (sprite.hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = sprite.hot.x - pWin->drawable.x;
+ rep.winY = sprite.hot.y - pWin->drawable.y;
+ for (t = sprite.win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+void
+InitEvents()
+{
+ int i;
+
+ sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ if (spriteTraceSize == 0)
+ {
+ spriteTraceSize = 32;
+ spriteTrace = (WindowPtr *)malloc(32*sizeof(WindowPtr));
+ if (!spriteTrace)
+ FatalError("failed to allocate spriteTrace");
+ }
+ spriteTraceGood = 0;
+ lastEventMask = OwnerGrabButtonMask;
+ filters[MotionNotify] = PointerMotionMask;
+ sprite.win = NullWindow;
+ sprite.current = NullCursor;
+ sprite.hotLimits.x1 = 0;
+ sprite.hotLimits.y1 = 0;
+ sprite.hotLimits.x2 = 0;
+ sprite.hotLimits.y2 = 0;
+ sprite.confined = FALSE;
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ free(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+}
+
+void
+CloseDownEvents(void)
+{
+ free(spriteTrace);
+ spriteTrace = NULL;
+ spriteTraceSize = 0;
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32 &&
+ !permitOldBugs)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = KeyPress;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return(BadValue);
+ }
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+ (stuff->key < keybd->key->curKeySyms.minKeyCode))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ grab = CreateGrab(client->index, keybd, pWin,
+ (Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+ (Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+ keybd, stuff->modifiers, KeyPress, stuff->key,
+ NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ confineTo = SecurityLookupWindow(stuff->confineTo, client,
+ DixReadAccess);
+ if (!confineTo)
+ return BadWindow;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, DixReadAccess);
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return BadCursor;
+ }
+ }
+
+
+ grab = CreateGrab(client->index, inputInfo.pointer, pWin,
+ permitOldBugs ? (Mask)(stuff->eventMask |
+ ButtonPressMask | ButtonReleaseMask) :
+ (Mask)stuff->eventMask,
+ (Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+ (Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+ ButtonPress, stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ pWin = SecurityLookupWindow(stuff->grabWindow, client, DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = inputInfo.pointer;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = inputInfo.keyboard;
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.detail.pMask = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus = keybd->focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+
+ if (mouse->grab &&
+ ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+ (*mouse->DeactivateGrab)(mouse);
+
+ /* Deactivating a keyboard grab should cause focus events. */
+
+ if (keybd->grab && (keybd->grab->window == pWin))
+ (*keybd->DeactivateGrab)(keybd);
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+ );
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+
+ if (mouse->valuator->motionHintWindow == pWin)
+ mouse->valuator->motionHintWindow = NullWindow;
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+#ifdef XINPUT
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab = inputInfo.pointer->grab;
+ WindowPtr confineTo;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(confineTo))
+ (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(confineTo, TRUE, TRUE);
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ register OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+ RT_CURSOR, DixWriteAccess);
+ if ( !pCursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (BadCursor);
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == sprite.screen);
+ else
+#endif
+ displayed = (pscr == sprite.hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(pscr, pCursor,
+ (pCursor == sprite.current) && displayed);
+ }
+ return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent eventTo, *eventFrom;
+ int i;
+
+ if (!pClient || pClient == serverClient || pClient->clientGone)
+ return;
+
+ for (i = 0; i < count; i++)
+ if ((events[i].u.u.type & 0x7f) != KeymapNotify)
+ events[i].u.u.sequenceNumber = pClient->sequence;
+
+#ifdef XKB
+ if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+ return;
+#endif
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (void *)&eventinfo);
+ }
+ if(pClient->swapped)
+ {
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, &eventTo);
+ WriteToClient(pClient, sizeof(xEvent), &eventTo);
+ }
+ }
+ else
+ {
+ WriteToClient(pClient, count * sizeof(xEvent), events);
+ }
+}
diff --git a/nx-X11/programs/Xserver/dix/extension.c b/nx-X11/programs/Xserver/dix/extension.c
new file mode 100644
index 000000000..a1701281d
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/extension.c
@@ -0,0 +1,456 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors,
+ int (*MainProc)(ClientPtr c1),
+ int (*SwappedMainProc)(ClientPtr c2),
+ void (*CloseDownProc)(ExtensionEntry *e),
+ unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+ int i;
+ register ExtensionEntry *ext, **newexts;
+
+ if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
+ return((ExtensionEntry *) NULL);
+ if ((lastEvent + NumEvents > LAST_EVENT) ||
+ (unsigned)(lastError + NumErrors > LAST_ERROR))
+ return((ExtensionEntry *) NULL);
+
+ ext = (ExtensionEntry *) malloc(sizeof(ExtensionEntry));
+ if (!ext)
+ return((ExtensionEntry *) NULL);
+ ext->name = (char *)malloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **)NULL;
+ if (!ext->name)
+ {
+ free(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) realloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts)
+ {
+ free(ext->name);
+ free(ext);
+ return((ExtensionEntry *) NULL);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = CloseDownProc;
+ ext->MinorOpcode = MinorOpcodeProc;
+ ProcVector[i + EXTENSION_BASE] = MainProc;
+ SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+ if (NumEvents)
+ {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + NumEvents;
+ lastEvent += NumEvents;
+ }
+ else
+ {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (NumErrors)
+ {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + NumErrors;
+ lastError += NumErrors;
+ }
+ else
+ {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+ return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **)realloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *)malloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+ return TRUE;
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+ int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+ if ((strlen(extensions[i]->name) == len) &&
+ !strncmp(extname, extensions[i]->name, len))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ if ((strlen(extensions[i]->aliases[j]) == len) &&
+ !strncmp(extname, extensions[i]->aliases[j], len))
+ break;
+ }
+ if (j >= 0) break;
+ }
+ return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name. Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+ int n;
+
+ n = FindExtension((char*)extname, strlen(extname));
+ if (n != -1)
+ return extensions[n];
+ else
+ return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+ int i = FindExtension(extname, strlen(extname));
+ if (i >= 0)
+ {
+ int majorop = extensions[i]->base;
+ extensions[i]->secure = secure;
+ if (secure)
+ {
+ UntrustedProcVector[majorop] = ProcVector[majorop];
+ SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+ }
+ else
+ {
+ UntrustedProcVector[majorop] = ProcBadRequest;
+ SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+ }
+ }
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((xReq *)client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+ register int i,j;
+
+ for (i = NumExtensions - 1; i >= 0; i--)
+ {
+ if (extensions[i]->CloseDown)
+ (* extensions[i]->CloseDown)(extensions[i]);
+ NumExtensions = i;
+ free(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ free(extensions[i]->aliases[j]);
+ free(extensions[i]->aliases);
+ free(extensions[i]);
+ }
+ free(extensions);
+ extensions = (ExtensionEntry **)NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+ for (i=0; i<MAXSCREENS; i++)
+ {
+ register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+ while (spentry->num)
+ {
+ spentry->num--;
+ free(spentry->procList[spentry->num].name);
+ }
+ free(spentry->procList);
+ spentry->procList = (ProcEntryPtr)NULL;
+ }
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ memset(&reply, 0, sizeof(xQueryExtensionReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ memset(&reply, 0, sizeof(xListExtensionsReply));
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)malloc(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XCSECURITY
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ free(buffer);
+ }
+ return(client->noClientException);
+}
+#endif
+
+ExtensionLookupProc
+LookupProc(char *name, GCPtr pGC)
+{
+ register int i;
+ register ScreenProcEntry *spentry;
+ spentry = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ return(spentry->procList[i].proc);
+ }
+ return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+ return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+ register ScreenProcEntry *spentry;
+ register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+ char *newname;
+ int i;
+
+ spentry = &AuxillaryScreenProcs[pScreen->myNum];
+ /* first replace duplicates */
+ if (spentry->num)
+ {
+ for (i = 0; i < spentry->num; i++)
+ if (strcmp(name, spentry->procList[i].name) == 0)
+ {
+ procEntry = &spentry->procList[i];
+ break;
+ }
+ }
+ if (procEntry)
+ procEntry->proc = proc;
+ else
+ {
+ newname = (char *)malloc(strlen(name)+1);
+ if (!newname)
+ return FALSE;
+ procEntry = (ProcEntryPtr)
+ realloc(spentry->procList,
+ sizeof(ProcEntryRec) * (spentry->num+1));
+ if (!procEntry)
+ {
+ free(newname);
+ return FALSE;
+ }
+ spentry->procList = procEntry;
+ procEntry += spentry->num;
+ procEntry->name = newname;
+ strcpy(newname, name);
+ procEntry->proc = proc;
+ spentry->num++;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/dix/ffs.c b/nx-X11/programs/Xserver/dix/ffs.c
new file mode 100644
index 000000000..e25d715dd
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/ffs.c
@@ -0,0 +1,36 @@
+/*
+
+Copyright 1996, 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 MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, 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.
+
+*/
+
+int
+ffs(int i)
+{
+ int j;
+ for (j = 1; (i & 1) == 0; j++)
+ i >>= 1;
+ return j;
+}
diff --git a/nx-X11/programs/Xserver/dix/gc.c b/nx-X11/programs/Xserver/dix/gc.c
new file mode 100644
index 000000000..d40334f5f
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/gc.c
@@ -0,0 +1,1286 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "dix.h"
+#include <assert.h>
+
+extern XID clientErrorValue;
+extern FontPtr defaultFont;
+
+static Bool CreateDefaultTile(GCPtr pGC);
+
+unsigned char DefaultDash[2] = {4, 4};
+
+void
+ValidateGC(DrawablePtr pDraw, GC *pGC)
+{
+ (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
+ pGC->stateChanges = 0;
+ pGC->serialNumber = pDraw->serialNumber;
+}
+
+
+/* dixChangeGC(client, pGC, mask, pC32, pUnion)
+ *
+ * This function was created as part of the Security extension
+ * implementation. The client performing the gc change must be passed so
+ * that access checks can be performed on any tiles, stipples, or fonts
+ * that are specified. ddxen can call this too; they should normally
+ * pass NullClient for the client since any access checking should have
+ * already been done at a higher level.
+ *
+ * Since we had to create a new function anyway, we decided to change the
+ * way the list of gc values is passed to eliminate the compiler warnings
+ * caused by the DoChangeGC interface. You can pass the values via pC32
+ * or pUnion, but not both; one of them must be NULL. If you don't need
+ * to pass any pointers, you can use either one:
+ *
+ * example calling dixChangeGC using pC32 parameter
+ *
+ * CARD32 v[2];
+ * v[0] = foreground;
+ * v[1] = background;
+ * dixChangeGC(client, pGC, GCForeground|GCBackground, v, NULL);
+ *
+ * example calling dixChangeGC using pUnion parameter;
+ * same effect as above
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = foreground;
+ * v[1].val = background;
+ * dixChangeGC(client, pGC, GCForeground|GCBackground, NULL, v);
+ *
+ * However, if you need to pass a pointer to a pixmap or font, you MUST
+ * use the pUnion parameter.
+ *
+ * example calling dixChangeGC passing pointers in the value list
+ * v[1].ptr is a pointer to a pixmap
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = FillTiled;
+ * v[1].ptr = pPixmap;
+ * dixChangeGC(client, pGC, GCFillStyle|GCTile, NULL, v);
+ *
+ * Note: we could have gotten by with just the pUnion parameter, but on
+ * 64 bit machines that would have forced us to copy the value list that
+ * comes in the ChangeGC request.
+ *
+ * Ideally, we'd change all the DoChangeGC calls to dixChangeGC, but this
+ * is far too many changes to consider at this time, so we've only
+ * changed the ones that caused compiler warnings. New code should use
+ * dixChangeGC.
+ *
+ * dpw
+ */
+
+#define NEXTVAL(_type, _var) { \
+ if (pC32) _var = (_type)*pC32++; \
+ else { \
+ _var = (_type)(pUnion->val); pUnion++; \
+ } \
+ }
+
+#define NEXT_PTR(_type, _var) { \
+ assert(pUnion); _var = (_type)pUnion->ptr; pUnion++; }
+
+int
+dixChangeGC(ClientPtr client, register GC *pGC, register BITS32 mask, CARD32 *pC32, ChangeGCValPtr pUnion)
+{
+ register BITS32 index2;
+ register int error = 0;
+ PixmapPtr pPixmap;
+ BITS32 maskQ;
+
+ assert( (pC32 && !pUnion) || (!pC32 && pUnion) );
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ maskQ = mask; /* save these for when we walk the GCque */
+ while (mask && !error)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ pGC->stateChanges |= index2;
+ switch (index2)
+ {
+ case GCFunction:
+ {
+ CARD8 newalu;
+ NEXTVAL(CARD8, newalu);
+ if (newalu <= GXset)
+ pGC->alu = newalu;
+ else
+ {
+ clientErrorValue = newalu;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCPlaneMask:
+ NEXTVAL(unsigned long, pGC->planemask);
+ break;
+ case GCForeground:
+ NEXTVAL(unsigned long, pGC->fgPixel);
+ /*
+ * this is for CreateGC
+ */
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = pGC->fgPixel;
+ }
+ break;
+ case GCBackground:
+ NEXTVAL(unsigned long, pGC->bgPixel);
+ break;
+ case GCLineWidth: /* ??? line width is a CARD16 */
+ NEXTVAL(CARD16, pGC->lineWidth);
+ break;
+ case GCLineStyle:
+ {
+ unsigned int newlinestyle;
+ NEXTVAL(unsigned int, newlinestyle);
+ if (newlinestyle <= LineDoubleDash)
+ pGC->lineStyle = newlinestyle;
+ else
+ {
+ clientErrorValue = newlinestyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCCapStyle:
+ {
+ unsigned int newcapstyle;
+ NEXTVAL(unsigned int, newcapstyle);
+ if (newcapstyle <= CapProjecting)
+ pGC->capStyle = newcapstyle;
+ else
+ {
+ clientErrorValue = newcapstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCJoinStyle:
+ {
+ unsigned int newjoinstyle;
+ NEXTVAL(unsigned int, newjoinstyle);
+ if (newjoinstyle <= JoinBevel)
+ pGC->joinStyle = newjoinstyle;
+ else
+ {
+ clientErrorValue = newjoinstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillStyle:
+ {
+ unsigned int newfillstyle;
+ NEXTVAL(unsigned int, newfillstyle);
+ if (newfillstyle <= FillOpaqueStippled)
+ pGC->fillStyle = newfillstyle;
+ else
+ {
+ clientErrorValue = newfillstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillRule:
+ {
+ unsigned int newfillrule;
+ NEXTVAL(unsigned int, newfillrule);
+ if (newfillrule <= WindingRule)
+ pGC->fillRule = newfillrule;
+ else
+ {
+ clientErrorValue = newfillrule;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCTile:
+ {
+ XID newpix = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(XID, newpix);
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ newpix, RT_PIXMAP, DixReadAccess);
+ }
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pGC->depth) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pPixmap;
+ }
+ }
+ else
+ {
+ clientErrorValue = newpix;
+ error = BadPixmap;
+ }
+ break;
+ }
+ case GCStipple:
+ {
+ XID newstipple = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(XID, newstipple)
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ newstipple, RT_PIXMAP, DixReadAccess);
+ }
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = pPixmap;
+ }
+ }
+ else
+ {
+ clientErrorValue = newstipple;
+ error = BadPixmap;
+ }
+ break;
+ }
+ case GCTileStipXOrigin:
+ NEXTVAL(INT16, pGC->patOrg.x);
+ break;
+ case GCTileStipYOrigin:
+ NEXTVAL(INT16, pGC->patOrg.y);
+ break;
+ case GCFont:
+ {
+ FontPtr pFont;
+ XID newfont = 0;
+ if (pUnion)
+ {
+ NEXT_PTR(FontPtr, pFont);
+ }
+ else
+ {
+ NEXTVAL(XID, newfont)
+ pFont = (FontPtr)SecurityLookupIDByType(client, newfont,
+ RT_FONT, DixReadAccess);
+ }
+ if (pFont)
+ {
+ pFont->refcnt++;
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+ pGC->font = pFont;
+ }
+ else
+ {
+ clientErrorValue = newfont;
+ error = BadFont;
+ }
+ break;
+ }
+ case GCSubwindowMode:
+ {
+ unsigned int newclipmode;
+ NEXTVAL(unsigned int, newclipmode);
+ if (newclipmode <= IncludeInferiors)
+ pGC->subWindowMode = newclipmode;
+ else
+ {
+ clientErrorValue = newclipmode;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCGraphicsExposures:
+ {
+ unsigned int newge;
+ NEXTVAL(unsigned int, newge);
+ if (newge <= xTrue)
+ pGC->graphicsExposures = newge;
+ else
+ {
+ clientErrorValue = newge;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCClipXOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.x);
+ break;
+ case GCClipYOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.y);
+ break;
+ case GCClipMask:
+ {
+ Pixmap pid = 0;
+ int clipType = 0;
+
+ if (pUnion)
+ {
+ NEXT_PTR(PixmapPtr, pPixmap);
+ }
+ else
+ {
+ NEXTVAL(Pixmap, pid)
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid, RT_PIXMAP, DixReadAccess);
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+ else if (!pUnion && (pid != None))
+ {
+ clientErrorValue = pid;
+ error = BadPixmap;
+ }
+ if(error == Success)
+ {
+ (*pGC->funcs->ChangeClip)(pGC, clipType,
+ (void *)pPixmap, 0);
+ }
+ break;
+ }
+ case GCDashOffset:
+ NEXTVAL(INT16, pGC->dashOffset);
+ break;
+ case GCDashList:
+ {
+ CARD8 newdash;
+ NEXTVAL(CARD8, newdash);
+ if (newdash == 4)
+ {
+ if (pGC->dash != DefaultDash)
+ {
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ }
+ }
+ else if (newdash != 0)
+ {
+ unsigned char *dash;
+
+ dash = (unsigned char *)malloc(2 * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = dash;
+ dash[0] = newdash;
+ dash[1] = newdash;
+ }
+ else
+ error = BadAlloc;
+ }
+ else
+ {
+ clientErrorValue = newdash;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCArcMode:
+ {
+ unsigned int newarcmode;
+ NEXTVAL(unsigned int, newarcmode);
+ if (newarcmode <= ArcPieSlice)
+ pGC->arcMode = newarcmode;
+ else
+ {
+ clientErrorValue = newarcmode;
+ error = BadValue;
+ }
+ break;
+ }
+ default:
+ clientErrorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ } /* end while mask && !error */
+
+ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pGC))
+ {
+ pGC->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pGC->funcs->ChangeGC)(pGC, maskQ);
+ return error;
+}
+
+#undef NEXTVAL
+#undef NEXT_PTR
+
+/* Publically defined entry to ChangeGC. Just calls dixChangeGC and tells
+ * it that all of the entries are constants or IDs */
+int
+ChangeGC(register GC *pGC, register BITS32 mask, XID *pval)
+{
+ return (dixChangeGC(NullClient, pGC, mask, pval, NULL));
+}
+
+/* DoChangeGC(pGC, mask, pval, fPointer)
+ mask is a set of bits indicating which values to change.
+ pval contains an appropriate value for each mask.
+ fPointer is true if the values for tiles, stipples, fonts or clipmasks
+ are pointers instead of IDs. Note: if you are passing pointers you
+ MUST declare the array of values as type void*! Other data types
+ may not be large enough to hold pointers on some machines. Yes,
+ this means you have to cast to (XID *) when you pass the array to
+ DoChangeGC. Similarly, if you are not passing pointers (fPointer = 0) you
+ MUST declare the array as type XID (not unsigned long!), or again the wrong
+ size data type may be used. To avoid this cruftiness, use dixChangeGC
+ above.
+
+ if there is an error, the value is marked as changed
+ anyway, which is probably wrong, but infrequent.
+
+NOTE:
+ all values sent over the protocol for ChangeGC requests are
+32 bits long
+*/
+int
+DoChangeGC(register GC *pGC, register BITS32 mask, XID *pval, int fPointer)
+{
+ if (fPointer)
+ /* XXX might be a problem on 64 bit big-endian servers */
+ return dixChangeGC(NullClient, pGC, mask, NULL, (ChangeGCValPtr)pval);
+ else
+ return dixChangeGC(NullClient, pGC, mask, pval, NULL);
+}
+
+
+/* CreateGC(pDrawable, mask, pval, pStatus)
+ creates a default GC for the given drawable, using mask to fill
+ in any non-default values.
+ Returns a pointer to the new GC on success, NULL otherwise.
+ returns status of non-default fields in pStatus
+BUG:
+ should check for failure to create default tile
+
+*/
+
+static GCPtr
+AllocateGC(ScreenPtr pScreen)
+{
+ GCPtr pGC;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pGC = (GCPtr)malloc(pScreen->totalGCSize);
+ if (pGC)
+ {
+ ppriv = (DevUnion *)(pGC + 1);
+ pGC->devPrivates = ppriv;
+ sizes = pScreen->GCPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->GCPrivateLen);
+ for (i = pScreen->GCPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+ }
+ return pGC;
+}
+
+GCPtr
+CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus)
+{
+ register GCPtr pGC;
+
+ pGC = AllocateGC(pDrawable->pScreen);
+ if (!pGC)
+ {
+ *pStatus = BadAlloc;
+ return (GCPtr)NULL;
+ }
+
+ pGC->pScreen = pDrawable->pScreen;
+ pGC->depth = pDrawable->depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pGC->funcs = 0;
+
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ if (mask & GCForeground)
+ {
+ /*
+ * magic special case -- ChangeGC checks for this condition
+ * and snags the Foreground value to create a pseudo default-tile
+ */
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = NullPixmap;
+ }
+ else
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ }
+
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = (void *)NULL;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->dashOffset = 0;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ /* use the default font and stipple */
+ pGC->font = defaultFont;
+ defaultFont->refcnt++;
+ pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
+ pGC->stipple->refcnt++;
+
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ if (!(*pGC->pScreen->CreateGC)(pGC))
+ *pStatus = BadAlloc;
+ else if (mask)
+ *pStatus = ChangeGC(pGC, mask, pval);
+ else
+ *pStatus = Success;
+ if (*pStatus != Success)
+ {
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ pGC->tileIsPixel = TRUE; /* undo special case */
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+
+ return (pGC);
+}
+
+static Bool
+CreateDefaultTile (GCPtr pGC)
+{
+ XID tmpval[3];
+ PixmapPtr pTile;
+ GCPtr pgcScratch;
+ xRectangle rect;
+ CARD16 w, h;
+
+ w = 1;
+ h = 1;
+ (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
+ pTile = (PixmapPtr)
+ (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
+ w, h, pGC->depth, 0);
+ pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
+ if (!pTile || !pgcScratch)
+ {
+ if (pTile)
+ (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
+ if (pgcScratch)
+ FreeScratchGC(pgcScratch);
+ return FALSE;
+ }
+ tmpval[0] = GXcopy;
+ tmpval[1] = pGC->tile.pixel;
+ tmpval[2] = FillSolid;
+ (void)ChangeGC(pgcScratch, GCFunction | GCForeground | GCFillStyle,
+ tmpval);
+ ValidateGC((DrawablePtr)pTile, pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
+ /* Always remember to free the scratch graphics context after use. */
+ FreeScratchGC(pgcScratch);
+
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pTile;
+ return TRUE;
+}
+
+int
+CopyGC(register GC *pgcSrc, register GC *pgcDst, register BITS32 mask)
+{
+ register BITS32 index2;
+ BITS32 maskQ;
+ int error = 0;
+
+ if (pgcSrc == pgcDst)
+ return Success;
+ pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgcDst->stateChanges |= mask;
+ maskQ = mask;
+ while (mask)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ switch (index2)
+ {
+ case GCFunction:
+ pgcDst->alu = pgcSrc->alu;
+ break;
+ case GCPlaneMask:
+ pgcDst->planemask = pgcSrc->planemask;
+ break;
+ case GCForeground:
+ pgcDst->fgPixel = pgcSrc->fgPixel;
+ break;
+ case GCBackground:
+ pgcDst->bgPixel = pgcSrc->bgPixel;
+ break;
+ case GCLineWidth:
+ pgcDst->lineWidth = pgcSrc->lineWidth;
+ break;
+ case GCLineStyle:
+ pgcDst->lineStyle = pgcSrc->lineStyle;
+ break;
+ case GCCapStyle:
+ pgcDst->capStyle = pgcSrc->capStyle;
+ break;
+ case GCJoinStyle:
+ pgcDst->joinStyle = pgcSrc->joinStyle;
+ break;
+ case GCFillStyle:
+ pgcDst->fillStyle = pgcSrc->fillStyle;
+ break;
+ case GCFillRule:
+ pgcDst->fillRule = pgcSrc->fillRule;
+ break;
+ case GCTile:
+ {
+ if (EqualPixUnion(pgcDst->tileIsPixel,
+ pgcDst->tile,
+ pgcSrc->tileIsPixel,
+ pgcSrc->tile))
+ {
+ break;
+ }
+ if (!pgcDst->tileIsPixel)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
+ pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
+ pgcDst->tile = pgcSrc->tile;
+ if (!pgcDst->tileIsPixel)
+ pgcDst->tile.pixmap->refcnt++;
+ break;
+ }
+ case GCStipple:
+ {
+ if (pgcDst->stipple == pgcSrc->stipple)
+ break;
+ if (pgcDst->stipple)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
+ pgcDst->stipple = pgcSrc->stipple;
+ if (pgcDst->stipple)
+ pgcDst->stipple->refcnt ++;
+ break;
+ }
+ case GCTileStipXOrigin:
+ pgcDst->patOrg.x = pgcSrc->patOrg.x;
+ break;
+ case GCTileStipYOrigin:
+ pgcDst->patOrg.y = pgcSrc->patOrg.y;
+ break;
+ case GCFont:
+ if (pgcDst->font == pgcSrc->font)
+ break;
+ if (pgcDst->font)
+ CloseFont(pgcDst->font, (Font)0);
+ if ((pgcDst->font = pgcSrc->font) != NullFont)
+ (pgcDst->font)->refcnt++;
+ break;
+ case GCSubwindowMode:
+ pgcDst->subWindowMode = pgcSrc->subWindowMode;
+ break;
+ case GCGraphicsExposures:
+ pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
+ break;
+ case GCClipXOrigin:
+ pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
+ break;
+ case GCClipYOrigin:
+ pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
+ break;
+ case GCClipMask:
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ break;
+ case GCDashOffset:
+ pgcDst->dashOffset = pgcSrc->dashOffset;
+ break;
+ case GCDashList:
+ if (pgcSrc->dash == DefaultDash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ {
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = pgcSrc->dash;
+ }
+ }
+ else
+ {
+ unsigned char *dash;
+ unsigned int i;
+
+ dash = (unsigned char *)malloc(pgcSrc->numInDashList *
+ sizeof(unsigned char));
+ if (dash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = dash;
+ for (i=0; i<pgcSrc->numInDashList; i++)
+ dash[i] = pgcSrc->dash[i];
+ }
+ else
+ error = BadAlloc;
+ }
+ break;
+ case GCArcMode:
+ pgcDst->arcMode = pgcSrc->arcMode;
+ break;
+ default:
+ clientErrorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pgcDst))
+ {
+ pgcDst->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
+ return error;
+}
+
+/**
+ * does the diX part of freeing the characteristics in the GC.
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeGC(void * value, XID gid)
+{
+ GCPtr pGC = (GCPtr)value;
+
+ CloseFont(pGC->font, (Font)0);
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ free(pGC);
+ return(Success);
+}
+
+void
+SetGCMask(GCPtr pGC, Mask selectMask, Mask newDataMask)
+{
+ pGC->stateChanges = (~selectMask & pGC->stateChanges) |
+ (selectMask & newDataMask);
+ if (selectMask & newDataMask)
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+}
+
+
+
+/* CreateScratchGC(pScreen, depth)
+ like CreateGC, but doesn't do the default tile or stipple,
+since we can't create them without already having a GC. any code
+using the tile or stipple has to set them explicitly anyway,
+since the state of the scratch gc is unknown. This is OK
+because ChangeGC() has to be able to deal with NULL tiles and
+stipples anyway (in case the CreateGC() call has provided a
+value for them -- we can't set the default tile until the
+client-supplied attributes are installed, since the fgPixel
+is what fills the default tile. (maybe this comment should
+go with CreateGC() or ChangeGC().)
+*/
+
+GCPtr
+CreateScratchGC(ScreenPtr pScreen, unsigned depth)
+{
+ register GCPtr pGC;
+
+ pGC = AllocateGC(pScreen);
+ if (!pGC)
+ return (GCPtr)NULL;
+
+ pGC->pScreen = pScreen;
+ pGC->depth = depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->font = defaultFont;
+ if ( pGC->font) /* necessary, because open of default font could fail */
+ pGC->font->refcnt++;
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->stipple = NullPixmap;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->dashOffset = 0;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ if (!(*pScreen->CreateGC)(pGC))
+ {
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+ return pGC;
+}
+
+void
+FreeGCperDepth(int screenNum)
+{
+ register int i;
+ register ScreenPtr pScreen;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ ppGC = pScreen->GCperDepth;
+
+ for (i = 0; i <= pScreen->numDepths; i++)
+ (void)FreeGC(ppGC[i], (XID)0);
+ pScreen->rgf = ~0L;
+}
+
+
+Bool
+CreateGCperDepth(int screenNum)
+{
+ register int i;
+ register ScreenPtr pScreen;
+ DepthPtr pDepth;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ pScreen->rgf = 0;
+ ppGC = pScreen->GCperDepth;
+ /* do depth 1 separately because it's not included in list */
+ if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
+ return FALSE;
+ ppGC[0]->graphicsExposures = FALSE;
+ /* Make sure we don't overflow GCperDepth[] */
+ if( pScreen->numDepths > MAXFORMATS )
+ return FALSE;
+
+ pDepth = pScreen->allowedDepths;
+ for (i=0; i<pScreen->numDepths; i++, pDepth++)
+ {
+ if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
+ {
+ for (; i >= 0; i--)
+ (void)FreeGC(ppGC[i], (XID)0);
+ return FALSE;
+ }
+ ppGC[i+1]->graphicsExposures = FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+CreateDefaultStipple(int screenNum)
+{
+ register ScreenPtr pScreen;
+ XID tmpval[3];
+ xRectangle rect;
+ CARD16 w, h;
+ GCPtr pgcScratch;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ w = 16;
+ h = 16;
+ (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
+ if (!(pScreen->PixmapPerDepth[0] =
+ (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
+ return FALSE;
+ /* fill stipple with 1 */
+ tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid;
+ pgcScratch = GetScratchGC(1, pScreen);
+ if (!pgcScratch)
+ {
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+ return FALSE;
+ }
+ (void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
+ pgcScratch, 1, &rect);
+ FreeScratchGC(pgcScratch);
+ return TRUE;
+}
+
+void
+FreeDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+}
+
+int
+SetDashes(register GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
+{
+ register long i;
+ register unsigned char *p, *indash;
+ BITS32 maskQ = 0;
+
+ i = ndash;
+ p = pdash;
+ while (i--)
+ {
+ if (!*p++)
+ {
+ /* dash segment must be > 0 */
+ clientErrorValue = 0;
+ return BadValue;
+ }
+ }
+
+ if (ndash & 1)
+ p = (unsigned char *)malloc(2 * ndash * sizeof(unsigned char));
+ else
+ p = (unsigned char *)malloc(ndash * sizeof(unsigned char));
+ if (!p)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ if (offset != pGC->dashOffset)
+ {
+ pGC->dashOffset = offset;
+ pGC->stateChanges |= GCDashOffset;
+ maskQ |= GCDashOffset;
+ }
+
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = ndash;
+ pGC->dash = p;
+ if (ndash & 1)
+ {
+ pGC->numInDashList += ndash;
+ indash = pdash;
+ i = ndash;
+ while (i--)
+ *p++ = *indash++;
+ }
+ while(ndash--)
+ *p++ = *pdash++;
+ pGC->stateChanges |= GCDashList;
+ maskQ |= GCDashList;
+
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, maskQ);
+ return Success;
+}
+
+int
+VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
+{
+ register xRectangle *prectP, *prectN;
+ register int i;
+
+ switch(ordering)
+ {
+ case Unsorted:
+ return CT_UNSORTED;
+ case YSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if(prectN->y < prectP->y)
+ return -1;
+ }
+ return CT_YSORTED;
+ case YXSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y < prectP->y) ||
+ ( (prectN->y == prectP->y) &&
+ (prectN->x < prectP->x) ) )
+ return -1;
+ }
+ return CT_YXSORTED;
+ case YXBanded:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y != prectP->y &&
+ prectN->y < prectP->y + (int) prectP->height) ||
+ ((prectN->y == prectP->y) &&
+ (prectN->height != prectP->height ||
+ prectN->x < prectP->x + (int) prectP->width)))
+ return -1;
+ }
+ return CT_YXBANDED;
+ }
+ return -1;
+}
+
+int
+SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
+ xRectangle *prects, int ordering)
+{
+ int newct, size;
+ xRectangle *prectsNew;
+
+ newct = VerifyRectOrder(nrects, prects, ordering);
+ if (newct < 0)
+ return(BadMatch);
+ size = nrects * sizeof(xRectangle);
+ prectsNew = (xRectangle *) malloc(size);
+ if (!prectsNew && size)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->clipOrg.x = xOrigin;
+ pGC->stateChanges |= GCClipXOrigin;
+
+ pGC->clipOrg.y = yOrigin;
+ pGC->stateChanges |= GCClipYOrigin;
+
+ if (size)
+ memmove((char *)prectsNew, (char *)prects, size);
+ (*pGC->funcs->ChangeClip)(pGC, newct, (void *)prectsNew, nrects);
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ return Success;
+}
+
+
+/*
+ sets reasonable defaults
+ if we can get a pre-allocated one, use it and mark it as used.
+ if we can't, create one out of whole cloth (The Velveteen GC -- if
+ you use it often enough it will become real.)
+*/
+GCPtr
+GetScratchGC(register unsigned depth, register ScreenPtr pScreen)
+{
+ register int i;
+ register GCPtr pGC;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ if ( pScreen->GCperDepth[i]->depth == depth &&
+ !(pScreen->rgf & (1L << (i+1)))
+ )
+ {
+ pScreen->rgf |= (1L << (i+1));
+ pGC = (pScreen->GCperDepth[i]);
+
+ pGC->alu = GXcopy;
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcChord;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = FALSE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ if (pGC->clientClipType != CT_NONE)
+ (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
+ pGC->stateChanges = (1 << (GCLastBit+1)) - 1;
+ return pGC;
+ }
+ /* if we make it this far, need to roll our own */
+ pGC = CreateScratchGC(pScreen, depth);
+ if (pGC)
+ pGC->graphicsExposures = FALSE;
+ return pGC;
+}
+
+/*
+ if the gc to free is in the table of pre-existing ones,
+mark it as available.
+ if not, free it for real
+*/
+void
+FreeScratchGC(register GCPtr pGC)
+{
+ register ScreenPtr pScreen = pGC->pScreen;
+ register int i;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ {
+ if ( pScreen->GCperDepth[i] == pGC)
+ {
+ pScreen->rgf &= ~(1L << (i+1));
+ return;
+ }
+ }
+ (void)FreeGC(pGC, (GContext)0);
+}
diff --git a/nx-X11/programs/Xserver/dix/globals.c b/nx-X11/programs/Xserver/dix/globals.c
new file mode 100644
index 000000000..f9fa544ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/globals.c
@@ -0,0 +1,161 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "input.h"
+#include "dixfont.h"
+#include "site.h"
+#include "dixstruct.h"
+#include "os.h"
+
+ScreenInfo screenInfo;
+KeybdCtrl defaultKeyboardControl = {
+ DEFAULT_KEYBOARD_CLICK,
+ DEFAULT_BELL,
+ DEFAULT_BELL_PITCH,
+ DEFAULT_BELL_DURATION,
+ DEFAULT_AUTOREPEAT,
+ DEFAULT_AUTOREPEATS,
+ DEFAULT_LEDS,
+ 0};
+
+PtrCtrl defaultPointerControl = {
+ DEFAULT_PTR_NUMERATOR,
+ DEFAULT_PTR_DENOMINATOR,
+ DEFAULT_PTR_THRESHOLD,
+ 0};
+
+ClientPtr *clients;
+ClientPtr serverClient;
+int currentMaxClients; /* current size of clients array */
+long maxBigRequestSize = MAX_BIG_REQUEST_SIZE;
+
+unsigned long globalSerialNumber = 0;
+unsigned long serverGeneration = 0;
+
+/* these next four are initialized in main.c */
+CARD32 ScreenSaverTime;
+CARD32 ScreenSaverInterval;
+int ScreenSaverBlanking;
+int ScreenSaverAllowExposures;
+
+#ifdef DPMSExtension
+# ifndef DEFAULT_STANDBY_TIME
+# define DEFAULT_STANDBY_TIME DEFAULT_SCREEN_SAVER_TIME * 2
+# endif
+# ifndef DEFAULT_SUSPEND_TIME
+# define DEFAULT_SUSPEND_TIME DEFAULT_SCREEN_SAVER_TIME * 3
+# endif
+# ifndef DEFAULT_OFF_TIME
+# define DEFAULT_OFF_TIME DEFAULT_SCREEN_SAVER_TIME * 4
+# endif
+# ifndef DEFAULT_DPMS_ENABLED
+# define DEFAULT_DPMS_ENABLED FALSE
+# endif
+CARD32 defaultDPMSStandbyTime = DEFAULT_STANDBY_TIME;
+CARD32 defaultDPMSSuspendTime = DEFAULT_SUSPEND_TIME;
+CARD32 defaultDPMSOffTime = DEFAULT_OFF_TIME;
+CARD16 DPMSPowerLevel = 0;
+Bool defaultDPMSEnabled = DEFAULT_DPMS_ENABLED;
+Bool DPMSEnabledSwitch = FALSE; /* these denote the DPMS command line */
+Bool DPMSDisabledSwitch = FALSE; /* switch states */
+Bool DPMSCapableFlag = FALSE;
+CARD32 DPMSStandbyTime;
+CARD32 DPMSSuspendTime;
+CARD32 DPMSOffTime;
+Bool DPMSEnabled;
+#endif
+
+CARD32 defaultScreenSaverTime = DEFAULT_SCREEN_SAVER_TIME;
+CARD32 defaultScreenSaverInterval = DEFAULT_SCREEN_SAVER_INTERVAL;
+int defaultScreenSaverBlanking = DEFAULT_SCREEN_SAVER_BLANKING;
+int defaultScreenSaverAllowExposures = DEFAULT_SCREEN_SAVER_EXPOSURES;
+#ifndef NOLOGOHACK
+int logoScreenSaver = DEFAULT_LOGO_SCREEN_SAVER;
+#endif
+
+char *defaultFontPath = COMPILEDDEFAULTFONTPATH;
+char *defaultTextFont = COMPILEDDEFAULTFONT;
+char *defaultCursorFont = COMPILEDCURSORFONT;
+char *defaultDisplayClass = COMPILEDDISPLAYCLASS;
+FontPtr defaultFont; /* not declared in dix.h to avoid including font.h in
+ every compilation of dix code */
+Bool loadableFonts = FALSE;
+CursorPtr rootCursor;
+Bool blackRoot=FALSE;
+ClientPtr requestingClient; /* XXX this should be obsolete now, remove? */
+
+TimeStamp currentTime;
+TimeStamp lastDeviceEventTime;
+
+Bool permitOldBugs = FALSE; /* turn off some error checking, to permit certain
+ * old broken clients (like R2/R3 xterms) to work
+ */
+
+int defaultColorVisualClass = -1;
+int monitorResolution = 0;
+
+char *display;
+int displayfd = -1;
+Bool explicit_display = FALSE;
+
+CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
+int argcGlobal;
+char **argvGlobal;
+
+DDXPointRec dixScreenOrigins[MAXSCREENS];
+
+char *ConnectionInfo;
diff --git a/nx-X11/programs/Xserver/dix/glyphcurs.c b/nx-X11/programs/Xserver/dix/glyphcurs.c
new file mode 100644
index 000000000..5e36f158c
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/glyphcurs.c
@@ -0,0 +1,195 @@
+/************************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+#ifndef NXAGENT_SERVER
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ ChangeGCVal gcval[3];
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)malloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+ cm->height, 1,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ (*pScreen->DestroyPixmap)(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ free(pbits);
+ return BadAlloc;
+ }
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ /* fill the pixmap with 0 */
+ gcval[0].val = GXcopy;
+ gcval[1].val = 0;
+ gcval[2].ptr = (void *)pfont;
+ dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+ NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ gcval[0].val = 1;
+ dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
+ ValidateGC((DrawablePtr)ppix, pGC);
+ (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+ 1, (unsigned short *)char2b);
+ (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ (*pScreen->DestroyPixmap)(ppix);
+ return Success;
+}
+#endif /* NXAGENT_SERVER */
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+ CharInfoPtr pci;
+ unsigned long nglyphs;
+ CARD8 chs[2];
+ FontEncoding encoding;
+
+ chs[0] = ch >> 8;
+ chs[1] = ch;
+ encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+ if (encoding == Linear16Bit)
+ {
+ if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+ return FALSE;
+ }
+ else
+ {
+ if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+ return FALSE;
+ if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+ return FALSE;
+ }
+ (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+ if (nglyphs == 0)
+ return FALSE;
+ cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ cm->height = pci->metrics.descent + pci->metrics.ascent;
+ if (pci->metrics.leftSideBearing > 0)
+ {
+ cm->width += pci->metrics.leftSideBearing;
+ cm->xhot = 0;
+ }
+ else
+ {
+ cm->xhot = -pci->metrics.leftSideBearing;
+ if (pci->metrics.rightSideBearing < 0)
+ cm->width -= pci->metrics.rightSideBearing;
+ }
+ if (pci->metrics.ascent < 0)
+ {
+ cm->height -= pci->metrics.ascent;
+ cm->yhot = 0;
+ }
+ else
+ {
+ cm->yhot = pci->metrics.ascent;
+ if (pci->metrics.descent < 0)
+ cm->height -= pci->metrics.descent;
+ }
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/dix/grabs.c b/nx-X11/programs/Xserver/dix/grabs.c
new file mode 100644
index 000000000..0068676c2
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/grabs.c
@@ -0,0 +1,435 @@
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "misc.h"
+#include <nx-X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "cursorstr.h"
+#include "dixgrabs.h"
+
+#define BITMASK(i) (((Mask)1) << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+GrabPtr
+CreateGrab(
+ int client,
+ DeviceIntPtr device,
+ WindowPtr window,
+ Mask eventMask,
+ Bool ownerEvents, Bool keyboardMode, Bool pointerMode,
+ DeviceIntPtr modDevice,
+ unsigned short modifiers,
+ int type,
+ KeyCode keybut, /* key or button */
+ WindowPtr confineTo,
+ CursorPtr cursor)
+{
+ GrabPtr grab;
+
+ grab = (GrabPtr)malloc(sizeof(GrabRec));
+ if (!grab)
+ return (GrabPtr)NULL;
+ grab->resource = FakeClientID(client);
+ grab->device = device;
+ grab->coreGrab = ((device == inputInfo.keyboard) ||
+ (device == inputInfo.pointer));
+ grab->window = window;
+ grab->eventMask = eventMask;
+ grab->ownerEvents = ownerEvents;
+ grab->keyboardMode = keyboardMode;
+ grab->pointerMode = pointerMode;
+ grab->modifiersDetail.exact = modifiers;
+ grab->modifiersDetail.pMask = NULL;
+ grab->modifierDevice = modDevice;
+ grab->coreMods = ((modDevice == inputInfo.keyboard) ||
+ (modDevice == inputInfo.pointer));
+ grab->type = type;
+ grab->detail.exact = keybut;
+ grab->detail.pMask = NULL;
+ grab->confineTo = confineTo;
+ grab->cursor = cursor;
+ if (cursor)
+ cursor->refcnt++;
+ return grab;
+
+}
+
+static void
+FreeGrab(GrabPtr pGrab)
+{
+ if (pGrab->modifiersDetail.pMask != NULL)
+ free(pGrab->modifiersDetail.pMask);
+
+ if (pGrab->detail.pMask != NULL)
+ free(pGrab->detail.pMask);
+
+ if (pGrab->cursor)
+ FreeCursor(pGrab->cursor, (Cursor)0);
+
+ free(pGrab);
+}
+
+int
+DeletePassiveGrab(void * value, XID id)
+{
+ register GrabPtr g, prev;
+ GrabPtr pGrab = (GrabPtr)value;
+
+ /* it is OK if the grab isn't found */
+ prev = 0;
+ for (g = (wPassiveGrabs (pGrab->window)); g; g = g->next)
+ {
+ if (pGrab == g)
+ {
+ if (prev)
+ prev->next = g->next;
+ else
+ if (!(pGrab->window->optional->passiveGrabs = g->next))
+ CheckWindowOptionalNeed (pGrab->window);
+ break;
+ }
+ prev = g;
+ }
+ FreeGrab(pGrab);
+ return Success;
+}
+
+static Mask *
+DeleteDetailFromMask(Mask *pDetailMask, unsigned short detail)
+{
+ register Mask *mask;
+ register int i;
+
+ mask = (Mask *)malloc(sizeof(Mask) * MasksPerDetailMask);
+ if (mask)
+ {
+ if (pDetailMask)
+ for (i = 0; i < MasksPerDetailMask; i++)
+ mask[i]= pDetailMask[i];
+ else
+ for (i = 0; i < MasksPerDetailMask; i++)
+ mask[i]= ~0L;
+ BITCLEAR(mask, detail);
+ }
+ return mask;
+}
+
+static Bool
+IsInGrabMask(
+ DetailRec firstDetail,
+ DetailRec secondDetail,
+ unsigned short exception)
+{
+ if (firstDetail.exact == exception)
+ {
+ if (firstDetail.pMask == NULL)
+ return TRUE;
+
+ /* (at present) never called with two non-null pMasks */
+ if (secondDetail.exact == exception)
+ return FALSE;
+
+ if (GETBIT(firstDetail.pMask, secondDetail.exact))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+IdenticalExactDetails(
+ unsigned short firstExact,
+ unsigned short secondExact,
+ unsigned short exception)
+{
+ if ((firstExact == exception) || (secondExact == exception))
+ return FALSE;
+
+ if (firstExact == secondExact)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+DetailSupersedesSecond(
+ DetailRec firstDetail,
+ DetailRec secondDetail,
+ unsigned short exception)
+{
+ if (IsInGrabMask(firstDetail, secondDetail, exception))
+ return TRUE;
+
+ if (IdenticalExactDetails(firstDetail.exact, secondDetail.exact,
+ exception))
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool
+GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return FALSE;
+
+ if (DetailSupersedesSecond(pFirstGrab->detail,
+ pSecondGrab->detail, (unsigned short)AnyKey))
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
+{
+ if ((pFirstGrab->device != pSecondGrab->device) ||
+ (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
+ (pFirstGrab->type != pSecondGrab->type))
+ return FALSE;
+
+ if (GrabSupersedesSecond(pFirstGrab, pSecondGrab) ||
+ GrabSupersedesSecond(pSecondGrab, pFirstGrab))
+ return TRUE;
+
+ if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail,
+ (unsigned short)AnyKey)
+ &&
+ DetailSupersedesSecond(pFirstGrab->modifiersDetail,
+ pSecondGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return TRUE;
+
+ if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail,
+ (unsigned short)AnyKey)
+ &&
+ DetailSupersedesSecond(pSecondGrab->modifiersDetail,
+ pFirstGrab->modifiersDetail,
+ (unsigned short)AnyModifier))
+ return TRUE;
+
+ return FALSE;
+}
+
+int
+AddPassiveGrabToList(GrabPtr pGrab)
+{
+ GrabPtr grab;
+
+ for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
+ {
+ if (GrabMatchesSecond(pGrab, grab))
+ {
+ if (CLIENT_BITS(pGrab->resource) != CLIENT_BITS(grab->resource))
+ {
+ FreeGrab(pGrab);
+ return BadAccess;
+ }
+ }
+ }
+
+ if (!pGrab->window->optional && !MakeWindowOptional (pGrab->window))
+ {
+ FreeGrab(pGrab);
+ return BadAlloc;
+ }
+ pGrab->next = pGrab->window->optional->passiveGrabs;
+ pGrab->window->optional->passiveGrabs = pGrab;
+ if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (void *)pGrab))
+ return Success;
+ return BadAlloc;
+}
+
+/* the following is kinda complicated, because we need to be able to back out
+ * if any allocation fails
+ */
+
+Bool
+DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
+{
+ register GrabPtr grab;
+ GrabPtr *deletes, *adds;
+ Mask ***updates, **details;
+ int i, ndels, nadds, nups;
+ Bool ok;
+
+#define UPDATE(mask,exact) \
+ if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \
+ ok = FALSE; \
+ else \
+ updates[nups++] = &(mask)
+
+ i = 0;
+ for (grab = wPassiveGrabs(pMinuendGrab->window); grab; grab = grab->next)
+ i++;
+ if (!i)
+ return TRUE;
+ deletes = (GrabPtr *)malloc(i * sizeof(GrabPtr));
+ adds = (GrabPtr *)malloc(i * sizeof(GrabPtr));
+ updates = (Mask ***)malloc(i * sizeof(Mask **));
+ details = (Mask **)malloc(i * sizeof(Mask *));
+ if (!deletes || !adds || !updates || !details)
+ {
+ if (details) free(details);
+ if (updates) free(updates);
+ if (adds) free(adds);
+ if (deletes) free(deletes);
+ return FALSE;
+ }
+ ndels = nadds = nups = 0;
+ ok = TRUE;
+ for (grab = wPassiveGrabs(pMinuendGrab->window);
+ grab && ok;
+ grab = grab->next)
+ {
+ if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) ||
+ !GrabMatchesSecond(grab, pMinuendGrab))
+ continue;
+ if (GrabSupersedesSecond(pMinuendGrab, grab))
+ {
+ deletes[ndels++] = grab;
+ }
+ else if ((grab->detail.exact == AnyKey)
+ && (grab->modifiersDetail.exact != AnyModifier))
+ {
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+ }
+ else if ((grab->modifiersDetail.exact == AnyModifier)
+ && (grab->detail.exact != AnyKey))
+ {
+ UPDATE(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact);
+ }
+ else if ((pMinuendGrab->detail.exact != AnyKey)
+ && (pMinuendGrab->modifiersDetail.exact != AnyModifier))
+ {
+ GrabPtr pNewGrab;
+
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+
+ pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
+ grab->window, (Mask)grab->eventMask,
+ (Bool)grab->ownerEvents,
+ (Bool)grab->keyboardMode,
+ (Bool)grab->pointerMode,
+ grab->modifierDevice,
+ AnyModifier, (int)grab->type,
+ pMinuendGrab->detail.exact,
+ grab->confineTo, grab->cursor);
+ if (!pNewGrab)
+ ok = FALSE;
+ else if (!(pNewGrab->modifiersDetail.pMask =
+ DeleteDetailFromMask(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact))
+ ||
+ (!pNewGrab->window->optional &&
+ !MakeWindowOptional(pNewGrab->window)))
+ {
+ FreeGrab(pNewGrab);
+ ok = FALSE;
+ }
+ else if (!AddResource(pNewGrab->resource, RT_PASSIVEGRAB,
+ (void *)pNewGrab))
+ ok = FALSE;
+ else
+ adds[nadds++] = pNewGrab;
+ }
+ else if (pMinuendGrab->detail.exact == AnyKey)
+ {
+ UPDATE(grab->modifiersDetail.pMask,
+ pMinuendGrab->modifiersDetail.exact);
+ }
+ else
+ {
+ UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
+ }
+ }
+
+ if (!ok)
+ {
+ for (i = 0; i < nadds; i++)
+ FreeResource(adds[i]->resource, RT_NONE);
+ for (i = 0; i < nups; i++)
+ free(details[i]);
+ }
+ else
+ {
+ for (i = 0; i < ndels; i++)
+ FreeResource(deletes[i]->resource, RT_NONE);
+ for (i = 0; i < nadds; i++)
+ {
+ grab = adds[i];
+ grab->next = grab->window->optional->passiveGrabs;
+ grab->window->optional->passiveGrabs = grab;
+ }
+ for (i = 0; i < nups; i++)
+ {
+ free(*updates[i]);
+ *updates[i] = details[i];
+ }
+ }
+ free(details);
+ free(updates);
+ free(adds);
+ free(deletes);
+ return ok;
+
+#undef UPDATE
+}
diff --git a/nx-X11/programs/Xserver/dix/initatoms.c b/nx-X11/programs/Xserver/dix/initatoms.c
new file mode 100644
index 000000000..5f6244a76
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/initatoms.c
@@ -0,0 +1,84 @@
+/* THIS IS A GENERATED FILE
+ *
+ * Do not change! Changing this file implies a protocol change!
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xatom.h>
+#include "misc.h"
+#include "dix.h"
+void MakePredeclaredAtoms()
+{
+ if (MakeAtom("PRIMARY", 7, 1) != XA_PRIMARY) AtomError();
+ if (MakeAtom("SECONDARY", 9, 1) != XA_SECONDARY) AtomError();
+ if (MakeAtom("ARC", 3, 1) != XA_ARC) AtomError();
+ if (MakeAtom("ATOM", 4, 1) != XA_ATOM) AtomError();
+ if (MakeAtom("BITMAP", 6, 1) != XA_BITMAP) AtomError();
+ if (MakeAtom("CARDINAL", 8, 1) != XA_CARDINAL) AtomError();
+ if (MakeAtom("COLORMAP", 8, 1) != XA_COLORMAP) AtomError();
+ if (MakeAtom("CURSOR", 6, 1) != XA_CURSOR) AtomError();
+ if (MakeAtom("CUT_BUFFER0", 11, 1) != XA_CUT_BUFFER0) AtomError();
+ if (MakeAtom("CUT_BUFFER1", 11, 1) != XA_CUT_BUFFER1) AtomError();
+ if (MakeAtom("CUT_BUFFER2", 11, 1) != XA_CUT_BUFFER2) AtomError();
+ if (MakeAtom("CUT_BUFFER3", 11, 1) != XA_CUT_BUFFER3) AtomError();
+ if (MakeAtom("CUT_BUFFER4", 11, 1) != XA_CUT_BUFFER4) AtomError();
+ if (MakeAtom("CUT_BUFFER5", 11, 1) != XA_CUT_BUFFER5) AtomError();
+ if (MakeAtom("CUT_BUFFER6", 11, 1) != XA_CUT_BUFFER6) AtomError();
+ if (MakeAtom("CUT_BUFFER7", 11, 1) != XA_CUT_BUFFER7) AtomError();
+ if (MakeAtom("DRAWABLE", 8, 1) != XA_DRAWABLE) AtomError();
+ if (MakeAtom("FONT", 4, 1) != XA_FONT) AtomError();
+ if (MakeAtom("INTEGER", 7, 1) != XA_INTEGER) AtomError();
+ if (MakeAtom("PIXMAP", 6, 1) != XA_PIXMAP) AtomError();
+ if (MakeAtom("POINT", 5, 1) != XA_POINT) AtomError();
+ if (MakeAtom("RECTANGLE", 9, 1) != XA_RECTANGLE) AtomError();
+ if (MakeAtom("RESOURCE_MANAGER", 16, 1) != XA_RESOURCE_MANAGER) AtomError();
+ if (MakeAtom("RGB_COLOR_MAP", 13, 1) != XA_RGB_COLOR_MAP) AtomError();
+ if (MakeAtom("RGB_BEST_MAP", 12, 1) != XA_RGB_BEST_MAP) AtomError();
+ if (MakeAtom("RGB_BLUE_MAP", 12, 1) != XA_RGB_BLUE_MAP) AtomError();
+ if (MakeAtom("RGB_DEFAULT_MAP", 15, 1) != XA_RGB_DEFAULT_MAP) AtomError();
+ if (MakeAtom("RGB_GRAY_MAP", 12, 1) != XA_RGB_GRAY_MAP) AtomError();
+ if (MakeAtom("RGB_GREEN_MAP", 13, 1) != XA_RGB_GREEN_MAP) AtomError();
+ if (MakeAtom("RGB_RED_MAP", 11, 1) != XA_RGB_RED_MAP) AtomError();
+ if (MakeAtom("STRING", 6, 1) != XA_STRING) AtomError();
+ if (MakeAtom("VISUALID", 8, 1) != XA_VISUALID) AtomError();
+ if (MakeAtom("WINDOW", 6, 1) != XA_WINDOW) AtomError();
+ if (MakeAtom("WM_COMMAND", 10, 1) != XA_WM_COMMAND) AtomError();
+ if (MakeAtom("WM_HINTS", 8, 1) != XA_WM_HINTS) AtomError();
+ if (MakeAtom("WM_CLIENT_MACHINE", 17, 1) != XA_WM_CLIENT_MACHINE) AtomError();
+ if (MakeAtom("WM_ICON_NAME", 12, 1) != XA_WM_ICON_NAME) AtomError();
+ if (MakeAtom("WM_ICON_SIZE", 12, 1) != XA_WM_ICON_SIZE) AtomError();
+ if (MakeAtom("WM_NAME", 7, 1) != XA_WM_NAME) AtomError();
+ if (MakeAtom("WM_NORMAL_HINTS", 15, 1) != XA_WM_NORMAL_HINTS) AtomError();
+ if (MakeAtom("WM_SIZE_HINTS", 13, 1) != XA_WM_SIZE_HINTS) AtomError();
+ if (MakeAtom("WM_ZOOM_HINTS", 13, 1) != XA_WM_ZOOM_HINTS) AtomError();
+ if (MakeAtom("MIN_SPACE", 9, 1) != XA_MIN_SPACE) AtomError();
+ if (MakeAtom("NORM_SPACE", 10, 1) != XA_NORM_SPACE) AtomError();
+ if (MakeAtom("MAX_SPACE", 9, 1) != XA_MAX_SPACE) AtomError();
+ if (MakeAtom("END_SPACE", 9, 1) != XA_END_SPACE) AtomError();
+ if (MakeAtom("SUPERSCRIPT_X", 13, 1) != XA_SUPERSCRIPT_X) AtomError();
+ if (MakeAtom("SUPERSCRIPT_Y", 13, 1) != XA_SUPERSCRIPT_Y) AtomError();
+ if (MakeAtom("SUBSCRIPT_X", 11, 1) != XA_SUBSCRIPT_X) AtomError();
+ if (MakeAtom("SUBSCRIPT_Y", 11, 1) != XA_SUBSCRIPT_Y) AtomError();
+ if (MakeAtom("UNDERLINE_POSITION", 18, 1) != XA_UNDERLINE_POSITION) AtomError();
+ if (MakeAtom("UNDERLINE_THICKNESS", 19, 1) != XA_UNDERLINE_THICKNESS) AtomError();
+ if (MakeAtom("STRIKEOUT_ASCENT", 16, 1) != XA_STRIKEOUT_ASCENT) AtomError();
+ if (MakeAtom("STRIKEOUT_DESCENT", 17, 1) != XA_STRIKEOUT_DESCENT) AtomError();
+ if (MakeAtom("ITALIC_ANGLE", 12, 1) != XA_ITALIC_ANGLE) AtomError();
+ if (MakeAtom("X_HEIGHT", 8, 1) != XA_X_HEIGHT) AtomError();
+ if (MakeAtom("QUAD_WIDTH", 10, 1) != XA_QUAD_WIDTH) AtomError();
+ if (MakeAtom("WEIGHT", 6, 1) != XA_WEIGHT) AtomError();
+ if (MakeAtom("POINT_SIZE", 10, 1) != XA_POINT_SIZE) AtomError();
+ if (MakeAtom("RESOLUTION", 10, 1) != XA_RESOLUTION) AtomError();
+ if (MakeAtom("COPYRIGHT", 9, 1) != XA_COPYRIGHT) AtomError();
+ if (MakeAtom("NOTICE", 6, 1) != XA_NOTICE) AtomError();
+ if (MakeAtom("FONT_NAME", 9, 1) != XA_FONT_NAME) AtomError();
+ if (MakeAtom("FAMILY_NAME", 11, 1) != XA_FAMILY_NAME) AtomError();
+ if (MakeAtom("FULL_NAME", 9, 1) != XA_FULL_NAME) AtomError();
+ if (MakeAtom("CAP_HEIGHT", 10, 1) != XA_CAP_HEIGHT) AtomError();
+ if (MakeAtom("WM_CLASS", 8, 1) != XA_WM_CLASS) AtomError();
+ if (MakeAtom("WM_TRANSIENT_FOR", 16, 1) != XA_WM_TRANSIENT_FOR) AtomError();
+}
diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c
new file mode 100644
index 000000000..3f3c079e4
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/main.c
@@ -0,0 +1,578 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $TOG: main.c /main/86 1998/02/09 14:20:03 kaleb $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xos.h> /* for unistd.h */
+#include <nx-X11/Xproto.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "extension.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS_XFONT2 */
+#include "opaque.h"
+#include "servermd.h"
+#include "site.h"
+#include "dixfont.h"
+#include "extnsionst.h"
+#include "client.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#else
+#include "dixevents.h" /* InitEvents() */
+#include "dispatch.h" /* InitProcVectors() */
+#endif
+
+#ifdef DPMSExtension
+#define DPMS_SERVER
+#include <nx-X11/extensions/dpms.h>
+#include "dpmsproc.h"
+#endif
+
+extern int InitClientPrivates(ClientPtr client);
+
+extern void Dispatch(void);
+
+xConnSetupPrefix connSetupPrefix;
+
+extern FontPtr defaultFont;
+
+extern void InitProcVectors(void);
+extern Bool CreateGCperDepthArray(void);
+
+extern void FreeScreen(ScreenPtr pScreen);
+
+#ifndef PANORAMIX
+static
+#endif
+Bool CreateConnectionBlock(void);
+
+PaddingInfo PixmapWidthPaddingInfo[33];
+
+int connBlockScreenStart;
+
+static int restart = 0;
+
+void
+NotImplemented(xEvent *from, xEvent *to)
+{
+ FatalError("Not implemented");
+}
+
+/*
+ * Dummy entry for ReplySwapVector[]
+ */
+
+void
+ReplyNotSwappd(
+ ClientPtr pClient ,
+ int size ,
+ void * pbuf
+ )
+{
+ FatalError("Not implemented");
+}
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ int i, error;
+ char *xauthfile;
+ HWEventQueueType alwaysCheckForInput[2];
+
+ display = "0";
+
+ InitGlobals();
+
+ /* Quartz support on Mac OS X requires that the Cocoa event loop be in
+ * the main thread. This allows the X server main to be called again
+ * from another thread. */
+#if defined(__DARWIN__) && defined(DARWIN_WITH_QUARTZ)
+ DarwinHandleGUI(argc, argv, envp);
+#endif
+
+ /* Notice if we're restarted. Probably this is because we jumped through
+ * an uninitialized pointer */
+ if (restart)
+ FatalError("server restarted. Jumped through uninitialized pointer?\n");
+ else
+ restart = 1;
+
+ CheckUserParameters(argc, argv, envp);
+
+ CheckUserAuthorization();
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+ ExpandCommandLine(&argc, &argv);
+#endif
+
+ InitConnectionLimits();
+
+ /* These are needed by some routines which are called from interrupt
+ * handlers, thus have no direct calling path back to main and thus
+ * can't be passed argc, argv as parameters */
+ argcGlobal = argc;
+ argvGlobal = argv;
+ /* prep X authority file from environment; this can be overriden by a
+ * command line option */
+ xauthfile = getenv("XAUTHORITY");
+ if (xauthfile) InitAuthorization (xauthfile);
+ ProcessCommandLine(argc, argv);
+
+ alwaysCheckForInput[0] = 0;
+ alwaysCheckForInput[1] = 1;
+ while(1)
+ {
+ serverGeneration++;
+ ScreenSaverTime = defaultScreenSaverTime;
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+#ifdef DPMSExtension
+ DPMSStandbyTime = defaultDPMSStandbyTime;
+ DPMSSuspendTime = defaultDPMSSuspendTime;
+ DPMSOffTime = defaultDPMSOffTime;
+ DPMSEnabled = defaultDPMSEnabled;
+ DPMSPowerLevel = 0;
+#endif
+ InitBlockAndWakeupHandlers();
+ /* Perform any operating system dependent initializations you'd like */
+ OsInit();
+ if(serverGeneration == 1)
+ {
+ CreateWellKnownSockets();
+ InitProcVectors();
+ clients = (ClientPtr *)malloc(MAXCLIENTS * sizeof(ClientPtr));
+ if (!clients)
+ FatalError("couldn't create client array");
+ for (i=1; i<MAXCLIENTS; i++)
+ clients[i] = NullClient;
+ serverClient = (ClientPtr)malloc(sizeof(ClientRec));
+ if (!serverClient)
+ FatalError("couldn't create server client");
+ InitClient(serverClient, 0, (void *)NULL);
+ }
+ else
+ ResetWellKnownSockets ();
+ clients[0] = serverClient;
+ currentMaxClients = 1;
+
+ if (!InitClientResources(serverClient)) /* for root resources */
+ FatalError("couldn't init server resources");
+
+ SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
+ screenInfo.arraySize = MAXSCREENS;
+ screenInfo.numScreens = 0;
+ screenInfo.numVideoScreens = -1;
+
+ InitAtoms();
+ InitEvents();
+#ifdef HAS_XFONT2
+ xfont2_init_glyph_caching();
+#else
+ InitGlyphCaching();
+#endif /* of HAS_XFONT2 */
+ ResetClientPrivates();
+ ResetScreenPrivates();
+ ResetWindowPrivates();
+ ResetGCPrivates();
+#ifdef PIXPRIV
+ ResetPixmapPrivates();
+#endif
+ ResetColormapPrivates();
+ ResetDevicePrivateIndex();
+ InitFonts();
+ InitCallbackManager();
+ InitVisualWrap();
+ InitOutput(&screenInfo, argc, argv);
+
+ if (screenInfo.numScreens < 1)
+ FatalError("no screens found");
+ if (screenInfo.numVideoScreens < 0)
+ screenInfo.numVideoScreens = screenInfo.numScreens;
+ InitExtensions(argc, argv);
+ if (!InitClientPrivates(serverClient))
+ FatalError("failed to allocate serverClient devprivates");
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ if (!CreateScratchPixmapsForScreen(i))
+ FatalError("failed to create scratch pixmaps");
+ if (pScreen->CreateScreenResources &&
+ !(*pScreen->CreateScreenResources)(pScreen))
+ FatalError("failed to create screen resources");
+ if (!CreateGCperDepth(i))
+ FatalError("failed to create scratch GCs");
+ if (!CreateDefaultStipple(i))
+ FatalError("failed to create default stipple");
+ if (!CreateRootWindow(pScreen))
+ FatalError("failed to create root window");
+ }
+ InitInput(argc, argv);
+ if (InitAndStartDevices() != Success)
+ FatalError("failed to initialize core devices");
+ ReserveClientIds(serverClient);
+
+ if (loadableFonts) {
+ SetFontPath(serverClient, 0, (unsigned char *)defaultFontPath);
+ } else {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ ErrorF("failed to set default font path '%s'\n",
+ defaultFontPath);
+ }
+ if (!SetDefaultFont(defaultTextFont))
+ FatalError("could not open default font '%s'", defaultTextFont);
+ if (!(rootCursor = CreateRootCursor(defaultCursorFont, 0)))
+ FatalError("could not open default cursor font '%s'",
+ defaultCursorFont);
+#ifdef DPMSExtension
+ /* check all screens, looking for DPMS Capabilities */
+ DPMSCapableFlag = DPMSSupported();
+ if (!DPMSCapableFlag)
+ DPMSEnabled = FALSE;
+#endif
+
+#ifdef PANORAMIX
+ /*
+ * Consolidate window and colourmap information for each screen
+ */
+ if (!noPanoramiXExtension)
+ PanoramiXConsolidate();
+#endif
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ InitRootWindow(screenInfo.screens[i]->root);
+ DefineInitialRootWindow(screenInfo.screens[0]->root);
+ SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
+#ifdef DPMSExtension
+ SetDPMSTimers();
+#endif
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ if (!PanoramiXCreateConnectionBlock())
+ FatalError("could not create connection block info");
+ } else
+#endif
+ {
+ if (!CreateConnectionBlock())
+ FatalError("could not create connection block info");
+ }
+
+ NotifyParentProcess();
+
+ Dispatch();
+
+ /* Now free up whatever must be freed */
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
+ FreeScreenSaverTimer();
+ CloseDownExtensions();
+
+#ifdef PANORAMIX
+ {
+ Bool remember_it = noPanoramiXExtension;
+ noPanoramiXExtension = TRUE;
+ FreeAllResources();
+ noPanoramiXExtension = remember_it;
+ }
+#else
+ FreeAllResources();
+#endif
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ screenInfo.screens[i]->root = NullWindow;
+ CloseDownDevices();
+ CloseDownEvents();
+
+ for (i = screenInfo.numScreens - 1; i >= 0; i--)
+ {
+ FreeScratchPixmapsForScreen(i);
+ FreeGCperDepth(i);
+ FreeDefaultStipple(i);
+ (* screenInfo.screens[i]->CloseScreen)(screenInfo.screens[i]);
+ FreeScreen(screenInfo.screens[i]);
+ screenInfo.numScreens = i;
+ }
+ FreeFonts();
+
+#ifdef DPMSExtension
+ FreeDPMSTimers();
+#endif
+ FreeAuditTimer();
+
+ ReleaseClientIds(serverClient);
+ free(serverClient->devPrivates);
+ serverClient->devPrivates = NULL;
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ CloseWellKnownConnections();
+ }
+
+ OsCleanup((dispatchException & DE_TERMINATE) != 0);
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ ddxGiveUp();
+ break;
+ }
+
+ free(ConnectionInfo);
+ ConnectionInfo = NULL;
+ }
+ return(0);
+}
+
+static int VendorRelease = VENDOR_RELEASE;
+static char *VendorString = VENDOR_STRING;
+
+void
+SetVendorRelease(int release)
+{
+ VendorRelease = release;
+}
+
+void
+SetVendorString(char *string)
+{
+ VendorString = string;
+}
+
+static int padlength[4] = {0, 3, 2, 1};
+
+#ifndef PANORAMIX
+static
+#endif
+Bool
+CreateConnectionBlock()
+{
+ xConnSetup setup;
+ xWindowRoot root;
+ xDepth depth;
+ xVisualType visual;
+ xPixmapFormat format;
+ unsigned long vid;
+ int i, j, k,
+ lenofblock,
+ sizesofar = 0;
+ char *pBuf;
+
+
+ memset(&setup, 0, sizeof(xConnSetup));
+ /* Leave off the ridBase and ridMask, these must be sent with
+ connection */
+
+ setup.release = VendorRelease;
+ /*
+ * per-server image and bitmap parameters are defined in Xmd.h
+ */
+ setup.imageByteOrder = screenInfo.imageByteOrder;
+
+ setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
+ setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
+
+ setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
+ setup.motionBufferSize = NumMotionEvents();
+ setup.numRoots = screenInfo.numScreens;
+ setup.nbytesVendor = strlen(VendorString);
+ setup.numFormats = screenInfo.numPixmapFormats;
+ setup.maxRequestSize = MAX_REQUEST_SIZE;
+ QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
+
+ lenofblock = sizeof(xConnSetup) +
+ ((setup.nbytesVendor + 3) & ~3) +
+ (setup.numFormats * sizeof(xPixmapFormat)) +
+ (setup.numRoots * sizeof(xWindowRoot));
+ ConnectionInfo = (char *) malloc(lenofblock);
+ if (!ConnectionInfo)
+ return FALSE;
+
+ memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
+ sizesofar = sizeof(xConnSetup);
+ pBuf = ConnectionInfo + sizeof(xConnSetup);
+
+ memmove(pBuf, VendorString, (int)setup.nbytesVendor);
+ sizesofar += setup.nbytesVendor;
+ pBuf += setup.nbytesVendor;
+ i = padlength[setup.nbytesVendor & 3];
+ sizesofar += i;
+ while (--i >= 0)
+ *pBuf++ = 0;
+
+ memset(&format, 0, sizeof(xPixmapFormat));
+ for (i=0; i<screenInfo.numPixmapFormats; i++)
+ {
+ format.depth = screenInfo.formats[i].depth;
+ format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
+ format.scanLinePad = screenInfo.formats[i].scanlinePad;
+ memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
+ pBuf += sizeof(xPixmapFormat);
+ sizesofar += sizeof(xPixmapFormat);
+ }
+
+ connBlockScreenStart = sizesofar;
+ memset(&depth, 0, sizeof(xDepth));
+ memset(&visual, 0, sizeof(xVisualType));
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ pScreen = screenInfo.screens[i];
+ root.windowId = screenInfo.screens[i]->root->drawable.id;
+ root.defaultColormap = pScreen->defColormap;
+ root.whitePixel = pScreen->whitePixel;
+ root.blackPixel = pScreen->blackPixel;
+ root.currentInputMask = 0; /* filled in when sent */
+ root.pixWidth = pScreen->width;
+ root.pixHeight = pScreen->height;
+ root.mmWidth = pScreen->mmWidth;
+ root.mmHeight = pScreen->mmHeight;
+ root.minInstalledMaps = pScreen->minInstalledCmaps;
+ root.maxInstalledMaps = pScreen->maxInstalledCmaps;
+ root.rootVisualID = pScreen->rootVisual;
+ root.backingStore = pScreen->backingStoreSupport;
+ root.saveUnders = pScreen->saveUnderSupport != NotUseful;
+ root.rootDepth = pScreen->rootDepth;
+ root.nDepths = pScreen->numDepths;
+ memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
+ sizesofar += sizeof(xWindowRoot);
+ pBuf += sizeof(xWindowRoot);
+
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ lenofblock += sizeof(xDepth) +
+ (pDepth->numVids * sizeof(xVisualType));
+ pBuf = (char *)realloc(ConnectionInfo, lenofblock);
+ if (!pBuf)
+ {
+ free(ConnectionInfo);
+ return FALSE;
+ }
+ ConnectionInfo = pBuf;
+ pBuf += sizesofar;
+ depth.depth = pDepth->depth;
+ depth.nVisuals = pDepth->numVids;
+ memmove(pBuf, (char *)&depth, sizeof(xDepth));
+ pBuf += sizeof(xDepth);
+ sizesofar += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ vid = pDepth->vids[k];
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != vid;
+ pVisual++)
+ ;
+ visual.visualID = vid;
+ visual.class = pVisual->class;
+ visual.bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual.colormapEntries = pVisual->ColormapEntries;
+ visual.redMask = pVisual->redMask;
+ visual.greenMask = pVisual->greenMask;
+ visual.blueMask = pVisual->blueMask;
+ memmove(pBuf, (char *)&visual, sizeof(xVisualType));
+ pBuf += sizeof(xVisualType);
+ sizesofar += sizeof(xVisualType);
+ }
+ }
+ }
+ connSetupPrefix.success = xTrue;
+ connSetupPrefix.length = lenofblock/4;
+ connSetupPrefix.majorVersion = X_PROTOCOL;
+ connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/dix/pixmap.c b/nx-X11/programs/Xserver/dix/pixmap.c
new file mode 100644
index 000000000..747120b48
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/pixmap.c
@@ -0,0 +1,150 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "site.h"
+
+
+/*
+ * Scratch pixmap management and device independent pixmap allocation
+ * function.
+ */
+
+
+/* callable by ddx */
+PixmapPtr
+GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
+ int bitsPerPixel, int devKind, void * pPixData)
+{
+ PixmapPtr pPixmap = pScreen->pScratchPixmap;
+
+ if (pPixmap)
+ pScreen->pScratchPixmap = NULL;
+ else
+ /* width and height of 0 means don't allocate any pixmap data */
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
+
+ if (pPixmap) {
+ if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData))
+ return pPixmap;
+ (*pScreen->DestroyPixmap)(pPixmap);
+ }
+ return NullPixmap;
+}
+
+
+/* callable by ddx */
+void
+FreeScratchPixmapHeader(PixmapPtr pPixmap)
+{
+ if (pPixmap)
+ {
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
+ pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
+ if (pScreen->pScratchPixmap)
+ (*pScreen->DestroyPixmap)(pPixmap);
+ else
+ pScreen->pScratchPixmap = pPixmap;
+ }
+}
+
+
+Bool
+CreateScratchPixmapsForScreen(int scrnum)
+{
+ /* let it be created on first use */
+ screenInfo.screens[scrnum]->pScratchPixmap = NULL;
+ return TRUE;
+}
+
+
+void
+FreeScratchPixmapsForScreen(int scrnum)
+{
+ FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
+}
+
+
+/* callable by ddx */
+PixmapPtr
+AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
+{
+ PixmapPtr pPixmap;
+#ifdef PIXPRIV
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned *sizes;
+ unsigned size;
+ int i;
+
+ if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
+ return NullPixmap;
+
+ /*
+ * FIXME: Allocate 4 bytes at the end of each pixmap. This
+ * is a quick workaround intended to fix a problem reported
+ * by Valgrind due to fbBlt() writing just after the end of
+ * the pixmap buffer. This may be a RENDER bug.
+ */
+
+ pPixmap = (PixmapPtr)malloc(pScreen->totalPixmapSize + pixDataSize + 4);
+ if (!pPixmap)
+ return NullPixmap;
+ ppriv = (DevUnion *)(pPixmap + 1);
+ pPixmap->devPrivates = ppriv;
+ sizes = pScreen->PixmapPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->PixmapPrivateLen);
+ for (i = pScreen->PixmapPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ((size = *sizes) != 0)
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+#else
+ pPixmap = (PixmapPtr)malloc(sizeof(PixmapRec) + pixDataSize);
+#endif
+ return pPixmap;
+}
diff --git a/nx-X11/programs/Xserver/dix/privates.c b/nx-X11/programs/Xserver/dix/privates.c
new file mode 100644
index 000000000..a7009054c
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/privates.c
@@ -0,0 +1,398 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "servermd.h"
+#include "site.h"
+#include "inputstr.h"
+
+/*
+ * See the Wrappers and devPrivates section in "Definition of the
+ * Porting Layer for the X v11 Sample Server" (doc/Server/ddx.tbl.ms)
+ * for information on how to use devPrivates.
+ */
+
+/*
+ * client private machinery
+ */
+
+static int clientPrivateCount;
+int clientPrivateLen;
+unsigned *clientPrivateSizes;
+unsigned totalClientSize;
+
+void
+ResetClientPrivates()
+{
+ clientPrivateCount = 0;
+ clientPrivateLen = 0;
+ free(clientPrivateSizes);
+ clientPrivateSizes = (unsigned *)NULL;
+ totalClientSize =
+ ((sizeof(ClientRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
+}
+
+int
+AllocateClientPrivateIndex()
+{
+ return clientPrivateCount++;
+}
+
+Bool
+AllocateClientPrivate(int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= clientPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)realloc(clientPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (clientPrivateLen <= index2)
+ {
+ nsizes[clientPrivateLen++] = 0;
+ totalClientSize += sizeof(DevUnion);
+ }
+ clientPrivateSizes = nsizes;
+ }
+ oldamount = clientPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ clientPrivateSizes[index2] = amount;
+ totalClientSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+/*
+ * screen private machinery
+ */
+
+int screenPrivateCount;
+
+void
+ResetScreenPrivates()
+{
+ screenPrivateCount = 0;
+}
+
+/* this can be called after some screens have been created,
+ * so we have to worry about resizing existing devPrivates
+ */
+int
+AllocateScreenPrivateIndex()
+{
+ int idx;
+ int i;
+ ScreenPtr pScreen;
+ DevUnion *nprivs;
+
+ idx = screenPrivateCount++;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ nprivs = (DevUnion *)realloc(pScreen->devPrivates,
+ screenPrivateCount * sizeof(DevUnion));
+ if (!nprivs)
+ {
+ screenPrivateCount--;
+ return -1;
+ }
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pScreen->devPrivates = nprivs;
+ }
+ return idx;
+}
+
+
+/*
+ * window private machinery
+ */
+
+static int windowPrivateCount;
+
+void
+ResetWindowPrivates()
+{
+ windowPrivateCount = 0;
+}
+
+int
+AllocateWindowPrivateIndex()
+{
+ return windowPrivateCount++;
+}
+
+Bool
+AllocateWindowPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->WindowPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)realloc(pScreen->WindowPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->WindowPrivateLen <= index2)
+ {
+ nsizes[pScreen->WindowPrivateLen++] = 0;
+ pScreen->totalWindowSize += sizeof(DevUnion);
+ }
+ pScreen->WindowPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->WindowPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->WindowPrivateSizes[index2] = amount;
+ pScreen->totalWindowSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+
+/*
+ * gc private machinery
+ */
+
+static int gcPrivateCount;
+
+void
+ResetGCPrivates()
+{
+ gcPrivateCount = 0;
+}
+
+int
+AllocateGCPrivateIndex()
+{
+ return gcPrivateCount++;
+}
+
+Bool
+AllocateGCPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->GCPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)realloc(pScreen->GCPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->GCPrivateLen <= index2)
+ {
+ nsizes[pScreen->GCPrivateLen++] = 0;
+ pScreen->totalGCSize += sizeof(DevUnion);
+ }
+ pScreen->GCPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->GCPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->GCPrivateSizes[index2] = amount;
+ pScreen->totalGCSize += (amount - oldamount);
+ }
+ return TRUE;
+}
+
+
+/*
+ * pixmap private machinery
+ */
+#ifdef PIXPRIV
+static int pixmapPrivateCount;
+
+void
+ResetPixmapPrivates()
+{
+ pixmapPrivateCount = 0;
+}
+
+int
+AllocatePixmapPrivateIndex()
+{
+ return pixmapPrivateCount++;
+}
+
+Bool
+AllocatePixmapPrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+ unsigned oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= pScreen->PixmapPrivateLen)
+ {
+ unsigned *nsizes;
+ nsizes = (unsigned *)realloc(pScreen->PixmapPrivateSizes,
+ (index2 + 1) * sizeof(unsigned));
+ if (!nsizes)
+ return FALSE;
+ while (pScreen->PixmapPrivateLen <= index2)
+ {
+ nsizes[pScreen->PixmapPrivateLen++] = 0;
+ pScreen->totalPixmapSize += sizeof(DevUnion);
+ }
+ pScreen->PixmapPrivateSizes = nsizes;
+ }
+ oldamount = pScreen->PixmapPrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ pScreen->PixmapPrivateSizes[index2] = amount;
+ pScreen->totalPixmapSize += (amount - oldamount);
+ }
+ pScreen->totalPixmapSize = BitmapBytePad(pScreen->totalPixmapSize * 8);
+ return TRUE;
+}
+#endif
+
+
+/*
+ * colormap private machinery
+ */
+
+int colormapPrivateCount;
+
+void
+ResetColormapPrivates()
+{
+ colormapPrivateCount = 0;
+}
+
+
+int
+AllocateColormapPrivateIndex (InitCmapPrivFunc initPrivFunc)
+{
+ int index;
+ int i;
+ ColormapPtr pColormap;
+ DevUnion *privs;
+
+ index = colormapPrivateCount++;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ /*
+ * AllocateColormapPrivateIndex may be called after the
+ * default colormap has been created on each screen!
+ *
+ * We must resize the devPrivates array for the default
+ * colormap on each screen, making room for this new private.
+ * We also call the initialization function 'initPrivFunc' on
+ * the new private allocated for each default colormap.
+ */
+
+ ScreenPtr pScreen = screenInfo.screens[i];
+
+ pColormap = (ColormapPtr) LookupIDByType (
+ pScreen->defColormap, RT_COLORMAP);
+
+ if (pColormap)
+ {
+ privs = (DevUnion *) realloc (pColormap->devPrivates,
+ colormapPrivateCount * sizeof(DevUnion));
+ if (!privs) {
+ colormapPrivateCount--;
+ return -1;
+ }
+ bzero(&privs[index], sizeof(DevUnion));
+ pColormap->devPrivates = privs;
+ if (!(*initPrivFunc)(pColormap,index))
+ {
+ colormapPrivateCount--;
+ return -1;
+ }
+ }
+ }
+
+ return index;
+}
+
+/*
+ * device private machinery
+ */
+
+static int devicePrivateIndex = 0;
+
+int
+AllocateDevicePrivateIndex()
+{
+ return devicePrivateIndex++;
+}
+
+Bool
+AllocateDevicePrivate(DeviceIntPtr device, int index)
+{
+ if (device->nPrivates < ++index) {
+ DevUnion *nprivs = (DevUnion *) realloc(device->devPrivates,
+ index * sizeof(DevUnion));
+ if (!nprivs)
+ return FALSE;
+ device->devPrivates = nprivs;
+ bzero(&nprivs[device->nPrivates], sizeof(DevUnion)
+ * (index - device->nPrivates));
+ device->nPrivates = index;
+ return TRUE;
+ } else {
+ return TRUE;
+ }
+}
+
+void
+ResetDevicePrivateIndex(void)
+{
+ devicePrivateIndex = 0;
+}
diff --git a/nx-X11/programs/Xserver/dix/property.c b/nx-X11/programs/Xserver/dix/property.c
new file mode 100644
index 000000000..66c38f56c
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/property.c
@@ -0,0 +1,694 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ * ChangeProperty, DeleteProperty, GetProperties,
+ * ListProperties
+ *
+ * Properties below to windows. A allocate slots each time
+ * a property is added. No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+ PropertyPtr pProp;
+ register int j;
+
+ pProp = pWin->userProps;
+ while (pProp)
+ {
+ ErrorF( "%x %x\n", pProp->propertyName, pProp->type);
+ ErrorF("property format: %d\n", pProp->format);
+ ErrorF("property data: \n");
+ for (j=0; j<(pProp->format/8)*pProp->size; j++)
+ ErrorF("%c\n", pProp->data[j]);
+ pProp = pProp->next;
+ }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+ int i, j, delta;
+ REQUEST(xRotatePropertiesReq);
+ WindowPtr pWin;
+ register Atom * atoms;
+ PropertyPtr * props; /* array of pointer */
+ PropertyPtr pProp;
+
+ REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!stuff->nAtoms)
+ return(Success);
+ atoms = (Atom *) & stuff[1];
+ props = (PropertyPtr *)malloc(stuff->nAtoms * sizeof(PropertyPtr));
+ if (!props)
+ return(BadAlloc);
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+#ifdef XCSECURITY
+ char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+ DixReadAccess|DixWriteAccess);
+#endif
+ if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+ || (SecurityErrorOperation == action)
+#endif
+ )
+ {
+ free(props);
+ client->errorValue = atoms[i];
+ return BadAtom;
+ }
+#ifdef XCSECURITY
+ if (SecurityIgnoreOperation == action)
+ {
+ free(props);
+ return Success;
+ }
+#endif
+ for (j = i + 1; j < stuff->nAtoms; j++)
+ if (atoms[j] == atoms[i])
+ {
+ free(props);
+ return BadMatch;
+ }
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == atoms[i])
+ goto found;
+ pProp = pProp->next;
+ }
+ free(props);
+ return BadMatch;
+found:
+ props[i] = pProp;
+ }
+ delta = stuff->nPositions;
+
+ /* If the rotation is a complete 360 degrees, then moving the properties
+ around and generating PropertyNotify events should be skipped. */
+
+ if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ {
+ while (delta < 0) /* faster if abs value is small */
+ delta += stuff->nAtoms;
+ for (i = 0; i < stuff->nAtoms; i++)
+ {
+ /* Generate a PropertyNotify event for each property whose value
+ is changed in the order in which they appear in the request. */
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = props[i]->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+
+ props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ }
+ }
+ free(props);
+ return Success;
+}
+
+#ifndef NXAGENT_SERVER
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ DixWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (void *)&stuff[1], TRUE);
+ if (err != Success)
+ return err;
+ else
+ return client->noClientException;
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, void * value,
+ Bool sendevent)
+{
+ PropertyPtr pProp;
+ int sizeInBytes;
+ int totalSize;
+ void * data;
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)malloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (void *)malloc(totalSize);
+ if (!data && len)
+ {
+ free(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (void *)realloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (void *)realloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (void *)malloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ free(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ xEvent event;
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+}
+#endif /* NXAGENT_SERVER */
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+ PropertyPtr pProp, prevProp;
+
+ if (!(pProp = wUserProps (pWin)))
+ return(Success);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == propName)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ if (pProp)
+ {
+ xEvent event;
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ {
+ prevProp->next = pProp->next;
+ }
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ free(pProp->data);
+ free(pProp);
+ }
+ return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+ PropertyPtr pProp, pNextProp;
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ pNextProp = pProp->next;
+ free(pProp->data);
+ free(pProp);
+ pProp = pNextProp;
+ }
+}
+
+static int
+NullPropertyReply(
+ ClientPtr client,
+ ATOM propertyType,
+ int format,
+ xGetPropertyReply *reply)
+{
+ reply->nItems = 0;
+ reply->length = 0;
+ reply->bytesAfter = 0;
+ reply->propertyType = propertyType;
+ reply->format = format;
+ WriteReplyToClient(client, sizeof(xGenericReply), reply);
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ memset(&reply, 0, sizeof(xGetPropertyReply));
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+ {
+ Mask access_mode = DixReadAccess;
+
+ if (stuff->delete)
+ access_mode |= DixDestroyAccess;
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ free(pProp->data);
+ free(pProp);
+ }
+ return(client->noClientException);
+}
+#endif /* NXAGENT_SERVER */
+
+int
+ProcListProperties(ClientPtr client)
+{
+ Atom *pAtoms = NULL, *temppAtoms;
+ xListPropertiesReply xlpr;
+ int numProps = 0;
+ WindowPtr pWin;
+ PropertyPtr pProp;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ pProp = pProp->next;
+ numProps++;
+ }
+ if (numProps)
+ if(!(pAtoms = (Atom *)malloc(numProps * sizeof(Atom))))
+ return(BadAlloc);
+
+ memset(&xlpr, 0, sizeof(xListPropertiesReply));
+ xlpr.type = X_Reply;
+ xlpr.nProperties = numProps;
+ xlpr.length = (numProps * sizeof(Atom)) >> 2;
+ xlpr.sequenceNumber = client->sequence;
+ pProp = wUserProps (pWin);
+ temppAtoms = pAtoms;
+ while (pProp)
+ {
+ *temppAtoms++ = pProp->propertyName;
+ pProp = pProp->next;
+ }
+ WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+ if (numProps)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ free(pAtoms);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDeleteProperty(register ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xDeletePropertyReq);
+ int result;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ DixDestroyAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+ result = DeleteProperty(pWin, stuff->property);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
diff --git a/nx-X11/programs/Xserver/dix/region.c b/nx-X11/programs/Xserver/dix/region.c
new file mode 100644
index 000000000..46e8845bf
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/region.c
@@ -0,0 +1,1742 @@
+/***********************************************************
+
+Copyright 1987, 1988, 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.
+
+
+Copyright 1987, 1988, 1989 by
+Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <pixman.h>
+
+#include "regionstr.h"
+#include <nx-X11/Xprotostr.h>
+#include "gc.h"
+
+#if defined (__GNUC__) && !defined (NO_INLINES)
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+
+#undef assert
+#ifdef DEBUG
+#define assert(expr) {if (!(expr)) \
+ FatalError("Assertion failed file %s, line %d: expr\n", \
+ __FILE__, __LINE__); }
+#else
+#define assert(expr)
+#endif
+
+#define good(reg) assert(RegionIsValid(reg))
+
+/*
+ * The functions in this file implement the Region abstraction used extensively
+ * throughout the X11 sample server. A Region is simply a set of disjoint
+ * (non-overlapping) rectangles, plus an "extent" rectangle which is the
+ * smallest single rectangle that contains all the non-overlapping rectangles.
+ *
+ * A Region is implemented as a "y-x-banded" array of rectangles. This array
+ * imposes two degrees of order. First, all rectangles are sorted by top side
+ * y coordinate first (y1), and then by left side x coordinate (x1).
+ *
+ * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
+ * band has the same top y coordinate (y1), and each has the same bottom y
+ * coordinate (y2). Thus all rectangles in a band differ only in their left
+ * and right side (x1 and x2). Bands are implicit in the array of rectangles:
+ * there is no separate list of band start pointers.
+ *
+ * The y-x band representation does not minimize rectangles. In particular,
+ * if a rectangle vertically crosses a band (the rectangle has scanlines in
+ * the y1 to y2 area spanned by the band), then the rectangle may be broken
+ * down into two or more smaller rectangles stacked one atop the other.
+ *
+ * ----------- -----------
+ * | | | | band 0
+ * | | -------- ----------- --------
+ * | | | | in y-x banded | | | | band 1
+ * | | | | form is | | | |
+ * ----------- | | ----------- --------
+ * | | | | band 2
+ * -------- --------
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible: no two rectangles within a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course).
+ *
+ * Adam de Boor wrote most of the original region code. Joel McCormack
+ * substantially modified or rewrote most of the core arithmetic routines,
+ * and added RegionValidate in order to support several speed improvements
+ * to miValidateTree. Bob Scheifler changed the representation to be more
+ * compact when empty or a single rectangle, and did a bunch of gratuitous
+ * reformatting.
+ */
+
+/* true iff two Boxes overlap */
+#define EXTENTCHECK(r1,r2) \
+ (!( ((r1)->x2 <= (r2)->x1) || \
+ ((r1)->x1 >= (r2)->x2) || \
+ ((r1)->y2 <= (r2)->y1) || \
+ ((r1)->y1 >= (r2)->y2) ) )
+
+/* true iff (x,y) is in Box */
+#define INBOX(r,x,y) \
+ ( ((r)->x2 > x) && \
+ ((r)->x1 <= x) && \
+ ((r)->y2 > y) && \
+ ((r)->y1 <= y) )
+
+/* true iff Box r1 contains Box r2 */
+#define SUBSUMES(r1,r2) \
+ ( ((r1)->x1 <= (r2)->x1) && \
+ ((r1)->x2 >= (r2)->x2) && \
+ ((r1)->y1 <= (r2)->y1) && \
+ ((r1)->y2 >= (r2)->y2) )
+
+#define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
+
+#define RECTALLOC_BAIL(pReg,n,bail) \
+if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
+ if (!RegionRectAlloc(pReg, n)) { goto bail; }
+
+#define RECTALLOC(pReg,n) \
+if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
+ if (!RegionRectAlloc(pReg, n)) { return FALSE; }
+
+#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2) \
+{ \
+ pNextRect->x1 = nx1; \
+ pNextRect->y1 = ny1; \
+ pNextRect->x2 = nx2; \
+ pNextRect->y2 = ny2; \
+ pNextRect++; \
+}
+
+#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2) \
+{ \
+ if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\
+ { \
+ if (!RegionRectAlloc(pReg, 1)) \
+ return FALSE; \
+ pNextRect = RegionTop(pReg); \
+ } \
+ ADDRECT(pNextRect,nx1,ny1,nx2,ny2); \
+ pReg->data->numRects++; \
+ assert(pReg->data->numRects<=pReg->data->size); \
+}
+
+
+#define DOWNSIZE(reg,numRects) \
+if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
+{ \
+ size_t NewSize = RegionSizeof(numRects); \
+ RegDataPtr NewData = \
+ (NewSize > 0) ? (RegDataPtr)realloc((reg)->data, NewSize) : NULL; \
+ if (NewData) \
+ { \
+ NewData->size = (numRects); \
+ (reg)->data = NewData; \
+ } \
+}
+
+
+pixman_box16_t RegionEmptyBox = {0, 0, 0, 0};
+RegDataRec RegionEmptyData = {0, 0};
+
+RegDataRec RegionBrokenData = {0, 0};
+RegionRec RegionBrokenRegion = { { 0, 0, 0, 0 }, &RegionBrokenData };
+
+#ifdef DEBUG
+int
+RegionPrint(rgn)
+ RegionPtr rgn;
+{
+ int num, size;
+ register int i;
+ BoxPtr rects;
+
+ num = RegionNumRects(rgn);
+ size = RegionSize(rgn);
+ rects = RegionRects(rgn);
+ ErrorF("num: %d size: %d\n", num, size);
+ ErrorF("extents: %d %d %d %d\n",
+ rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);
+ for (i = 0; i < num; i++)
+ ErrorF("%d %d %d %d \n",
+ rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
+ ErrorF("\n");
+ return(num);
+}
+#endif /* DEBUG */
+
+#ifdef DEBUG
+Bool
+RegionIsValid(reg)
+ RegionPtr reg;
+{
+ register int i, numRects;
+
+ if ((reg->extents.x1 > reg->extents.x2) ||
+ (reg->extents.y1 > reg->extents.y2))
+ return FALSE;
+ numRects = RegionNumRects(reg);
+ if (!numRects)
+ return ((reg->extents.x1 == reg->extents.x2) &&
+ (reg->extents.y1 == reg->extents.y2) &&
+ (reg->data->size || (reg->data == &RegionEmptyData)));
+ else if (numRects == 1)
+ return (!reg->data);
+ else
+ {
+ register BoxPtr pboxP, pboxN;
+ BoxRec box;
+
+ pboxP = RegionRects(reg);
+ box = *pboxP;
+ box.y2 = pboxP[numRects-1].y2;
+ pboxN = pboxP + 1;
+ for (i = numRects; --i > 0; pboxP++, pboxN++)
+ {
+ if ((pboxN->x1 >= pboxN->x2) ||
+ (pboxN->y1 >= pboxN->y2))
+ return FALSE;
+ if (pboxN->x1 < box.x1)
+ box.x1 = pboxN->x1;
+ if (pboxN->x2 > box.x2)
+ box.x2 = pboxN->x2;
+ if ((pboxN->y1 < pboxP->y1) ||
+ ((pboxN->y1 == pboxP->y1) &&
+ ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))
+ return FALSE;
+ }
+ return ((box.x1 == reg->extents.x1) &&
+ (box.x2 == reg->extents.x2) &&
+ (box.y1 == reg->extents.y1) &&
+ (box.y2 == reg->extents.y2));
+ }
+}
+
+#endif /* DEBUG */
+
+
+/*****************************************************************
+ * RegionCreate(rect, size)
+ * This routine does a simple malloc to make a structure of
+ * REGION of "size" number of rectangles.
+ *****************************************************************/
+
+RegionPtr
+RegionCreate(rect, size)
+ BoxPtr rect;
+ int size;
+{
+ register RegionPtr pReg;
+ size_t newSize;
+ pReg = (RegionPtr)malloc(sizeof(RegionRec));
+ if (!pReg)
+ return &RegionBrokenRegion;
+ if (rect)
+ {
+ pReg->extents = *rect;
+ pReg->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ pReg->extents = RegionEmptyBox;
+ newSize = RegionSizeof(size);
+ if ((size > 1) && (newSize > 0) &&
+ (pReg->data = malloc(newSize)))
+ {
+ pReg->data->size = size;
+ pReg->data->numRects = 0;
+ }
+ else
+ pReg->data = &RegionEmptyData;
+ }
+ return(pReg);
+}
+
+void
+RegionDestroy(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ xfreeData(pReg);
+ if (pReg != &RegionBrokenRegion)
+ free(pReg);
+}
+
+Bool
+RegionBreak (pReg)
+ RegionPtr pReg;
+{
+ xfreeData (pReg);
+ pReg->extents = RegionEmptyBox;
+ pReg->data = &RegionBrokenData;
+ return FALSE;
+}
+
+Bool
+RegionRectAlloc(
+ register RegionPtr pRgn,
+ int n)
+{
+ RegDataPtr data;
+ size_t rgnSize;
+
+ if (!pRgn->data)
+ {
+ n++;
+ rgnSize = RegionSizeof(n);
+ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
+ if (!pRgn->data)
+ return RegionBreak (pRgn);
+ pRgn->data->numRects = 1;
+ *RegionBoxptr(pRgn) = pRgn->extents;
+ }
+ else if (!pRgn->data->size)
+ {
+ rgnSize = RegionSizeof(n);
+ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL;
+ if (!pRgn->data)
+ return RegionBreak (pRgn);
+ pRgn->data->numRects = 0;
+ }
+ else
+ {
+ if (n == 1)
+ {
+ n = pRgn->data->numRects;
+ if (n > 500) /* XXX pick numbers out of a hat */
+ n = 250;
+ }
+ n += pRgn->data->numRects;
+ rgnSize = RegionSizeof(n);
+ data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL;
+ if (!data)
+ return RegionBreak (pRgn);
+ pRgn->data = data;
+ }
+ pRgn->data->size = n;
+ return TRUE;
+}
+
+
+
+/*======================================================================
+ * Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionCoalesce --
+ * Attempt to merge the boxes in the current band with those in the
+ * previous one. We are guaranteed that the current band extends to
+ * the end of the rects array. Used only by RegionOp.
+ *
+ * Results:
+ * The new index for the previous band.
+ *
+ * Side Effects:
+ * If coalescing takes place:
+ * - rectangles in the previous band will have their y2 fields
+ * altered.
+ * - pReg->data->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+INLINE static int
+RegionCoalesce (
+ register RegionPtr pReg, /* Region to coalesce */
+ int prevStart, /* Index of start of previous band */
+ int curStart) /* Index of start of current band */
+{
+ register BoxPtr pPrevBox; /* Current box in previous band */
+ register BoxPtr pCurBox; /* Current box in current band */
+ register int numRects; /* Number rectangles in both bands */
+ register int y2; /* Bottom of current band */
+ /*
+ * Figure out how many rectangles are in the band.
+ */
+ numRects = curStart - prevStart;
+ assert(numRects == pReg->data->numRects - curStart);
+
+ if (!numRects) return curStart;
+
+ /*
+ * The bands may only be coalesced if the bottom of the previous
+ * matches the top scanline of the current.
+ */
+ pPrevBox = RegionBox(pReg, prevStart);
+ pCurBox = RegionBox(pReg, curStart);
+ if (pPrevBox->y2 != pCurBox->y1) return curStart;
+
+ /*
+ * Make sure the bands have boxes in the same places. This
+ * assumes that boxes have been added in such a way that they
+ * cover the most area possible. I.e. two boxes in a band must
+ * have some horizontal space between them.
+ */
+ y2 = pCurBox->y2;
+
+ do {
+ if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) {
+ return (curStart);
+ }
+ pPrevBox++;
+ pCurBox++;
+ numRects--;
+ } while (numRects);
+
+ /*
+ * The bands may be merged, so set the bottom y of each box
+ * in the previous band to the bottom y of the current band.
+ */
+ numRects = curStart - prevStart;
+ pReg->data->numRects -= numRects;
+ do {
+ pPrevBox--;
+ pPrevBox->y2 = y2;
+ numRects--;
+ } while (numRects);
+ return prevStart;
+}
+
+
+/* Quicky macro to avoid trivial reject procedure calls to RegionCoalesce */
+
+#define Coalesce(newReg, prevBand, curBand) \
+ if (curBand - prevBand == newReg->data->numRects - curBand) { \
+ prevBand = RegionCoalesce(newReg, prevBand, curBand); \
+ } else { \
+ prevBand = curBand; \
+ }
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionAppendNonO --
+ * Handle a non-overlapping band for the union and subtract operations.
+ * Just adds the (top/bottom-clipped) rectangles into the region.
+ * Doesn't have to check for subsumption or anything.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * pReg->data->numRects is incremented and the rectangles overwritten
+ * with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+INLINE static Bool
+RegionAppendNonO (
+ register RegionPtr pReg,
+ register BoxPtr r,
+ BoxPtr rEnd,
+ register int y1,
+ register int y2)
+{
+ register BoxPtr pNextRect;
+ register int newRects;
+
+ newRects = rEnd - r;
+
+ assert(y1 < y2);
+ assert(newRects != 0);
+
+ /* Make sure we have enough space for all rectangles to be added */
+ RECTALLOC(pReg, newRects);
+ pNextRect = RegionTop(pReg);
+ pReg->data->numRects += newRects;
+ do {
+ assert(r->x1 < r->x2);
+ ADDRECT(pNextRect, r->x1, y1, r->x2, y2);
+ r++;
+ } while (r != rEnd);
+
+ return TRUE;
+}
+
+#define FindBand(r, rBandEnd, rEnd, ry1) \
+{ \
+ ry1 = r->y1; \
+ rBandEnd = r+1; \
+ while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \
+ rBandEnd++; \
+ } \
+}
+
+#define AppendRegions(newReg, r, rEnd) \
+{ \
+ int newRects; \
+ if ((newRects = rEnd - r)) { \
+ RECTALLOC(newReg, newRects); \
+ memmove((char *)RegionTop(newReg),(char *)r, \
+ newRects * sizeof(BoxRec)); \
+ newReg->data->numRects += newRects; \
+ } \
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionOp --
+ * Apply an operation to two regions. Called by RegionUnion, RegionInverse,
+ * RegionSubtract, RegionIntersect.... Both regions MUST have at least one
+ * rectangle, and cannot be the same object.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The new region is overwritten.
+ * pOverlap set to TRUE if overlapFunc ever returns TRUE.
+ *
+ * Notes:
+ * The idea behind this function is to view the two regions as sets.
+ * Together they cover a rectangle of area that this function divides
+ * into horizontal bands where points are covered only by one region
+ * or by both. For the first case, the nonOverlapFunc is called with
+ * each the band and the band's upper and lower extents. For the
+ * second, the overlapFunc is called to process the entire band. It
+ * is responsible for clipping the rectangles in the band, though
+ * this function provides the boundaries.
+ * At the end of each band, the new region is coalesced, if possible,
+ * to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+typedef Bool (*OverlapProcPtr)(
+ RegionPtr pReg,
+ BoxPtr r1,
+ BoxPtr r1End,
+ BoxPtr r2,
+ BoxPtr r2End,
+ short y1,
+ short y2,
+ Bool *pOverlap);
+
+static Bool
+RegionOp(
+ RegionPtr newReg, /* Place to store result */
+ RegionPtr reg1, /* First region in operation */
+ RegionPtr reg2, /* 2d region in operation */
+ OverlapProcPtr overlapFunc, /* Function to call for over-
+ * lapping bands */
+ Bool appendNon1, /* Append non-overlapping bands */
+ /* in region 1 ? */
+ Bool appendNon2, /* Append non-overlapping bands */
+ /* in region 2 ? */
+ Bool *pOverlap)
+{
+ register BoxPtr r1; /* Pointer into first region */
+ register BoxPtr r2; /* Pointer into 2d region */
+ BoxPtr r1End; /* End of 1st region */
+ BoxPtr r2End; /* End of 2d region */
+ short ybot; /* Bottom of intersection */
+ short ytop; /* Top of intersection */
+ RegDataPtr oldData; /* Old data for newReg */
+ int prevBand; /* Index of start of
+ * previous band in newReg */
+ int curBand; /* Index of start of current
+ * band in newReg */
+ register BoxPtr r1BandEnd; /* End of current band in r1 */
+ register BoxPtr r2BandEnd; /* End of current band in r2 */
+ short top; /* Top of non-overlapping band */
+ short bot; /* Bottom of non-overlapping band*/
+ register int r1y1; /* Temps for r1->y1 and r2->y1 */
+ register int r2y1;
+ int newSize;
+ int numRects;
+
+ /*
+ * Break any region computed from a broken region
+ */
+ if (RegionNar (reg1) || RegionNar(reg2))
+ return RegionBreak (newReg);
+
+ /*
+ * Initialization:
+ * set r1, r2, r1End and r2End appropriately, save the rectangles
+ * of the destination region until the end in case it's one of
+ * the two source regions, then mark the "new" region empty, allocating
+ * another array of rectangles for it to use.
+ */
+
+ r1 = RegionRects(reg1);
+ newSize = RegionNumRects(reg1);
+ r1End = r1 + newSize;
+ numRects = RegionNumRects(reg2);
+ r2 = RegionRects(reg2);
+ r2End = r2 + numRects;
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+
+ oldData = (RegDataPtr)NULL;
+ if (((newReg == reg1) && (newSize > 1)) ||
+ ((newReg == reg2) && (numRects > 1)))
+ {
+ oldData = newReg->data;
+ newReg->data = &RegionEmptyData;
+ }
+ /* guess at new size */
+ if (numRects > newSize)
+ newSize = numRects;
+ newSize <<= 1;
+ if (!newReg->data)
+ newReg->data = &RegionEmptyData;
+ else if (newReg->data->size)
+ newReg->data->numRects = 0;
+ if (newSize > newReg->data->size)
+ if (!RegionRectAlloc(newReg, newSize))
+ return FALSE;
+
+ /*
+ * Initialize ybot.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+
+ ybot = min(r1->y1, r2->y1);
+
+ /*
+ * prevBand serves to mark the start of the previous band so rectangles
+ * can be coalesced into larger rectangles. qv. RegionCoalesce, above.
+ * In the beginning, there is no previous band, so prevBand == curBand
+ * (curBand is set later on, of course, but the first band will always
+ * start at index 0). prevBand and curBand must be indices because of
+ * the possible expansion, and resultant moving, of the new region's
+ * array of rectangles.
+ */
+ prevBand = 0;
+
+ do {
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1y1 < r2y1) {
+ if (appendNon1) {
+ top = max(r1y1, ybot);
+ bot = min(r1->y2, r2y1);
+ if (top != bot) {
+ curBand = newReg->data->numRects;
+ RegionAppendNonO(newReg, r1, r1BandEnd, top, bot);
+ Coalesce(newReg, prevBand, curBand);
+ }
+ }
+ ytop = r2y1;
+ } else if (r2y1 < r1y1) {
+ if (appendNon2) {
+ top = max(r2y1, ybot);
+ bot = min(r2->y2, r1y1);
+ if (top != bot) {
+ curBand = newReg->data->numRects;
+ RegionAppendNonO(newReg, r2, r2BandEnd, top, bot);
+ Coalesce(newReg, prevBand, curBand);
+ }
+ }
+ ytop = r1y1;
+ } else {
+ ytop = r1y1;
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot > ytop
+ */
+ ybot = min(r1->y2, r2->y2);
+ if (ybot > ytop) {
+ curBand = newReg->data->numRects;
+ (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
+ pOverlap);
+ Coalesce(newReg, prevBand, curBand);
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->y2 == ybot) r1 = r1BandEnd;
+ if (r2->y2 == ybot) r2 = r2BandEnd;
+
+ } while (r1 != r1End && r2 != r2End);
+
+ /*
+ * Deal with whichever region (if any) still has rectangles left.
+ *
+ * We only need to worry about banding and coalescing for the very first
+ * band left. After that, we can just group all remaining boxes,
+ * regardless of how many bands, into one final append to the list.
+ */
+
+ if ((r1 != r1End) && appendNon1) {
+ /* Do first nonOverlap1Func call, which may be able to coalesce */
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ curBand = newReg->data->numRects;
+ RegionAppendNonO(newReg, r1, r1BandEnd, max(r1y1, ybot), r1->y2);
+ Coalesce(newReg, prevBand, curBand);
+ /* Just append the rest of the boxes */
+ AppendRegions(newReg, r1BandEnd, r1End);
+
+ } else if ((r2 != r2End) && appendNon2) {
+ /* Do first nonOverlap2Func call, which may be able to coalesce */
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+ curBand = newReg->data->numRects;
+ RegionAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2);
+ Coalesce(newReg, prevBand, curBand);
+ /* Append rest of boxes */
+ AppendRegions(newReg, r2BandEnd, r2End);
+ }
+
+ if (oldData)
+ free(oldData);
+
+ if (!(numRects = newReg->data->numRects))
+ {
+ xfreeData(newReg);
+ newReg->data = &RegionEmptyData;
+ }
+ else if (numRects == 1)
+ {
+ newReg->extents = *RegionBoxptr(newReg);
+ xfreeData(newReg);
+ newReg->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ DOWNSIZE(newReg, numRects);
+ }
+
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionSetExtents --
+ * Reset the extents of a region to what they should be. Called by
+ * RegionSubtract and RegionIntersect as they can't figure it out along the
+ * way or do so easily, as RegionUnion can.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+RegionSetExtents (pReg)
+ register RegionPtr pReg;
+{
+ register BoxPtr pBox, pBoxEnd;
+
+ if (!pReg->data)
+ return;
+ if (!pReg->data->size)
+ {
+ pReg->extents.x2 = pReg->extents.x1;
+ pReg->extents.y2 = pReg->extents.y1;
+ return;
+ }
+
+ pBox = RegionBoxptr(pReg);
+ pBoxEnd = RegionEnd(pReg);
+
+ /*
+ * Since pBox is the first rectangle in the region, it must have the
+ * smallest y1 and since pBoxEnd is the last rectangle in the region,
+ * it must have the largest y2, because of banding. Initialize x1 and
+ * x2 from pBox and pBoxEnd, resp., as good things to initialize them
+ * to...
+ */
+ pReg->extents.x1 = pBox->x1;
+ pReg->extents.y1 = pBox->y1;
+ pReg->extents.x2 = pBoxEnd->x2;
+ pReg->extents.y2 = pBoxEnd->y2;
+
+ assert(pReg->extents.y1 < pReg->extents.y2);
+ while (pBox <= pBoxEnd) {
+ if (pBox->x1 < pReg->extents.x1)
+ pReg->extents.x1 = pBox->x1;
+ if (pBox->x2 > pReg->extents.x2)
+ pReg->extents.x2 = pBox->x2;
+ pBox++;
+ };
+
+ assert(pReg->extents.x1 < pReg->extents.x2);
+}
+
+#define MERGERECT(r) \
+{ \
+ if (r->x1 <= x2) { \
+ /* Merge with current rectangle */ \
+ if (r->x1 < x2) *pOverlap = TRUE; \
+ if (x2 < r->x2) x2 = r->x2; \
+ } else { \
+ /* Add current rectangle, start new one */ \
+ NEWRECT(pReg, pNextRect, x1, y1, x2, y2); \
+ x1 = r->x1; \
+ x2 = r->x2; \
+ } \
+ r++; \
+}
+
+/*======================================================================
+ * Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionUnionO --
+ * Handle an overlapping band for the union operation. Picks the
+ * left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * pReg is overwritten.
+ * pOverlap is set to TRUE if any boxes overlap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+RegionUnionO (
+ register RegionPtr pReg,
+ register BoxPtr r1,
+ BoxPtr r1End,
+ register BoxPtr r2,
+ BoxPtr r2End,
+ short y1,
+ short y2,
+ Bool *pOverlap)
+{
+ register BoxPtr pNextRect;
+ register int x1; /* left and right side of current union */
+ register int x2;
+
+ assert (y1 < y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ pNextRect = RegionTop(pReg);
+
+ /* Start off current rectangle */
+ if (r1->x1 < r2->x1)
+ {
+ x1 = r1->x1;
+ x2 = r1->x2;
+ r1++;
+ }
+ else
+ {
+ x1 = r2->x1;
+ x2 = r2->x2;
+ r2++;
+ }
+ while (r1 != r1End && r2 != r2End)
+ {
+ if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2);
+ }
+
+ /* Finish off whoever (if any) is left */
+ if (r1 != r1End)
+ {
+ do
+ {
+ MERGERECT(r1);
+ } while (r1 != r1End);
+ }
+ else if (r2 != r2End)
+ {
+ do
+ {
+ MERGERECT(r2);
+ } while (r2 != r2End);
+ }
+
+ /* Add current rectangle */
+ NEWRECT(pReg, pNextRect, x1, y1, x2, y2);
+
+ return TRUE;
+}
+
+/*======================================================================
+ * Batch Rectangle Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionAppend --
+ *
+ * "Append" the rgn rectangles onto the end of dstrgn, maintaining
+ * knowledge of YX-banding when it's easy. Otherwise, dstrgn just
+ * becomes a non-y-x-banded random collection of rectangles, and not
+ * yet a true region. After a sequence of appends, the caller must
+ * call RegionValidate to ensure that a valid region is constructed.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * dstrgn is modified if rgn has rectangles.
+ *
+ */
+Bool
+RegionAppend(dstrgn, rgn)
+ register RegionPtr dstrgn;
+ register RegionPtr rgn;
+{
+ int numRects, dnumRects, size;
+ BoxPtr new, old;
+ Bool prepend;
+
+ if (RegionNar(rgn))
+ return RegionBreak (dstrgn);
+
+ if (!rgn->data && (dstrgn->data == &RegionEmptyData))
+ {
+ dstrgn->extents = rgn->extents;
+ dstrgn->data = (RegDataPtr)NULL;
+ return TRUE;
+ }
+
+ numRects = RegionNumRects(rgn);
+ if (!numRects)
+ return TRUE;
+ prepend = FALSE;
+ size = numRects;
+ dnumRects = RegionNumRects(dstrgn);
+ if (!dnumRects && (size < 200))
+ size = 200; /* XXX pick numbers out of a hat */
+ RECTALLOC(dstrgn, size);
+ old = RegionRects(rgn);
+ if (!dnumRects)
+ dstrgn->extents = rgn->extents;
+ else if (dstrgn->extents.x2 > dstrgn->extents.x1)
+ {
+ register BoxPtr first, last;
+
+ first = old;
+ last = RegionBoxptr(dstrgn) + (dnumRects - 1);
+ if ((first->y1 > last->y2) ||
+ ((first->y1 == last->y1) && (first->y2 == last->y2) &&
+ (first->x1 > last->x2)))
+ {
+ if (rgn->extents.x1 < dstrgn->extents.x1)
+ dstrgn->extents.x1 = rgn->extents.x1;
+ if (rgn->extents.x2 > dstrgn->extents.x2)
+ dstrgn->extents.x2 = rgn->extents.x2;
+ dstrgn->extents.y2 = rgn->extents.y2;
+ }
+ else
+ {
+ first = RegionBoxptr(dstrgn);
+ last = old + (numRects - 1);
+ if ((first->y1 > last->y2) ||
+ ((first->y1 == last->y1) && (first->y2 == last->y2) &&
+ (first->x1 > last->x2)))
+ {
+ prepend = TRUE;
+ if (rgn->extents.x1 < dstrgn->extents.x1)
+ dstrgn->extents.x1 = rgn->extents.x1;
+ if (rgn->extents.x2 > dstrgn->extents.x2)
+ dstrgn->extents.x2 = rgn->extents.x2;
+ dstrgn->extents.y1 = rgn->extents.y1;
+ }
+ else
+ dstrgn->extents.x2 = dstrgn->extents.x1;
+ }
+ }
+ if (prepend)
+ {
+ new = RegionBox(dstrgn, numRects);
+ if (dnumRects == 1)
+ *new = *RegionBoxptr(dstrgn);
+ else
+ memmove((char *)new,(char *)RegionBoxptr(dstrgn),
+ dnumRects * sizeof(BoxRec));
+ new = RegionBoxptr(dstrgn);
+ }
+ else
+ new = RegionBoxptr(dstrgn) + dnumRects;
+ if (numRects == 1)
+ *new = *old;
+ else
+ memmove((char *)new, (char *)old, numRects * sizeof(BoxRec));
+ dstrgn->data->numRects += numRects;
+ return TRUE;
+}
+
+
+#define ExchangeRects(a, b) \
+{ \
+ BoxRec t; \
+ t = rects[a]; \
+ rects[a] = rects[b]; \
+ rects[b] = t; \
+}
+
+static void
+QuickSortRects(
+ register BoxRec rects[],
+ register int numRects)
+{
+ register int y1;
+ register int x1;
+ register int i, j;
+ register BoxPtr r;
+
+ /* Always called with numRects > 1 */
+
+ do
+ {
+ if (numRects == 2)
+ {
+ if (rects[0].y1 > rects[1].y1 ||
+ (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
+ ExchangeRects(0, 1);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ ExchangeRects(0, numRects >> 1);
+ y1 = rects[0].y1;
+ x1 = rects[0].x1;
+
+ /* Partition array */
+ i = 0;
+ j = numRects;
+ do
+ {
+ r = &(rects[i]);
+ do
+ {
+ r++;
+ i++;
+ } while (i != numRects &&
+ (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
+ r = &(rects[j]);
+ do
+ {
+ r--;
+ j--;
+ } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
+ if (i < j)
+ ExchangeRects(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeRects(0, j);
+
+ /* Recurse */
+ if (numRects-j-1 > 1)
+ QuickSortRects(&rects[j+1], numRects-j-1);
+ numRects = j;
+ } while (numRects > 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * RegionValidate --
+ *
+ * Take a ``region'' which is a non-y-x-banded random collection of
+ * rectangles, and compute a nice region which is the union of all the
+ * rectangles.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The passed-in ``region'' may be modified.
+ * pOverlap set to TRUE if any retangles overlapped, else FALSE;
+ *
+ * Strategy:
+ * Step 1. Sort the rectangles into ascending order with primary key y1
+ * and secondary key x1.
+ *
+ * Step 2. Split the rectangles into the minimum number of proper y-x
+ * banded regions. This may require horizontally merging
+ * rectangles, and vertically coalescing bands. With any luck,
+ * this step in an identity tranformation (ala the Box widget),
+ * or a coalescing into 1 box (ala Menus).
+ *
+ * Step 3. Merge the separate regions down to a single region by calling
+ * RegionUnion. Maximize the work each RegionUnion call does by using
+ * a binary merge.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+Bool
+RegionValidate(badreg, pOverlap)
+ RegionPtr badreg;
+ Bool *pOverlap;
+{
+ /* Descriptor for regions under construction in Step 2. */
+ typedef struct {
+ RegionRec reg;
+ int prevBand;
+ int curBand;
+ } RegionInfo;
+
+ int numRects; /* Original numRects for badreg */
+ RegionInfo *ri; /* Array of current regions */
+ int numRI; /* Number of entries used in ri */
+ int sizeRI; /* Number of entries available in ri */
+ int i; /* Index into rects */
+ register int j; /* Index into ri */
+ register RegionInfo *rit; /* &ri[j] */
+ register RegionPtr reg; /* ri[j].reg */
+ register BoxPtr box; /* Current box in rects */
+ register BoxPtr riBox; /* Last box in ri[j].reg */
+ register RegionPtr hreg; /* ri[j_half].reg */
+ Bool ret = TRUE;
+
+ *pOverlap = FALSE;
+ if (!badreg->data)
+ {
+ good(badreg);
+ return TRUE;
+ }
+ numRects = badreg->data->numRects;
+ if (!numRects)
+ {
+ if (RegionNar(badreg))
+ return FALSE;
+ good(badreg);
+ return TRUE;
+ }
+ if (badreg->extents.x1 < badreg->extents.x2)
+ {
+ if ((numRects) == 1)
+ {
+ xfreeData(badreg);
+ badreg->data = (RegDataPtr) NULL;
+ }
+ else
+ {
+ DOWNSIZE(badreg, numRects);
+ }
+ good(badreg);
+ return TRUE;
+ }
+
+ /* Step 1: Sort the rects array into ascending (y1, x1) order */
+ QuickSortRects(RegionBoxptr(badreg), numRects);
+
+ /* Step 2: Scatter the sorted array into the minimum number of regions */
+
+ /* Set up the first region to be the first rectangle in badreg */
+ /* Note that step 2 code will never overflow the ri[0].reg rects array */
+ ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo));
+ if (!ri)
+ return RegionBreak (badreg);
+ sizeRI = 4;
+ numRI = 1;
+ ri[0].prevBand = 0;
+ ri[0].curBand = 0;
+ ri[0].reg = *badreg;
+ box = RegionBoxptr(&ri[0].reg);
+ ri[0].reg.extents = *box;
+ ri[0].reg.data->numRects = 1;
+
+ /* Now scatter rectangles into the minimum set of valid regions. If the
+ next rectangle to be added to a region would force an existing rectangle
+ in the region to be split up in order to maintain y-x banding, just
+ forget it. Try the next region. If it doesn't fit cleanly into any
+ region, make a new one. */
+
+ for (i = numRects; --i > 0;)
+ {
+ box++;
+ /* Look for a region to append box to */
+ for (j = numRI, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ riBox = RegionEnd(reg);
+
+ if (box->y1 == riBox->y1 && box->y2 == riBox->y2)
+ {
+ /* box is in same band as riBox. Merge or append it */
+ if (box->x1 <= riBox->x2)
+ {
+ /* Merge it with riBox */
+ if (box->x1 < riBox->x2) *pOverlap = TRUE;
+ if (box->x2 > riBox->x2) riBox->x2 = box->x2;
+ }
+ else
+ {
+ RECTALLOC_BAIL(reg, 1, bail);
+ *RegionTop(reg) = *box;
+ reg->data->numRects++;
+ }
+ goto NextRect; /* So sue me */
+ }
+ else if (box->y1 >= riBox->y2)
+ {
+ /* Put box into new band */
+ if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
+ if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1;
+ Coalesce(reg, rit->prevBand, rit->curBand);
+ rit->curBand = reg->data->numRects;
+ RECTALLOC_BAIL(reg, 1, bail);
+ *RegionTop(reg) = *box;
+ reg->data->numRects++;
+ goto NextRect;
+ }
+ /* Well, this region was inappropriate. Try the next one. */
+ } /* for j */
+
+ /* Uh-oh. No regions were appropriate. Create a new one. */
+ if (sizeRI == numRI)
+ {
+ /* Oops, allocate space for new region information */
+ sizeRI <<= 1;
+ rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
+ if (!rit)
+ goto bail;
+ ri = rit;
+ rit = &ri[numRI];
+ }
+ numRI++;
+ rit->prevBand = 0;
+ rit->curBand = 0;
+ rit->reg.extents = *box;
+ rit->reg.data = (RegDataPtr)NULL;
+ if (!RegionRectAlloc(&rit->reg, (i+numRI) / numRI)) /* MUST force allocation */
+ goto bail;
+NextRect: ;
+ } /* for i */
+
+ /* Make a final pass over each region in order to Coalesce and set
+ extents.x2 and extents.y2 */
+
+ for (j = numRI, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ riBox = RegionEnd(reg);
+ reg->extents.y2 = riBox->y2;
+ if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
+ Coalesce(reg, rit->prevBand, rit->curBand);
+ if (reg->data->numRects == 1) /* keep unions happy below */
+ {
+ xfreeData(reg);
+ reg->data = (RegDataPtr)NULL;
+ }
+ }
+
+ /* Step 3: Union all regions into a single region */
+ while (numRI > 1)
+ {
+ int half = numRI/2;
+ for (j = numRI & 1; j < (half + (numRI & 1)); j++)
+ {
+ reg = &ri[j].reg;
+ hreg = &ri[j+half].reg;
+ if (!RegionOp(reg, reg, hreg, RegionUnionO, TRUE, TRUE, pOverlap))
+ ret = FALSE;
+ if (hreg->extents.x1 < reg->extents.x1)
+ reg->extents.x1 = hreg->extents.x1;
+ if (hreg->extents.y1 < reg->extents.y1)
+ reg->extents.y1 = hreg->extents.y1;
+ if (hreg->extents.x2 > reg->extents.x2)
+ reg->extents.x2 = hreg->extents.x2;
+ if (hreg->extents.y2 > reg->extents.y2)
+ reg->extents.y2 = hreg->extents.y2;
+ xfreeData(hreg);
+ }
+ numRI -= half;
+ }
+ *badreg = ri[0].reg;
+ free(ri);
+ good(badreg);
+ return ret;
+bail:
+ for (i = 0; i < numRI; i++)
+ xfreeData(&ri[i].reg);
+ free (ri);
+ return RegionBreak (badreg);
+}
+
+RegionPtr
+RegionFromRects(nrects, prect, ctype)
+ int nrects;
+ register xRectangle *prect;
+ int ctype;
+{
+ register RegionPtr pRgn;
+ register RegDataPtr pData;
+ register BoxPtr pBox;
+ register int i;
+ int x1, y1, x2, y2;
+ size_t newSize;
+
+ pRgn = RegionCreate(NullBox, 0);
+ if (RegionNar (pRgn))
+ return pRgn;
+ if (!nrects)
+ return pRgn;
+ if (nrects == 1)
+ {
+ x1 = prect->x;
+ y1 = prect->y;
+ if ((x2 = x1 + (int) prect->width) > MAXSHORT)
+ x2 = MAXSHORT;
+ if ((y2 = y1 + (int) prect->height) > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 != x2 && y1 != y2)
+ {
+ pRgn->extents.x1 = x1;
+ pRgn->extents.y1 = y1;
+ pRgn->extents.x2 = x2;
+ pRgn->extents.y2 = y2;
+ pRgn->data = (RegDataPtr)NULL;
+ }
+ return pRgn;
+ }
+ newSize = RegionSizeof(nrects);
+ pData = newSize > 0 ? malloc(newSize) : NULL;
+ if (!pData)
+ {
+ RegionBreak (pRgn);
+ return pRgn;
+ }
+ pBox = (BoxPtr) (pData + 1);
+ for (i = nrects; --i >= 0; prect++)
+ {
+ x1 = prect->x;
+ y1 = prect->y;
+ if ((x2 = x1 + (int) prect->width) > MAXSHORT)
+ x2 = MAXSHORT;
+ if ((y2 = y1 + (int) prect->height) > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 != x2 && y1 != y2)
+ {
+ pBox->x1 = x1;
+ pBox->y1 = y1;
+ pBox->x2 = x2;
+ pBox->y2 = y2;
+ pBox++;
+ }
+ }
+ if (pBox != (BoxPtr) (pData + 1))
+ {
+ pData->size = nrects;
+ pData->numRects = pBox - (BoxPtr) (pData + 1);
+ pRgn->data = pData;
+ if (ctype != CT_YXBANDED)
+ {
+ Bool overlap; /* result ignored */
+ pRgn->extents.x1 = pRgn->extents.x2 = 0;
+ RegionValidate(pRgn, &overlap);
+ }
+ else
+ RegionSetExtents(pRgn);
+ good(pRgn);
+ }
+ else
+ {
+ free (pData);
+ }
+ return pRgn;
+}
+
+Bool
+miRegionDataCopy(
+ register RegionPtr dst,
+ register RegionPtr src)
+{
+ good(dst);
+ good(src);
+ if (dst->data)
+ return TRUE;
+ if (dst == src)
+ return TRUE;
+ if (!src->data || !src->data->size)
+ {
+ xfreeData(dst);
+ dst->data = (RegDataPtr)NULL;
+ return TRUE;
+ }
+ if (!dst->data || (dst->data->size < src->data->numRects))
+ {
+ size_t newSize = RegionSizeof(src->data->numRects);
+ xfreeData(dst);
+ dst->data = newSize > 0 ? malloc(newSize) : NULL;
+ if (!dst->data)
+ return RegionBreak (dst);
+ }
+ dst->data->size = src->data->size;
+ dst->data->numRects = src->data->numRects;
+ return TRUE;
+}
+
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ register int tw; \
+ \
+ tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+/* ||| I should apply the merge sort code to rectangle sorting above, and see
+ if mapping time can be improved. But right now I've been at work 12 hours,
+ so forget it.
+*/
+
+static void QuickSortSpans(
+ register DDXPointRec spans[],
+ register int widths[],
+ register int numSpans)
+{
+ register int y;
+ register int i, j, m;
+ register DDXPointPtr r;
+
+ /* Always called with numSpans > 1 */
+ /* Sorts only by y, doesn't bother to sort by x */
+
+ do
+ {
+ if (numSpans < 9)
+ {
+ /* Do insertion sort */
+ register int yprev;
+
+ yprev = spans[0].y;
+ i = 1;
+ do
+ { /* while i != numSpans */
+ y = spans[i].y;
+ if (yprev > y)
+ {
+ /* spans[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; y >= spans[j].y; j++) {}
+ tpt = spans[i];
+ tw = widths[i];
+ for (k = i; k != j; k--)
+ {
+ spans[k] = spans[k-1];
+ widths[k] = widths[k-1];
+ }
+ spans[j] = tpt;
+ widths[j] = tw;
+ y = spans[i].y;
+ } /* if out of order */
+ yprev = y;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ y = spans[0].y;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do
+ {
+ r = &(spans[i]);
+ do
+ {
+ r++;
+ i++;
+ } while (i != numSpans && r->y < y);
+ r = &(spans[j]);
+ do
+ {
+ r--;
+ j--;
+ } while (y < r->y);
+ if (i < j)
+ ExchangeSpans(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans(0, j);
+
+ /* Recurse */
+ if (numSpans-j-1 > 1)
+ QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
+ numSpans = j;
+ } while (numSpans > 1);
+}
+
+#define NextBand() \
+{ \
+ clipy1 = pboxBandStart->y1; \
+ clipy2 = pboxBandStart->y2; \
+ pboxBandEnd = pboxBandStart + 1; \
+ while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
+ pboxBandEnd++; \
+ } \
+ for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
+}
+
+/*
+ Clip a list of scanlines to a region. The caller has allocated the
+ space. FSorted is non-zero if the scanline origins are in ascending
+ order.
+ returns the number of new, clipped scanlines.
+*/
+
+int
+RegionClipSpans(
+ RegionPtr prgnDst,
+ register DDXPointPtr ppt,
+ register int *pwidth,
+ int nspans,
+ register DDXPointPtr pptNew,
+ int *pwidthNew,
+ int fSorted)
+{
+ register DDXPointPtr pptLast;
+ int *pwidthNewStart; /* the vengeance of Xerox! */
+ register int y, x1, x2;
+ register int numRects;
+
+ good(prgnDst);
+ pptLast = ppt + nspans;
+ pwidthNewStart = pwidthNew;
+
+ if (!prgnDst->data)
+ {
+ /* Do special fast code with clip boundaries in registers(?) */
+ /* It doesn't pay much to make use of fSorted in this case,
+ so we lump everything together. */
+
+ register int clipx1, clipx2, clipy1, clipy2;
+
+ clipx1 = prgnDst->extents.x1;
+ clipy1 = prgnDst->extents.y1;
+ clipx2 = prgnDst->extents.x2;
+ clipy2 = prgnDst->extents.y2;
+
+ for (; ppt != pptLast; ppt++, pwidth++)
+ {
+ y = ppt->y;
+ x1 = ppt->x;
+ if (clipy1 <= y && y < clipy2)
+ {
+ x2 = x1 + *pwidth;
+ if (x1 < clipx1) x1 = clipx1;
+ if (x2 > clipx2) x2 = clipx2;
+ if (x1 < x2)
+ {
+ /* part of span in clip rectangle */
+ pptNew->x = x1;
+ pptNew->y = y;
+ *pwidthNew = x2 - x1;
+ pptNew++;
+ pwidthNew++;
+ }
+ }
+ } /* end for */
+
+ }
+ else if ((numRects = prgnDst->data->numRects))
+ {
+ /* Have to clip against many boxes */
+ BoxPtr pboxBandStart, pboxBandEnd;
+ register BoxPtr pbox;
+ register BoxPtr pboxLast;
+ register int clipy1, clipy2;
+
+ /* In this case, taking advantage of sorted spans gains more than
+ the sorting costs. */
+ if ((! fSorted) && (nspans > 1))
+ QuickSortSpans(ppt, pwidth, nspans);
+
+ pboxBandStart = RegionBoxptr(prgnDst);
+ pboxLast = pboxBandStart + numRects;
+
+ NextBand();
+
+ for (; ppt != pptLast; )
+ {
+ y = ppt->y;
+ if (y < clipy2)
+ {
+ /* span is in the current band */
+ pbox = pboxBandStart;
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ do
+ { /* For each box in band */
+ register int newx1, newx2;
+
+ newx1 = x1;
+ newx2 = x2;
+ if (newx1 < pbox->x1) newx1 = pbox->x1;
+ if (newx2 > pbox->x2) newx2 = pbox->x2;
+ if (newx1 < newx2)
+ {
+ /* Part of span in clip rectangle */
+ pptNew->x = newx1;
+ pptNew->y = y;
+ *pwidthNew = newx2 - newx1;
+ pptNew++;
+ pwidthNew++;
+ }
+ pbox++;
+ } while (pbox != pboxBandEnd);
+ ppt++;
+ pwidth++;
+ }
+ else
+ {
+ /* Move to next band, adjust ppt as needed */
+ pboxBandStart = pboxBandEnd;
+ if (pboxBandStart == pboxLast)
+ break; /* We're completely done */
+ NextBand();
+ }
+ }
+ }
+ return (pwidthNew - pwidthNewStart);
+}
+
+/* find the band in a region with the most rectangles */
+int
+miFindMaxBand(prgn)
+ RegionPtr prgn;
+{
+ register int nbox;
+ register BoxPtr pbox;
+ register int nThisBand;
+ register int nMaxBand = 0;
+ short yThisBand;
+
+ good(prgn);
+ nbox = RegionNumRects(prgn);
+ pbox = RegionRects(prgn);
+
+ while(nbox > 0)
+ {
+ yThisBand = pbox->y1;
+ nThisBand = 0;
+ while((nbox > 0) && (pbox->y1 == yThisBand))
+ {
+ nbox--;
+ pbox++;
+ nThisBand++;
+ }
+ if (nThisBand > nMaxBand)
+ nMaxBand = nThisBand;
+ }
+ return (nMaxBand);
+}
diff --git a/nx-X11/programs/Xserver/dix/resource.c b/nx-X11/programs/Xserver/dix/resource.c
new file mode 100644
index 000000000..8d2b612d7
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/resource.c
@@ -0,0 +1,936 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+static void RebuildTable(
+ int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ XID id;
+ RESTYPE type;
+ void * value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ XID fakeID;
+ XID endFakeID;
+ XID expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+ ResourceNames[type & TypeMask] = MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *)realloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+
+#ifdef XResExtension
+ {
+ Atom *newnames;
+ newnames = realloc(ResourceNames, (next + 1) * sizeof(Atom));
+ if(!newnames)
+ return 0;
+ ResourceNames = newnames;
+ ResourceNames[next] = 0;
+ }
+#endif
+
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i, j;
+
+ if (client == serverClient)
+ {
+ lastResourceType = RT_LASTPREDEF;
+ lastResourceClass = RC_LASTPREDEF;
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ free(DeleteFuncs);
+ DeleteFuncs = (DeleteType *)malloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+ DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+ DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+ DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+ DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+ DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+ DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+ DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+ DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+ DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+ if(ResourceNames)
+ free(ResourceNames);
+ ResourceNames = malloc((lastResourceType + 1) * sizeof(Atom));
+ if(!ResourceNames)
+ return FALSE;
+#endif
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *)malloc(INITBUCKETS*sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ /* Many IDs allocated from the server client are visible to clients,
+ * so we don't use the SERVER_BIT for them, but we have to start
+ * past the magic value constants used in the protocol. For normal
+ * clients, we can start from zero, with SERVER_BIT set.
+ */
+ clientTable[i].fakeID = client->clientAsMask |
+ (client->index ? SERVER_BIT : SERVER_MINID);
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ clientTable[i].expectID = client->clientAsMask;
+ for (j=0; j<INITBUCKETS; j++)
+ {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize)
+ {
+ case 6:
+ return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+ case 7:
+ return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+ case 8:
+ return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+ case 9:
+ return ((int)(0x1FF & (id ^ (id>>9))));
+ case 10:
+ return ((int)(0x3FF & (id ^ (id>>10))));
+ case 11:
+ return ((int)(0x7FF & (id ^ (id>>11))));
+ }
+ return -1;
+}
+
+static XID
+AvailableID(
+ register int client,
+ register XID id,
+ register XID maxid,
+ register XID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[Hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+ register XID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ XID goodid;
+
+ id = (Mask)client << CLIENTOFFSET;
+ if (server)
+ id |= client ? SERVER_BIT : SERVER_MINID;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid)
+ id = maxid = 0;
+ *minp = id;
+ *maxp = maxid;
+}
+
+/**
+ * GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ * This function tries to find count unused XIDs for the given client. It
+ * puts the IDs in the array pids and returns the number found, which should
+ * almost always be the number requested.
+ *
+ * The circumstances that lead to a call to this function are very rare.
+ * Xlib must run out of IDs while trying to generate a request that wants
+ * multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ * No rocket science in the implementation; just iterate over all
+ * possible IDs for the given client and pick the first count IDs
+ * that aren't in use. A more efficient algorithm could probably be
+ * invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+ unsigned int found = 0;
+ XID id = pClient->clientAsMask;
+ XID maxid;
+
+ maxid = id | RESOURCE_ID_MASK;
+ while ( (found < count) && (id <= maxid) )
+ {
+ if (!LookupIDByClass(id, RC_ANY))
+ {
+ pids[found++] = id;
+ }
+ id++;
+ }
+ return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+ XID id, maxid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ GetXIDRange(client, TRUE, &id, &maxid);
+ if (!id) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+#ifndef NXAGENT_SERVER
+Bool
+AddResource(XID id, RESTYPE type, void * value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)malloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+#endif /* NXAGENT_SERVER */
+
+static void
+RebuildTable(int client)
+{
+ register int j;
+ register ResourcePtr res, next;
+ ResourcePtr **tails, *resources;
+ register ResourcePtr **tptr, *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend
+ * on resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **)malloc(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *)malloc(j * sizeof(ResourcePtr));
+ if (!resources)
+ {
+ free(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+ {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++)
+ {
+ for (res = *rptr; res; res = next)
+ {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[Hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ free(tails);
+ clientTable[client].buckets *= 2;
+ free(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+#ifndef NXAGENT_SERVER
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ free(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ free(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, void * value)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+#ifndef NXAGENT_SERVER
+void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ void * cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+ (*func)(this->value, this->id, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ void * cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+ (*func)(this->value, this->id, this->type, cdata);
+ if (*eltptr != elements)
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+void *
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ void * cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ if (!client)
+ client = serverClient;
+
+ resources = clientTable[client->index].resources;
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ }
+ }
+ }
+ return NULL;
+}
+#endif /* NXAGENT_SERVER */
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+ ResourcePtr *resources;
+ ResourcePtr this;
+ ResourcePtr *prev;
+ int j;
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ prev = &resources[j];
+ while ( (this = *prev) )
+ {
+ RESTYPE rtype = this->type;
+ if (rtype & RC_NEVERRETAIN)
+ {
+ *prev = this->next;
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ free(this);
+ }
+ else
+ prev = &this->next;
+ }
+ }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /* This routine shouldn't be called with a null client, but just in
+ case ... */
+
+ if (!client)
+ return;
+
+ HandleSaveSet(client);
+
+ resources = clientTable[client->index].resources;
+ for (j=0; j < clientTable[client->index].buckets; j++)
+ {
+ /* It may seem silly to update the head of this resource list as
+ we delete the members, since the entire list will be deleted any way,
+ but there are some resource deletion functions "FreeClientPixels" for
+ one which do a LookupID on another resource id (a Colormap id in this
+ case), so the resource list must be kept valid up to the point that
+ it is deleted, so every time we delete a resource, we must update the
+ head, just like in FreeResource. I hope that this doesn't slow down
+ mass deletion appreciably. PRH */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head)
+ {
+ RESTYPE rtype = this->type;
+ *head = this->next;
+ (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ free(this);
+ }
+ }
+ free(clientTable[client->index].resources);
+ clientTable[client->index].resources = NULL;
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+ int i;
+
+ for (i = currentMaxClients; --i >= 0; )
+ {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+ XID minid, maxid;
+
+ if (!noPanoramiXExtension) {
+ minid = client->clientAsMask | (client->index ?
+ SERVER_BIT : SERVER_MINID);
+ maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+ if ((id >= minid) && (id <= maxid))
+ return TRUE;
+ }
+#endif /* PANORAMIX */
+ return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+ ((clientTable[client->index].expectID <= id) ||
+ !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system. They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+void *
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+ int cid;
+ register ResourcePtr res;
+ void * retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert( (rtype & TypeMask) <= lastResourceType);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+ return retval;
+}
+
+
+void *
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+ int cid;
+ register ResourcePtr res = NULL;
+ void * retval = NULL;
+
+ assert(client == NullClient ||
+ (client->index <= currentMaxClients && clients[client->index] == client));
+ assert (classes >= lastResourceClass);
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ {
+ retval = res->value;
+ break;
+ }
+ }
+ if (retval && client && client->CheckAccess)
+ retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+ return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+void *
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ return SecurityLookupIDByType(NullClient, id, rtype,
+ DixUnknownAccess);
+}
+
+void *
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ return SecurityLookupIDByClass(NullClient, id, classes,
+ DixUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ * LookupIDByType returns the object with the given id and type, else NULL.
+ */
+void *
+LookupIDByType(XID id, RESTYPE rtype)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ return res->value;
+ }
+ return (void *)NULL;
+}
+
+/*
+ * LookupIDByClass returns the object with the given id and any one of the
+ * given classes, else NULL.
+ */
+void *
+LookupIDByClass(XID id, RESTYPE classes)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+ clientTable[cid].buckets)
+ {
+ res = clientTable[cid].resources[Hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ return res->value;
+ }
+ return (void *)NULL;
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/dix/swaprep.c b/nx-X11/programs/Xserver/dix/swaprep.c
new file mode 100644
index 000000000..74dae817d
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/swaprep.c
@@ -0,0 +1,1220 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "scrnintstr.h"
+#include "swaprep.h"
+#include "globals.h"
+
+static void SwapFontInfo(xQueryFontReply *pr);
+
+static void SwapCharInfo(xCharInfo *pInfo);
+
+static void SwapFont(xQueryFontReply *pr, Bool hasGlyphs);
+
+/**
+ * Thanks to Jack Palevich for testing and subsequently rewriting all this
+ *
+ * \param size size in bytes
+ */
+void
+Swap32Write(ClientPtr pClient, int size, register CARD32 *pbuf)
+{
+ register int i;
+
+ size >>= 2;
+ for(i = 0; i < size; i++)
+ /* brackets are mandatory here, because "swapl" macro expands
+ to several statements */
+ {
+ swapl(&pbuf[i]);
+ }
+ WriteToClient(pClient, size << 2, pbuf);
+}
+
+/**
+ *
+ * \param size size in bytes
+ */
+void
+CopySwap32Write(ClientPtr pClient, int size, CARD32 *pbuf)
+{
+ int bufsize = size;
+ CARD32 *pbufT;
+ register CARD32 *from, *to, *fromLast, *toLast;
+ CARD32 tmpbuf[1];
+
+ /* Allocate as big a buffer as we can... */
+ while (!(pbufT = (CARD32 *) malloc(bufsize)))
+ {
+ bufsize >>= 1;
+ if (bufsize == 4)
+ {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+
+ /* convert lengths from # of bytes to # of longs */
+ size >>= 2;
+ bufsize >>= 2;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+ to = pbufT;
+ toLast = to + min (bufsize, fromLast - from);
+ nbytes = (toLast - to) << 2;
+ while (to < toLast) {
+ /* can't write "cpswapl(*from++, *to++)" because cpswapl is a macro
+ that evaulates its args more than once */
+ cpswapl(*from, *to);
+ from++;
+ to++;
+ }
+ WriteToClient (pClient, nbytes, pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ free ((char *) pbufT);
+}
+
+/**
+ *
+ * \param size size in bytes
+ */
+void
+CopySwap16Write(ClientPtr pClient, int size, short *pbuf)
+{
+ int bufsize = size;
+ short *pbufT;
+ register short *from, *to, *fromLast, *toLast;
+ short tmpbuf[2];
+
+ /* Allocate as big a buffer as we can... */
+ while (!(pbufT = (short *) malloc(bufsize)))
+ {
+ bufsize >>= 1;
+ if (bufsize == 4)
+ {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+
+ /* convert lengths from # of bytes to # of shorts */
+ size >>= 1;
+ bufsize >>= 1;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+ to = pbufT;
+ toLast = to + min (bufsize, fromLast - from);
+ nbytes = (toLast - to) << 1;
+ while (to < toLast) {
+ /* can't write "cpswaps(*from++, *to++)" because cpswaps is a macro
+ that evaulates its args more than once */
+ cpswaps(*from, *to);
+ from++;
+ to++;
+ }
+ WriteToClient (pClient, nbytes, pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ free ((char *) pbufT);
+}
+
+
+/* Extra-small reply */
+void
+SGenericReply(ClientPtr pClient, int size, xGenericReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ WriteToClient(pClient, size, pRep);
+}
+
+/* Extra-large reply */
+void
+SGetWindowAttributesReply(ClientPtr pClient, int size,
+ xGetWindowAttributesReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->visualID);
+ swaps(&pRep->class);
+ swapl(&pRep->backingBitPlanes);
+ swapl(&pRep->backingPixel);
+ swapl(&pRep->colormap);
+ swapl(&pRep->allEventMasks);
+ swapl(&pRep->yourEventMask);
+ swaps(&pRep->doNotPropagateMask);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetGeometryReply(ClientPtr pClient, int size, xGetGeometryReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->root);
+ swaps(&pRep->x);
+ swaps(&pRep->y);
+ swaps(&pRep->width);
+ swaps(&pRep->height);
+ swaps(&pRep->borderWidth);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SQueryTreeReply(ClientPtr pClient, int size, xQueryTreeReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->root);
+ swapl(&pRep->parent);
+ swaps(&pRep->nChildren);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SInternAtomReply(ClientPtr pClient, int size, xInternAtomReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->atom);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetAtomNameReply(ClientPtr pClient, int size, xGetAtomNameReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nameLength);
+ WriteToClient(pClient, size, pRep);
+}
+
+
+void
+SGetPropertyReply(ClientPtr pClient, int size, xGetPropertyReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->propertyType);
+ swapl(&pRep->bytesAfter);
+ swapl(&pRep->nItems);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SListPropertiesReply(ClientPtr pClient, int size, xListPropertiesReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nProperties);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetSelectionOwnerReply(ClientPtr pClient, int size,
+ xGetSelectionOwnerReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->owner);
+ WriteToClient(pClient, size, pRep);
+}
+
+
+void
+SQueryPointerReply(ClientPtr pClient, int size, xQueryPointerReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->root);
+ swapl(&pRep->child);
+ swaps(&pRep->rootX);
+ swaps(&pRep->rootY);
+ swaps(&pRep->winX);
+ swaps(&pRep->winY);
+ swaps(&pRep->mask);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SwapTimecoord(xTimecoord* pCoord)
+{
+ swapl(&pCoord->time);
+ swaps(&pCoord->x);
+ swaps(&pCoord->y);
+}
+
+void
+SwapTimeCoordWrite(ClientPtr pClient, int size, xTimecoord *pRep)
+{
+ int i, n;
+ xTimecoord *pRepT;
+
+ n = size / sizeof(xTimecoord);
+ pRepT = pRep;
+ for(i = 0; i < n; i++)
+ {
+ SwapTimecoord(pRepT);
+ pRepT++;
+ }
+ WriteToClient(pClient, size, pRep);
+
+}
+void
+SGetMotionEventsReply(ClientPtr pClient, int size, xGetMotionEventsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->nEvents);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+STranslateCoordsReply(ClientPtr pClient, int size, xTranslateCoordsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->child);
+ swaps(&pRep->dstX);
+ swaps(&pRep->dstY);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetInputFocusReply(ClientPtr pClient, int size, xGetInputFocusReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->focus);
+ WriteToClient(pClient, size, pRep);
+}
+
+/* extra long reply */
+void
+SQueryKeymapReply(ClientPtr pClient, int size, xQueryKeymapReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ WriteToClient(pClient, size, pRep);
+}
+
+static
+void
+SwapCharInfo(xCharInfo *pInfo)
+{
+ swaps(&pInfo->leftSideBearing);
+ swaps(&pInfo->rightSideBearing);
+ swaps(&pInfo->characterWidth);
+ swaps(&pInfo->ascent);
+ swaps(&pInfo->descent);
+ swaps(&pInfo->attributes);
+}
+
+static void
+SwapFontInfo(xQueryFontReply *pr)
+{
+ swaps(&pr->minCharOrByte2);
+ swaps(&pr->maxCharOrByte2);
+ swaps(&pr->defaultChar);
+ swaps(&pr->nFontProps);
+ swaps(&pr->fontAscent);
+ swaps(&pr->fontDescent);
+ SwapCharInfo( &pr->minBounds);
+ SwapCharInfo( &pr->maxBounds);
+ swapl(&pr->nCharInfos);
+}
+
+static
+void
+SwapFont(xQueryFontReply *pr, Bool hasGlyphs)
+{
+ unsigned i;
+ xCharInfo * pxci;
+ unsigned nchars, nprops;
+ char *pby;
+
+ swaps(&pr->sequenceNumber);
+ swapl(&pr->length);
+ nchars = pr->nCharInfos;
+ nprops = pr->nFontProps;
+ SwapFontInfo(pr);
+ pby = (char *) &pr[1];
+ /* Font properties are an atom and either an int32 or a CARD32, so
+ * they are always 2 4 byte values */
+ for(i = 0; i < nprops; i++)
+ {
+ swapl((int *)pby);
+ pby += 4;
+ swapl((int *)pby);
+ pby += 4;
+ }
+ if (hasGlyphs)
+ {
+ pxci = (xCharInfo *)pby;
+ for(i = 0; i< nchars; i++, pxci++)
+ SwapCharInfo(pxci);
+ }
+}
+
+void
+SQueryFontReply(ClientPtr pClient, int size, xQueryFontReply *pRep)
+{
+ SwapFont(pRep, TRUE);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SQueryTextExtentsReply(ClientPtr pClient, int size, xQueryTextExtentsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->fontAscent);
+ swaps(&pRep->fontDescent);
+ swaps(&pRep->overallAscent);
+ swaps(&pRep->overallDescent);
+ swapl(&pRep->overallWidth);
+ swapl(&pRep->overallLeft);
+ swapl(&pRep->overallRight);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SListFontsReply(ClientPtr pClient, int size, xListFontsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nFonts);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SListFontsWithInfoReply(ClientPtr pClient, int size,
+ xListFontsWithInfoReply *pRep)
+{
+ SwapFont((xQueryFontReply *)pRep, FALSE);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetFontPathReply(ClientPtr pClient, int size, xGetFontPathReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nPaths);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetImageReply(ClientPtr pClient, int size, xGetImageReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->visual);
+ WriteToClient(pClient, size, pRep);
+ /* Fortunately, image doesn't need swapping */
+}
+
+void
+SListInstalledColormapsReply(ClientPtr pClient, int size,
+ xListInstalledColormapsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nColormaps);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SAllocColorReply(pClient, size, pRep)
+ ClientPtr pClient;
+ int size;
+ xAllocColorReply *pRep;
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->red);
+ swaps(&pRep->green);
+ swaps(&pRep->blue);
+ swapl(&pRep->pixel);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SAllocNamedColorReply(ClientPtr pClient, int size, xAllocNamedColorReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->pixel);
+ swaps(&pRep->exactRed);
+ swaps(&pRep->exactGreen);
+ swaps(&pRep->exactBlue);
+ swaps(&pRep->screenRed);
+ swaps(&pRep->screenGreen);
+ swaps(&pRep->screenBlue);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SAllocColorCellsReply(ClientPtr pClient, int size, xAllocColorCellsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nPixels);
+ swaps(&pRep->nMasks);
+ WriteToClient(pClient, size, pRep);
+}
+
+
+void
+SAllocColorPlanesReply(ClientPtr pClient, int size, xAllocColorPlanesReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nPixels);
+ swapl(&pRep->redMask);
+ swapl(&pRep->greenMask);
+ swapl(&pRep->blueMask);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SwapRGB(xrgb *prgb)
+{
+ swaps(&prgb->red);
+ swaps(&prgb->green);
+ swaps(&prgb->blue);
+}
+
+void
+SQColorsExtend(ClientPtr pClient, int size, xrgb *prgb)
+{
+ int i, n;
+ xrgb *prgbT;
+
+ n = size / sizeof(xrgb);
+ prgbT = prgb;
+ for(i = 0; i < n; i++)
+ {
+ SwapRGB(prgbT);
+ prgbT++;
+ }
+ WriteToClient(pClient, size, prgb);
+}
+
+void
+SQueryColorsReply(ClientPtr pClient, int size, xQueryColorsReply* pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nColors);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SLookupColorReply(ClientPtr pClient, int size, xLookupColorReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->exactRed);
+ swaps(&pRep->exactGreen);
+ swaps(&pRep->exactBlue);
+ swaps(&pRep->screenRed);
+ swaps(&pRep->screenGreen);
+ swaps(&pRep->screenBlue);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SQueryBestSizeReply(ClientPtr pClient, int size, xQueryBestSizeReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->width);
+ swaps(&pRep->height);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SListExtensionsReply(ClientPtr pClient, int size, xListExtensionsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetKeyboardMappingReply(ClientPtr pClient, int size,
+ xGetKeyboardMappingReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetPointerMappingReply(ClientPtr pClient, int size,
+ xGetPointerMappingReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetModifierMappingReply(ClientPtr pClient, int size,
+ xGetModifierMappingReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetKeyboardControlReply(ClientPtr pClient, int size, xGetKeyboardControlReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->ledMask);
+ swaps(&pRep->bellPitch);
+ swaps(&pRep->bellDuration);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetPointerControlReply(ClientPtr pClient, int size, xGetPointerControlReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->accelNumerator);
+ swaps(&pRep->accelDenominator);
+ swaps(&pRep->threshold);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SGetScreenSaverReply(ClientPtr pClient, int size, xGetScreenSaverReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swaps(&pRep->timeout);
+ swaps(&pRep->interval);
+ WriteToClient(pClient, size, pRep);
+}
+
+void
+SLHostsExtend(ClientPtr pClient, int size, char *buf)
+{
+ char *bufT = buf;
+ char *endbuf = buf + size;
+ while (bufT < endbuf) {
+ xHostEntry *host = (xHostEntry *) bufT;
+ int len = host->length;
+ swaps (&host->length);
+ bufT += sizeof (xHostEntry) + (((len + 3) >> 2) << 2);
+ }
+ WriteToClient (pClient, size, buf);
+}
+
+void
+SListHostsReply(ClientPtr pClient, int size, xListHostsReply *pRep)
+{
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swaps(&pRep->nHosts);
+ WriteToClient(pClient, size, pRep);
+}
+
+
+
+void
+SErrorEvent(xError *from, xError *to)
+{
+ to->type = X_Error;
+ to->errorCode = from->errorCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->resourceID, to->resourceID);
+ cpswaps(from->minorCode, to->minorCode);
+ to->majorCode = from->majorCode;
+}
+
+void
+SKeyButtonPtrEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.keyButtonPointer.time,
+ to->u.keyButtonPointer.time);
+ cpswapl(from->u.keyButtonPointer.root,
+ to->u.keyButtonPointer.root);
+ cpswapl(from->u.keyButtonPointer.event,
+ to->u.keyButtonPointer.event);
+ cpswapl(from->u.keyButtonPointer.child,
+ to->u.keyButtonPointer.child);
+ cpswaps(from->u.keyButtonPointer.rootX,
+ to->u.keyButtonPointer.rootX);
+ cpswaps(from->u.keyButtonPointer.rootY,
+ to->u.keyButtonPointer.rootY);
+ cpswaps(from->u.keyButtonPointer.eventX,
+ to->u.keyButtonPointer.eventX);
+ cpswaps(from->u.keyButtonPointer.eventY,
+ to->u.keyButtonPointer.eventY);
+ cpswaps(from->u.keyButtonPointer.state,
+ to->u.keyButtonPointer.state);
+ to->u.keyButtonPointer.sameScreen =
+ from->u.keyButtonPointer.sameScreen;
+}
+
+void
+SEnterLeaveEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.enterLeave.time, to->u.enterLeave.time);
+ cpswapl(from->u.enterLeave.root, to->u.enterLeave.root);
+ cpswapl(from->u.enterLeave.event, to->u.enterLeave.event);
+ cpswapl(from->u.enterLeave.child, to->u.enterLeave.child);
+ cpswaps(from->u.enterLeave.rootX, to->u.enterLeave.rootX);
+ cpswaps(from->u.enterLeave.rootY, to->u.enterLeave.rootY);
+ cpswaps(from->u.enterLeave.eventX, to->u.enterLeave.eventX);
+ cpswaps(from->u.enterLeave.eventY, to->u.enterLeave.eventY);
+ cpswaps(from->u.enterLeave.state, to->u.enterLeave.state);
+ to->u.enterLeave.mode = from->u.enterLeave.mode;
+ to->u.enterLeave.flags = from->u.enterLeave.flags;
+}
+
+void
+SFocusEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.focus.window, to->u.focus.window);
+ to->u.focus.mode = from->u.focus.mode;
+}
+
+void
+SExposeEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.expose.window, to->u.expose.window);
+ cpswaps(from->u.expose.x, to->u.expose.x);
+ cpswaps(from->u.expose.y, to->u.expose.y);
+ cpswaps(from->u.expose.width, to->u.expose.width);
+ cpswaps(from->u.expose.height, to->u.expose.height);
+ cpswaps(from->u.expose.count, to->u.expose.count);
+}
+
+void
+SGraphicsExposureEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.graphicsExposure.drawable,
+ to->u.graphicsExposure.drawable);
+ cpswaps(from->u.graphicsExposure.x,
+ to->u.graphicsExposure.x);
+ cpswaps(from->u.graphicsExposure.y,
+ to->u.graphicsExposure.y);
+ cpswaps(from->u.graphicsExposure.width,
+ to->u.graphicsExposure.width);
+ cpswaps(from->u.graphicsExposure.height,
+ to->u.graphicsExposure.height);
+ cpswaps(from->u.graphicsExposure.minorEvent,
+ to->u.graphicsExposure.minorEvent);
+ cpswaps(from->u.graphicsExposure.count,
+ to->u.graphicsExposure.count);
+ to->u.graphicsExposure.majorEvent =
+ from->u.graphicsExposure.majorEvent;
+}
+
+void
+SNoExposureEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.noExposure.drawable, to->u.noExposure.drawable);
+ cpswaps(from->u.noExposure.minorEvent, to->u.noExposure.minorEvent);
+ to->u.noExposure.majorEvent = from->u.noExposure.majorEvent;
+}
+
+void
+SVisibilityEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.visibility.window, to->u.visibility.window);
+ to->u.visibility.state = from->u.visibility.state;
+}
+
+void
+SCreateNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.createNotify.window, to->u.createNotify.window);
+ cpswapl(from->u.createNotify.parent, to->u.createNotify.parent);
+ cpswaps(from->u.createNotify.x, to->u.createNotify.x);
+ cpswaps(from->u.createNotify.y, to->u.createNotify.y);
+ cpswaps(from->u.createNotify.width, to->u.createNotify.width);
+ cpswaps(from->u.createNotify.height, to->u.createNotify.height);
+ cpswaps(from->u.createNotify.borderWidth,
+ to->u.createNotify.borderWidth);
+ to->u.createNotify.override = from->u.createNotify.override;
+}
+
+void
+SDestroyNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.destroyNotify.event, to->u.destroyNotify.event);
+ cpswapl(from->u.destroyNotify.window, to->u.destroyNotify.window);
+}
+
+void
+SUnmapNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.unmapNotify.event, to->u.unmapNotify.event);
+ cpswapl(from->u.unmapNotify.window, to->u.unmapNotify.window);
+ to->u.unmapNotify.fromConfigure = from->u.unmapNotify.fromConfigure;
+}
+
+void
+SMapNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.mapNotify.event, to->u.mapNotify.event);
+ cpswapl(from->u.mapNotify.window, to->u.mapNotify.window);
+ to->u.mapNotify.override = from->u.mapNotify.override;
+}
+
+void
+SMapRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.mapRequest.parent, to->u.mapRequest.parent);
+ cpswapl(from->u.mapRequest.window, to->u.mapRequest.window);
+}
+
+void
+SReparentEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.reparent.event, to->u.reparent.event);
+ cpswapl(from->u.reparent.window, to->u.reparent.window);
+ cpswapl(from->u.reparent.parent, to->u.reparent.parent);
+ cpswaps(from->u.reparent.x, to->u.reparent.x);
+ cpswaps(from->u.reparent.y, to->u.reparent.y);
+ to->u.reparent.override = from->u.reparent.override;
+}
+
+void
+SConfigureNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.configureNotify.event,
+ to->u.configureNotify.event);
+ cpswapl(from->u.configureNotify.window,
+ to->u.configureNotify.window);
+ cpswapl(from->u.configureNotify.aboveSibling,
+ to->u.configureNotify.aboveSibling);
+ cpswaps(from->u.configureNotify.x, to->u.configureNotify.x);
+ cpswaps(from->u.configureNotify.y, to->u.configureNotify.y);
+ cpswaps(from->u.configureNotify.width, to->u.configureNotify.width);
+ cpswaps(from->u.configureNotify.height,
+ to->u.configureNotify.height);
+ cpswaps(from->u.configureNotify.borderWidth,
+ to->u.configureNotify.borderWidth);
+ to->u.configureNotify.override = from->u.configureNotify.override;
+}
+
+void
+SConfigureRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail; /* actually stack-mode */
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.configureRequest.parent,
+ to->u.configureRequest.parent);
+ cpswapl(from->u.configureRequest.window,
+ to->u.configureRequest.window);
+ cpswapl(from->u.configureRequest.sibling,
+ to->u.configureRequest.sibling);
+ cpswaps(from->u.configureRequest.x, to->u.configureRequest.x);
+ cpswaps(from->u.configureRequest.y, to->u.configureRequest.y);
+ cpswaps(from->u.configureRequest.width,
+ to->u.configureRequest.width);
+ cpswaps(from->u.configureRequest.height,
+ to->u.configureRequest.height);
+ cpswaps(from->u.configureRequest.borderWidth,
+ to->u.configureRequest.borderWidth);
+ cpswaps(from->u.configureRequest.valueMask,
+ to->u.configureRequest.valueMask);
+}
+
+
+void
+SGravityEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.gravity.event, to->u.gravity.event);
+ cpswapl(from->u.gravity.window, to->u.gravity.window);
+ cpswaps(from->u.gravity.x, to->u.gravity.x);
+ cpswaps(from->u.gravity.y, to->u.gravity.y);
+}
+
+void
+SResizeRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.resizeRequest.window, to->u.resizeRequest.window);
+ cpswaps(from->u.resizeRequest.width, to->u.resizeRequest.width);
+ cpswaps(from->u.resizeRequest.height, to->u.resizeRequest.height);
+}
+
+void
+SCirculateEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.circulate.event, to->u.circulate.event);
+ cpswapl(from->u.circulate.window, to->u.circulate.window);
+ cpswapl(from->u.circulate.parent, to->u.circulate.parent);
+ to->u.circulate.place = from->u.circulate.place;
+}
+
+void
+SPropertyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.property.window, to->u.property.window);
+ cpswapl(from->u.property.atom, to->u.property.atom);
+ cpswapl(from->u.property.time, to->u.property.time);
+ to->u.property.state = from->u.property.state;
+}
+
+void
+SSelectionClearEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionClear.time, to->u.selectionClear.time);
+ cpswapl(from->u.selectionClear.window, to->u.selectionClear.window);
+ cpswapl(from->u.selectionClear.atom, to->u.selectionClear.atom);
+}
+
+void
+SSelectionRequestEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionRequest.time, to->u.selectionRequest.time);
+ cpswapl(from->u.selectionRequest.owner,
+ to->u.selectionRequest.owner);
+ cpswapl(from->u.selectionRequest.requestor,
+ to->u.selectionRequest.requestor);
+ cpswapl(from->u.selectionRequest.selection,
+ to->u.selectionRequest.selection);
+ cpswapl(from->u.selectionRequest.target,
+ to->u.selectionRequest.target);
+ cpswapl(from->u.selectionRequest.property,
+ to->u.selectionRequest.property);
+}
+
+void
+SSelectionNotifyEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.selectionNotify.time, to->u.selectionNotify.time);
+ cpswapl(from->u.selectionNotify.requestor,
+ to->u.selectionNotify.requestor);
+ cpswapl(from->u.selectionNotify.selection,
+ to->u.selectionNotify.selection);
+ cpswapl(from->u.selectionNotify.target,
+ to->u.selectionNotify.target);
+ cpswapl(from->u.selectionNotify.property,
+ to->u.selectionNotify.property);
+}
+
+void
+SColormapEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.colormap.window, to->u.colormap.window);
+ cpswapl(from->u.colormap.colormap, to->u.colormap.colormap);
+ to->u.colormap.new = from->u.colormap.new;
+ to->u.colormap.state = from->u.colormap.state;
+}
+
+void
+SMappingEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ to->u.mappingNotify.request = from->u.mappingNotify.request;
+ to->u.mappingNotify.firstKeyCode =
+ from->u.mappingNotify.firstKeyCode;
+ to->u.mappingNotify.count = from->u.mappingNotify.count;
+}
+
+void
+SClientMessageEvent(xEvent *from, xEvent *to)
+{
+ to->u.u.type = from->u.u.type;
+ to->u.u.detail = from->u.u.detail; /* actually format */
+ cpswaps(from->u.u.sequenceNumber, to->u.u.sequenceNumber);
+ cpswapl(from->u.clientMessage.window, to->u.clientMessage.window);
+ cpswapl(from->u.clientMessage.u.l.type,
+ to->u.clientMessage.u.l.type);
+ switch (from->u.u.detail) {
+ case 8:
+ memmove(to->u.clientMessage.u.b.bytes,
+ from->u.clientMessage.u.b.bytes,20);
+ break;
+ case 16:
+ cpswaps(from->u.clientMessage.u.s.shorts0,
+ to->u.clientMessage.u.s.shorts0);
+ cpswaps(from->u.clientMessage.u.s.shorts1,
+ to->u.clientMessage.u.s.shorts1);
+ cpswaps(from->u.clientMessage.u.s.shorts2,
+ to->u.clientMessage.u.s.shorts2);
+ cpswaps(from->u.clientMessage.u.s.shorts3,
+ to->u.clientMessage.u.s.shorts3);
+ cpswaps(from->u.clientMessage.u.s.shorts4,
+ to->u.clientMessage.u.s.shorts4);
+ cpswaps(from->u.clientMessage.u.s.shorts5,
+ to->u.clientMessage.u.s.shorts5);
+ cpswaps(from->u.clientMessage.u.s.shorts6,
+ to->u.clientMessage.u.s.shorts6);
+ cpswaps(from->u.clientMessage.u.s.shorts7,
+ to->u.clientMessage.u.s.shorts7);
+ cpswaps(from->u.clientMessage.u.s.shorts8,
+ to->u.clientMessage.u.s.shorts8);
+ cpswaps(from->u.clientMessage.u.s.shorts9,
+ to->u.clientMessage.u.s.shorts9);
+ break;
+ case 32:
+ cpswapl(from->u.clientMessage.u.l.longs0,
+ to->u.clientMessage.u.l.longs0);
+ cpswapl(from->u.clientMessage.u.l.longs1,
+ to->u.clientMessage.u.l.longs1);
+ cpswapl(from->u.clientMessage.u.l.longs2,
+ to->u.clientMessage.u.l.longs2);
+ cpswapl(from->u.clientMessage.u.l.longs3,
+ to->u.clientMessage.u.l.longs3);
+ cpswapl(from->u.clientMessage.u.l.longs4,
+ to->u.clientMessage.u.l.longs4);
+ break;
+ }
+}
+
+void
+SKeymapNotifyEvent(xEvent *from, xEvent *to)
+{
+ /* Keymap notify events are special; they have no
+ sequence number field, and contain entirely 8-bit data */
+ *to = *from;
+}
+
+void
+SwapConnSetupInfo(
+ char *pInfo,
+ char *pInfoT
+)
+{
+ int i, j, k;
+ xConnSetup *pConnSetup = (xConnSetup *)pInfo;
+ xDepth *depth;
+ xWindowRoot *root;
+
+ SwapConnSetup(pConnSetup, (xConnSetup *)pInfoT);
+ pInfo += sizeof(xConnSetup);
+ pInfoT += sizeof(xConnSetup);
+
+ /* Copy the vendor string */
+ i = (pConnSetup->nbytesVendor + 3) & ~3;
+ memcpy(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ /* The Pixmap formats don't need to be swapped, just copied. */
+ i = sizeof(xPixmapFormat) * pConnSetup->numFormats;
+ memcpy(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ for(i = 0; i < pConnSetup->numRoots; i++)
+ {
+ root = (xWindowRoot*)pInfo;
+ SwapWinRoot(root, (xWindowRoot *)pInfoT);
+ pInfo += sizeof(xWindowRoot);
+ pInfoT += sizeof(xWindowRoot);
+
+ for(j = 0; j < root->nDepths; j++)
+ {
+ depth = (xDepth*)pInfo;
+ ((xDepth *)pInfoT)->depth = depth->depth;
+ cpswaps(depth->nVisuals, ((xDepth *)pInfoT)->nVisuals);
+ pInfo += sizeof(xDepth);
+ pInfoT += sizeof(xDepth);
+ for(k = 0; k < depth->nVisuals; k++)
+ {
+ SwapVisual((xVisualType *)pInfo, (xVisualType *)pInfoT);
+ pInfo += sizeof(xVisualType);
+ pInfoT += sizeof(xVisualType);
+ }
+ }
+ }
+}
+
+
+void
+WriteSConnectionInfo(ClientPtr pClient, unsigned long size, char *pInfo)
+{
+ char *pInfoTBase;
+
+ pInfoTBase = (char *) malloc(size);
+ if (!pInfoTBase)
+ {
+ pClient->noClientException = -1;
+ return;
+ }
+ SwapConnSetupInfo(pInfo, pInfoTBase);
+ WriteToClient(pClient, (int)size, pInfoTBase);
+ free(pInfoTBase);
+}
+
+void
+SwapConnSetup(xConnSetup *pConnSetup, xConnSetup *pConnSetupT)
+{
+ cpswapl(pConnSetup->release, pConnSetupT->release);
+ cpswapl(pConnSetup->ridBase, pConnSetupT->ridBase);
+ cpswapl(pConnSetup->ridMask, pConnSetupT->ridMask);
+ cpswapl(pConnSetup->motionBufferSize, pConnSetupT->motionBufferSize);
+ cpswaps(pConnSetup->nbytesVendor, pConnSetupT->nbytesVendor);
+ cpswaps(pConnSetup->maxRequestSize, pConnSetupT->maxRequestSize);
+ pConnSetupT->minKeyCode = pConnSetup->minKeyCode;
+ pConnSetupT->maxKeyCode = pConnSetup->maxKeyCode;
+ pConnSetupT->numRoots = pConnSetup->numRoots;
+ pConnSetupT->numFormats = pConnSetup->numFormats;
+ pConnSetupT->imageByteOrder = pConnSetup->imageByteOrder;
+ pConnSetupT->bitmapBitOrder = pConnSetup->bitmapBitOrder;
+ pConnSetupT->bitmapScanlineUnit = pConnSetup->bitmapScanlineUnit;
+ pConnSetupT->bitmapScanlinePad = pConnSetup->bitmapScanlinePad;
+}
+
+void
+SwapWinRoot(xWindowRoot *pRoot, xWindowRoot *pRootT)
+{
+ cpswapl(pRoot->windowId, pRootT->windowId);
+ cpswapl(pRoot->defaultColormap, pRootT->defaultColormap);
+ cpswapl(pRoot->whitePixel, pRootT->whitePixel);
+ cpswapl(pRoot->blackPixel, pRootT->blackPixel);
+ cpswapl(pRoot->currentInputMask, pRootT->currentInputMask);
+ cpswaps(pRoot->pixWidth, pRootT->pixWidth);
+ cpswaps(pRoot->pixHeight, pRootT->pixHeight);
+ cpswaps(pRoot->mmWidth, pRootT->mmWidth);
+ cpswaps(pRoot->mmHeight, pRootT->mmHeight);
+ cpswaps(pRoot->minInstalledMaps, pRootT->minInstalledMaps);
+ cpswaps(pRoot->maxInstalledMaps, pRootT->maxInstalledMaps);
+ cpswapl(pRoot->rootVisualID, pRootT->rootVisualID);
+ pRootT->backingStore = pRoot->backingStore;
+ pRootT->saveUnders = pRoot->saveUnders;
+ pRootT->rootDepth = pRoot->rootDepth;
+ pRootT->nDepths = pRoot->nDepths;
+}
+
+void
+SwapVisual(xVisualType *pVis, xVisualType *pVisT)
+{
+ cpswapl(pVis->visualID, pVisT->visualID);
+ pVisT->class = pVis->class;
+ pVisT->bitsPerRGB = pVis->bitsPerRGB;
+ cpswaps(pVis->colormapEntries, pVisT->colormapEntries);
+ cpswapl(pVis->redMask, pVisT->redMask);
+ cpswapl(pVis->greenMask, pVisT->greenMask);
+ cpswapl(pVis->blueMask, pVisT->blueMask);
+}
+
+void
+SwapConnSetupPrefix(xConnSetupPrefix *pcspFrom, xConnSetupPrefix *pcspTo)
+{
+ pcspTo->success = pcspFrom->success;
+ pcspTo->lengthReason = pcspFrom->lengthReason;
+ cpswaps(pcspFrom->majorVersion, pcspTo->majorVersion);
+ cpswaps(pcspFrom->minorVersion, pcspTo->minorVersion);
+ cpswaps(pcspFrom->length, pcspTo->length);
+}
+
+void
+WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix *pcsp)
+{
+ xConnSetupPrefix cspT;
+
+ SwapConnSetupPrefix(pcsp, &cspT);
+ WriteToClient(pClient, sizeof(cspT), &cspT);
+}
diff --git a/nx-X11/programs/Xserver/dix/swapreq.c b/nx-X11/programs/Xserver/dix/swapreq.c
new file mode 100644
index 000000000..7ea841e12
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/swapreq.c
@@ -0,0 +1,1019 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xprotostr.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h" /* for SendEvent */
+#include "swapreq.h"
+
+/* Thanks to Jack Palevich for testing and subsequently rewriting all this */
+
+/* Byte swap a list of longs */
+
+void
+SwapLongs (register CARD32 *list, register unsigned long count)
+{
+ while (count >= 8) {
+ swapl(list+0);
+ swapl(list+1);
+ swapl(list+2);
+ swapl(list+3);
+ swapl(list+4);
+ swapl(list+5);
+ swapl(list+6);
+ swapl(list+7);
+ list += 8;
+ count -= 8;
+ }
+ if (count != 0) {
+ do {
+ swapl(list);
+ list++;
+ } while (--count != 0);
+ }
+}
+
+/* Byte swap a list of shorts */
+
+void
+SwapShorts (register short *list, register unsigned long count)
+{
+ while (count >= 16) {
+ swaps(list+0);
+ swaps(list+1);
+ swaps(list+2);
+ swaps(list+3);
+ swaps(list+4);
+ swaps(list+5);
+ swaps(list+6);
+ swaps(list+7);
+ swaps(list+8);
+ swaps(list+9);
+ swaps(list+10);
+ swaps(list+11);
+ swaps(list+12);
+ swaps(list+13);
+ swaps(list+14);
+ swaps(list+15);
+ list += 16;
+ count -= 16;
+ }
+ if (count != 0) {
+ do {
+ swaps(list);
+ list++;
+ } while (--count != 0);
+ }
+}
+
+/* The following is used for all requests that have
+ no fields to be swapped (except "length") */
+int
+SProcSimpleReq(register ClientPtr client)
+{
+ REQUEST(xReq);
+ swaps(&stuff->length);
+ return(*ProcVector[stuff->reqType])(client);
+}
+
+/* The following is used for all requests that have
+ only a single 32-bit field to be swapped, coming
+ right after the "length" field */
+int
+SProcResourceReq(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xResourceReq); /* not EXACT */
+ swapl(&stuff->id);
+ return(*ProcVector[stuff->reqType])(client);
+}
+
+int
+SProcCreateWindow(register ClientPtr client)
+{
+ REQUEST(xCreateWindowReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+ swapl(&stuff->wid);
+ swapl(&stuff->parent);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swaps(&stuff->borderWidth);
+ swaps(&stuff->class);
+ swapl(&stuff->visual);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_CreateWindow])(client));
+}
+
+int
+SProcChangeWindowAttributes(register ClientPtr client)
+{
+ REQUEST(xChangeWindowAttributesReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ swapl(&stuff->window);
+ swapl(&stuff->valueMask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeWindowAttributes])(client));
+}
+
+int
+SProcReparentWindow(register ClientPtr client)
+{
+ REQUEST(xReparentWindowReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ swapl(&stuff->window);
+ swapl(&stuff->parent);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ return((* ProcVector[X_ReparentWindow])(client));
+}
+
+int
+SProcConfigureWindow(register ClientPtr client)
+{
+ REQUEST(xConfigureWindowReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ swapl(&stuff->window);
+ swaps(&stuff->mask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ConfigureWindow])(client));
+
+}
+
+
+int
+SProcInternAtom(register ClientPtr client)
+{
+ REQUEST(xInternAtomReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xInternAtomReq);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_InternAtom])(client));
+}
+
+int
+SProcChangeProperty(register ClientPtr client)
+{
+ REQUEST(xChangePropertyReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ swapl(&stuff->window);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->nUnits);
+ switch ( stuff->format ) {
+ case 8 :
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return((* ProcVector[X_ChangeProperty])(client));
+}
+
+int
+SProcDeleteProperty(register ClientPtr client)
+{
+ REQUEST(xDeletePropertyReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ swapl(&stuff->window);
+ swapl(&stuff->property);
+ return((* ProcVector[X_DeleteProperty])(client));
+
+}
+
+int
+SProcGetProperty(register ClientPtr client)
+{
+ REQUEST(xGetPropertyReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+ swapl(&stuff->window);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->longOffset);
+ swapl(&stuff->longLength);
+ return((* ProcVector[X_GetProperty])(client));
+}
+
+int
+SProcSetSelectionOwner(register ClientPtr client)
+{
+ REQUEST(xSetSelectionOwnerReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ swapl(&stuff->window);
+ swapl(&stuff->selection);
+ swapl(&stuff->time);
+ return((* ProcVector[X_SetSelectionOwner])(client));
+}
+
+int
+SProcConvertSelection(register ClientPtr client)
+{
+ REQUEST(xConvertSelectionReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ swapl(&stuff->requestor);
+ swapl(&stuff->selection);
+ swapl(&stuff->target);
+ swapl(&stuff->property);
+ swapl(&stuff->time);
+ return((* ProcVector[X_ConvertSelection])(client));
+}
+
+int
+SProcSendEvent(register ClientPtr client)
+{
+ xEvent eventT;
+ EventSwapPtr proc;
+ REQUEST(xSendEventReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSendEventReq);
+ swapl(&stuff->destination);
+ swapl(&stuff->eventMask);
+
+ /* Swap event */
+ proc = EventSwapVector[stuff->event.u.u.type & 0177];
+ if (!proc || proc == NotImplemented) /* no swapping proc; invalid event type? */
+ return (BadValue);
+ (*proc)(&stuff->event, &eventT);
+ stuff->event = eventT;
+
+ return((* ProcVector[X_SendEvent])(client));
+}
+
+int
+SProcGrabPointer(register ClientPtr client)
+{
+ REQUEST(xGrabPointerReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->eventMask);
+ swapl(&stuff->confineTo);
+ swapl(&stuff->cursor);
+ swapl(&stuff->time);
+ return((* ProcVector[X_GrabPointer])(client));
+}
+
+int
+SProcGrabButton(register ClientPtr client)
+{
+ REQUEST(xGrabButtonReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->eventMask);
+ swapl(&stuff->confineTo);
+ swapl(&stuff->cursor);
+ swaps(&stuff->modifiers);
+ return((* ProcVector[X_GrabButton])(client));
+}
+
+int
+SProcUngrabButton(register ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ return((* ProcVector[X_UngrabButton])(client));
+}
+
+int
+SProcChangeActivePointerGrab(register ClientPtr client)
+{
+ REQUEST(xChangeActivePointerGrabReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ swapl(&stuff->cursor);
+ swapl(&stuff->time);
+ swaps(&stuff->eventMask);
+ return((* ProcVector[X_ChangeActivePointerGrab])(client));
+}
+
+int
+SProcGrabKeyboard(register ClientPtr client)
+{
+ REQUEST(xGrabKeyboardReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+ swapl(&stuff->grabWindow);
+ swapl(&stuff->time);
+ return((* ProcVector[X_GrabKeyboard])(client));
+}
+
+int
+SProcGrabKey(register ClientPtr client)
+{
+ REQUEST(xGrabKeyReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ return((* ProcVector[X_GrabKey])(client));
+}
+
+int
+SProcUngrabKey(register ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ swapl(&stuff->grabWindow);
+ swaps(&stuff->modifiers);
+ return((* ProcVector[X_UngrabKey])(client));
+}
+
+int
+SProcGetMotionEvents(register ClientPtr client)
+{
+ REQUEST(xGetMotionEventsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+ swapl(&stuff->window);
+ swapl(&stuff->start);
+ swapl(&stuff->stop);
+ return((* ProcVector[X_GetMotionEvents])(client));
+}
+
+int
+SProcTranslateCoords(register ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ swapl(&stuff->srcWid);
+ swapl(&stuff->dstWid);
+ swaps(&stuff->srcX);
+ swaps(&stuff->srcY);
+ return((* ProcVector[X_TranslateCoords])(client));
+}
+
+int
+SProcWarpPointer(register ClientPtr client)
+{
+ REQUEST(xWarpPointerReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+ swapl(&stuff->srcWid);
+ swapl(&stuff->dstWid);
+ swaps(&stuff->srcX);
+ swaps(&stuff->srcY);
+ swaps(&stuff->srcWidth);
+ swaps(&stuff->srcHeight);
+ swaps(&stuff->dstX);
+ swaps(&stuff->dstY);
+ return((* ProcVector[X_WarpPointer])(client));
+}
+
+int
+SProcSetInputFocus(register ClientPtr client)
+{
+ REQUEST(xSetInputFocusReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+ swapl(&stuff->focus);
+ swapl(&stuff->time);
+ return((* ProcVector[X_SetInputFocus])(client));
+}
+
+int
+SProcOpenFont(register ClientPtr client)
+{
+ REQUEST(xOpenFontReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xOpenFontReq);
+ swapl(&stuff->fid);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_OpenFont])(client));
+}
+
+int
+SProcListFonts(register ClientPtr client)
+{
+ REQUEST(xListFontsReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xListFontsReq);
+ swaps(&stuff->maxNames);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_ListFonts])(client));
+}
+
+int
+SProcListFontsWithInfo(register ClientPtr client)
+{
+ REQUEST(xListFontsWithInfoReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xListFontsWithInfoReq);
+ swaps(&stuff->maxNames);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_ListFontsWithInfo])(client));
+}
+
+int
+SProcSetFontPath(register ClientPtr client)
+{
+ REQUEST(xSetFontPathReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+ swaps(&stuff->nFonts);
+ return((* ProcVector[X_SetFontPath])(client));
+}
+
+int
+SProcCreatePixmap(register ClientPtr client)
+{
+ REQUEST(xCreatePixmapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ swapl(&stuff->pid);
+ swapl(&stuff->drawable);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return((* ProcVector[X_CreatePixmap])(client));
+}
+
+int
+SProcCreateGC(register ClientPtr client)
+{
+ REQUEST(xCreateGCReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ swapl(&stuff->gc);
+ swapl(&stuff->drawable);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_CreateGC])(client));
+}
+
+int
+SProcChangeGC(register ClientPtr client)
+{
+ REQUEST(xChangeGCReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ swapl(&stuff->gc);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeGC])(client));
+}
+
+int
+SProcCopyGC(register ClientPtr client)
+{
+ REQUEST(xCopyGCReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ swapl(&stuff->srcGC);
+ swapl(&stuff->dstGC);
+ swapl(&stuff->mask);
+ return((* ProcVector[X_CopyGC])(client));
+}
+
+int
+SProcSetDashes(register ClientPtr client)
+{
+ REQUEST(xSetDashesReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSetDashesReq);
+ swapl(&stuff->gc);
+ swaps(&stuff->dashOffset);
+ swaps(&stuff->nDashes);
+ return((* ProcVector[X_SetDashes])(client));
+
+}
+
+int
+SProcSetClipRectangles(register ClientPtr client)
+{
+ REQUEST(xSetClipRectanglesReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ swapl(&stuff->gc);
+ swaps(&stuff->xOrigin);
+ swaps(&stuff->yOrigin);
+ SwapRestS(stuff);
+ return((* ProcVector[X_SetClipRectangles])(client));
+}
+
+int
+SProcClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ swapl(&stuff->window);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return((* ProcVector[X_ClearArea])(client));
+}
+
+int
+SProcCopyArea(register ClientPtr client)
+{
+ REQUEST(xCopyAreaReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+ swapl(&stuff->srcDrawable);
+ swapl(&stuff->dstDrawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->srcX);
+ swaps(&stuff->srcY);
+ swaps(&stuff->dstX);
+ swaps(&stuff->dstY);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return((* ProcVector[X_CopyArea])(client));
+}
+
+int
+SProcCopyPlane(register ClientPtr client)
+{
+ REQUEST(xCopyPlaneReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+ swapl(&stuff->srcDrawable);
+ swapl(&stuff->dstDrawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->srcX);
+ swaps(&stuff->srcY);
+ swaps(&stuff->dstX);
+ swaps(&stuff->dstY);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->bitPlane);
+ return((* ProcVector[X_CopyPlane])(client));
+}
+
+/* The following routine is used for all Poly drawing requests
+ (except FillPoly, which uses a different request format) */
+int
+SProcPoly(register ClientPtr client)
+{
+ REQUEST(xPolyPointReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ SwapRestS(stuff);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+/* cannot use SProcPoly for this one, because xFillPolyReq
+ is longer than xPolyPointReq, and we don't want to swap
+ the difference as shorts! */
+int
+SProcFillPoly(register ClientPtr client)
+{
+ REQUEST(xFillPolyReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ SwapRestS(stuff);
+ return((* ProcVector[X_FillPoly])(client));
+}
+
+int
+SProcPutImage(register ClientPtr client)
+{
+ REQUEST(xPutImageReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swaps(&stuff->dstX);
+ swaps(&stuff->dstY);
+ /* Image should already be swapped */
+ return((* ProcVector[X_PutImage])(client));
+
+}
+
+int
+SProcGetImage(register ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xGetImageReq);
+ swapl(&stuff->drawable);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->planeMask);
+ return((* ProcVector[X_GetImage])(client));
+}
+
+/* ProcPolyText used for both PolyText8 and PolyText16 */
+
+int
+SProcPolyText(register ClientPtr client)
+{
+ REQUEST(xPolyTextReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+/* ProcImageText used for both ImageText8 and ImageText16 */
+
+int
+SProcImageText(register ClientPtr client)
+{
+ REQUEST(xImageTextReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xImageTextReq);
+ swapl(&stuff->drawable);
+ swapl(&stuff->gc);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ return((* ProcVector[stuff->reqType])(client));
+}
+
+int
+SProcCreateColormap(register ClientPtr client)
+{
+ REQUEST(xCreateColormapReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+ swapl(&stuff->mid);
+ swapl(&stuff->window);
+ swapl(&stuff->visual);
+ return((* ProcVector[X_CreateColormap])(client));
+}
+
+
+int
+SProcCopyColormapAndFree(register ClientPtr client)
+{
+ REQUEST(xCopyColormapAndFreeReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ swapl(&stuff->mid);
+ swapl(&stuff->srcCmap);
+ return((* ProcVector[X_CopyColormapAndFree])(client));
+
+}
+
+int
+SProcAllocColor(register ClientPtr client)
+{
+ REQUEST(xAllocColorReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ swapl(&stuff->cmap);
+ swaps(&stuff->red);
+ swaps(&stuff->green);
+ swaps(&stuff->blue);
+ return((* ProcVector[X_AllocColor])(client));
+}
+
+int
+SProcAllocNamedColor(register ClientPtr client)
+{
+ REQUEST(xAllocNamedColorReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xAllocNamedColorReq);
+ swapl(&stuff->cmap);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_AllocNamedColor])(client));
+}
+
+int
+SProcAllocColorCells(register ClientPtr client)
+{
+ REQUEST(xAllocColorCellsReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ swapl(&stuff->cmap);
+ swaps(&stuff->colors);
+ swaps(&stuff->planes);
+ return((* ProcVector[X_AllocColorCells])(client));
+}
+
+int
+SProcAllocColorPlanes(register ClientPtr client)
+{
+ REQUEST(xAllocColorPlanesReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ swapl(&stuff->cmap);
+ swaps(&stuff->colors);
+ swaps(&stuff->red);
+ swaps(&stuff->green);
+ swaps(&stuff->blue);
+ return((* ProcVector[X_AllocColorPlanes])(client));
+}
+
+int
+SProcFreeColors(register ClientPtr client)
+{
+ REQUEST(xFreeColorsReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ swapl(&stuff->cmap);
+ swapl(&stuff->planeMask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_FreeColors])(client));
+
+}
+
+void
+SwapColorItem(xColorItem *pItem)
+{
+ swapl(&pItem->pixel);
+ swaps(&pItem->red);
+ swaps(&pItem->green);
+ swaps(&pItem->blue);
+}
+
+int
+SProcStoreColors(register ClientPtr client)
+{
+ long count;
+ xColorItem *pItem;
+
+ REQUEST(xStoreColorsReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ swapl(&stuff->cmap);
+ pItem = (xColorItem *) &stuff[1];
+ for(count = LengthRestB(stuff)/sizeof(xColorItem); --count >= 0; )
+ SwapColorItem(pItem++);
+ return((* ProcVector[X_StoreColors])(client));
+}
+
+int
+SProcStoreNamedColor (register ClientPtr client)
+{
+ REQUEST(xStoreNamedColorReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xStoreNamedColorReq);
+ swapl(&stuff->cmap);
+ swapl(&stuff->pixel);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_StoreNamedColor])(client));
+}
+
+int
+SProcQueryColors (register ClientPtr client)
+{
+ REQUEST(xQueryColorsReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ swapl(&stuff->cmap);
+ SwapRestL(stuff);
+ return((* ProcVector[X_QueryColors])(client));
+}
+
+int
+SProcLookupColor (register ClientPtr client)
+{
+ REQUEST(xLookupColorReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xLookupColorReq);
+ swapl(&stuff->cmap);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_LookupColor])(client));
+}
+
+int
+SProcCreateCursor (register ClientPtr client)
+{
+ REQUEST(xCreateCursorReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ swapl(&stuff->cid);
+ swapl(&stuff->source);
+ swapl(&stuff->mask);
+ swaps(&stuff->foreRed);
+ swaps(&stuff->foreGreen);
+ swaps(&stuff->foreBlue);
+ swaps(&stuff->backRed);
+ swaps(&stuff->backGreen);
+ swaps(&stuff->backBlue);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ return((* ProcVector[X_CreateCursor])(client));
+}
+
+int
+SProcCreateGlyphCursor (register ClientPtr client)
+{
+ REQUEST(xCreateGlyphCursorReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ swapl(&stuff->cid);
+ swapl(&stuff->source);
+ swapl(&stuff->mask);
+ swaps(&stuff->sourceChar);
+ swaps(&stuff->maskChar);
+ swaps(&stuff->foreRed);
+ swaps(&stuff->foreGreen);
+ swaps(&stuff->foreBlue);
+ swaps(&stuff->backRed);
+ swaps(&stuff->backGreen);
+ swaps(&stuff->backBlue);
+ return((* ProcVector[X_CreateGlyphCursor])(client));
+}
+
+
+int
+SProcRecolorCursor (register ClientPtr client)
+{
+ REQUEST(xRecolorCursorReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ swapl(&stuff->cursor);
+ swaps(&stuff->foreRed);
+ swaps(&stuff->foreGreen);
+ swaps(&stuff->foreBlue);
+ swaps(&stuff->backRed);
+ swaps(&stuff->backGreen);
+ swaps(&stuff->backBlue);
+ return((* ProcVector[X_RecolorCursor])(client));
+}
+
+int
+SProcQueryBestSize (register ClientPtr client)
+{
+ REQUEST(xQueryBestSizeReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+ swapl(&stuff->drawable);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return((* ProcVector[X_QueryBestSize])(client));
+
+}
+
+int
+SProcQueryExtension (register ClientPtr client)
+{
+ REQUEST(xQueryExtensionReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xQueryExtensionReq);
+ swaps(&stuff->nbytes);
+ return((* ProcVector[X_QueryExtension])(client));
+}
+
+int
+SProcChangeKeyboardMapping (register ClientPtr client)
+{
+ REQUEST(xChangeKeyboardMappingReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeKeyboardMapping])(client));
+}
+
+
+int
+SProcChangeKeyboardControl (register ClientPtr client)
+{
+ REQUEST(xChangeKeyboardControlReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return((* ProcVector[X_ChangeKeyboardControl])(client));
+}
+
+int
+SProcChangePointerControl (register ClientPtr client)
+{
+ REQUEST(xChangePointerControlReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xChangePointerControlReq);
+ swaps(&stuff->accelNum);
+ swaps(&stuff->accelDenum);
+ swaps(&stuff->threshold);
+ return((* ProcVector[X_ChangePointerControl])(client));
+}
+
+
+int
+SProcSetScreenSaver (register ClientPtr client)
+{
+ REQUEST(xSetScreenSaverReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ swaps(&stuff->timeout);
+ swaps(&stuff->interval);
+ return((* ProcVector[X_SetScreenSaver])(client));
+}
+
+int
+SProcChangeHosts (register ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xChangeHostsReq);
+ swaps(&stuff->hostLength);
+ return((* ProcVector[X_ChangeHosts])(client));
+
+}
+
+int SProcRotateProperties (register ClientPtr client)
+{
+ REQUEST(xRotatePropertiesReq);
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xRotatePropertiesReq);
+ swapl(&stuff->window);
+ swaps(&stuff->nAtoms);
+ swaps(&stuff->nPositions);
+ SwapRestL(stuff);
+ return ((* ProcVector[X_RotateProperties])(client));
+}
+
+int
+SProcNoOperation(register ClientPtr client)
+{
+ REQUEST(xReq);
+ swaps(&stuff->length);
+ return ((* ProcVector[X_NoOperation])(client));
+}
+
+void
+SwapConnClientPrefix(xConnClientPrefix *pCCP)
+{
+ swaps(&pCCP->majorVersion);
+ swaps(&pCCP->minorVersion);
+ swaps(&pCCP->nbytesAuthProto);
+ swaps(&pCCP->nbytesAuthString);
+}
diff --git a/nx-X11/programs/Xserver/dix/tables.c b/nx-X11/programs/Xserver/dix/tables.c
new file mode 100644
index 000000000..624522daf
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/tables.c
@@ -0,0 +1,510 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "windowstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "dixevents.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+
+int (* InitialVector[3]) (
+ ClientPtr /* client */
+ ) =
+{
+ 0,
+ ProcInitialConnection,
+ ProcEstablishConnection
+};
+
+int (* ProcVector[256]) (
+ ClientPtr /* client */
+ ) =
+{
+ ProcBadRequest,
+ ProcCreateWindow,
+ ProcChangeWindowAttributes,
+ ProcGetWindowAttributes,
+ ProcDestroyWindow,
+ ProcDestroySubwindows, /* 5 */
+ ProcChangeSaveSet,
+ ProcReparentWindow,
+ ProcMapWindow,
+ ProcMapSubwindows,
+ ProcUnmapWindow, /* 10 */
+ ProcUnmapSubwindows,
+ ProcConfigureWindow,
+ ProcCirculateWindow,
+ ProcGetGeometry,
+ ProcQueryTree, /* 15 */
+ ProcInternAtom,
+ ProcGetAtomName,
+ ProcChangeProperty,
+ ProcDeleteProperty,
+ ProcGetProperty, /* 20 */
+ ProcListProperties,
+ ProcSetSelectionOwner,
+ ProcGetSelectionOwner,
+ ProcConvertSelection,
+ ProcSendEvent, /* 25 */
+ ProcGrabPointer,
+ ProcUngrabPointer,
+ ProcGrabButton,
+ ProcUngrabButton,
+ ProcChangeActivePointerGrab, /* 30 */
+ ProcGrabKeyboard,
+ ProcUngrabKeyboard,
+ ProcGrabKey,
+ ProcUngrabKey,
+ ProcAllowEvents, /* 35 */
+ ProcGrabServer,
+ ProcUngrabServer,
+ ProcQueryPointer,
+ ProcGetMotionEvents,
+ ProcTranslateCoords, /* 40 */
+ ProcWarpPointer,
+ ProcSetInputFocus,
+ ProcGetInputFocus,
+ ProcQueryKeymap,
+ ProcOpenFont, /* 45 */
+ ProcCloseFont,
+ ProcQueryFont,
+ ProcQueryTextExtents,
+ ProcListFonts,
+ ProcListFontsWithInfo, /* 50 */
+ ProcSetFontPath,
+ ProcGetFontPath,
+ ProcCreatePixmap,
+ ProcFreePixmap,
+ ProcCreateGC, /* 55 */
+ ProcChangeGC,
+ ProcCopyGC,
+ ProcSetDashes,
+ ProcSetClipRectangles,
+ ProcFreeGC, /* 60 */
+ ProcClearToBackground,
+ ProcCopyArea,
+ ProcCopyPlane,
+ ProcPolyPoint,
+ ProcPolyLine, /* 65 */
+ ProcPolySegment,
+ ProcPolyRectangle,
+ ProcPolyArc,
+ ProcFillPoly,
+ ProcPolyFillRectangle, /* 70 */
+ ProcPolyFillArc,
+ ProcPutImage,
+ ProcGetImage,
+ ProcPolyText,
+ ProcPolyText, /* 75 */
+ ProcImageText8,
+ ProcImageText16,
+ ProcCreateColormap,
+ ProcFreeColormap,
+ ProcCopyColormapAndFree, /* 80 */
+ ProcInstallColormap,
+ ProcUninstallColormap,
+ ProcListInstalledColormaps,
+ ProcAllocColor,
+ ProcAllocNamedColor, /* 85 */
+ ProcAllocColorCells,
+ ProcAllocColorPlanes,
+ ProcFreeColors,
+ ProcStoreColors,
+ ProcStoreNamedColor, /* 90 */
+ ProcQueryColors,
+ ProcLookupColor,
+ ProcCreateCursor,
+ ProcCreateGlyphCursor,
+ ProcFreeCursor, /* 95 */
+ ProcRecolorCursor,
+ ProcQueryBestSize,
+ ProcQueryExtension,
+ ProcListExtensions,
+ ProcChangeKeyboardMapping, /* 100 */
+ ProcGetKeyboardMapping,
+ ProcChangeKeyboardControl,
+ ProcGetKeyboardControl,
+ ProcBell,
+ ProcChangePointerControl, /* 105 */
+ ProcGetPointerControl,
+ ProcSetScreenSaver,
+ ProcGetScreenSaver,
+ ProcChangeHosts,
+ ProcListHosts, /* 110 */
+ ProcChangeAccessControl,
+ ProcChangeCloseDownMode,
+ ProcKillClient,
+ ProcRotateProperties,
+ ProcForceScreenSaver, /* 115 */
+ ProcSetPointerMapping,
+ ProcGetPointerMapping,
+ ProcSetModifierMapping,
+ ProcGetModifierMapping,
+ 0, /* 120 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 125 */
+ 0,
+ ProcNoOperation
+};
+
+int (* SwappedProcVector[256]) (
+ ClientPtr /* client */
+ ) =
+{
+ ProcBadRequest,
+ SProcCreateWindow,
+ SProcChangeWindowAttributes,
+ SProcResourceReq, /* GetWindowAttributes */
+ SProcResourceReq, /* DestroyWindow */
+ SProcResourceReq, /* 5 DestroySubwindows */
+ SProcResourceReq, /* SProcChangeSaveSet, */
+ SProcReparentWindow,
+ SProcResourceReq, /* MapWindow */
+ SProcResourceReq, /* MapSubwindows */
+ SProcResourceReq, /* 10 UnmapWindow */
+ SProcResourceReq, /* UnmapSubwindows */
+ SProcConfigureWindow,
+ SProcResourceReq, /* SProcCirculateWindow, */
+ SProcResourceReq, /* GetGeometry */
+ SProcResourceReq, /* 15 QueryTree */
+ SProcInternAtom,
+ SProcResourceReq, /* SProcGetAtomName, */
+ SProcChangeProperty,
+ SProcDeleteProperty,
+ SProcGetProperty, /* 20 */
+ SProcResourceReq, /* SProcListProperties, */
+ SProcSetSelectionOwner,
+ SProcResourceReq, /* SProcGetSelectionOwner, */
+ SProcConvertSelection,
+ SProcSendEvent, /* 25 */
+ SProcGrabPointer,
+ SProcResourceReq, /* SProcUngrabPointer, */
+ SProcGrabButton,
+ SProcUngrabButton,
+ SProcChangeActivePointerGrab, /* 30 */
+ SProcGrabKeyboard,
+ SProcResourceReq, /* SProcUngrabKeyboard, */
+ SProcGrabKey,
+ SProcUngrabKey,
+ SProcResourceReq, /* 35 SProcAllowEvents, */
+ SProcSimpleReq, /* SProcGrabServer, */
+ SProcSimpleReq, /* SProcUngrabServer, */
+ SProcResourceReq, /* SProcQueryPointer, */
+ SProcGetMotionEvents,
+ SProcTranslateCoords, /*40 */
+ SProcWarpPointer,
+ SProcSetInputFocus,
+ SProcSimpleReq, /* SProcGetInputFocus, */
+ SProcSimpleReq, /* QueryKeymap, */
+ SProcOpenFont, /* 45 */
+ SProcResourceReq, /* SProcCloseFont, */
+ SProcResourceReq, /* SProcQueryFont, */
+ SProcResourceReq, /* SProcQueryTextExtents, */
+ SProcListFonts,
+ SProcListFontsWithInfo, /* 50 */
+ SProcSetFontPath,
+ SProcSimpleReq, /* GetFontPath, */
+ SProcCreatePixmap,
+ SProcResourceReq, /* SProcFreePixmap, */
+ SProcCreateGC, /* 55 */
+ SProcChangeGC,
+ SProcCopyGC,
+ SProcSetDashes,
+ SProcSetClipRectangles,
+ SProcResourceReq, /* 60 SProcFreeGC, */
+ SProcClearToBackground,
+ SProcCopyArea,
+ SProcCopyPlane,
+ SProcPoly, /* PolyPoint, */
+ SProcPoly, /* 65 PolyLine */
+ SProcPoly, /* PolySegment, */
+ SProcPoly, /* PolyRectangle, */
+ SProcPoly, /* PolyArc, */
+ SProcFillPoly,
+ SProcPoly, /* 70 PolyFillRectangle */
+ SProcPoly, /* PolyFillArc, */
+ SProcPutImage,
+ SProcGetImage,
+ SProcPolyText,
+ SProcPolyText, /* 75 */
+ SProcImageText,
+ SProcImageText,
+ SProcCreateColormap,
+ SProcResourceReq, /* SProcFreeColormap, */
+ SProcCopyColormapAndFree, /* 80 */
+ SProcResourceReq, /* SProcInstallColormap, */
+ SProcResourceReq, /* SProcUninstallColormap, */
+ SProcResourceReq, /* SProcListInstalledColormaps, */
+ SProcAllocColor,
+ SProcAllocNamedColor, /* 85 */
+ SProcAllocColorCells,
+ SProcAllocColorPlanes,
+ SProcFreeColors,
+ SProcStoreColors,
+ SProcStoreNamedColor, /* 90 */
+ SProcQueryColors,
+ SProcLookupColor,
+ SProcCreateCursor,
+ SProcCreateGlyphCursor,
+ SProcResourceReq, /* 95 SProcFreeCursor, */
+ SProcRecolorCursor,
+ SProcQueryBestSize,
+ SProcQueryExtension,
+ SProcSimpleReq, /* ListExtensions, */
+ SProcChangeKeyboardMapping, /* 100 */
+ SProcSimpleReq, /* GetKeyboardMapping, */
+ SProcChangeKeyboardControl,
+ SProcSimpleReq, /* GetKeyboardControl, */
+ SProcSimpleReq, /* Bell, */
+ SProcChangePointerControl, /* 105 */
+ SProcSimpleReq, /* GetPointerControl, */
+ SProcSetScreenSaver,
+ SProcSimpleReq, /* GetScreenSaver, */
+ SProcChangeHosts,
+ SProcSimpleReq, /* 110 ListHosts, */
+ SProcSimpleReq, /* SProcChangeAccessControl, */
+ SProcSimpleReq, /* SProcChangeCloseDownMode, */
+ SProcResourceReq, /* SProcKillClient, */
+ SProcRotateProperties,
+ SProcSimpleReq, /* 115 ForceScreenSaver */
+ SProcSimpleReq, /* SetPointerMapping, */
+ SProcSimpleReq, /* GetPointerMapping, */
+ SProcSimpleReq, /* SetModifierMapping, */
+ SProcSimpleReq, /* GetModifierMapping, */
+ 0, /* 120 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 125 */
+ 0,
+ SProcNoOperation
+};
+
+EventSwapPtr EventSwapVector[128] =
+{
+ (EventSwapPtr)SErrorEvent,
+ NotImplemented,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent,
+ SKeyButtonPtrEvent, /* 5 */
+ SKeyButtonPtrEvent,
+ SEnterLeaveEvent,
+ SEnterLeaveEvent,
+ SFocusEvent,
+ SFocusEvent, /* 10 */
+ SKeymapNotifyEvent,
+ SExposeEvent,
+ SGraphicsExposureEvent,
+ SNoExposureEvent,
+ SVisibilityEvent, /* 15 */
+ SCreateNotifyEvent,
+ SDestroyNotifyEvent,
+ SUnmapNotifyEvent,
+ SMapNotifyEvent,
+ SMapRequestEvent, /* 20 */
+ SReparentEvent,
+ SConfigureNotifyEvent,
+ SConfigureRequestEvent,
+ SGravityEvent,
+ SResizeRequestEvent, /* 25 */
+ SCirculateEvent,
+ SCirculateEvent,
+ SPropertyEvent,
+ SSelectionClearEvent,
+ SSelectionRequestEvent, /* 30 */
+ SSelectionNotifyEvent,
+ SColormapEvent,
+ SClientMessageEvent,
+ SMappingEvent,
+};
+
+
+ReplySwapPtr ReplySwapVector[256] =
+{
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetWindowAttributesReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 5 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 10 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetGeometryReply,
+ (ReplySwapPtr)SQueryTreeReply, /* 15 */
+ (ReplySwapPtr)SInternAtomReply,
+ (ReplySwapPtr)SGetAtomNameReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetPropertyReply, /* 20 */
+ (ReplySwapPtr)SListPropertiesReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetSelectionOwnerReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 25 */
+ (ReplySwapPtr)SGenericReply, /* SGrabPointerReply, */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 30 */
+ (ReplySwapPtr)SGenericReply, /* SGrabKeyboardReply, */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 35 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryPointerReply,
+ (ReplySwapPtr)SGetMotionEventsReply,
+ (ReplySwapPtr)STranslateCoordsReply, /* 40 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetInputFocusReply,
+ (ReplySwapPtr)SQueryKeymapReply,
+ ReplyNotSwappd, /* 45 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryFontReply,
+ (ReplySwapPtr)SQueryTextExtentsReply,
+ (ReplySwapPtr)SListFontsReply,
+ (ReplySwapPtr)SListFontsWithInfoReply, /* 50 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetFontPathReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 55 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 60 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 65 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 70 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetImageReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 75 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 80 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SListInstalledColormapsReply,
+ (ReplySwapPtr)SAllocColorReply,
+ (ReplySwapPtr)SAllocNamedColorReply, /* 85 */
+ (ReplySwapPtr)SAllocColorCellsReply,
+ (ReplySwapPtr)SAllocColorPlanesReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 90 */
+ (ReplySwapPtr)SQueryColorsReply,
+ (ReplySwapPtr)SLookupColorReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 95 */
+ ReplyNotSwappd,
+ (ReplySwapPtr)SQueryBestSizeReply,
+ (ReplySwapPtr)SGenericReply, /* SQueryExtensionReply, */
+ (ReplySwapPtr)SListExtensionsReply,
+ ReplyNotSwappd, /* 100 */
+ (ReplySwapPtr)SGetKeyboardMappingReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetKeyboardControlReply,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 105 */
+ (ReplySwapPtr)SGetPointerControlReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SGetScreenSaverReply,
+ ReplyNotSwappd,
+ (ReplySwapPtr)SListHostsReply, /* 110 */
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd,
+ ReplyNotSwappd, /* 115 */
+ (ReplySwapPtr)SGenericReply, /* SetPointerMapping */
+ (ReplySwapPtr)SGetPointerMappingReply,
+ (ReplySwapPtr)SGenericReply, /* SetModifierMapping */
+ (ReplySwapPtr)SGetModifierMappingReply, /* 119 */
+ ReplyNotSwappd, /* 120 */
+ ReplyNotSwappd, /* 121 */
+ ReplyNotSwappd, /* 122 */
+ ReplyNotSwappd, /* 123 */
+ ReplyNotSwappd, /* 124 */
+ ReplyNotSwappd, /* 125 */
+ ReplyNotSwappd, /* 126 */
+ ReplyNotSwappd, /* NoOperation */
+ ReplyNotSwappd
+};
diff --git a/nx-X11/programs/Xserver/dix/window.c b/nx-X11/programs/Xserver/dix/window.c
new file mode 100644
index 000000000..ba9cfc2d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/window.c
@@ -0,0 +1,3841 @@
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+/******
+ * Window stuff for server
+ *
+ * CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ * GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ * HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ * UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+ CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+ (!( ((b1)->x2 <= (b2)->x1) || \
+ ( ((b1)->x1 >= (b2)->x2)) || \
+ ( ((b1)->y2 <= (b2)->y1)) || \
+ ( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+ ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+#if defined(DEBUG) || (defined(NXAGENT_SERVER) && defined(WINDOW_TREE_DEBUG))
+/******
+ * PrintWindowTree
+ * For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+ WindowPtr p2;
+ int i;
+
+ while (p1)
+ {
+ p2 = p1->firstChild;
+ for (i=0; i<indent; i++) ErrorF( " ");
+ ErrorF( "%x\n", p1->drawable.id);
+ RegionPrint(&p1->clipList);
+ PrintChildren(p2, indent+4);
+ p1 = p1->nextSib;
+ }
+}
+
+PrintWindowTree()
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ErrorF( "WINDOW %d\n", i);
+ pWin = screenInfo.screens[i]->root;
+ RegionPrint(&pWin->clipList);
+ p1 = pWin->firstChild;
+ PrintChildren(p1, 4);
+ }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, void * data)
+{
+ register int result;
+ register WindowPtr pChild;
+
+ if (!(pChild = pWin))
+ return(WT_NOMATCH);
+ while (1)
+ {
+ result = (* func)(pChild, data);
+ if (result == WT_STOPWALKING)
+ return(WT_STOPWALKING);
+ if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ * Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ * each window. If FUNC returns WT_WALKCHILDREN, traverse the children,
+ * if it returns WT_DONTWALKCHILDREN, dont. If it returns WT_STOPWALKING
+ * exit WalkTree. Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, void * data)
+{
+ return(TraverseTree(pScreen->root, func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool disableBackingStore = FALSE;
+Bool enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+ pWin->prevSib = NullWindow;
+ pWin->firstChild = NullWindow;
+ pWin->lastChild = NullWindow;
+
+ pWin->valdata = (ValidatePtr)NULL;
+ pWin->optional = (WindowOptPtr)NULL;
+ pWin->cursorIsNone = TRUE;
+
+ pWin->backingStore = NotUseful;
+ pWin->DIXsaveUnder = FALSE;
+ pWin->backStorage = (void *) NULL;
+
+ pWin->mapped = FALSE; /* off */
+ pWin->realized = FALSE; /* off */
+ pWin->viewable = FALSE;
+ pWin->visibility = VisibilityNotViewable;
+ pWin->overrideRedirect = FALSE;
+ pWin->saveUnder = FALSE;
+
+ pWin->bitGravity = ForgetGravity;
+ pWin->winGravity = NorthWestGravity;
+
+ pWin->eventMask = 0;
+ pWin->deliverableEvents = 0;
+ pWin->dontPropagate = 0;
+ pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+ pWin->srcBuffer = DBE_FRONT_BUFFER;
+ pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+ pWin->redirectDraw = 0;
+#endif
+}
+
+#ifndef NXAGENT_SERVER
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth, 0);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ if (blackRoot)
+ bzero(back, sizeof(back));
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+}
+#endif /* NXAGENT_SERVER */
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ register char *ptr;
+ register DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ pWin = (WindowPtr)malloc(pScreen->totalWindowSize);
+ if (pWin)
+ {
+ ppriv = (DevUnion *)(pWin + 1);
+ pWin->devPrivates = ppriv;
+ sizes = pScreen->WindowPrivateSizes;
+ ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+ for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+ }
+ return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ * Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ PixmapFormatRec *format;
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ return FALSE;
+
+ savedScreenInfo[pScreen->myNum].pWindow = NULL;
+ savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ screenIsSaved = SCREEN_SAVER_OFF;
+
+ pScreen->root = pWin;
+
+ pWin->drawable.pScreen = pScreen;
+ pWin->drawable.type = DRAWABLE_WINDOW;
+
+ pWin->drawable.depth = pScreen->rootDepth;
+ for (format = screenInfo.formats;
+ format->depth != pScreen->rootDepth;
+ format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->parent = NullWindow;
+ SetWindowToDefaults(pWin);
+
+ pWin->optional = (WindowOptRec *) malloc (sizeof (WindowOptRec));
+ if (!pWin->optional)
+ return FALSE;
+
+ pWin->optional->dontPropagateMask = 0;
+ pWin->optional->otherEventMasks = 0;
+ pWin->optional->otherClients = NULL;
+ pWin->optional->passiveGrabs = NULL;
+ pWin->optional->userProps = NULL;
+ pWin->optional->backingBitPlanes = ~0L;
+ pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+ pWin->optional->boundingShape = NULL;
+ pWin->optional->clipShape = NULL;
+ pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ pWin->optional->inputMasks = NULL;
+#endif
+ pWin->optional->colormap = pScreen->defColormap;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->nextSib = NullWindow;
+
+ pWin->drawable.id = FakeClientID(0);
+
+ pWin->origin.x = pWin->origin.y = 0;
+ pWin->drawable.height = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.x = pWin->drawable.y = 0;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ RegionInit(&pWin->clipList, &box, 1);
+ RegionInit(&pWin->winSize, &box, 1);
+ RegionInit(&pWin->borderSize, &box, 1);
+ RegionInit(&pWin->borderClip, &box, 1);
+
+ pWin->drawable.class = InputOutput;
+ pWin->optional->visual = pScreen->rootVisual;
+
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = pScreen->whitePixel;
+
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = pScreen->blackPixel;
+ pWin->borderWidth = 0;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *)pWin))
+ return FALSE;
+
+ if (disableBackingStore)
+ pScreen->backingStoreSupport = NotUseful;
+ if (enableBackingStore)
+ pScreen->backingStoreSupport = Always;
+
+#ifdef DO_SAVE_UNDERS
+ if ((pScreen->backingStoreSupport != NotUseful) &&
+ (pScreen->saveUnderSupport == NotUseful))
+ {
+ /*
+ * If the screen has backing-store but no save-unders, let the
+ * clients know we can support save-unders using backing-store.
+ */
+ pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+
+ return TRUE;
+}
+
+#ifndef NXAGENT_SERVER
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ MakeRootTile(pWin);
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+ MapWindow(pWin, serverClient);
+}
+#endif /* NXAGENT_SERVER */
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize. The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+ register int x, register int y,
+ register int w, register int h)
+{
+ BoxRec box;
+
+ box = *(RegionExtents(&pWin->winSize));
+ /* we do these calculations to avoid overflows */
+ if (x > box.x1)
+ box.x1 = x;
+ if (y > box.y1)
+ box.y1 = y;
+ x += w;
+ if (x < box.x2)
+ box.x2 = x;
+ y += h;
+ if (y < box.y2)
+ box.y2 = y;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ RegionReset(Rgn, &box);
+ RegionIntersect(Rgn, Rgn, &pWin->winSize);
+}
+
+static RealChildHeadProc realChildHeadProc = NULL;
+
+void
+RegisterRealChildHeadProc (RealChildHeadProc proc)
+{
+ realChildHeadProc = proc;
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+ if (realChildHeadProc) {
+ return realChildHeadProc (pWin);
+ }
+
+ if (!pWin->parent &&
+ (screenIsSaved == SCREEN_SAVER_ON) &&
+ (HasSaverWindow (pWin->drawable.pScreen->myNum)))
+ return (pWin->firstChild);
+ else
+ return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ * Makes a window in response to client request
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+ unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+ int depth, ClientPtr client, VisualID visual, int *error)
+{
+ register WindowPtr pWin;
+ WindowPtr pHead;
+ register ScreenPtr pScreen;
+ xEvent event;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ PixmapFormatRec *format;
+ register WindowOptPtr ancwopt;
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ *error = BadValue;
+ client->errorValue = class;
+ return NullWindow;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent) {
+ visual = ancwopt->visual;
+ }
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+ }
+
+ if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ if (((vmask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ *error = BadMatch;
+ return NullWindow;
+ }
+
+ pWin = AllocateWindow(pScreen);
+ if (!pWin)
+ {
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->drawable = pParent->drawable;
+ pWin->drawable.depth = depth;
+ if (depth == pParent->drawable.depth)
+ pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+ else
+ {
+ for (format = screenInfo.formats; format->depth != depth; format++)
+ ;
+ pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+ }
+ if (class == InputOnly)
+ pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pWin->drawable.id = wid;
+ pWin->drawable.class = class;
+
+ pWin->parent = pParent;
+ SetWindowToDefaults(pWin);
+
+ if (visual != ancwopt->visual)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ free (pWin);
+ *error = BadAlloc;
+ return NullWindow;
+ }
+ pWin->optional->visual = visual;
+ pWin->optional->colormap = None;
+ }
+
+ pWin->borderWidth = bw;
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows;
+ * they make it too easy to steal window contents
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0;
+ }
+ else
+#endif
+ pWin->backgroundState = None;
+
+ pWin->borderIsPixel = pParent->borderIsPixel;
+ pWin->border = pParent->border;
+ if (pWin->borderIsPixel == FALSE)
+ pWin->border.pixmap->refcnt++;
+
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ pWin->drawable.width = w;
+ pWin->drawable.height = h;
+ pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ /* set up clip list correctly for unobscured WindowPtr */
+ RegionNull(&pWin->clipList);
+ RegionNull(&pWin->borderClip);
+ RegionNull(&pWin->winSize);
+ RegionNull(&pWin->borderSize);
+
+ pHead = RealChildHead(pParent);
+ if (pHead)
+ {
+ pWin->nextSib = pHead->nextSib;
+ if (pHead->nextSib)
+ pHead->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pHead->nextSib = pWin;
+ pWin->prevSib = pHead;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ if (!(*pScreen->CreateWindow)(pWin))
+ {
+ *error = BadAlloc;
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ if (!(vmask & CWEventMask))
+ RecalculateDeliverableEvents(pWin);
+
+ if (vmask)
+ *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+ else
+ *error = Success;
+
+ if (*error != Success)
+ {
+ DeleteWindow(pWin, None);
+ return NullWindow;
+ }
+ if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+ {
+ XID value = defaultBackingStore;
+ (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+ pWin->forcedBS = TRUE;
+ }
+
+ if (SubSend(pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = CreateNotify;
+ event.u.createNotify.window = wid;
+ event.u.createNotify.parent = pParent->drawable.id;
+ event.u.createNotify.x = x;
+ event.u.createNotify.y = y;
+ event.u.createNotify.width = w;
+ event.u.createNotify.height = h;
+ event.u.createNotify.borderWidth = bw;
+ event.u.createNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pParent, &event, 1, NullWindow);
+ }
+ return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DeleteWindowFromAnySaveSet(pWin);
+ DeleteWindowFromAnySelections(pWin);
+ DeleteWindowFromAnyEvents(pWin, TRUE);
+ RegionUninit(&pWin->clipList);
+ RegionUninit(&pWin->winSize);
+ RegionUninit(&pWin->borderClip);
+ RegionUninit(&pWin->borderSize);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ RegionDestroy(wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionDestroy(wClipShape (pWin));
+ if (wInputShape (pWin))
+ RegionDestroy(wInputShape (pWin));
+#endif
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+ DeleteAllWindowProperties(pWin);
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->DestroyWindow)(pWin);
+ DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+ register WindowPtr pChild, pSib, pParent;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ xEvent event;
+
+ if (!(pChild = pWin->firstChild))
+ return;
+ UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+ while (1)
+ {
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (1)
+ {
+ pParent = pChild->parent;
+ if (SubStrSend(pChild, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pChild->drawable.id;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ FreeResource(pChild->drawable.id, RT_WINDOW);
+ pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder && pChild->viewable)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ (*UnrealizeWindow)(pChild);
+ }
+ FreeWindowResources(pChild);
+ free(pChild);
+ if ( (pChild = pSib) )
+ break;
+ pChild = pParent;
+ pChild->firstChild = NullWindow;
+ pChild->lastChild = NullWindow;
+ if (pChild == pWin)
+ return;
+ }
+ }
+}
+
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+#ifndef NXAGENT_SERVER
+int
+DeleteWindow(void * value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+ free(pWin);
+ return Success;
+}
+#endif /* NXAGENT_SERVER */
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+ /* XXX
+ * The protocol is quite clear that each window should be
+ * destroyed in turn, however, unmapping all of the first
+ * eliminates most of the calls to ValidateTree. So,
+ * this implementation is incorrect in that all of the
+ * UnmapNotifies occur before all of the DestroyNotifies.
+ * If you care, simply delete the call to UnmapSubwindows.
+ */
+ UnmapSubwindows(pWin);
+ while (pWin->lastChild)
+ FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+ ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ * ChangeWindowAttributes
+ *
+ * The value-mask specifies which attributes are to be changed; the
+ * value-list contains one value for each one bit in the mask, from least
+ * to most significant bit in the mask.
+ *****/
+
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+ register Mask index2;
+ register XID *pVlist;
+ PixmapPtr pPixmap;
+ Pixmap pixID;
+ CursorPtr pCursor, pOldCursor;
+ Cursor cursorID;
+ WindowPtr pChild;
+ Colormap cmap;
+ ColormapPtr pCmap;
+ xEvent xE;
+ int result;
+ register ScreenPtr pScreen;
+ Mask vmaskCopy = 0;
+ register Mask tmask;
+ unsigned int val;
+ int error;
+ Bool checkOptional = FALSE;
+ Bool borderRelative = FALSE;
+ WindowPtr pLayerWin;
+
+ if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+ return BadMatch;
+
+ error = Success;
+ pScreen = pWin->drawable.pScreen;
+ pVlist = vlist;
+ tmask = vmask;
+ while (tmask)
+ {
+ index2 = (Mask) lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ pVlist++;
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pixID == None)
+ {
+#ifdef XCSECURITY
+ /* can't let untrusted clients have background None windows */
+ if (client->trustLevel == XSecurityClientTrusted)
+ {
+#endif
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = None;
+#ifdef XCSECURITY
+ }
+ else
+ { /* didn't change the background to None, so don't tell ddx */
+ index2 = 0;
+ }
+#endif
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (pWin->parent &&
+ pWin->drawable.depth != pWin->parent->drawable.depth)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ if (!pWin->parent)
+ MakeRootTile(pWin);
+ else
+ pWin->backgroundState = ParentRelative;
+ borderRelative = TRUE;
+ /* Note that the parent's backgroundTile's refcnt is NOT
+ * incremented. */
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, DixReadAccess);
+ if (pPixmap != (PixmapPtr) NULL)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ if (pWin->backgroundState == ParentRelative)
+ borderRelative = TRUE;
+ if (pWin->backgroundState == BackgroundPixmap)
+ (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = (CARD32 ) *pVlist;
+ /* background pixel overrides background pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBackPixmap;
+ pVlist++;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ pVlist++;
+ if (pixID == CopyFromParent)
+ {
+ if (!pWin->parent ||
+ (pWin->drawable.depth != pWin->parent->drawable.depth))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->border = pWin->parent->border;
+ if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+ {
+ index2 = CWBorderPixel;
+ }
+ else
+ {
+ pWin->parent->border.pixmap->refcnt++;
+ }
+ }
+ else
+ {
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+ RT_PIXMAP, DixReadAccess);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != pWin->drawable.depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ else
+ {
+ error = BadPixmap;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ if (pWin->borderIsPixel == FALSE)
+ (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+ pWin->borderIsPixel = TRUE;
+ pWin->border.pixel = (CARD32) *pVlist;
+ /* border pixel overrides border pixmap,
+ so don't let the ddx layer see both bits */
+ vmaskCopy &= ~CWBorderPixmap;
+ pVlist++;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->bitGravity = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if (val > StaticGravity)
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->winGravity = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ pVlist++;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->backingStore = val;
+ pWin->forcedBS = FALSE;
+ break;
+ case CWBackingPlanes:
+ if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+ if ((CARD32)*pVlist == (CARD32)~0L)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWBackingPixel:
+ if (pWin->optional || (CARD32) *pVlist) {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ pWin->optional->backingPixel = (CARD32) *pVlist;
+ if (!*pVlist)
+ checkOptional = TRUE;
+ }
+ pVlist++;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+#ifdef DO_SAVE_UNDERS
+ if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+ DO_SAVE_UNDERS(pWin))
+ {
+ /*
+ * Re-check all siblings and inferiors for obscurity or
+ * exposition (hee hee).
+ */
+ if (pWin->saveUnder)
+ deltaSaveUndersViewable--;
+ else
+ deltaSaveUndersViewable++;
+ pWin->saveUnder = val;
+
+ if (pWin->firstChild)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+ if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+ pWin->nextSib);
+ }
+ else
+ {
+ if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+ (*pScreen->PostChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ }
+ }
+ else
+ {
+ /* If we're changing the saveUnder attribute of the root
+ * window, all we do is set pWin->saveUnder so that
+ * GetWindowAttributes returns the right value. We don't
+ * do the "normal" save-under processing (as above).
+ * Hope that doesn't cause any problems.
+ */
+ pWin->saveUnder = val;
+ }
+#else
+ pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+ break;
+ case CWEventMask:
+
+ /*
+ * TODO: Some applications like java bean shell
+ * don' t work if they cannot monitor the root
+ * window for Structure Redirect events. However
+ * this doesn't seem to be the best solution, since
+ * also an X server with a window manager running,
+ * doesn't allow to monitor for those events, but
+ * the java bean shell works flawlessy on this
+ * server.
+ *
+ * #ifdef NXAGENT_SERVER
+ * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+ * {
+ * return BadAccess;
+ * }
+ * #endif
+ */
+
+ result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWDontPropagate:
+ result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+ &checkOptional);
+ if (result)
+ {
+ error = result;
+ goto PatchUp;
+ }
+ pVlist++;
+ break;
+ case CWOverrideRedirect:
+ val = (BOOL ) *pVlist;
+ pVlist++;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ error = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ pWin->overrideRedirect = val;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ pVlist++;
+ if (cmap == CopyFromParent)
+ {
+ if (pWin->parent &&
+ (!pWin->optional ||
+ pWin->optional->visual == wVisual (pWin->parent)))
+ {
+ cmap = wColormap (pWin->parent);
+ }
+ else
+ cmap = None;
+ }
+ if (cmap == None)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+ RT_COLORMAP, DixReadAccess);
+ if (!pCmap)
+ {
+ error = BadColor;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != wVisual (pWin) ||
+ pCmap->pScreen != pScreen)
+ {
+ error = BadMatch;
+ goto PatchUp;
+ }
+ if (cmap != wColormap (pWin))
+ {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && cmap == wColormap (pWin->parent))
+ checkOptional = TRUE;
+
+ /*
+ * propagate the original colormap to any children
+ * inheriting it
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pWin->optional->colormap = cmap;
+
+ /*
+ * check on any children now matching the new colormap
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional->colormap == cmap)
+ CheckWindowOptionalNeed (pChild);
+ }
+
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pWin->drawable.id;
+ xE.u.colormap.colormap = cmap;
+ xE.u.colormap.new = xTrue;
+ xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+ DeliverEvents(pWin, &xE, 1, NullWindow);
+ }
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ pVlist++;
+ /*
+ * install the new
+ */
+ if ( cursorID == None)
+ {
+ if (pWin == pWin->drawable.pScreen->root)
+ pCursor = rootCursor;
+ else
+ pCursor = (CursorPtr) None;
+ }
+ else
+ {
+ pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+ RT_CURSOR, DixReadAccess);
+ if (!pCursor)
+ {
+ error = BadCursor;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ }
+
+ if (pCursor != wCursor (pWin))
+ {
+ /*
+ * patch up child windows so they don't lose cursors.
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (!pChild->optional && !pChild->cursorIsNone &&
+ !MakeWindowOptional (pChild))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+
+ pOldCursor = 0;
+ if (pCursor == (CursorPtr) None)
+ {
+ pWin->cursorIsNone = TRUE;
+ if (pWin->optional)
+ {
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = (CursorPtr) None;
+ checkOptional = TRUE;
+ }
+ } else {
+ if (!pWin->optional)
+ {
+ if (!MakeWindowOptional (pWin))
+ {
+ error = BadAlloc;
+ goto PatchUp;
+ }
+ }
+ else if (pWin->parent && pCursor == wCursor (pWin->parent))
+ checkOptional = TRUE;
+ pOldCursor = pWin->optional->cursor;
+ pWin->optional->cursor = pCursor;
+ pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ /*
+ * check on any children now matching the new cursor
+ */
+
+ for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+ {
+ if (pChild->optional &&
+ (pChild->optional->cursor == pCursor))
+ CheckWindowOptionalNeed (pChild);
+ }
+ }
+
+ if (pWin->realized)
+ WindowHasNewCursor( pWin);
+
+ /* Can't free cursor until here - old cursor
+ * is needed in WindowHasNewCursor
+ */
+ if (pOldCursor)
+ FreeCursor (pOldCursor, (Cursor)0);
+ }
+ break;
+ default:
+ error = BadValue;
+ client->errorValue = vmask;
+ goto PatchUp;
+ }
+ vmaskCopy |= index2;
+ }
+PatchUp:
+ if (checkOptional)
+ CheckWindowOptionalNeed (pWin);
+
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+ /*
+ If the border contents have changed, redraw the border.
+ Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+ for the tile to be rotated, and the correct function selected.
+ */
+ if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+ && pWin->viewable && HasBorder (pWin))
+ {
+ RegionRec exposed;
+
+ RegionNull(&exposed);
+ RegionSubtract(&exposed, &pWin->borderClip, &pWin->winSize);
+ (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+ RegionUninit(&exposed);
+ }
+ return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ * Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+ wa->type = X_Reply;
+ wa->bitGravity = pWin->bitGravity;
+ wa->winGravity = pWin->winGravity;
+ if (pWin->forcedBS && pWin->backingStore != Always)
+ wa->backingStore = NotUseful;
+ else
+ wa->backingStore = pWin->backingStore;
+ wa->length = (sizeof(xGetWindowAttributesReply) -
+ sizeof(xGenericReply)) >> 2;
+ wa->sequenceNumber = client->sequence;
+ wa->backingBitPlanes = wBackingBitPlanes (pWin);
+ wa->backingPixel = wBackingPixel (pWin);
+ wa->saveUnder = (BOOL)pWin->saveUnder;
+ wa->override = pWin->overrideRedirect;
+ if (!pWin->mapped)
+ wa->mapState = IsUnmapped;
+ else if (pWin->realized)
+ wa->mapState = IsViewable;
+ else
+ wa->mapState = IsUnviewable;
+
+ wa->colormap = wColormap (pWin);
+ wa->mapInstalled = (wa->colormap == None) ? xFalse
+ : IsMapInstalled(wa->colormap, pWin);
+
+ wa->yourEventMask = EventMaskForClient(pWin, client);
+ wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+ wa->doNotPropagateMask = wDontPropagateMask (pWin);
+ wa->class = pWin->drawable.class;
+ wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+ register WindowPtr pParent = pWin->parent;
+ WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+ if (pWin->nextSib != pNextSib)
+ {
+ WindowPtr pOldNextSib = pWin->nextSib;
+
+ if (!pNextSib) /* move to bottom */
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ /* if (pWin->nextSib) */ /* is always True: pNextSib == NULL
+ * and pWin->nextSib != pNextSib
+ * therefore pWin->nextSib != NULL */
+ pFirstChange = pWin->nextSib;
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pParent->lastChild->nextSib = pWin;
+ pWin->prevSib = pParent->lastChild;
+ pWin->nextSib = NullWindow;
+ pParent->lastChild = pWin;
+ }
+ else if (pParent->firstChild == pNextSib) /* move to top */
+ {
+ pFirstChange = pWin;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = (WindowPtr ) NULL;
+ pNextSib->prevSib = pWin;
+ pParent->firstChild = pWin;
+ }
+ else /* move in middle of list */
+ {
+ WindowPtr pOldNext = pWin->nextSib;
+
+ pFirstChange = NullWindow;
+ if (pParent->firstChild == pWin)
+ pFirstChange = pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin) {
+ pFirstChange = pWin;
+ pParent->lastChild = pWin->prevSib;
+ }
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ pWin->nextSib = pNextSib;
+ pWin->prevSib = pNextSib->prevSib;
+ if (pNextSib->prevSib)
+ pNextSib->prevSib->nextSib = pWin;
+ pNextSib->prevSib = pWin;
+ if (!pFirstChange) { /* do we know it yet? */
+ pFirstChange = pParent->firstChild; /* no, search from top */
+ while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+ pFirstChange = pFirstChange->nextSib;
+ }
+ }
+ if(pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+ }
+
+#ifdef ROOTLESS
+ /*
+ * In rootless mode we can't optimize away window restacks.
+ * There may be non-X windows around, so even if the window
+ * is in the correct position from X's point of view,
+ * the underlying window system may want to reorder it.
+ */
+ else if (pWin->drawable.pScreen->RestackWindow)
+ (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+ return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+ RegionPtr pRgn;
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ pRgn = RegionCreate(&box, 1);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ RegionTranslate(pRgn, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ RegionIntersect(pRgn, pRgn, wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionIntersect(pRgn, pRgn, wClipShape (pWin));
+ RegionTranslate(pRgn, pWin->drawable.x, pWin->drawable.y);
+ }
+#endif
+ return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x;
+ box.y1 = pWin->drawable.y;
+ box.x2 = pWin->drawable.x + pWin->drawable.width;
+ box.y2 = pWin->drawable.y + pWin->drawable.height;
+ RegionReset(&pWin->winSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+ pWin->drawable.x, pWin->drawable.y,
+ (int)pWin->drawable.width,
+ (int)pWin->drawable.height);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ RegionTranslate(&pWin->winSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ if (wBoundingShape (pWin))
+ RegionIntersect(&pWin->winSize, &pWin->winSize,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionIntersect(&pWin->winSize, &pWin->winSize,
+ wClipShape (pWin));
+ RegionTranslate(&pWin->winSize, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+ int bw;
+
+ if (HasBorder (pWin)) {
+ bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+ if (pWin->redirectDraw)
+ {
+ BoxRec box;
+
+ box.x1 = pWin->drawable.x - bw;
+ box.y1 = pWin->drawable.y - bw;
+ box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+ box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+ RegionReset(&pWin->borderSize, &box);
+ }
+ else
+#endif
+ ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+ pWin->drawable.x - bw, pWin->drawable.y - bw,
+ (int)(pWin->drawable.width + (bw<<1)),
+ (int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+ if (wBoundingShape (pWin)) {
+ RegionTranslate(&pWin->borderSize, - pWin->drawable.x,
+ - pWin->drawable.y);
+ RegionIntersect(&pWin->borderSize, &pWin->borderSize,
+ wBoundingShape (pWin));
+ RegionTranslate(&pWin->borderSize, pWin->drawable.x,
+ pWin->drawable.y);
+ RegionUnion(&pWin->borderSize, &pWin->borderSize,
+ &pWin->winSize);
+ }
+#endif
+ } else {
+ RegionCopy(&pWin->borderSize,
+ &pWin->winSize);
+ }
+}
+
+/**
+ *
+ * \param x,y new window position
+ * \param oldx,oldy old window position
+ * \param destx,desty position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+ int dw, int dh, unsigned gravity,
+ register int *destx, register int *desty)
+{
+ switch (gravity) {
+ case NorthGravity:
+ *destx = x + dw / 2;
+ *desty = y;
+ break;
+ case NorthEastGravity:
+ *destx = x + dw;
+ *desty = y;
+ break;
+ case WestGravity:
+ *destx = x;
+ *desty = y + dh / 2;
+ break;
+ case CenterGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh / 2;
+ break;
+ case EastGravity:
+ *destx = x + dw;
+ *desty = y + dh / 2;
+ break;
+ case SouthWestGravity:
+ *destx = x;
+ *desty = y + dh;
+ break;
+ case SouthGravity:
+ *destx = x + dw / 2;
+ *desty = y + dh;
+ break;
+ case SouthEastGravity:
+ *destx = x + dw;
+ *desty = y + dh;
+ break;
+ case StaticGravity:
+ *destx = oldx;
+ *desty = oldy;
+ break;
+ default:
+ *destx = x;
+ *desty = y;
+ break;
+ }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+#ifndef NXAGENT_SERVER
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+ (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+ (*pScreen->PositionWindow)(pChild,
+ pChild->drawable.x, pChild->drawable.y);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+#endif /* NXAGENT_SERVER */
+
+#define GET_INT16(m, f) \
+ if (m & mask) \
+ { \
+ f = (INT16) *pVlist;\
+ pVlist++; \
+ }
+#define GET_CARD16(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD16) *pVlist;\
+ pVlist++;\
+ }
+
+#define GET_CARD8(m, f) \
+ if (m & mask) \
+ { \
+ f = (CARD8) *pVlist;\
+ pVlist++;\
+ }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ * returns Above if pSib above pMe in stack or Below otherwise
+ */
+
+static int
+IsSiblingAboveMe(
+ register WindowPtr pMe,
+ register WindowPtr pSib)
+{
+ register WindowPtr pWin;
+
+ pWin = pMe->parent->firstChild;
+ while (pWin)
+ {
+ if (pWin == pSib)
+ return(Above);
+ else if (pWin == pMe)
+ return(Below);
+ pWin = pWin->nextSib;
+ }
+ return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+ register WindowPtr pWin,
+ register BoxPtr pBox)
+{
+ pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+ pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+ pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+ + wBorderWidth (pWin);
+ pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+ + wBorderWidth (pWin);
+ return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin) (wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+ register WindowPtr pWin,
+ BoxPtr pBox)
+{
+ RegionPtr pRgn;
+
+ pRgn = RegionCreate(pBox, 1);
+ if (wBoundingShape (pWin)) {
+ RegionTranslate(pRgn, -pWin->origin.x,
+ -pWin->origin.y);
+ RegionIntersect(pRgn, pRgn, wBoundingShape (pWin));
+ RegionTranslate(pRgn, pWin->origin.x,
+ pWin->origin.y);
+ }
+ return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+ WindowPtr pWin,
+ BoxPtr pWinBox,
+ WindowPtr pSib,
+ BoxPtr pSibBox)
+{
+ RegionPtr pWinRgn, pSibRgn;
+ Bool ret;
+
+ if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+ return TRUE;
+ pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+ pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+ RegionIntersect(pWinRgn, pWinRgn, pSibRgn);
+ ret = RegionNotEmpty(pWinRgn);
+ RegionDestroy(pWinRgn);
+ RegionDestroy(pSibRgn);
+ return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+ WindowPtr pWin,
+ WindowPtr pHead,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+ WindowPtr pWin,
+ register BoxPtr box)
+{
+ register WindowPtr pSib;
+ BoxRec sboxrec;
+ register BoxPtr sbox;
+
+ for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+ {
+ if (pSib->mapped)
+ {
+ sbox = WindowExtents(pSib, &sboxrec);
+ if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+ && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+ )
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+}
+
+/*
+ * WhereDoIGoInTheStack()
+ * Given pWin and pSib and the relationshipe smode, return
+ * the window that pWin should go ABOVE.
+ * If a pSib is specified:
+ * Above: pWin is placed just above pSib
+ * Below: pWin is placed just below pSib
+ * TopIf: if pSib occludes pWin, then pWin is placed
+ * at the top of the stack
+ * BottomIf: if pWin occludes pSib, then pWin is
+ * placed at the bottom of the stack
+ * Opposite: if pSib occludes pWin, then pWin is placed at the
+ * top of the stack, else if pWin occludes pSib, then
+ * pWin is placed at the bottom of the stack
+ *
+ * If pSib is NULL:
+ * Above: pWin is placed at the top of the stack
+ * Below: pWin is placed at the bottom of the stack
+ * TopIf: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack
+ * BottomIf: if pWin occludes any sibline, then pWin is placed at
+ * the bottom of the stack
+ * Opposite: if any sibling occludes pWin, then pWin is placed at
+ * the top of the stack, else if pWin occludes any
+ * sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ short x,
+ short y,
+ unsigned short w,
+ unsigned short h,
+ int smode)
+{
+ BoxRec box;
+ WindowPtr pHead, pFirst;
+
+ if ((pWin == pWin->parent->firstChild) &&
+ (pWin == pWin->parent->lastChild))
+ return((WindowPtr ) NULL);
+ pHead = RealChildHead(pWin->parent);
+ pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + (int)w;
+ box.y2 = y + (int)h;
+ switch (smode)
+ {
+ case Above:
+ if (pSib)
+ return(pSib);
+ else if (pWin == pFirst)
+ return(pWin->nextSib);
+ else
+ return(pFirst);
+ case Below:
+ if (pSib)
+ if (pSib->nextSib != pWin)
+ return(pSib->nextSib);
+ else
+ return(pWin->nextSib);
+ else
+ return NullWindow;
+ case TopIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+ (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ return(pFirst);
+ else
+ return(pWin->nextSib);
+ case BottomIf:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+ (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return(pWin->nextSib);
+ case Opposite:
+ if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+ return(pWin->nextSib);
+ else if (pSib)
+ {
+ if (RegionContainsRect(&pSib->borderSize, &box) != rgnOUT)
+ {
+ if (IsSiblingAboveMe(pWin, pSib) == Above)
+ return(pFirst);
+ else
+ return NullWindow;
+ }
+ else
+ return(pWin->nextSib);
+ }
+ else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+ {
+ /* If I'm occluded, I can't possibly be the first child
+ * if (pWin == pWin->parent->firstChild)
+ * return pWin->nextSib;
+ */
+ return(pFirst);
+ }
+ else if (IOverlapAnyWindow(pWin, &box))
+ return NullWindow;
+ else
+ return pWin->nextSib;
+ default:
+ {
+ ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+ return pWin->nextSib;
+ }
+ }
+}
+
+static void
+ReflectStackChange(
+ register WindowPtr pWin,
+ register WindowPtr pSib,
+ VTKind kind)
+{
+/* Note that pSib might be NULL */
+
+ Bool WasViewable = (Bool)pWin->viewable;
+ Bool anyMarked;
+ WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* if this is a root window, can't be restacked */
+ if (!pWin->parent)
+ return;
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ &pLayerWin);
+ if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+#ifndef NXAGENT_SERVER
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, DixReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+ ))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ memset(&eventT, 0, sizeof(xEvent));
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+#endif /* NXAGENT_SERVER */
+
+
+/******
+ *
+ * CirculateWindow
+ * For RaiseLowest, raises the lowest mapped child (if any) that is
+ * obscured by another child to the top of the stack. For LowerHighest,
+ * lowers the highest mapped child (if any) that is obscuring another
+ * child to the bottom of the stack. Exposure processing is performed
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+ register WindowPtr pWin, pHead, pFirst;
+ xEvent event;
+ BoxRec box;
+
+ /*
+ * #ifdef NXAGENT_SERVER
+ * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+ * nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+ * {
+ * nxagentCirculateRootlessWindows(direction);
+ * return Success;
+ * }
+ * #endif
+ */
+
+ pHead = RealChildHead(pParent);
+ pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+ if (direction == RaiseLowest)
+ {
+ for (pWin = pParent->lastChild;
+ (pWin != pHead) &&
+ !(pWin->mapped &&
+ AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+ pWin = pWin->prevSib) ;
+ if (pWin == pHead)
+ return Success;
+ }
+ else
+ {
+ for (pWin = pFirst;
+ pWin &&
+ !(pWin->mapped &&
+ IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+ pWin = pWin->nextSib) ;
+ if (!pWin)
+ return Success;
+ }
+
+ event.u.circulate.window = pWin->drawable.id;
+ event.u.circulate.parent = pParent->drawable.id;
+ event.u.circulate.event = pParent->drawable.id;
+ if (direction == RaiseLowest)
+ event.u.circulate.place = PlaceOnTop;
+ else
+ event.u.circulate.place = PlaceOnBottom;
+
+ if (RedirectSend(pParent))
+ {
+ event.u.u.type = CirculateRequest;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ event.u.u.type = CirculateNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ ReflectStackChange(pWin,
+ (direction == RaiseLowest) ? pFirst : NullWindow,
+ VTStack);
+
+ return(Success);
+}
+
+static int
+CompareWIDs(
+ WindowPtr pWin,
+ void * value) /* must conform to VisitWindowProcPtr */
+{
+ Window *wid = (Window *)value;
+
+ if (pWin->drawable.id == *wid)
+ return(WT_STOPWALKING);
+ else
+ return(WT_WALKCHILDREN);
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+#ifndef NXAGENT_SERVER
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (void *)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+#endif /* NXAGENT_SERVER */
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+ register WindowPtr pChild;
+ RealizeWindowProcPtr Realize;
+
+ Realize = pWin->drawable.pScreen->RealizeWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->mapped)
+ {
+ pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable++;
+#endif
+ pChild->viewable = (pChild->drawable.class == InputOutput);
+ (* Realize)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+#ifndef NXAGENT_SERVER
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XCSECURITY
+ /* don't let an untrusted client map a child-of-trusted-window, InputOnly
+ * window; too easy to steal device input
+ */
+ if ( (client->trustLevel != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+ ))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ RegionNull(&temp);
+ RegionCopy(&temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ RegionUninit(&temp);
+ }
+
+ return(Success);
+}
+#endif /* NXAGENT_SERVER */
+
+/*****
+ * MapSubwindows
+ * Performs a MapWindow all unmapped children of the window, in top
+ * to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+ register WindowPtr pWin;
+ WindowPtr pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+ WindowPtr pFirstSaveUndered = NullWindow;
+#endif
+ register ScreenPtr pScreen;
+ register Mask parentRedirect;
+ register Mask parentNotify;
+ xEvent event;
+ Bool anyMarked;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ pScreen = pParent->drawable.pScreen;
+ parentRedirect = RedirectSend(pParent);
+ parentNotify = SubSend(pParent);
+ anyMarked = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (!pWin->mapped)
+ {
+ if (parentRedirect && !pWin->overrideRedirect)
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ continue;
+ }
+
+ pWin->mapped = TRUE;
+ if (parentNotify || StrSend(pWin))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pFirstMapped)
+ pFirstMapped = pWin;
+ if (pParent->realized)
+ {
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = TRUE;
+ }
+#endif /* DO_SAVE_UNDERS */
+ }
+ }
+ }
+ }
+
+ if (pFirstMapped)
+ {
+ pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+ if (pLayerWin->parent != pParent) {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+ pLayerWin,
+ (WindowPtr *)NULL);
+ pFirstMapped = pLayerWin;
+ }
+ if (anyMarked)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pLayerWin->parent != pParent)
+ {
+ if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+ pLayerWin);
+ }
+ }
+ else if (dosave)
+ {
+ dosave = FALSE;
+ for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+ {
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+ pWin->nextSib);
+ if (dosave && !pFirstSaveUndered)
+ pFirstSaveUndered = pWin;
+ }
+ }
+ }
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin,
+ pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+ VTMap);
+ WindowsRestructured ();
+ }
+}
+
+static void
+UnrealizeTree(
+ WindowPtr pWin,
+ Bool fromConfigure)
+{
+ register WindowPtr pChild;
+ UnrealizeWindowProcPtr Unrealize;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+ MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->realized)
+ {
+ pChild->realized = FALSE;
+ pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+ PanoramiXRes *win;
+ win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+ XRT_WINDOW);
+ if(win)
+ win->u.win.visibility = VisibilityNotViewable;
+ }
+#endif
+ (* Unrealize)(pChild);
+ DeleteWindowFromAnyEvents(pChild, FALSE);
+ if (pChild->viewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ if (pChild->saveUnder)
+ deltaSaveUndersViewable--;
+#endif
+ pChild->viewable = FALSE;
+ if (pChild->backStorage)
+ (*pChild->drawable.pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ (* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ return;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+#ifndef NXAGENT_SERVER
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+#endif /* NXAGENT_SERVER */
+
+/*****
+ * UnmapSubwindows
+ * Performs an UnmapWindow request with the specified mode on all mapped
+ * children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+ register WindowPtr pChild, pHead;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ Bool anyMarked = FALSE;
+ Mask parentNotify;
+ WindowPtr pLayerWin = NULL;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (!pWin->firstChild)
+ return;
+ parentNotify = SubSend(pWin);
+ pHead = RealChildHead(pWin);
+
+ if (wasViewable)
+ pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (pChild->mapped)
+ {
+ if (parentNotify || StrSend(pChild))
+ {
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pChild->drawable.id;
+ event.u.unmapNotify.fromConfigure = xFalse;
+ DeliverEvents(pChild, &event, 1, NullWindow);
+ }
+ if (pChild->viewable)
+ {
+ pChild->valdata = UnmapValData;
+ anyMarked = TRUE;
+ }
+ pChild->mapped = FALSE;
+ if (pChild->realized)
+ UnrealizeTree(pChild, FALSE);
+ if (wasViewable)
+ {
+#ifdef DO_SAVE_UNDERS
+ pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (pChild->backStorage)
+ (*pScreen->SaveDoomedAreas)(
+ pChild, &pChild->clipList, 0, 0);
+ }
+ }
+ }
+ if (wasViewable)
+ {
+ if (anyMarked)
+ {
+ if (pLayerWin->parent == pWin)
+ (*pScreen->MarkWindow)(pWin);
+ else
+ {
+ WindowPtr ptmp;
+ (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+
+ /* Windows between pWin and pLayerWin may not have been marked */
+ ptmp = pWin;
+
+ while (ptmp != pLayerWin->parent)
+ {
+ (*pScreen->MarkWindow)(ptmp);
+ ptmp = ptmp->parent;
+ }
+ pHead = pWin->firstChild;
+ }
+ (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+ }
+ if (wasRealized)
+ WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ register int j;
+
+ for (j=0; j<client->numSaved; j++)
+ {
+ pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+ if (SaveSetToRoot(client->saveSet[j]))
+ pParent = pWin->drawable.pScreen->root;
+ else
+#endif
+ {
+ pParent = pWin->parent;
+ while (pParent && (wClient (pParent) == client))
+ pParent = pParent->parent;
+ }
+ if (pParent)
+ {
+ if (pParent != pWin->parent)
+ {
+ ReparentWindow(pWin, pParent,
+ pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+ pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+ client);
+ if(!pWin->realized && pWin->mapped)
+ pWin->mapped = FALSE;
+ }
+#ifdef XFIXES
+ if (SaveSetRemap (client->saveSet[j]))
+#endif
+ MapWindow(pWin, client);
+ }
+ }
+ free(client->saveSet);
+ client->numSaved = 0;
+ client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ * \param x,y in root
+ * \param box "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+ if (!pWin->realized)
+ return (FALSE);
+ if (RegionContainsPoint(&pWin->clipList, x, y, box))
+ return(TRUE);
+ return(FALSE);
+}
+
+/**
+ *
+ * \param x,y in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+
+ if (!pWin->realized)
+ return (FALSE);
+ if (RegionContainsPoint(&pWin->borderClip,
+ x, y, &box)
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return(TRUE);
+ return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+ RegionPtr pReg;
+
+ pReg = RegionCreate(NullBox, 1);
+ if (pWin->parent ||
+ screenIsSaved != SCREEN_SAVER_ON ||
+ !HasSaverWindow (pWin->drawable.pScreen->myNum))
+ {
+ RegionIntersect(pReg, &pWin->borderClip, &pWin->winSize);
+ }
+ return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+ xEvent event;
+#ifndef NO_XINERAMA_PORT
+ unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+ /* This is not quite correct yet, but it's close */
+ if(!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ WindowPtr pWin2;
+ int i, Scrnum;
+
+ Scrnum = pWin->drawable.pScreen->myNum;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+ if(!win || (win->u.win.visibility == visibility))
+ return;
+
+ switch(visibility) {
+ case VisibilityUnobscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility == VisibilityPartiallyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ case VisibilityPartiallyObscured:
+ if(Scrnum) {
+ pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+ if (pWin2) pWin = pWin2;
+ }
+ break;
+ case VisibilityFullyObscured:
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ if(i == Scrnum) continue;
+
+ pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+ if (pWin2) {
+ if(pWin2->visibility != VisibilityFullyObscured)
+ return;
+
+ if(!i) pWin = pWin2;
+ }
+ }
+ break;
+ }
+
+ win->u.win.visibility = visibility;
+ }
+#endif
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = VisibilityNotify;
+ event.u.visibility.window = pWin->drawable.id;
+ event.u.visibility.state = visibility;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+ WindowPtr pWin
+);
+#endif
+
+#ifndef NXAGENT_SERVER
+void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
+#endif /* NXAGENT_SERVER */
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+ int j;
+ int result;
+ XID attributes[3];
+ Mask mask;
+ WindowPtr pWin;
+ CursorMetricRec cm;
+ unsigned char *srcbits, *mskbits;
+ CursorPtr cursor;
+ XID cursorID = 0;
+ int attri;
+
+ mask = 0;
+ attri = 0;
+ switch (kind) {
+ case SCREEN_IS_TILED:
+ switch (screenInfo.screens[i]->root->backgroundState) {
+ case BackgroundPixel:
+ attributes[attri++] = screenInfo.screens[i]->root->background.pixel;
+ mask |= CWBackPixel;
+ break;
+ case BackgroundPixmap:
+ attributes[attri++] = None;
+ mask |= CWBackPixmap;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SCREEN_IS_BLACK:
+ attributes[attri++] = screenInfo.screens[i]->root->drawable.pScreen->blackPixel;
+ mask |= CWBackPixel;
+ break;
+ }
+ mask |= CWOverrideRedirect;
+ attributes[attri++] = xTrue;
+
+ /*
+ * create a blank cursor
+ */
+
+ cm.width=16;
+ cm.height=16;
+ cm.xhot=8;
+ cm.yhot=8;
+ srcbits = (unsigned char *)malloc( BitmapBytePad(32)*16);
+ mskbits = (unsigned char *)malloc( BitmapBytePad(32)*16);
+ if (!srcbits || !mskbits)
+ {
+ free(srcbits);
+ free(mskbits);
+ cursor = 0;
+ }
+ else
+ {
+ for (j=0; j<BitmapBytePad(32)*16; j++)
+ srcbits[j] = mskbits[j] = 0x0;
+ cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+ if (cursor)
+ {
+ cursorID = FakeClientID(0);
+ if (AddResource (cursorID, RT_CURSOR, (void *) cursor))
+ {
+ attributes[attri] = cursorID;
+ mask |= CWCursor;
+ }
+ else
+ cursor = 0;
+ }
+ else
+ {
+ free (srcbits);
+ free (mskbits);
+ }
+ }
+
+ pWin = savedScreenInfo[i].pWindow =
+ CreateWindow(savedScreenInfo[i].wid,
+ screenInfo.screens[i]->root,
+ -RANDOM_WIDTH, -RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+ (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+ 0, InputOutput, mask, attributes, 0, serverClient,
+ wVisual (screenInfo.screens[i]->root), &result);
+
+ if (cursor)
+ FreeResource (cursorID, RT_NONE);
+
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW,
+ (void *)savedScreenInfo[i].pWindow))
+ return FALSE;
+
+ if (mask & CWBackPixmap)
+ {
+ MakeRootTile (pWin);
+ (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+ }
+ MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+ if (kind == SCREEN_IS_TILED && logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure. Assumptions: some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+ do
+ w = w->parent;
+ while (!w->optional);
+ return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules. If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (!w->parent)
+ return;
+ optional = w->optional;
+ if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+ return;
+ if (optional->otherEventMasks != 0)
+ return;
+ if (optional->otherClients != NULL)
+ return;
+ if (optional->passiveGrabs != NULL)
+ return;
+ if (optional->userProps != NULL)
+ return;
+ if (optional->backingBitPlanes != ~0L)
+ return;
+ if (optional->backingPixel != 0)
+ return;
+#ifdef SHAPE
+ if (optional->boundingShape != NULL)
+ return;
+ if (optional->clipShape != NULL)
+ return;
+ if (optional->inputShape != NULL)
+ return;
+#endif
+#ifdef XINPUT
+ if (optional->inputMasks != NULL)
+ return;
+#endif
+ parentOptional = FindWindowWithOptional(w)->optional;
+ if (optional->visual != parentOptional->visual)
+ return;
+ if (optional->cursor != None &&
+ (optional->cursor != parentOptional->cursor ||
+ w->parent->cursorIsNone))
+ return;
+ if (optional->colormap != parentOptional->colormap)
+ return;
+ DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+ register WindowOptPtr optional;
+ register WindowOptPtr parentOptional;
+
+ if (pWin->optional)
+ return TRUE;
+ optional = (WindowOptPtr) malloc (sizeof (WindowOptRec));
+ if (!optional)
+ return FALSE;
+ optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+ optional->otherEventMasks = 0;
+ optional->otherClients = NULL;
+ optional->passiveGrabs = NULL;
+ optional->userProps = NULL;
+ optional->backingBitPlanes = ~0L;
+ optional->backingPixel = 0;
+#ifdef SHAPE
+ optional->boundingShape = NULL;
+ optional->clipShape = NULL;
+ optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+ optional->inputMasks = NULL;
+#endif
+ parentOptional = FindWindowWithOptional(pWin)->optional;
+ optional->visual = parentOptional->visual;
+ if (!pWin->cursorIsNone)
+ {
+ optional->cursor = parentOptional->cursor;
+ optional->cursor->refcnt++;
+ }
+ else
+ {
+ optional->cursor = None;
+ }
+ optional->colormap = parentOptional->colormap;
+ pWin->optional = optional;
+ return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+ if (!pWin->optional)
+ return;
+ /*
+ * everything is peachy. Delete the optional record
+ * and clean up
+ */
+ /*
+ * TOG changed this code to:
+ *
+ * if (pWin->cursorIsNone == FALSE)
+ * FreeCursor (pWin->optional->cursor, (Cursor)0);
+ * pWin->cursorIsNone = TRUE;
+ *
+ * This is blatently wrong; windows without optionals can have
+ * two different cursor values, either None or sharing their
+ * parents cursor. This difference is controlled by the
+ * cursorIsNone value; when TRUE, the window has no cursor,
+ * when false, it shares its cursor with its parent; TOG
+ * made it impossible for a window to have a cursor without
+ * an optional record.
+ */
+ if (pWin->optional->cursor)
+ {
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->cursorIsNone = FALSE;
+ }
+ else
+ pWin->cursorIsNone = TRUE;
+ free (pWin->optional);
+ pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned int width, height, size;
+ GC *pGC;
+ int thin, gap, d31;
+ DDXPointRec poly[4];
+ ChangeGCVal fore[2], back[2];
+ xrgb rgb[2];
+ BITS32 fmask, bmask;
+ ColormapPtr cmap;
+
+ pDraw = (DrawablePtr)pWin;
+ pScreen = pDraw->pScreen;
+ x = -pWin->origin.x;
+ y = -pWin->origin.y;
+ width = pScreen->width;
+ height = pScreen->height;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pGC)
+ return;
+
+ if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ if ((pWin->backgroundState == BackgroundPixel) &&
+ (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+ Pixel querypixels[2];
+
+ querypixels[0] = fore[0].val;
+ querypixels[1] = pWin->background.pixel;
+ QueryColors(cmap, 2, querypixels, rgb);
+ if ((rgb[0].red == rgb[1].red) &&
+ (rgb[0].green == rgb[1].green) &&
+ (rgb[0].blue == rgb[1].blue)) {
+ if (fore[0].val == pScreen->blackPixel)
+ fore[0].val = pScreen->whitePixel;
+ else
+ fore[0].val = pScreen->blackPixel;
+ }
+ }
+ fore[1].val = FillSolid;
+ fmask = GCForeground|GCFillStyle;
+ if (pWin->backgroundState == BackgroundPixel) {
+ back[0].val = pWin->background.pixel;
+ back[1].val = FillSolid;
+ bmask = GCForeground|GCFillStyle;
+ } else {
+ back[0].val = 0;
+ back[1].val = 0;
+ dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+ NULL, back);
+ back[0].val = FillTiled;
+ back[1].ptr = pWin->background.pixmap;
+ bmask = GCFillStyle|GCTile;
+ }
+
+ /* should be the same as the reference function XmuDrawLogo() */
+
+ size = width;
+ if (height < width)
+ size = height;
+ size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+ size &= ~1;
+ x += rand() % (width - size);
+ y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ * -----
+ * / /
+ * / /
+ * / /
+ * / /
+ * /____/
+ * d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+ thin = (size / 11);
+ if (thin < 1) thin = 1;
+ gap = (thin+3) / 4;
+ d31 = thin + thin + gap;
+ poly[0].x = x + size; poly[0].y = y;
+ poly[1].x = x + size-d31; poly[1].y = y;
+ poly[2].x = x + 0; poly[2].y = y + size;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ * ------
+ * / /
+ * / __ /
+ * / / /
+ * / / /
+ * /__/__/
+ */
+
+ poly[0].x = x + d31/2; poly[0].y = y + size;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)+(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + d31; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ * ------
+ * / / /
+ * /--/ /
+ * / /
+ * / /
+ * /_____/
+ */
+
+ poly[0].x = x + size - d31/2; poly[0].y = y;
+ poly[1].x = x + size / 2; poly[1].y = y + size/2;
+ poly[2].x = x + (size/2)-(d31-(d31/2)); poly[2].y = y + size/2;
+ poly[3].x = x + size - d31; poly[3].y = y;
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ * b
+ * -----
+ * \ \
+ * \ \
+ * \ \
+ * \ \
+ * \____\
+ */
+
+ poly[0].x = x; poly[0].y = y;
+ poly[1].x = x + size/4; poly[1].y = y;
+ poly[2].x = x + size; poly[2].y = y + size;
+ poly[3].x = x + size - size/4; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ * /
+ * /
+ * /
+ * /
+ * /
+ */
+
+ poly[0].x = x + size- thin; poly[0].y = y;
+ poly[1].x = x + size-( thin+gap); poly[1].y = y;
+ poly[2].x = x + thin; poly[2].y = y + size;
+ poly[3].x = x + thin + gap; poly[3].y = y + size;
+ dixChangeGC(NullClient, pGC, bmask, NULL, back);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+ FreeScratchGC(pGC);
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/dix/xpstubs.c b/nx-X11/programs/Xserver/dix/xpstubs.c
new file mode 100644
index 000000000..ade0847d3
--- /dev/null
+++ b/nx-X11/programs/Xserver/dix/xpstubs.c
@@ -0,0 +1,48 @@
+/*
+Copyright 1996, 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.
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/font.h>
+
+Bool
+XpClientIsBitmapClient(
+ ClientPtr client)
+{
+ return TRUE;
+}
+
+Bool
+XpClientIsPrintClient(
+ ClientPtr client,
+ FontPathElementPtr fpe)
+{
+ return FALSE;
+}
diff --git a/nx-X11/programs/Xserver/fb/Imakefile b/nx-X11/programs/Xserver/fb/Imakefile
new file mode 100644
index 000000000..5daa10c6f
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/Imakefile
@@ -0,0 +1,164 @@
+NULL =
+
+#include <Server.tmpl>
+
+#ifdef FbNoPixelAddrCode
+FB_DEFINES=-DFBNOPIXADDR -DFBNO24BIT
+#endif
+
+#if HasShm
+SHM_DEFINES = ShmDefines
+#endif
+
+#if BuildRender
+RENDERSRC = fbcompose.c
+RENDEROBJ = fbcompose.o
+#endif
+
+#if defined(NXAgentServer) && NXAgentServer
+NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+#if defined(NXAgentServer) && NXAgentServer
+ DEFINES = $(FB_DEFINES) $(NX_DEFINES)
+#else
+ DEFINES = $(FB_DEFINES)
+#endif
+
+SRCS = $(XFMODSRC) \
+ fballpriv.c \
+ fbbits.c \
+ fbblt.c \
+ fbbltone.c \
+ fbbstore.c \
+ fbcmap.c \
+ $(RENDERSRC) \
+ fbcopy.c \
+ fbedge.c \
+ fbfill.c \
+ fbfillrect.c \
+ fbfillsp.c \
+ fbgc.c \
+ fbgetsp.c \
+ fbglyph.c \
+ fbimage.c \
+ fbline.c \
+ fboverlay.c \
+ fbpixmap.c \
+ fbpoint.c \
+ fbpush.c \
+ fbscreen.c \
+ fbseg.c \
+ fbsetsp.c \
+ fbsolid.c \
+ fbstipple.c \
+ fbtile.c \
+ fbtrap.c \
+ fbutil.c \
+ fbwindow.c \
+ fb24_32.c \
+ fbpict.c \
+ $(NULL)
+
+OBJS = $(XFMODOBJ) \
+ fbarc.o \
+ fballpriv.o \
+ fbbits.o \
+ fbblt.o \
+ fbbltone.o \
+ fbbstore.o \
+ fbcmap.o \
+ $(RENDEROBJ) \
+ fbcopy.o \
+ fbedge.o \
+ fbfill.o \
+ fbfillrect.o \
+ fbfillsp.o \
+ fbgc.o \
+ fbgetsp.o \
+ fbglyph.o \
+ fbimage.o \
+ fbline.o \
+ fboverlay.o \
+ fbpixmap.o \
+ fbpoint.o \
+ fbpush.o \
+ fbscreen.o \
+ fbseg.o \
+ fbsetsp.o \
+ fbsolid.o \
+ fbstipple.o \
+ fbtile.o \
+ fbtrap.o \
+ fbutil.o \
+ fbwindow.o \
+ fb24_32.o \
+ fbpict.o \
+ $(NULL)
+
+ INCLUDES = -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/common $(EXTRAINCLUDES) \
+ -I$(SERVERSRC)/render -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = $(SERVERSRC)/dix/llib-ldix.ln $(SERVERSRC)/os/llib-los.ln \
+ $(SERVERSRC)/mi/llib-lmi.ln
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(fb,$(OBJS))
+
+LintLibraryTarget(fb,$(SRCS))
+
+NormalLintTarget($(SRCS))
+
+
+DependTarget()
+
+#ifdef IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+SpecialCObjectRule(fboverlay,$(ICONFIGFILES),$(SHM_DEFINES))
+
+#ifdef LinkDirectory
+LinkSourceFile(fb24_32.c,LinkDirectory)
+LinkSourceFile(fballpriv.c,LinkDirectory)
+LinkSourceFile(fbarc.c,LinkDirectory)
+LinkSourceFile(fbbits.c,LinkDirectory)
+LinkSourceFile(fbblt.c,LinkDirectory)
+LinkSourceFile(fbbltone.c,LinkDirectory)
+LinkSourceFile(fbbstore.c,LinkDirectory)
+LinkSourceFile(fbcmap.c,LinkDirectory)
+#if BuildRender
+LinkSourceFile(fbcompose.c,LinkDirectory)
+#endif
+LinkSourceFile(fbcopy.c,LinkDirectory)
+LinkSourceFile(fbfill.c,LinkDirectory)
+LinkSourceFile(fbfillrect.c,LinkDirectory)
+LinkSourceFile(fbfillsp.c,LinkDirectory)
+LinkSourceFile(fbgc.c,LinkDirectory)
+LinkSourceFile(fbgetsp.c,LinkDirectory)
+LinkSourceFile(fbglyph.c,LinkDirectory)
+LinkSourceFile(fbimage.c,LinkDirectory)
+LinkSourceFile(fbline.c,LinkDirectory)
+LinkSourceFile(fbmodule.c,LinkDirectory)
+LinkSourceFile(fboverlay.c,LinkDirectory)
+LinkSourceFile(fbpict.c,LinkDirectory)
+LinkSourceFile(fbpixmap.c,LinkDirectory)
+LinkSourceFile(fbpoint.c,LinkDirectory)
+LinkSourceFile(fbpush.c,LinkDirectory)
+LinkSourceFile(fbscreen.c,LinkDirectory)
+LinkSourceFile(fbseg.c,LinkDirectory)
+LinkSourceFile(fbsetsp.c,LinkDirectory)
+LinkSourceFile(fbsolid.c,LinkDirectory)
+LinkSourceFile(fbstipple.c,LinkDirectory)
+LinkSourceFile(fbtile.c,LinkDirectory)
+LinkSourceFile(fbtrap.c,LinkDirectory)
+LinkSourceFile(fbutil.c,LinkDirectory)
+LinkSourceFile(fbwindow.c,LinkDirectory)
+#endif
+
+InstallDriverSDKLibraryModule(fb,$(DRIVERSDKMODULEDIR),.)
+InstallDriverSDKNonExecFile(fb.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(fbrop.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/fb/fb.h b/nx-X11/programs/Xserver/fb/fb.h
new file mode 100644
index 000000000..61bf18caf
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fb.h
@@ -0,0 +1,2047 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+
+#ifndef _FB_H_
+#define _FB_H_
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "pixmap.h"
+#include "pixmapstr.h"
+#include "region.h"
+#include "gcstruct.h"
+#include "colormap.h"
+#include "miscstruct.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "migc.h"
+#include "mibstore.h"
+#ifdef RENDER
+#include "picturestr.h"
+#else
+#include "picture.h"
+#endif
+
+/*
+ * This single define controls the basic size of data manipulated
+ * by this software; it must be log2(sizeof (FbBits) * 8)
+ */
+
+#ifndef FB_SHIFT
+#define FB_SHIFT LOG2_BITMAP_PAD
+#endif
+
+#if FB_SHIFT < LOG2_BITMAP_PAD
+ error FB_SHIFT must be >= LOG2_BITMAP_PAD
+#endif
+
+#define FB_UNIT (1 << FB_SHIFT)
+#define FB_HALFUNIT (1 << (FB_SHIFT-1))
+#define FB_MASK (FB_UNIT - 1)
+#define FB_ALLONES ((FbBits) -1)
+
+#if GLYPHPADBYTES != 4
+#error "GLYPHPADBYTES must be 4"
+#endif
+/* whether to bother to include 24bpp support */
+#ifndef FBNO24BIT
+#define FB_24BIT
+#endif
+
+/*
+ * Unless otherwise instructed, fb includes code to advertise 24bpp
+ * windows with 32bpp image format for application compatibility
+ */
+
+#ifdef FB_24BIT
+#ifndef FBNO24_32
+#define FB_24_32BIT
+#endif
+#endif
+
+#define FB_STIP_SHIFT LOG2_BITMAP_PAD
+#define FB_STIP_UNIT (1 << FB_STIP_SHIFT)
+#define FB_STIP_MASK (FB_STIP_UNIT - 1)
+#define FB_STIP_ALLONES ((FbStip) -1)
+
+#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0)
+#define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0)
+
+#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT)))
+#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT)))
+
+#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1))
+
+#if FB_SHIFT == 6
+# ifdef WIN32
+typedef unsigned __int64 FbBits;
+# else
+# if defined(__alpha__) || defined(__alpha) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__sparc64__) || defined(_LP64) || \
+ defined(__s390x__) || \
+ defined(amd64) || defined (__amd64__) || \
+ defined (__powerpc64__)
+typedef unsigned long FbBits;
+# else
+typedef unsigned long long FbBits;
+# endif
+# endif
+#endif
+
+#if FB_SHIFT == 5
+typedef CARD32 FbBits;
+#endif
+
+#if FB_SHIFT == 4
+typedef CARD16 FbBits;
+#endif
+
+#if LOG2_BITMAP_PAD == FB_SHIFT
+typedef FbBits FbStip;
+#else
+# if LOG2_BITMAP_PAD == 5
+typedef CARD32 FbStip;
+# endif
+#endif
+
+typedef int FbStride;
+
+
+#ifdef FB_DEBUG
+extern void fbValidateDrawable(DrawablePtr d);
+extern void fbInitializeDrawable(DrawablePtr d);
+extern void fbSetBits (FbStip *bits, int stride, FbStip data);
+#define FB_HEAD_BITS (FbStip) (0xbaadf00d)
+#define FB_TAIL_BITS (FbStip) (0xbaddf0ad)
+#else
+#define fbValidateDrawable(d)
+#define fdInitializeDrawable(d)
+#endif
+
+#include "fbrop.h"
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define FbScrLeft(x,n) ((x) >> (n))
+#define FbScrRight(x,n) ((x) << (n))
+/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */
+#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1))
+#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n)))
+#define FbPatternOffsetBits 0
+#else
+#define FbScrLeft(x,n) ((x) << (n))
+#define FbScrRight(x,n) ((x) >> (n))
+/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */
+#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n)))
+#define FbStipMoveLsb(x,s,n) (x)
+#define FbPatternOffsetBits (sizeof (FbBits) - 1)
+#endif
+
+#include "micoord.h"
+
+#define FbStipLeft(x,n) FbScrLeft(x,n)
+#define FbStipRight(x,n) FbScrRight(x,n)
+
+#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0)
+#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0)
+
+#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0)
+#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0)
+
+#define FbLeftMask(x) ( ((x) & FB_MASK) ? \
+ FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0)
+#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0)
+
+#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \
+ FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0)
+#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \
+ FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0)
+
+#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK))
+
+#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \
+ FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK))
+
+
+#define FbMaskBits(x,w,l,n,r) { \
+ n = (w); \
+ r = FbRightMask((x)+n); \
+ l = FbLeftMask(x); \
+ if (l) { \
+ n -= FB_UNIT - ((x) & FB_MASK); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= FB_SHIFT; \
+}
+
+#ifdef FBNOPIXADDR
+#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) FbMaskBits(x,w,l,n,r)
+#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \
+ *dst = FbDoMaskRRop(*dst,and,xor,l); \
+}
+#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \
+ *dst = FbDoMaskRRop(*dst,and,xor,r); \
+}
+#else
+
+#define FbByteMaskInvalid 0x10
+
+#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1)))
+
+#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o)))
+#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3))
+#define FbStorePart(dst,off,t,xor) (*FbPtrOffset(dst,off,t) = \
+ FbSelectPart(xor,off,t))
+#ifndef FbSelectPart
+#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t)
+#endif
+
+#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \
+ n = (w); \
+ lb = 0; \
+ rb = 0; \
+ r = FbRightMask((x)+n); \
+ if (r) { \
+ /* compute right byte length */ \
+ if ((copy) && (((x) + n) & 7) == 0) { \
+ rb = (((x) + n) & FB_MASK) >> 3; \
+ } else { \
+ rb = FbByteMaskInvalid; \
+ } \
+ } \
+ l = FbLeftMask(x); \
+ if (l) { \
+ /* compute left byte length */ \
+ if ((copy) && ((x) & 7) == 0) { \
+ lb = ((x) & FB_MASK) >> 3; \
+ } else { \
+ lb = FbByteMaskInvalid; \
+ } \
+ /* subtract out the portion painted by leftMask */ \
+ n -= FB_UNIT - ((x) & FB_MASK); \
+ if (n < 0) { \
+ if (lb != FbByteMaskInvalid) { \
+ if (rb == FbByteMaskInvalid) { \
+ lb = FbByteMaskInvalid; \
+ } else if (rb) { \
+ lb |= (rb - lb) << (FB_SHIFT - 3); \
+ rb = 0; \
+ } \
+ } \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ }\
+ } \
+ n >>= FB_SHIFT; \
+}
+
+#if FB_SHIFT == 6
+#define FbDoLeftMaskByteRRop6Cases(dst,xor) \
+ case (sizeof (FbBits) - 7) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 7) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 7) | (3 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 7) | (4 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 7) | (5 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 7) | (6 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 7): \
+ FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \
+ break; \
+ case (sizeof (FbBits) - 6) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 6) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 6) | (3 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 6) | (4 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 6) | (5 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 6): \
+ FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \
+ break; \
+ case (sizeof (FbBits) - 5) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 5) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 5) | (3 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 5) | (4 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 5): \
+ FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \
+ break; \
+ case (sizeof (FbBits) - 4) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 4) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ break; \
+ case (sizeof (FbBits) - 4) | (3 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 4): \
+ FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \
+ break;
+
+#define FbDoRightMaskByteRRop6Cases(dst,xor) \
+ case 4: \
+ FbStorePart(dst,0,CARD32,xor); \
+ break; \
+ case 5: \
+ FbStorePart(dst,0,CARD32,xor); \
+ FbStorePart(dst,4,CARD8,xor); \
+ break; \
+ case 6: \
+ FbStorePart(dst,0,CARD32,xor); \
+ FbStorePart(dst,4,CARD16,xor); \
+ break; \
+ case 7: \
+ FbStorePart(dst,0,CARD32,xor); \
+ FbStorePart(dst,4,CARD16,xor); \
+ FbStorePart(dst,6,CARD8,xor); \
+ break;
+#else
+#define FbDoLeftMaskByteRRop6Cases(dst,xor)
+#define FbDoRightMaskByteRRop6Cases(dst,xor)
+#endif
+
+#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \
+ switch (lb) { \
+ FbDoLeftMaskByteRRop6Cases(dst,xor) \
+ case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case sizeof (FbBits) - 3: \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ case sizeof (FbBits) - 2: \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \
+ break; \
+ case sizeof (FbBits) - 1: \
+ FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \
+ break; \
+ default: \
+ *dst = FbDoMaskRRop(*dst, and, xor, l); \
+ break; \
+ } \
+}
+
+
+#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \
+ switch (rb) { \
+ case 1: \
+ FbStorePart(dst,0,CARD8,xor); \
+ break; \
+ case 2: \
+ FbStorePart(dst,0,CARD16,xor); \
+ break; \
+ case 3: \
+ FbStorePart(dst,0,CARD16,xor); \
+ FbStorePart(dst,2,CARD8,xor); \
+ break; \
+ FbDoRightMaskByteRRop6Cases(dst,xor) \
+ default: \
+ *dst = FbDoMaskRRop (*dst, and, xor, r); \
+ } \
+}
+#endif
+
+#define FbMaskStip(x,w,l,n,r) { \
+ n = (w); \
+ r = FbRightStipMask((x)+n); \
+ l = FbLeftStipMask(x); \
+ if (l) { \
+ n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= FB_STIP_SHIFT; \
+}
+
+/*
+ * These macros are used to transparently stipple
+ * in copy mode; the expected usage is with 'n' constant
+ * so all of the conditional parts collapse into a minimal
+ * sequence of partial word writes
+ *
+ * 'n' is the bytemask of which bytes to store, 'a' is the address
+ * of the FbBits base unit, 'o' is the offset within that unit
+ *
+ * The term "lane" comes from the hardware term "byte-lane" which
+ */
+
+#define FbLaneCase1(n,a,o) ((n) == 0x01 ? \
+ (*(CARD8 *) ((a)+FbPatternOffset(o,CARD8)) = \
+ fgxor) : 0)
+#define FbLaneCase2(n,a,o) ((n) == 0x03 ? \
+ (*(CARD16 *) ((a)+FbPatternOffset(o,CARD16)) = \
+ fgxor) : \
+ ((void)FbLaneCase1((n)&1,a,o), \
+ FbLaneCase1((n)>>1,a,(o)+1)))
+#define FbLaneCase4(n,a,o) ((n) == 0x0f ? \
+ (*(CARD32 *) ((a)+FbPatternOffset(o,CARD32)) = \
+ fgxor) : \
+ ((void)FbLaneCase2((n)&3,a,o), \
+ FbLaneCase2((n)>>2,a,(o)+2)))
+#define FbLaneCase8(n,a,o) ((n) == 0x0ff ? (*(FbBits *) ((a)+(o)) = fgxor) : \
+ ((void)FbLaneCase4((n)&15,a,o), \
+ FbLaneCase4((n)>>4,a,(o)+4)))
+
+#if FB_SHIFT == 6
+#define FbLaneCase(n,a) FbLaneCase8(n,(CARD8 *) (a),0)
+#endif
+
+#if FB_SHIFT == 5
+#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0)
+#endif
+
+/* Rotate a filled pixel value to the specified alignement */
+#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b)))
+#define FbRot24Stip(p,b) (FbStipRight(p,b) | FbStipLeft(p,24-(b)))
+
+/* step a filled pixel value to the next/previous FB_UNIT alignment */
+#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24)))
+#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24))
+#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24)))
+#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24))
+
+/* step a rotation value to the next/previous rotation value */
+#if FB_UNIT == 64
+#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8)
+#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8)
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define FbFirst24Rot(x) (((x) + 8) % 24)
+#else
+#define FbFirst24Rot(x) ((x) % 24)
+#endif
+
+#endif
+
+#if FB_UNIT == 32
+#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8)
+#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8)
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define FbFirst24Rot(x) (((x) + 16) % 24)
+#else
+#define FbFirst24Rot(x) ((x) % 24)
+#endif
+#endif
+
+#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8)
+#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8)
+
+/* Whether 24-bit specific code is needed for this filled pixel value */
+#define FbCheck24Pix(p) ((p) == FbNext24Pix(p))
+
+/* Macros for dealing with dashing */
+
+#define FbDashDeclare \
+ unsigned char *__dash, *__firstDash, *__lastDash
+
+#define FbDashInit(pGC,pPriv,dashOffset,dashlen,even) { \
+ (even) = TRUE; \
+ __firstDash = (pGC)->dash; \
+ __lastDash = __firstDash + (pGC)->numInDashList; \
+ (dashOffset) %= (pPriv)->dashLength; \
+ \
+ __dash = __firstDash; \
+ while ((dashOffset) >= ((dashlen) = *__dash)) \
+ { \
+ (dashOffset) -= (dashlen); \
+ (even) = 1-(even); \
+ if (++__dash == __lastDash) \
+ __dash = __firstDash; \
+ } \
+ (dashlen) -= (dashOffset); \
+}
+
+#define FbDashNext(dashlen) { \
+ if (++__dash == __lastDash) \
+ __dash = __firstDash; \
+ (dashlen) = *__dash; \
+}
+
+/* as numInDashList is always even, this case can skip a test */
+
+#define FbDashNextEven(dashlen) { \
+ (dashlen) = *++__dash; \
+}
+
+#define FbDashNextOdd(dashlen) FbDashNext(dashlen)
+
+#define FbDashStep(dashlen,even) { \
+ if (!--(dashlen)) { \
+ FbDashNext(dashlen); \
+ (even) = 1-(even); \
+ } \
+}
+
+/* XXX fb*PrivateIndex should be static, but it breaks the ABI */
+
+extern int fbGCPrivateIndex;
+extern int fbGetGCPrivateIndex(void);
+#ifndef FB_NO_WINDOW_PIXMAPS
+extern int fbWinPrivateIndex;
+extern int fbGetWinPrivateIndex(void);
+#endif
+extern const GCOps fbGCOps;
+extern const GCFuncs fbGCFuncs;
+
+#ifdef TEKX11
+#define FB_OLD_GC
+#define FB_OLD_SCREEN
+#endif
+
+#ifdef FB_OLD_SCREEN
+# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */
+#endif
+
+#ifdef FB_24_32BIT
+#define FB_SCREEN_PRIVATE
+#endif
+
+#ifdef FB_SCREEN_PRIVATE
+extern int fbScreenPrivateIndex;
+extern int fbGetScreenPrivateIndex(void);
+
+/* private field of a screen */
+typedef struct {
+ unsigned char win32bpp; /* window bpp for 32-bpp images */
+ unsigned char pix32bpp; /* pixmap bpp for 32-bpp images */
+} FbScreenPrivRec, *FbScreenPrivPtr;
+
+#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \
+ (pScreen)->devPrivates[fbGetScreenPrivateIndex()].ptr)
+#endif
+
+/* private field of GC */
+typedef struct {
+#ifdef FB_OLD_GC
+ unsigned char pad1;
+ unsigned char pad2;
+ unsigned char pad3;
+ unsigned fExpose:1;
+ unsigned freeCompClip:1;
+ PixmapPtr pRotatedPixmap;
+ RegionPtr pCompositeClip;
+#endif
+ FbBits and, xor; /* reduced rop values */
+ FbBits bgand, bgxor; /* for stipples */
+ FbBits fg, bg, pm; /* expanded and filled */
+ unsigned int dashLength; /* total of all dash elements */
+ unsigned char oneRect; /* clip list is single rectangle */
+ unsigned char evenStipple; /* stipple is even */
+ unsigned char bpp; /* current drawable bpp */
+} FbGCPrivRec, *FbGCPrivPtr;
+
+#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\
+ (pGC)->devPrivates[fbGetGCPrivateIndex()].ptr)
+
+#ifdef FB_OLD_GC
+#define fbGetCompositeClip(pGC) (fbGetGCPrivate(pGC)->pCompositeClip)
+#define fbGetExpose(pGC) (fbGetGCPrivate(pGC)->fExpose)
+#define fbGetFreeCompClip(pGC) (fbGetGCPrivate(pGC)->freeCompClip)
+#define fbGetRotatedPixmap(pGC) (fbGetGCPrivate(pGC)->pRotatedPixmap)
+#else
+#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip)
+#define fbGetExpose(pGC) ((pGC)->fExpose)
+#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip)
+#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap)
+#endif
+
+#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate)
+#ifdef FB_NO_WINDOW_PIXMAPS
+#define fbGetWindowPixmap(d) fbGetScreenPixmap(((DrawablePtr) (d))->pScreen)
+#else
+#define fbGetWindowPixmap(pWin) ((PixmapPtr)\
+ ((WindowPtr) (pWin))->devPrivates[fbGetWinPrivateIndex()].ptr)
+#endif
+
+#ifdef ROOTLESS
+#define __fbPixDrawableX(pPix) ((pPix)->drawable.x)
+#define __fbPixDrawableY(pPix) ((pPix)->drawable.y)
+#else
+#define __fbPixDrawableX(pPix) 0
+#define __fbPixDrawableY(pPix) 0
+#endif
+
+#ifdef COMPOSITE
+#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix) - (pPix)->screen_x)
+#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix) - (pPix)->screen_y)
+#else
+#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix))
+#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix))
+#endif
+#define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix))
+#define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix))
+
+#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
+ _pPix = fbGetWindowPixmap(pDrawable); \
+ (xoff) = __fbPixOffXWin(_pPix); \
+ (yoff) = __fbPixOffYWin(_pPix); \
+ } else { \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (xoff) = __fbPixOffXPix(_pPix); \
+ (yoff) = __fbPixOffYPix(_pPix); \
+ } \
+ (pointer) = (FbBits *) _pPix->devPrivate.ptr; \
+ (stride) = ((int) _pPix->devKind) / sizeof (FbBits); (void)(stride); \
+ (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \
+}
+
+#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
+ _pPix = fbGetWindowPixmap(pDrawable); \
+ (xoff) = __fbPixOffXWin(_pPix); \
+ (yoff) = __fbPixOffYWin(_pPix); \
+ } else { \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (xoff) = __fbPixOffXPix(_pPix); \
+ (yoff) = __fbPixOffYPix(_pPix); \
+ } \
+ (pointer) = (FbStip *) _pPix->devPrivate.ptr; \
+ (stride) = ((int) _pPix->devKind) / sizeof (FbStip); (void)(stride); \
+ (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \
+}
+
+/*
+ * XFree86 empties the root BorderClip when the VT is inactive,
+ * here's a macro which uses that to disable GetImage and GetSpans
+ */
+
+#define fbWindowEnabled(pWin) \
+ RegionNotEmpty(\
+ &(pWin)->drawable.pScreen->root->borderClip)
+
+#define fbDrawableEnabled(pDrawable) \
+ ((pDrawable)->type == DRAWABLE_PIXMAP ? \
+ TRUE : fbWindowEnabled((WindowPtr) pDrawable))
+
+#ifdef FB_OLD_SCREEN
+#define BitsPerPixel(d) (\
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0)
+/*
+ * Accelerated tiles are power of 2 width <= FB_UNIT
+ */
+#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w))
+/*
+ * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp
+ * with dstBpp a power of 2 as well
+ */
+#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp))
+
+/*
+ * fb24_32.c
+ */
+void
+fb24_32GetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart);
+
+void
+fb24_32SetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted);
+
+void
+fb24_32PutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ CARD8 *src,
+ FbStride srcStride);
+
+void
+fb24_32GetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d);
+
+void
+fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+PixmapPtr
+fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel);
+
+Bool
+fb24_32CreateScreenResources(ScreenPtr pScreen);
+
+Bool
+fb24_32ModifyPixmapHeader (PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ void *pPixData);
+
+/*
+ * fballpriv.c
+ */
+Bool
+fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex);
+
+/*
+ * fbarc.c
+ */
+
+void
+fbPolyArc (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs);
+
+/*
+ * fbbits.c
+ */
+
+void
+fbBresSolid8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash8 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots8 (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc8 (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph8 (FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+
+void
+fbPolyline8 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ptsOrig);
+
+void
+fbPolySegment8 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg);
+
+void
+fbBresSolid16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots16(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc16(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph16(FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+
+void
+fbPolyline16 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ptsOrig);
+
+void
+fbPolySegment16 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg);
+
+
+void
+fbBresSolid24(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash24(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots24(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc24(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph24(FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+
+void
+fbPolyline24 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ptsOrig);
+
+void
+fbPolySegment24 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg);
+
+
+void
+fbBresSolid32(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbBresDash32(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbDots32(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor);
+
+void
+fbArc32(FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbGlyph32(FbBits *dstLine,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int height,
+ int shift);
+void
+fbPolyline32 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ptsOrig);
+
+void
+fbPolySegment32 (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg);
+
+/*
+ * fbblt.c
+ */
+void
+fbBlt (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ Bool reverse,
+ Bool upsidedown);
+
+void
+fbBlt24 (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse,
+ Bool upsidedown);
+
+void
+fbBltStip (FbStip *src,
+ FbStride srcStride, /* in FbStip units, not FbBits units */
+ int srcX,
+
+ FbStip *dst,
+ FbStride dstStride, /* in FbStip units, not FbBits units */
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp);
+
+/*
+ * fbbltone.c
+ */
+void
+fbBltOne (FbStip *src,
+ FbStride srcStride,
+ int srcX,
+ FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbBits fgand,
+ FbBits fbxor,
+ FbBits bgand,
+ FbBits bgxor);
+
+#ifdef FB_24BIT
+void
+fbBltOne24 (FbStip *src,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor);
+#endif
+
+void
+fbBltPlane (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+ int srcBpp,
+
+ FbStip *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbStip fgand,
+ FbStip fgxor,
+ FbStip bgand,
+ FbStip bgxor,
+ Pixel planeMask);
+
+/*
+ * fbbstore.c
+ */
+void
+fbSaveAreas(PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+void
+fbRestoreAreas(PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin);
+
+/*
+ * fbcmap.c
+ */
+int
+fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+
+void
+fbInstallColormap(ColormapPtr pmap);
+
+void
+fbUninstallColormap(ColormapPtr pmap);
+
+void
+fbResolveColor(unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual);
+
+Bool
+fbInitializeColormap(ColormapPtr pmap);
+
+int
+fbExpandDirectColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *indefs,
+ xColorItem *outdefs);
+
+Bool
+fbCreateDefColormap(ScreenPtr pScreen);
+
+void
+fbClearVisualTypes(void);
+
+Bool
+fbSetVisualTypes (int depth, int visuals, int bitsPerRGB);
+
+Bool
+fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
+ Pixel redMask, Pixel greenMask, Pixel blueMask);
+
+Bool
+fbInitVisuals (VisualPtr *visualp,
+ DepthPtr *depthp,
+ int *nvisualp,
+ int *ndepthp,
+ int *rootDepthp,
+ VisualID *defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB);
+
+/*
+ * fbcopy.c
+ */
+
+typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pDstBox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyNto1 (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyRegion (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure);
+
+RegionPtr
+fbDoCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ fbCopyProc copyProc,
+ Pixel bitplane,
+ void *closure);
+
+RegionPtr
+fbCopyArea (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut);
+
+RegionPtr
+fbCopyPlane (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ unsigned long bitplane);
+
+/*
+ * fbfill.c
+ */
+void
+fbFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int xa,
+ int ya,
+ int xb,
+ int yb,
+ FbBits and,
+ FbBits xor);
+
+/*
+ * fbfillrect.c
+ */
+void
+fbPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrectInit,
+ xRectangle *prectInit);
+
+#define fbPolyFillArc miPolyFillArc
+
+#define fbFillPolygon miFillPolygon
+
+/*
+ * fbfillsp.c
+ */
+void
+fbFillSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted);
+
+
+/*
+ * fbgc.c
+ */
+
+Bool
+fbCreateGC(GCPtr pGC);
+
+void
+fbPadPixmap (PixmapPtr pPixmap);
+
+void
+fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+
+/*
+ * fbgetsp.c
+ */
+void
+fbGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart);
+
+/*
+ * fbglyph.c
+ */
+
+Bool
+fbGlyphIn (RegionPtr pRegion,
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase);
+
+void
+fbImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void *pglyphBase);
+
+/*
+ * fbimage.c
+ */
+
+void
+fbPutImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage);
+
+void
+fbPutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ FbStip *src,
+ FbStride srcStride);
+
+void
+fbPutXYImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ FbBits fg,
+ FbBits bg,
+ FbBits pm,
+ int alu,
+ Bool opaque,
+
+ int x,
+ int y,
+ int width,
+ int height,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX);
+
+void
+fbGetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d);
+/*
+ * fbline.c
+ */
+
+void
+fbZeroLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt);
+
+void
+fbZeroSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSegs);
+
+void
+fbPolyLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt);
+
+void
+fbFixCoordModePrevious (int npt,
+ DDXPointPtr ppt);
+
+void
+fbPolySegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg);
+
+#define fbPolyRectangle miPolyRectangle
+
+/*
+ * fbpict.c
+ */
+
+Bool
+fbPictureInit (ScreenPtr pScreen,
+ PictFormatPtr formats,
+ int nformats);
+
+/*
+ * fbpixmap.c
+ */
+
+PixmapPtr
+fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
+ unsigned usage_hint);
+
+PixmapPtr
+fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint);
+
+Bool
+fbDestroyPixmap (PixmapPtr pPixmap);
+
+RegionPtr
+fbPixmapToRegion(PixmapPtr pPix);
+
+/*
+ * fbpoint.c
+ */
+
+void
+fbDots (FbBits *dstOrig,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits andOrig,
+ FbBits xorOrig);
+
+void
+fbPolyPoint (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit);
+
+/*
+ * fbpush.c
+ */
+void
+fbPushPattern (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+
+ int width,
+ int height);
+
+void
+fbPushFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbPush1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbPushImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height);
+
+void
+fbPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg);
+
+
+/*
+ * fbscreen.c
+ */
+
+Bool
+fbCloseScreen (ScreenPtr pScreen);
+
+Bool
+fbRealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+Bool
+fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+void
+fbQueryBestSize (int class,
+ unsigned short *width, unsigned short *height,
+ ScreenPtr pScreen);
+
+#ifndef FB_OLD_SCREEN
+PixmapPtr
+_fbGetWindowPixmap (WindowPtr pWindow);
+
+void
+_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap);
+#endif
+
+Bool
+fbSetupScreen(ScreenPtr pScreen,
+ void *pbits, /* pointer to screen bitmap */
+ int xsize, /* in pixels */
+ int ysize,
+ int dpix, /* dots per inch */
+ int dpiy,
+ int width, /* pixel width of frame buffer */
+ int bpp); /* bits per pixel of frame buffer */
+
+Bool
+fbFinishScreenInit(ScreenPtr pScreen,
+ void *pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp);
+
+Bool
+fbScreenInit(ScreenPtr pScreen,
+ void *pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp);
+
+void
+fbInitializeBackingStore (ScreenPtr pScreen);
+
+/*
+ * fbseg.c
+ */
+typedef void FbBres (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+FbBres fbBresSolid, fbBresDash, fbBresFill, fbBresFillDash;
+/*
+ * fbsetsp.c
+ */
+
+void
+fbSetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted);
+
+FbBres *
+fbSelectBres (DrawablePtr pDrawable,
+ GCPtr pGC);
+
+void
+fbBres (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ int e,
+ int e1,
+ int e3,
+ int len);
+
+void
+fbSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xa,
+ int ya,
+ int xb,
+ int yb,
+ Bool drawLast,
+ int *dashOffset);
+
+
+/*
+ * fbsolid.c
+ */
+
+void
+fbSolid (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int bpp,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor);
+
+#ifdef FB_24BIT
+void
+fbSolid24 (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor);
+#endif
+
+/*
+ * fbstipple.c
+ */
+
+void
+fbTransparentSpan (FbBits *dst,
+ FbBits stip,
+ FbBits fgxor,
+ int n);
+
+void
+fbEvenStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+void
+fbOddStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+void
+fbStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+ Bool even,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot);
+
+/*
+ * fbtile.c
+ */
+
+void
+fbEvenTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int xRot,
+ int yRot);
+
+void
+fbOddTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot);
+
+void
+fbTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot);
+
+/*
+ * fbutil.c
+ */
+FbBits
+fbReplicatePixel (Pixel p, int bpp);
+
+void
+fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp);
+
+/*
+ * fbwindow.c
+ */
+
+Bool
+fbCreateWindow(WindowPtr pWin);
+
+Bool
+fbDestroyWindow(WindowPtr pWin);
+
+Bool
+fbMapWindow(WindowPtr pWindow);
+
+Bool
+fbPositionWindow(WindowPtr pWin, int x, int y);
+
+Bool
+fbUnmapWindow(WindowPtr pWindow);
+
+void
+fbCopyWindowProc (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure);
+
+void
+fbCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+Bool
+fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
+
+void
+fbFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ FbBits and,
+ FbBits xor);
+
+void
+fbFillRegionTiled (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ PixmapPtr pTile);
+
+void
+fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+
+
+#endif /* _FB_H_ */
diff --git a/nx-X11/programs/Xserver/fb/fb24_32.c b/nx-X11/programs/Xserver/fb/fb24_32.c
new file mode 100644
index 000000000..7255b5021
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fb24_32.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include "fb.h"
+
+/* X apps don't like 24bpp images, this code exposes 32bpp images */
+
+/*
+ * These two functions do a full CopyArea while reformatting
+ * the data between 24 and 32bpp. They try to go a bit faster
+ * by reading/writing aligned CARD32s where it's easy
+ */
+
+#define Get8(a) ((CARD32) *(a))
+
+#if BITMAP_BIT_ORDER == MSBFirst
+#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
+#define Put24(a,p) (((a)[0] = (CARD8) ((p) >> 16)), \
+ ((a)[1] = (CARD8) ((p) >> 8)), \
+ ((a)[2] = (CARD8) (p)))
+#else
+#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
+#define Put24(a,p) (((a)[0] = (CARD8) (p)), \
+ ((a)[1] = (CARD8) ((p) >> 8)), \
+ ((a)[2] = (CARD8) ((p) >> 16)))
+#endif
+
+typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ CARD8 *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm);
+
+static void
+fb24_32BltDown (CARD8 *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ CARD8 *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm)
+{
+ CARD32 *src;
+ CARD8 *dst;
+ int w;
+ Bool destInvarient;
+ CARD32 pixel, dpixel;
+ FbDeclareMergeRop ();
+
+ srcLine += srcX * 4;
+ dstLine += dstX * 3;
+
+ FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
+ destInvarient = FbDestInvarientMergeRop();
+
+ while (height--)
+ {
+ src = (CARD32 *) srcLine;
+ dst = dstLine;
+ srcLine += srcStride;
+ dstLine += dstStride;
+ w = width;
+ if (destInvarient)
+ {
+ while (((long) dst & 3) && w)
+ {
+ w--;
+ pixel = *src++;
+ pixel = FbDoDestInvarientMergeRop(pixel);
+ Put24 (dst, pixel);
+ dst += 3;
+ }
+ /* Do four aligned pixels at a time */
+ while (w >= 4)
+ {
+ CARD32 s0, s1;
+ s0 = *src++;
+ s0 = FbDoDestInvarientMergeRop(s0);
+ s1 = *src++;
+ s1 = FbDoDestInvarientMergeRop(s1);
+#if BITMAP_BIT_ORDER == LSBFirst
+ *(CARD32 *)(dst) = (s0 & 0xffffff) | (s1 << 24);
+#else
+ *(CARD32 *)(dst) = (s0 << 8) | ((s1 & 0xffffff) >> 16);
+#endif
+ s0 = *src++;
+ s0 = FbDoDestInvarientMergeRop(s0);
+#if BITMAP_BIT_ORDER == LSBFirst
+ *(CARD32 *)(dst+4) = ((s1 & 0xffffff) >> 8) | (s0 << 16);
+#else
+ *(CARD32 *)(dst+4) = (s1 << 16) | ((s0 & 0xffffff) >> 8);
+#endif
+ s1 = *src++;
+ s1 = FbDoDestInvarientMergeRop(s1);
+#if BITMAP_BIT_ORDER == LSBFirst
+ *(CARD32 *)(dst+8) = ((s0 & 0xffffff) >> 16) | (s1 << 8);
+#else
+ *(CARD32 *)(dst+8) = (s0 << 24) | (s1 & 0xffffff);
+#endif
+ dst += 12;
+ w -= 4;
+ }
+ while (w--)
+ {
+ pixel = *src++;
+ pixel = FbDoDestInvarientMergeRop(pixel);
+ Put24 (dst, pixel);
+ dst += 3;
+ }
+ }
+ else
+ {
+ while (w--)
+ {
+ pixel = *src++;
+ dpixel = Get24 (dst);
+ pixel = FbDoMergeRop(pixel, dpixel);
+ Put24 (dst, pixel);
+ dst += 3;
+ }
+ }
+ }
+}
+
+static void
+fb24_32BltUp (CARD8 *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ CARD8 *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm)
+{
+ CARD8 *src;
+ CARD32 *dst;
+ int w;
+ Bool destInvarient;
+ CARD32 pixel;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
+ destInvarient = FbDestInvarientMergeRop();
+
+ srcLine += srcX * 3;
+ dstLine += dstX * 4;
+
+ while (height--)
+ {
+ w = width;
+ src = srcLine;
+ dst = (CARD32 *) dstLine;
+ srcLine += srcStride;
+ dstLine += dstStride;
+ if (destInvarient)
+ {
+ while (((long) src & 3) && w)
+ {
+ w--;
+ pixel = Get24(src);
+ src += 3;
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+ }
+ /* Do four aligned pixels at a time */
+ while (w >= 4)
+ {
+ CARD32 s0, s1;
+
+ s0 = *(CARD32 *)(src);
+#if BITMAP_BIT_ORDER == LSBFirst
+ pixel = s0 & 0xffffff;
+#else
+ pixel = s0 >> 8;
+#endif
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+ s1 = *(CARD32 *)(src+4);
+#if BITMAP_BIT_ORDER == LSBFirst
+ pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
+#else
+ pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
+#endif
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+ s0 = *(CARD32 *)(src+8);
+#if BITMAP_BIT_ORDER == LSBFirst
+ pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
+#else
+ pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
+#endif
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+#if BITMAP_BIT_ORDER == LSBFirst
+ pixel = s0 >> 8;
+#else
+ pixel = s0 & 0xffffff;
+#endif
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+ src += 12;
+ w -= 4;
+ }
+ while (w)
+ {
+ w--;
+ pixel = Get24(src);
+ src += 3;
+ *dst++ = FbDoDestInvarientMergeRop(pixel);
+ }
+ }
+ else
+ {
+ while (w--)
+ {
+ pixel = Get24(src);
+ src += 3;
+ *dst = FbDoMergeRop(pixel, *dst);
+ dst++;
+ }
+ }
+ }
+}
+
+/*
+ * Spans functions; probably unused.
+ */
+void
+fb24_32GetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart)
+{
+ FbBits *srcBits;
+ CARD8 *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ CARD8 *dst;
+
+ fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
+ src = (CARD8 *) srcBits;
+ srcStride *= sizeof (FbBits);
+
+ while (nspans--)
+ {
+ dst = (CARD8 *) pchardstStart;
+ fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride,
+ ppt->x + srcXoff,
+
+ dst,
+ 1,
+ 0,
+
+ *pwidth,
+ 1,
+
+ GXcopy,
+ FB_ALLONES);
+
+ pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+}
+
+void
+fb24_32SetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ FbBits *dstBits;
+ CARD8 *dst, *d, *s;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ BoxPtr pbox;
+ int n;
+ int x1, x2;
+
+ fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+ dst = (CARD8 *) dstBits;
+ dstStride *= sizeof (FbBits);
+ while (nspans--)
+ {
+ d = dst + (ppt->y + dstYoff) * dstStride;
+ s = (CARD8 *) src;
+ n = RegionNumRects(pClip);
+ pbox = RegionRects (pClip);
+ while (n--)
+ {
+ if (pbox->y1 > ppt->y)
+ break;
+ if (pbox->y2 > ppt->y)
+ {
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ if (pbox->x1 > x1)
+ x1 = pbox->x1;
+ if (pbox->x2 < x2)
+ x2 = pbox->x2;
+ if (x1 < x2)
+ fb24_32BltDown (s,
+ 0,
+ (x1 - ppt->x),
+ d,
+ dstStride,
+ x1 + dstXoff,
+
+ (x2 - x1),
+ 1,
+ pGC->alu,
+ pPriv->pm);
+ }
+ }
+ src += PixmapBytePad (*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+}
+
+/*
+ * Clip and put 32bpp Z-format images to a 24bpp drawable
+ */
+void
+fb24_32PutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ CARD8 *src,
+ FbStride srcStride)
+{
+ FbBits *dstBits;
+ CARD8 *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+
+ fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+ dstStride *= sizeof(FbBits);
+ dst = (CARD8 *) dstBits;
+
+ for (nbox = RegionNumRects (pClip),
+ pbox = RegionRects(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fb24_32BltDown (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x),
+
+ dst + (y1 + dstYoff) * dstStride,
+ dstStride,
+ x1 + dstXoff,
+
+ (x2 - x1),
+ (y2 - y1),
+
+ alu,
+ pm);
+ }
+}
+
+void
+fb24_32GetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d)
+{
+ FbBits *srcBits;
+ CARD8 *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbStride dstStride;
+ FbBits pm;
+
+ fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
+ src = (CARD8 *) srcBits;
+ srcStride *= sizeof (FbBits);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ pm = fbReplicatePixel (planeMask, 32);
+ dstStride = PixmapBytePad(w, pDrawable->depth);
+ if (pm != FB_ALLONES)
+ memset (d, 0, dstStride * h);
+ fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
+ (CARD8 *) d, dstStride, 0,
+ w, h, GXcopy, pm);
+}
+
+void
+fb24_32CopyMtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits *srcBits;
+ CARD8 *src;
+ FbStride srcStride;
+ int srcBpp;
+ FbBits *dstBits;
+ CARD8 *dst;
+ FbStride dstStride;
+ int dstBpp;
+ fb24_32BltFunc blt;
+ int srcXoff, srcYoff;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
+ src = (CARD8 *) srcBits;
+ srcStride *= sizeof (FbBits);
+ fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+ dst = (CARD8 *) dstBits;
+ dstStride *= sizeof (FbBits);
+ if (srcBpp == 24)
+ blt = fb24_32BltUp;
+ else
+ blt = fb24_32BltDown;
+
+ while (nbox--)
+ {
+ (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff),
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff),
+
+ (pbox->x2 - pbox->x1),
+ (pbox->y2 - pbox->y1),
+
+ pGC->alu,
+ pPriv->pm);
+ pbox++;
+ }
+}
+
+PixmapPtr
+fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
+{
+ ScreenPtr pScreen = pOldTile->drawable.pScreen;
+ PixmapPtr pNewTile;
+ FbBits *old, *new;
+ FbStride oldStride, newStride;
+ int oldBpp, newBpp;
+ fb24_32BltFunc blt;
+ _X_UNUSED int oldXoff, oldYoff;
+ _X_UNUSED int newXoff, newYoff;
+
+ pNewTile = fbCreatePixmapBpp (pScreen,
+ pOldTile->drawable.width,
+ pOldTile->drawable.height,
+ pOldTile->drawable.depth,
+ bitsPerPixel, 0);
+ if (!pNewTile)
+ return 0;
+ fbGetDrawable (&pOldTile->drawable,
+ old, oldStride, oldBpp, oldXoff, oldYoff);
+ fbGetDrawable (&pNewTile->drawable,
+ new, newStride, newBpp, newXoff, newYoff);
+ if (oldBpp == 24)
+ blt = fb24_32BltUp;
+ else
+ blt = fb24_32BltDown;
+
+ (*blt) ((CARD8 *) old,
+ oldStride * sizeof (FbBits),
+ 0,
+
+ (CARD8 *) new,
+ newStride * sizeof (FbBits),
+ 0,
+
+ pOldTile->drawable.width,
+ pOldTile->drawable.height,
+
+ GXcopy,
+ FB_ALLONES);
+
+ return pNewTile;
+}
+
+typedef struct {
+ void * pbits;
+ int width;
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+Bool
+fb24_32CreateScreenResources(ScreenPtr pScreen)
+{
+ miScreenInitParmsPtr pScrInitParms;
+ int pitch;
+ Bool retval;
+
+ /* get the pitch before mi destroys it */
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+ pitch = BitmapBytePad(pScrInitParms->width * 24);
+
+ if((retval = miCreateScreenResources(pScreen))) {
+ /* fix the screen pixmap */
+ PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate;
+ pPix->drawable.bitsPerPixel = 24;
+ pPix->devKind = pitch;
+ }
+
+ return retval;
+}
+
+Bool
+fb24_32ModifyPixmapHeader (PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ void *pPixData)
+{
+ int bpp, w;
+
+ if (!pPixmap)
+ return FALSE;
+ bpp = bitsPerPixel;
+ if (bpp <= 0)
+ bpp = pPixmap->drawable.bitsPerPixel;
+ if (bpp == 24)
+ {
+ if (devKind < 0)
+ {
+ w = width;
+ if (w <= 0)
+ w = pPixmap->drawable.width;
+ devKind = BitmapBytePad(w * 24);
+ }
+ }
+ return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
+ devKind, pPixData);
+}
diff --git a/nx-X11/programs/Xserver/fb/fballpriv.c b/nx-X11/programs/Xserver/fb/fballpriv.c
new file mode 100644
index 000000000..d2d8866e2
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fballpriv.c
@@ -0,0 +1,92 @@
+/*
+ * Id: fballpriv.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#ifdef FB_SCREEN_PRIVATE
+int fbScreenPrivateIndex;
+int fbGetScreenPrivateIndex(void)
+{
+ return fbScreenPrivateIndex;
+}
+#endif
+int fbGCPrivateIndex;
+int fbGetGCPrivateIndex(void)
+{
+ return fbGCPrivateIndex;
+}
+#ifndef FB_NO_WINDOW_PIXMAPS
+int fbWinPrivateIndex;
+int fbGetWinPrivateIndex(void)
+{
+ return fbWinPrivateIndex;
+}
+#endif
+int fbGeneration;
+
+#ifdef FB_OLD_SCREEN
+#define miAllocateGCPrivateIndex() AllocateGCPrivateIndex()
+#endif
+
+Bool
+fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex)
+{
+ if (fbGeneration != serverGeneration)
+ {
+ fbGCPrivateIndex = miAllocateGCPrivateIndex ();
+#ifndef FB_NO_WINDOW_PIXMAPS
+ fbWinPrivateIndex = AllocateWindowPrivateIndex();
+#endif
+#ifdef FB_SCREEN_PRIVATE
+ fbScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (fbScreenPrivateIndex == -1)
+ return FALSE;
+#endif
+
+ fbGeneration = serverGeneration;
+ }
+ if (pGCIndex)
+ *pGCIndex = fbGCPrivateIndex;
+ if (!AllocateGCPrivate(pScreen, fbGCPrivateIndex, sizeof(FbGCPrivRec)))
+ return FALSE;
+#ifndef FB_NO_WINDOW_PIXMAPS
+ if (!AllocateWindowPrivate(pScreen, fbWinPrivateIndex, 0))
+ return FALSE;
+#endif
+#ifdef FB_SCREEN_PRIVATE
+ {
+ FbScreenPrivPtr pScreenPriv;
+
+ pScreenPriv = (FbScreenPrivPtr) malloc (sizeof (FbScreenPrivRec));
+ if (!pScreenPriv)
+ return FALSE;
+ pScreen->devPrivates[fbScreenPrivateIndex].ptr = (void *) pScreenPriv;
+ }
+#endif
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/fb/fbarc.c b/nx-X11/programs/Xserver/fb/fbarc.c
new file mode 100644
index 000000000..ae89e44d8
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbarc.c
@@ -0,0 +1,119 @@
+/*
+ * Id: fbarc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+#include "mizerarc.h"
+#include <limits.h>
+
+typedef void (*FbArc) (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int dx,
+ int dy,
+ FbBits and,
+ FbBits xor);
+
+void
+fbPolyArc (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs)
+{
+ FbArc arc;
+
+ if (pGC->lineWidth == 0)
+ {
+#ifndef FBNOPIXADDR
+ arc = 0;
+ if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid)
+ {
+ switch (pDrawable->bitsPerPixel)
+ {
+ case 8: arc = fbArc8; break;
+ case 16: arc = fbArc16; break;
+#ifdef FB_24BIT
+ case 24: arc = fbArc24; break;
+#endif
+ case 32: arc = fbArc32; break;
+ }
+ }
+ if (arc)
+ {
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ BoxRec box;
+ int x2, y2;
+ RegionPtr cclip;
+
+ cclip = fbGetCompositeClip (pGC);
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ while (narcs--)
+ {
+ if (miCanZeroArc (parcs))
+ {
+ box.x1 = parcs->x + pDrawable->x;
+ box.y1 = parcs->y + pDrawable->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)parcs->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)parcs->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
+ (RegionContainsRect(cclip, &box) == rgnIN) )
+ (*arc) (dst, dstStride, dstBpp,
+ parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff,
+ pPriv->and, pPriv->xor);
+ else
+ miZeroPolyArc(pDrawable, pGC, 1, parcs);
+ }
+ else
+ miPolyArc(pDrawable, pGC, 1, parcs);
+ parcs++;
+ }
+ }
+ else
+#endif
+ miZeroPolyArc (pDrawable, pGC, narcs, parcs);
+ }
+ else
+ miPolyArc (pDrawable, pGC, narcs, parcs);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbbits.c b/nx-X11/programs/Xserver/fb/fbbits.c
new file mode 100644
index 000000000..56b58df4e
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbbits.c
@@ -0,0 +1,178 @@
+/*
+ * Id: fbbits.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+#include "miline.h"
+#include "mizerarc.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef BITS
+#undef BITS2
+#undef BITS4
+
+#define BRESSOLID fbBresSolid8
+#define BRESDASH fbBresDash8
+#define DOTS fbDots8
+#define ARC fbArc8
+#define GLYPH fbGlyph8
+#define POLYLINE fbPolyline8
+#define POLYSEGMENT fbPolySegment8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef POLYLINE
+#undef POLYSEGMENT
+#undef BITS
+#undef BITS2
+#undef BITS4
+
+#define BRESSOLID fbBresSolid16
+#define BRESDASH fbBresDash16
+#define DOTS fbDots16
+#define ARC fbArc16
+#define GLYPH fbGlyph16
+#define POLYLINE fbPolyline16
+#define POLYSEGMENT fbPolySegment16
+#define BITS CARD16
+#define BITS2 CARD32
+#if FB_SHIFT == 6
+#define BITS4 FbBits
+#endif
+
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef POLYLINE
+#undef POLYSEGMENT
+#undef BITS
+#undef BITS2
+#if FB_SHIFT == 6
+#undef BITS4
+#endif
+
+#ifdef FB_24BIT
+#define BRESSOLID fbBresSolid24
+#define BRESDASH fbBresDash24
+#define DOTS fbDots24
+#define ARC fbArc24
+#define POLYLINE fbPolyline24
+#define POLYSEGMENT fbPolySegment24
+
+#define BITS CARD32
+#define BITSUNIT BYTE
+#define BITSMUL 3
+
+#define FbDoTypeStore(b,t,x,s) (*((t *) (b)) = (x) >> (s))
+#define FbDoTypeRRop(b,t,a,x,s) (*((t *) (b)) = FbDoRRop(*((t *) (b)),\
+ (a) >> (s), \
+ (x) >> (s)))
+#define FbDoTypeMaskRRop(b,t,a,x,m,s) (*((t *) (b)) = FbDoMaskRRop(*((t *) (b)),\
+ (a) >> (s), \
+ (x) >> (s), \
+ (m) >> (s))
+#if BITMAP_BIT_ORDER == LSBFirst
+#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \
+ (FbDoTypeStore (b, CARD8, x, 0), \
+ FbDoTypeStore ((b) + 1, CARD16, x, 8)) : \
+ (FbDoTypeStore (b, CARD16, x, 0), \
+ FbDoTypeStore ((b) + 2, CARD8, x, 16)))
+#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \
+ (FbDoTypeRRop(b,CARD8,a,x,0), \
+ FbDoTypeRRop((b)+1,CARD16,a,x,8)) : \
+ (FbDoTypeRRop(b,CARD16,a,x,0), \
+ FbDoTypeRRop((b)+2,CARD8,a,x,16)))
+#else
+#define BITSSTORE(b,x) ((unsigned long) (b) & 1 ? \
+ (FbDoTypeStore (b, CARD8, x, 16), \
+ FbDoTypeStore ((b) + 1, CARD16, x, 0)) : \
+ (FbDoTypeStore (b, CARD16, x, 8), \
+ FbDoTypeStore ((b) + 2, CARD8, x, 0)))
+#define BITSRROP(b,a,x) ((unsigned long) (b) & 1 ? \
+ (FbDoTypeRRop (b, CARD8, a, x, 16), \
+ FbDoTypeRRop ((b) + 1, CARD16, a, x, 0)) : \
+ (FbDoTypeRRop (b, CARD16, a, x, 8), \
+ FbDoTypeRRop ((b) + 2, CARD8, a, x, 0)))
+#endif
+
+#include "fbbits.h"
+
+#undef BITSSTORE
+#undef BITSRROP
+#undef BITSMUL
+#undef BITSUNIT
+#undef BITS
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef POLYLINE
+#undef POLYSEGMENT
+#endif /* FB_24BIT */
+
+#define BRESSOLID fbBresSolid32
+#define BRESDASH fbBresDash32
+#define DOTS fbDots32
+#define ARC fbArc32
+#define GLYPH fbGlyph32
+#define POLYLINE fbPolyline32
+#define POLYSEGMENT fbPolySegment32
+#define BITS CARD32
+#if FB_SHIFT == 6
+#define BITS2 FbBits
+#endif
+
+#include "fbbits.h"
+
+#undef BRESSOLID
+#undef BRESDASH
+#undef DOTS
+#undef ARC
+#undef GLYPH
+#undef POLYLINE
+#undef POLYSEGMENT
+#undef BITS
+#if FB_SHIFT == 6
+#undef BITS2
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbbits.h b/nx-X11/programs/Xserver/fb/fbbits.h
new file mode 100644
index 000000000..30fa21f1e
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbbits.h
@@ -0,0 +1,960 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+/*
+ * This file defines functions for drawing some primitives using
+ * underlying datatypes instead of masks
+ */
+
+#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef BITSMUL
+#define MUL BITSMUL
+#else
+#define MUL 1
+#endif
+
+#ifdef BITSSTORE
+#define STORE(b,x) BITSSTORE(b,x)
+#else
+#define STORE(b,x) (*(b) = (x))
+#endif
+
+#ifdef BITSRROP
+#define RROP(b,a,x) BITSRROP(b,a,x)
+#else
+#define RROP(b,a,x) (*(b) = FbDoRRop (*(b), (a), (x)))
+#endif
+
+#ifdef BITSUNIT
+#define UNIT BITSUNIT
+#define USE_SOLID
+#else
+#define UNIT BITS
+#endif
+
+/*
+ * Define the following before including this file:
+ *
+ * BRESSOLID name of function for drawing a solid segment
+ * BRESDASH name of function for drawing a dashed segment
+ * DOTS name of function for drawing dots
+ * ARC name of function for drawing a solid arc
+ * BITS type of underlying unit
+ */
+
+#ifdef BRESSOLID
+void
+BRESSOLID (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ UNIT *bits;
+ FbStride bitsStride;
+ FbStride majorStep, minorStep;
+ BITS xor = (BITS) pPriv->xor;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ if (signdy < 0)
+ bitsStride = -bitsStride;
+ if (axis == X_AXIS)
+ {
+ majorStep = signdx * MUL;
+ minorStep = bitsStride;
+ }
+ else
+ {
+ majorStep = bitsStride;
+ minorStep = signdx * MUL;
+ }
+ while (len--)
+ {
+ STORE(bits,xor);
+ bits += majorStep;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += minorStep;
+ e += e3;
+ }
+ }
+}
+#endif
+
+#ifdef BRESDASH
+void
+BRESDASH (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ UNIT *bits;
+ FbStride bitsStride;
+ FbStride majorStep, minorStep;
+ BITS xorfg, xorbg;
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ xorfg = (BITS) pPriv->xor;
+ xorbg = (BITS) pPriv->bgxor;
+
+ FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
+
+ bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ if (signdy < 0)
+ bitsStride = -bitsStride;
+ if (axis == X_AXIS)
+ {
+ majorStep = signdx * MUL;
+ minorStep = bitsStride;
+ }
+ else
+ {
+ majorStep = bitsStride;
+ minorStep = signdx * MUL;
+ }
+ if (dashlen >= len)
+ dashlen = len;
+ if (doOdd)
+ {
+ if (!even)
+ goto doubleOdd;
+ for (;;)
+ {
+ len -= dashlen;
+ while (dashlen--)
+ {
+ STORE(bits,xorfg);
+ bits += majorStep;
+ if ((e += e1) >= 0)
+ {
+ e += e3;
+ bits += minorStep;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextEven(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+doubleOdd:
+ len -= dashlen;
+ while (dashlen--)
+ {
+ STORE(bits,xorbg);
+ bits += majorStep;
+ if ((e += e1) >= 0)
+ {
+ e += e3;
+ bits += minorStep;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextOdd(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+ }
+ }
+ else
+ {
+ if (!even)
+ goto onOffOdd;
+ for (;;)
+ {
+ len -= dashlen;
+ while (dashlen--)
+ {
+ STORE(bits,xorfg);
+ bits += majorStep;
+ if ((e += e1) >= 0)
+ {
+ e += e3;
+ bits += minorStep;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextEven (dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+onOffOdd:
+ len -= dashlen;
+ while (dashlen--)
+ {
+ bits += majorStep;
+ if ((e += e1) >= 0)
+ {
+ e += e3;
+ bits += minorStep;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextOdd (dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+ }
+ }
+}
+#endif
+
+#ifdef DOTS
+void
+DOTS (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *ptsOrig,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor)
+{
+ INT32 *pts = (INT32 *) ptsOrig;
+ UNIT *bits = (UNIT *) dst;
+ UNIT *point;
+ BITS bxor = (BITS) xor;
+ BITS band = (BITS) and;
+ FbStride bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ INT32 ul, lr;
+ INT32 pt;
+
+ ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg);
+ lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1);
+
+ bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL;
+
+ if (and == 0)
+ {
+ while (npt--)
+ {
+ pt = *pts++;
+ if (!isClipped(pt,ul,lr))
+ {
+ point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
+ STORE(point,bxor);
+ }
+ }
+ }
+ else
+ {
+ while (npt--)
+ {
+ pt = *pts++;
+ if (!isClipped(pt,ul,lr))
+ {
+ point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
+ RROP(point,band,bxor);
+ }
+ }
+ }
+}
+#endif
+
+#ifdef ARC
+
+#define ARCCOPY(d) STORE(d,xorBits)
+#define ARCRROP(d) RROP(d,andBits,xorBits)
+
+void
+ARC (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ xArc *arc,
+ int drawX,
+ int drawY,
+ FbBits and,
+ FbBits xor)
+{
+ UNIT *bits;
+ FbStride bitsStride;
+ miZeroArcRec info;
+ Bool do360;
+ int x;
+ UNIT *yorgp, *yorgop;
+ BITS andBits, xorBits;
+ int yoffset, dyoffset;
+ int y, a, b, d, mask;
+ int k1, k3, dx, dy;
+
+ bits = (UNIT *) dst;
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ andBits = (BITS) and;
+ xorBits = (BITS) xor;
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgp = bits + ((info.yorg + drawY) * bitsStride);
+ yorgop = bits + ((info.yorgo + drawY) * bitsStride);
+ info.xorg = (info.xorg + drawX) * MUL;
+ info.xorgo = (info.xorgo + drawX) * MUL;
+ MIARCSETUP();
+ yoffset = y ? bitsStride : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+
+ if (!(arc->width & 1))
+ {
+ if (andBits == 0)
+ {
+ if (mask & 2)
+ ARCCOPY(yorgp + info.xorgo);
+ if (mask & 8)
+ ARCCOPY(yorgop + info.xorgo);
+ }
+ else
+ {
+ if (mask & 2)
+ ARCRROP(yorgp + info.xorgo);
+ if (mask & 8)
+ ARCRROP(yorgop + info.xorgo);
+ }
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int xoffset = bitsStride;
+ UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
+ UNIT *yorgohb = yorghb - info.h * MUL;
+
+ yorgp += info.xorg;
+ yorgop += info.xorg;
+ yorghb += info.h * MUL;
+ while (1)
+ {
+ if (andBits == 0)
+ {
+ ARCCOPY(yorgp + yoffset + x * MUL);
+ ARCCOPY(yorgp + yoffset - x * MUL);
+ ARCCOPY(yorgop - yoffset - x * MUL);
+ ARCCOPY(yorgop - yoffset + x * MUL);
+ }
+ else
+ {
+ ARCRROP(yorgp + yoffset + x * MUL);
+ ARCRROP(yorgp + yoffset - x * MUL);
+ ARCRROP(yorgop - yoffset - x * MUL);
+ ARCRROP(yorgop - yoffset + x * MUL);
+ }
+ if (a < 0)
+ break;
+ if (andBits == 0)
+ {
+ ARCCOPY(yorghb - xoffset - y * MUL);
+ ARCCOPY(yorgohb - xoffset + y * MUL);
+ ARCCOPY(yorgohb + xoffset + y * MUL);
+ ARCCOPY(yorghb + xoffset - y * MUL);
+ }
+ else
+ {
+ ARCRROP(yorghb - xoffset - y * MUL);
+ ARCRROP(yorgohb - xoffset + y * MUL);
+ ARCRROP(yorgohb + xoffset + y * MUL);
+ ARCRROP(yorghb + xoffset - y * MUL);
+ }
+ xoffset += bitsStride;
+ MIARCCIRCLESTEP(yoffset += bitsStride;);
+ }
+ yorgp -= info.xorg;
+ yorgop -= info.xorg;
+ x = info.w;
+ yoffset = info.h * bitsStride;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ if (andBits == 0)
+ {
+ ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
+ ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
+ ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
+ ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ else
+ {
+ ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
+ ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
+ ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
+ ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ if (andBits == 0)
+ {
+ if (mask & 1)
+ ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
+ if (mask & 2)
+ ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
+ if (mask & 4)
+ ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
+ if (mask & 8)
+ ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ else
+ {
+ if (mask & 1)
+ ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
+ if (mask & 2)
+ ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
+ if (mask & 4)
+ ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
+ if (mask & 8)
+ ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ if (andBits == 0)
+ {
+ if (mask & 1)
+ ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
+ if (mask & 4)
+ ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
+ if (arc->height & 1)
+ {
+ if (mask & 2)
+ ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
+ if (mask & 8)
+ ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ }
+ else
+ {
+ if (mask & 1)
+ ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
+ if (mask & 4)
+ ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
+ if (arc->height & 1)
+ {
+ if (mask & 2)
+ ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
+ if (mask & 8)
+ ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
+ }
+ }
+}
+#undef ARCCOPY
+#undef ARCRROP
+#endif
+
+#ifdef GLYPH
+#if BITMAP_BIT_ORDER == LSBFirst
+# define WRITE_ADDR1(n) (n)
+# define WRITE_ADDR2(n) (n)
+# define WRITE_ADDR4(n) (n)
+#else
+# define WRITE_ADDR1(n) ((n) ^ 3)
+# define WRITE_ADDR2(n) ((n) ^ 2)
+# define WRITE_ADDR4(n) ((n))
+#endif
+
+#define WRITE1(d,n,fg) ((d)[WRITE_ADDR1(n)] = (BITS) (fg))
+
+#ifdef BITS2
+# define WRITE2(d,n,fg) (*((BITS2 *) &((d)[WRITE_ADDR2(n)])) = (BITS2) (fg))
+#else
+# define WRITE2(d,n,fg) WRITE1(d,(n)+1,WRITE1(d,n,fg))
+#endif
+
+#ifdef BITS4
+# define WRITE4(d,n,fg) (*((BITS4 *) &((d)[WRITE_ADDR4(n)])) = (BITS4) (fg))
+#else
+# define WRITE4(d,n,fg) WRITE2(d,(n)+2,WRITE2(d,n,fg))
+#endif
+
+void
+GLYPH (FbBits *dstBits,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int x,
+ int height)
+{
+ int lshift;
+ FbStip bits;
+ BITS *dstLine;
+ BITS *dst;
+ int n;
+ int shift;
+
+ dstLine = (BITS *) dstBits;
+ dstLine += x & ~3;
+ dstStride *= (sizeof (FbBits) / sizeof (BITS));
+ shift = x & 3;
+ lshift = 4 - shift;
+ while (height--)
+ {
+ bits = *stipple++;
+ dst = (BITS *) dstLine;
+ n = lshift;
+ while (bits)
+ {
+ switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
+ case 0:
+ break;
+ case 1:
+ WRITE1(dst,0,fg);
+ break;
+ case 2:
+ WRITE1(dst,1,fg);
+ break;
+ case 3:
+ WRITE2(dst,0,fg);
+ break;
+ case 4:
+ WRITE1(dst,2,fg);
+ break;
+ case 5:
+ WRITE1(dst,0,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 6:
+ WRITE1(dst,1,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 7:
+ WRITE2(dst,0,fg);
+ WRITE1(dst,2,fg);
+ break;
+ case 8:
+ WRITE1(dst,3,fg);
+ break;
+ case 9:
+ WRITE1(dst,0,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 10:
+ WRITE1(dst,1,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 11:
+ WRITE2(dst,0,fg);
+ WRITE1(dst,3,fg);
+ break;
+ case 12:
+ WRITE2(dst,2,fg);
+ break;
+ case 13:
+ WRITE1(dst,0,fg);
+ WRITE2(dst,2,fg);
+ break;
+ case 14:
+ WRITE1(dst,1,fg);
+ WRITE2(dst,2,fg);
+ break;
+ case 15:
+ WRITE4(dst,0,fg);
+ break;
+ }
+ bits = FbStipLeft (bits, n);
+ n = 4;
+ dst += 4;
+ }
+ dstLine += dstStride;
+ }
+}
+#undef WRITE_ADDR1
+#undef WRITE_ADDR2
+#undef WRITE_ADDR4
+#undef WRITE1
+#undef WRITE2
+#undef WRITE4
+
+#endif
+
+#ifdef POLYLINE
+void
+POLYLINE (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ptsOrig)
+{
+ INT32 *pts = (INT32 *) ptsOrig;
+ int xoff = pDrawable->x;
+ int yoff = pDrawable->y;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC));
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ UNIT *bits, *bitsBase;
+ FbStride bitsStride;
+ BITS xor = fbGetGCPrivate(pGC)->xor;
+ BITS and = fbGetGCPrivate(pGC)->and;
+ int dashoffset = 0;
+
+ INT32 ul, lr;
+ INT32 pt1, pt2;
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+
+ if (mode == CoordModePrevious)
+ fbFixCoordModePrevious (npt, ptsOrig);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
+ ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
+ lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
+
+ pt1 = *pts++;
+ npt--;
+ pt2 = *pts++;
+ npt--;
+ for (;;)
+ {
+ if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr))
+ {
+ fbSegment (pDrawable, pGC,
+ intToX(pt1) + xoff, intToY(pt1) + yoff,
+ intToX(pt2) + xoff, intToY(pt2) + yoff,
+ npt == 0 && pGC->capStyle != CapNotLast,
+ &dashoffset);
+ if (!npt)
+ return;
+ pt1 = pt2;
+ pt2 = *pts++;
+ npt--;
+ }
+ else
+ {
+ bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
+ for (;;)
+ {
+ CalcLineDeltas (intToX(pt1), intToY(pt1),
+ intToX(pt2), intToY(pt2),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ stepmajor *= MUL;
+ if (len < e1)
+ {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR (e, octant, bias);
+ if (and == 0)
+ {
+ while (len--)
+ {
+ STORE(bits,xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ RROP(bits,and,xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ if (!npt)
+ {
+ if (pGC->capStyle != CapNotLast &&
+ pt2 != *((INT32 *) ptsOrig))
+ {
+ RROP(bits,and,xor);
+ }
+ return;
+ }
+ pt1 = pt2;
+ pt2 = *pts++;
+ --npt;
+ if (isClipped (pt2, ul, lr))
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#ifdef POLYSEGMENT
+void
+POLYSEGMENT (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg)
+{
+ INT32 *pts = (INT32 *) pseg;
+ int xoff = pDrawable->x;
+ int yoff = pDrawable->y;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC));
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ UNIT *bits, *bitsBase;
+ FbStride bitsStride;
+ FbBits xorBits = fbGetGCPrivate(pGC)->xor;
+ FbBits andBits = fbGetGCPrivate(pGC)->and;
+ BITS xor = xorBits;
+ BITS and = andBits;
+ int dashoffset = 0;
+
+ INT32 ul, lr;
+ INT32 pt1, pt2;
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+ Bool capNotLast;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
+ bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
+ ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
+ lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
+
+ capNotLast = pGC->capStyle == CapNotLast;
+
+ while (nseg--)
+ {
+ pt1 = *pts++;
+ pt2 = *pts++;
+ if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr))
+ {
+ fbSegment (pDrawable, pGC,
+ intToX(pt1) + xoff, intToY(pt1) + yoff,
+ intToX(pt2) + xoff, intToY(pt2) + yoff,
+ !capNotLast, &dashoffset);
+ }
+ else
+ {
+ CalcLineDeltas (intToX(pt1), intToY(pt1),
+ intToX(pt2), intToY(pt2),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ if (e1 == 0 && len > 3
+#if MUL != 1
+ && FbCheck24Pix(and) && FbCheck24Pix(xor)
+#endif
+ )
+ {
+ int x1, x2;
+ FbBits *dstLine;
+ int dstX, width;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ if (stepmajor < 0)
+ {
+ x1 = intToX(pt2);
+ x2 = intToX(pt1) + 1;
+ if (capNotLast)
+ x1++;
+ }
+ else
+ {
+ x1 = intToX(pt1);
+ x2 = intToX(pt2);
+ if (!capNotLast)
+ x2++;
+ }
+ dstX = (x1 + xoff + dstXoff) * (sizeof (UNIT) * 8 * MUL);
+ width = (x2 - x1) * (sizeof (UNIT) * 8 * MUL);
+
+ dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride;
+ dstLine += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits (dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ {
+ *dstLine = FbDoMaskRRop (*dstLine, andBits, xorBits, startmask);
+ dstLine++;
+ }
+ if (!andBits)
+ while (nmiddle--)
+ *dstLine++ = xorBits;
+ else
+ while (nmiddle--)
+ {
+ *dstLine = FbDoRRop (*dstLine, andBits, xorBits);
+ dstLine++;
+ }
+ if (endmask)
+ *dstLine = FbDoMaskRRop (*dstLine, andBits, xorBits, endmask);
+ }
+ else
+ {
+ stepmajor *= MUL;
+ bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
+ if (len < e1)
+ {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR (e, octant, bias);
+ if (!capNotLast)
+ len++;
+ if (and == 0)
+ {
+ while (len--)
+ {
+ STORE(bits,xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ RROP(bits,and,xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0)
+ {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+#undef MUL
+#undef STORE
+#undef RROP
+#undef UNIT
+#undef USE_SOLID
+
+#undef isClipped
diff --git a/nx-X11/programs/Xserver/fb/fbblt.c b/nx-X11/programs/Xserver/fb/fbblt.c
new file mode 100644
index 000000000..085a8e639
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbblt.c
@@ -0,0 +1,932 @@
+/*
+ * Id: fbblt.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#define InitializeShifts(sx,dx,ls,rs) { \
+ if (sx != dx) { \
+ if (sx > dx) { \
+ ls = sx - dx; \
+ rs = FB_UNIT - ls; \
+ } else { \
+ rs = dx - sx; \
+ ls = FB_UNIT - rs; \
+ } \
+ } \
+}
+
+void
+fbBlt (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ FbBits *src, *dst;
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ FbBits bits, bits1;
+ int n, nmiddle;
+ Bool destInvarient;
+ int startbyte, endbyte;
+ FbDeclareMergeRop ();
+
+#ifdef FB_24BIT
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
+ width, height, alu, pm, reverse, upsidedown);
+ return;
+ }
+#endif
+ FbInitializeMergeRop(alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+ if (upsidedown)
+ {
+ srcLine += (height - 1) * (srcStride);
+ dstLine += (height - 1) * (dstStride);
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
+ nmiddle, endmask, endbyte);
+ if (reverse)
+ {
+ srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ srcLine += srcX >> FB_SHIFT;
+ dstLine += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ }
+ if (srcX == dstX)
+ {
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = *--src;
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ *--dst = FbDoDestInvarientMergeRop(*--src);
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMergeRop (bits, *dst);
+ }
+ }
+ if (startmask)
+ {
+ bits = *--src;
+ --dst;
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+#if 0
+ /*
+ * This provides some speedup on screen->screen blts
+ * over the PCI bus, usually about 10%. But fb
+ * isn't usually used for this operation...
+ */
+ if (_ca2 + 1 == 0 && _cx2 == 0)
+ {
+ FbBits t1, t2, t3, t4;
+ while (n >= 4)
+ {
+ t1 = *src++;
+ t2 = *src++;
+ t3 = *src++;
+ t4 = *src++;
+ *dst++ = t1;
+ *dst++ = t2;
+ *dst++ = t3;
+ *dst++ = t4;
+ n -= 4;
+ }
+ }
+#endif
+ while (n--)
+ *dst++ = FbDoDestInvarientMergeRop(*src++);
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMergeRop (bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = *src;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = *--src;
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoDestInvarientMergeRop(bits);
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoMergeRop(bits, *dst);
+ }
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = *src++;
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(startmask, rightShift))
+ {
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoDestInvarientMergeRop(bits);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMergeRop(bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = *src;
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ }
+}
+
+#ifdef FB_24BIT
+
+#undef DEBUG_BLT24
+#ifdef DEBUG_BLT24
+
+static unsigned long
+getPixel (char *src, int x)
+{
+ unsigned long l;
+
+ l = 0;
+ memcpy (&l, src + x * 3, 3);
+ return l;
+}
+#endif
+
+static void
+fbBlt24Line (FbBits *src,
+ int srcX,
+
+ FbBits *dst,
+ int dstX,
+
+ int width,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse)
+{
+#ifdef DEBUG_BLT24
+ char *origDst = (char *) dst;
+ FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
+ int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
+ int origX = dstX / 24;
+#endif
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int n;
+
+ FbBits bits, bits1;
+ FbBits mask;
+
+ int rot;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop (alu, FB_ALLONES);
+ FbMaskBits(dstX, width, startmask, n, endmask);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse);
+#endif
+ if (reverse)
+ {
+ src += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK));
+ rot = FbPrev24Rot(rot);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot);
+#endif
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ src += srcX >> FB_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ rot = FbFirst24Rot (dstX);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX: %d rot: %d\n", dstX, rot);
+#endif
+ }
+ mask = FbRot24(pm,rot);
+#ifdef DEBUG_BLT24
+ ErrorF ("pm 0x%x mask 0x%x\n", pm, mask);
+#endif
+ if (srcX == dstX)
+ {
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ mask = FbPrev24Pix (mask);
+ }
+ while (n--)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask);
+ mask = FbPrev24Pix (mask);
+ }
+ if (startmask)
+ {
+ bits = *--src;
+ --dst;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = *src;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = *--src;
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ mask = FbPrev24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ *dst = FbDoMaskMergeRop(bits, *dst, mask);
+ mask = FbPrev24Pix(mask);
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = *--src;
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = *src++;
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = *src++;
+ bits |= FbScrRight(bits1, rightShift);
+ *dst = FbDoMaskMergeRop(bits, *dst, mask);
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = *src;
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
+ }
+ }
+ }
+#ifdef DEBUG_BLT24
+ {
+ int firstx, lastx, x;
+
+ firstx = origX;
+ if (firstx)
+ firstx--;
+ lastx = origX + width/24 + 1;
+ for (x = firstx; x <= lastx; x++)
+ ErrorF ("%06x ", getPixel (origDst, x));
+ ErrorF ("\n");
+ while (origNlw--)
+ ErrorF ("%08x ", *origLine++);
+ ErrorF ("\n");
+ }
+#endif
+}
+
+void
+fbBlt24 (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ if (upsidedown)
+ {
+ srcLine += (height-1) * srcStride;
+ dstLine += (height-1) * dstStride;
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ while (height--)
+ {
+ fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
+ srcLine += srcStride;
+ dstLine += dstStride;
+ }
+#ifdef DEBUG_BLT24
+ ErrorF ("\n");
+#endif
+}
+#endif /* FB_24BIT */
+
+#if FB_SHIFT == FB_STIP_SHIFT + 1
+
+/*
+ * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
+ * creating an ring of values stepped through for each line
+ */
+
+void
+fbBltOdd (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+ FbBits *src;
+ int leftShiftEven, rightShiftEven;
+ FbBits startmaskEven, endmaskEven;
+ int nmiddleEven;
+
+ FbBits *dst;
+ int leftShiftOdd, rightShiftOdd;
+ FbBits startmaskOdd, endmaskOdd;
+ int nmiddleOdd;
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ int srcX, dstX;
+
+ FbBits bits, bits1;
+ int n;
+
+ Bool destInvarient;
+ Bool even;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop (alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+
+ srcLine += srcXEven >> FB_SHIFT;
+ dstLine += dstXEven >> FB_SHIFT;
+ srcXEven &= FB_MASK;
+ dstXEven &= FB_MASK;
+ srcXOdd &= FB_MASK;
+ dstXOdd &= FB_MASK;
+
+ FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
+ FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
+
+ even = TRUE;
+ InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
+ InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
+ while (height--)
+ {
+ src = srcLine;
+ dst = dstLine;
+ if (even)
+ {
+ srcX = srcXEven;
+ dstX = dstXEven;
+ startmask = startmaskEven;
+ endmask = endmaskEven;
+ nmiddle = nmiddleEven;
+ leftShift = leftShiftEven;
+ rightShift = rightShiftEven;
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ srcX = srcXOdd;
+ dstX = dstXOdd;
+ startmask = startmaskOdd;
+ endmask = endmaskOdd;
+ nmiddle = nmiddleOdd;
+ leftShift = leftShiftOdd;
+ rightShift = rightShiftOdd;
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ if (srcX == dstX)
+ {
+ if (startmask)
+ {
+ bits = *src++;
+ *dst = FbDoMaskMergeRop (bits, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoDestInvarientMergeRop(bits);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = *src++;
+ *dst = FbDoMergeRop (bits, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = *src;
+ *dst = FbDoMaskMergeRop(bits, *dst, endmask);
+ }
+ }
+ else
+ {
+ bits = 0;
+ if (srcX > dstX)
+ bits = *src++;
+ if (startmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoMaskMergeRop (bits1, *dst, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoDestInvarientMergeRop(bits1);
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = *src++;
+ bits1 |= FbScrRight(bits, rightShift);
+ *dst = FbDoMergeRop(bits1, *dst);
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits = *src;
+ bits1 |= FbScrRight(bits, rightShift);
+ }
+ *dst = FbDoMaskMergeRop (bits1, *dst, endmask);
+ }
+ }
+ }
+}
+
+#ifdef FB_24BIT
+void
+fbBltOdd24 (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm)
+{
+ Bool even = TRUE;
+
+ while (height--)
+ {
+ if (even)
+ {
+ fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ }
+#if 0
+ fprintf (stderr, "\n");
+#endif
+}
+#endif
+
+#endif
+
+#if FB_STIP_SHIFT != FB_SHIFT
+void
+fbSetBltOdd (FbStip *stip,
+ FbStride stipStride,
+ int srcX,
+ FbBits **bits,
+ FbStride *strideEven,
+ FbStride *strideOdd,
+ int *srcXEven,
+ int *srcXOdd)
+{
+ int srcAdjust;
+ int strideAdjust;
+
+ /*
+ * bytes needed to align source
+ */
+ srcAdjust = (((int) stip) & (FB_MASK >> 3));
+ /*
+ * FbStip units needed to align stride
+ */
+ strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
+
+ *bits = (FbBits *) ((char *) stip - srcAdjust);
+ if (srcAdjust)
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride + 1);
+ *strideOdd = FbStipStrideToBitsStride (stipStride);
+
+ *srcXEven = srcX + (srcAdjust << 3);
+ *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
+ }
+ else
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride);
+ *strideOdd = FbStipStrideToBitsStride (stipStride + 1);
+
+ *srcXEven = srcX;
+ *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
+ }
+}
+#endif
+
+void
+fbBltStip (FbStip *src,
+ FbStride srcStride, /* in FbStip units, not FbBits units */
+ int srcX,
+
+ FbStip *dst,
+ FbStride dstStride, /* in FbStip units, not FbBits units */
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+#if FB_STIP_SHIFT != FB_SHIFT
+ if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
+ FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
+ {
+ FbStride srcStrideEven, srcStrideOdd;
+ FbStride dstStrideEven, dstStrideOdd;
+ int srcXEven, srcXOdd;
+ int dstXEven, dstXOdd;
+ FbBits *s, *d;
+ int sx, dx;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ fbSetBltOdd (src, srcStride, srcX,
+ &s,
+ &srcStrideEven, &srcStrideOdd,
+ &srcXEven, &srcXOdd);
+
+ fbSetBltOdd (dst, dstStride, dstX,
+ &d,
+ &dstStrideEven, &dstStrideOdd,
+ &dstXEven, &dstXOdd);
+
+#ifdef FB_24BIT
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBltOdd24 (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm);
+ }
+ else
+#endif
+ {
+ fbBltOdd (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm, bpp);
+ }
+ }
+ else
+#endif
+ {
+ fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride),
+ srcX,
+ (FbBits *) dst, FbStipStrideToBitsStride (dstStride),
+ dstX,
+ width, height,
+ alu, pm, bpp, FALSE, FALSE);
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbbltone.c b/nx-X11/programs/Xserver/fb/fbbltone.c
new file mode 100644
index 000000000..f06357a37
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbbltone.c
@@ -0,0 +1,879 @@
+/*
+ * Id: fbbltone.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+/*
+ * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ * leftShift = 12
+ * rightShift = 20
+ *
+ * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ *
+ * leftShift = 24
+ * rightShift = 8
+ */
+
+#define LoadBits {\
+ if (leftShift) { \
+ bitsRight = (src < srcEnd ? *src++ : 0); \
+ bits = (FbStipLeft (bitsLeft, leftShift) | \
+ FbStipRight(bitsRight, rightShift)); \
+ bitsLeft = bitsRight; \
+ } else \
+ bits = (src < srcEnd ? *src++ : 0); \
+}
+
+#ifndef FBNOPIXADDR
+
+#define LaneCases1(n,a) case n: (void)FbLaneCase(n,a); break
+#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a)
+#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a)
+#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a)
+#define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a)
+#define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a)
+#define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a)
+#define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a)
+#define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a)
+
+#if FB_SHIFT == 6
+#define LaneCases(a) LaneCases256(0,a)
+#endif
+
+#if FB_SHIFT == 5
+#define LaneCases(a) LaneCases16(0,a)
+#endif
+
+#if FB_SHIFT == 6
+CARD8 fb8Lane[256] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+98, 99, 100, 101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115,
+116, 117, 118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,
+134, 135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
+152, 153, 154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,
+170, 171, 172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,
+188, 189, 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
+206, 207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+224, 225, 226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
+242, 243, 244,245,246,247,248,249,250,251,252,253,254,255,
+};
+
+CARD8 fb16Lane[256] = {
+ 0x00, 0x03, 0x0c, 0x0f,
+ 0x30, 0x33, 0x3c, 0x3f,
+ 0xc0, 0xc3, 0xcc, 0xcf,
+ 0xf0, 0xf3, 0xfc, 0xff,
+};
+
+CARD8 fb32Lane[16] = {
+ 0x00, 0x0f, 0xf0, 0xff,
+};
+#endif
+
+#if FB_SHIFT == 5
+CARD8 fb8Lane[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+CARD8 fb16Lane[16] = {
+ 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+CARD8 fb32Lane[16] = {
+ 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#endif
+
+CARD8 *fbLaneTable[33] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ fb8Lane, 0, 0, 0, 0, 0, 0, 0,
+ fb16Lane, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ fb32Lane
+};
+#endif
+
+void
+fbBltOne (FbStip *src,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor)
+{
+ const FbBits *fbBits;
+ FbBits *srcEnd;
+ int pixelsPerDst; /* dst pixels per FbBits */
+ int unitsPerSrc; /* src patterns per FbStip */
+ int leftShift, rightShift; /* align source with dest */
+ FbBits startmask, endmask; /* dest scanline masks */
+ FbStip bits=0, bitsLeft, bitsRight;/* source bits */
+ FbStip left;
+ FbBits mask;
+ int nDst; /* dest longwords (w.o. end) */
+ int w;
+ int n, nmiddle;
+ int dstS; /* stipple-relative dst X coordinate */
+ Bool copy; /* accelerate dest-invariant */
+ Bool transparent; /* accelerate 0 nop */
+ int srcinc; /* source units consumed */
+ Bool endNeedsLoad = FALSE; /* need load for endmask */
+#ifndef FBNOPIXADDR
+ CARD8 *fbLane;
+#endif
+ int startbyte, endbyte;
+
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ {
+ fbBltOne24 (src, srcStride, srcX,
+ dst, dstStride, dstX, dstBpp,
+ width, height,
+ fgand, fgxor, bgand, bgxor);
+ return;
+ }
+#endif
+
+ /*
+ * Do not read past the end of the buffer!
+ */
+ srcEnd = src + height * srcStride;
+
+ /*
+ * Number of destination units in FbBits == number of stipple pixels
+ * used each time
+ */
+ pixelsPerDst = FB_UNIT / dstBpp;
+
+ /*
+ * Number of source stipple patterns in FbStip
+ */
+ unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
+
+ copy = FALSE;
+ transparent = FALSE;
+ if (bgand == 0 && fgand == 0)
+ copy = TRUE;
+ else if (bgand == FB_ALLONES && bgxor == 0)
+ transparent = TRUE;
+
+ /*
+ * Adjust source and dest to nearest FbBits boundary
+ */
+ src += srcX >> FB_STIP_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dstX &= FB_MASK;
+
+ FbMaskBitsBytes(dstX, width, copy,
+ startmask, startbyte, nmiddle, endmask, endbyte);
+
+ /*
+ * Compute effective dest alignment requirement for
+ * source -- must align source to dest unit boundary
+ */
+ dstS = dstX / dstBpp;
+ /*
+ * Compute shift constants for effective alignement
+ */
+ if (srcX >= dstS)
+ {
+ leftShift = srcX - dstS;
+ rightShift = FB_STIP_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstS - srcX;
+ leftShift = FB_STIP_UNIT - rightShift;
+ }
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ fbBits = 0; /* unused */
+ if (pixelsPerDst <= 8)
+ fbBits = fbStippleTable[pixelsPerDst];
+#ifndef FBNOPIXADDR
+ fbLane = 0;
+ if (transparent && fgand == 0 && dstBpp >= 8)
+ fbLane = fbLaneTable[dstBpp];
+#endif
+
+ /*
+ * Compute total number of destination words written, but
+ * don't count endmask
+ */
+ nDst = nmiddle;
+ if (startmask)
+ nDst++;
+
+ dstStride -= nDst;
+
+ /*
+ * Compute total number of source words consumed
+ */
+
+ srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;
+
+ if (srcX > dstS)
+ srcinc++;
+ if (endmask)
+ {
+ endNeedsLoad = nDst % unitsPerSrc == 0;
+ if (endNeedsLoad)
+ srcinc++;
+ }
+
+ srcStride -= srcinc;
+
+ /*
+ * Copy rectangle
+ */
+ while (height--)
+ {
+ w = nDst; /* total units across scanline */
+ n = unitsPerSrc; /* units avail in single stipple */
+ if (n > w)
+ n = w;
+
+ bitsLeft = 0;
+ if (srcX > dstS)
+ bitsLeft = *src++;
+ if (n)
+ {
+ /*
+ * Load first set of stipple bits
+ */
+ LoadBits;
+
+ /*
+ * Consume stipple bits for startmask
+ */
+ if (startmask)
+ {
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+#ifndef FBNOPIXADDR
+ if (fbLane)
+ {
+ fbTransparentSpan (dst, mask & startmask, fgxor, 1);
+ }
+ else
+#endif
+ {
+ if (mask || !transparent)
+ FbDoLeftMaskByteStippleRRop (dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ startbyte, startmask);
+ }
+ bits = FbStipLeft (bits, pixelsPerDst);
+ dst++;
+ n--;
+ w--;
+ }
+ /*
+ * Consume stipple bits across scanline
+ */
+ for (;;)
+ {
+ w -= n;
+ if (copy)
+ {
+ while (n--)
+ {
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ *dst = FbOpaqueStipple (mask, fgxor, bgxor);
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ else
+ {
+#ifndef FBNOPIXADDR
+ if (fbLane)
+ {
+ while (bits && n)
+ {
+ switch (fbLane[FbLeftStipBits(bits,pixelsPerDst)]) {
+ LaneCases((CARD8 *) dst);
+ }
+ bits = FbStipLeft(bits,pixelsPerDst);
+ dst++;
+ n--;
+ }
+ dst += n;
+ }
+ else
+#endif
+ {
+ while (n--)
+ {
+ left = FbLeftStipBits(bits,pixelsPerDst);
+ if (left || !transparent)
+ {
+ mask = fbBits[left];
+ *dst = FbStippleRRop (*dst, mask,
+ fgand, fgxor, bgand, bgxor);
+ }
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ }
+ if (!w)
+ break;
+ /*
+ * Load another set and reset number of available units
+ */
+ LoadBits;
+ n = unitsPerSrc;
+ if (n > w)
+ n = w;
+ }
+ }
+ /*
+ * Consume stipple bits for endmask
+ */
+ if (endmask)
+ {
+ if (endNeedsLoad)
+ {
+ LoadBits;
+ }
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+#ifndef FBNOPIXADDR
+ if (fbLane)
+ {
+ fbTransparentSpan (dst, mask & endmask, fgxor, 1);
+ }
+ else
+#endif
+ {
+ if (mask || !transparent)
+ FbDoRightMaskByteStippleRRop (dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ endbyte, endmask);
+ }
+ }
+ dst += dstStride;
+ src += srcStride;
+ }
+}
+
+#ifdef FB_24BIT
+
+/*
+ * Crufty macros to initialize the mask array, most of this
+ * is to avoid compile-time warnings about shift overflow
+ */
+
+#if BITMAP_BIT_ORDER == MSBFirst
+#define Mask24Pos(x,r) ((x)*24-(r))
+#else
+#define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0))
+#endif
+
+#define Mask24Neg(x,r) (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0)
+#define Mask24Check(x,r) (Mask24Pos(x,r) < 0 ? 0 : \
+ Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r))
+
+#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \
+ (Mask24Pos(x,r) < 0 ? \
+ 0xffffff >> Mask24Neg (x,r) : \
+ 0xffffff << Mask24Check(x,r)) : 0)
+
+#define SelMask24(b,n,r) ((((b) >> n) & 1) * Mask24(n,r))
+
+/*
+ * Untested for MSBFirst or FB_UNIT == 32
+ */
+
+#if FB_UNIT == 64
+#define C4_24(b,r) \
+ (SelMask24(b,0,r) | \
+ SelMask24(b,1,r) | \
+ SelMask24(b,2,r) | \
+ SelMask24(b,3,r))
+
+#define FbStip24New(rot) (2 + (rot != 0))
+#define FbStip24Len 4
+
+const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
+ /* rotate 0 */
+ {
+ C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0),
+ C4_24( 4, 0), C4_24( 5, 0), C4_24( 6, 0), C4_24( 7, 0),
+ C4_24( 8, 0), C4_24( 9, 0), C4_24(10, 0), C4_24(11, 0),
+ C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0),
+ },
+ /* rotate 8 */
+ {
+ C4_24( 0, 8), C4_24( 1, 8), C4_24( 2, 8), C4_24( 3, 8),
+ C4_24( 4, 8), C4_24( 5, 8), C4_24( 6, 8), C4_24( 7, 8),
+ C4_24( 8, 8), C4_24( 9, 8), C4_24(10, 8), C4_24(11, 8),
+ C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8),
+ },
+ /* rotate 16 */
+ {
+ C4_24( 0,16), C4_24( 1,16), C4_24( 2,16), C4_24( 3,16),
+ C4_24( 4,16), C4_24( 5,16), C4_24( 6,16), C4_24( 7,16),
+ C4_24( 8,16), C4_24( 9,16), C4_24(10,16), C4_24(11,16),
+ C4_24(12,16), C4_24(13,16), C4_24(14,16), C4_24(15,16),
+ }
+};
+
+#endif
+
+#if FB_UNIT == 32
+#define C2_24(b,r) \
+ (SelMask24(b,0,r) | \
+ SelMask24(b,1,r))
+
+#define FbStip24Len 2
+#if BITMAP_BIT_ORDER == MSBFirst
+#define FbStip24New(rot) (1 + (rot == 0))
+#else
+#define FbStip24New(rot) (1 + (rot == 8))
+#endif
+
+const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
+ /* rotate 0 */
+ {
+ C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0),
+ },
+ /* rotate 8 */
+ {
+ C2_24( 0, 8), C2_24 ( 1, 8), C2_24 ( 2, 8), C2_24 ( 3, 8),
+ },
+ /* rotate 16 */
+ {
+ C2_24( 0,16), C2_24 ( 1,16), C2_24 ( 2,16), C2_24 ( 3,16),
+ }
+};
+#endif
+
+#if BITMAP_BIT_ORDER == LSBFirst
+
+#define FbMergeStip24Bits(left, right, new) \
+ (FbStipLeft (left, new) | FbStipRight ((right), (FbStip24Len - (new))))
+
+#define FbMergePartStip24Bits(left, right, llen, rlen) \
+ (left | FbStipRight(right, llen))
+
+#else
+
+#define FbMergeStip24Bits(left, right, new) \
+ ((FbStipLeft (left, new) & ((1 << FbStip24Len) - 1)) | right)
+
+#define FbMergePartStip24Bits(left, right, llen, rlen) \
+ (FbStipLeft(left, rlen) | right)
+
+#endif
+
+#define fbFirstStipBits(len,stip) {\
+ int __len = (len); \
+ if (len <= remain) { \
+ stip = FbLeftStipBits(bits, len); \
+ } else { \
+ stip = FbLeftStipBits(bits, remain); \
+ bits = (src < srcEnd ? *src++ : 0); \
+ __len = (len) - remain; \
+ stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
+ remain, __len); \
+ remain = FB_STIP_UNIT; \
+ } \
+ bits = FbStipLeft (bits, __len); \
+ remain -= __len; \
+}
+
+#define fbInitStipBits(offset,len,stip) {\
+ bits = FbStipLeft (*src++,offset); \
+ remain = FB_STIP_UNIT - offset; \
+ fbFirstStipBits(len,stip); \
+ stip = FbMergeStip24Bits (0, stip, len); \
+}
+
+#define fbNextStipBits(rot,stip) {\
+ int __new = FbStip24New(rot); \
+ FbStip __right; \
+ fbFirstStipBits(__new, __right); \
+ stip = FbMergeStip24Bits (stip, __right, __new); \
+ rot = FbNext24Rot (rot); \
+}
+
+/*
+ * Use deep mask tables that incorporate rotation, pull
+ * a variable number of bits out of the stipple and
+ * reuse the right bits as needed for the next write
+ *
+ * Yes, this is probably too much code, but most 24-bpp screens
+ * have no acceleration so this code is used for stipples, copyplane
+ * and text
+ */
+void
+fbBltOne24 (FbStip *srcLine,
+ FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits *dst,
+ FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+
+ FbBits fgand, /* rrop values */
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor)
+{
+ FbStip *src, *srcEnd;
+ FbBits leftMask, rightMask, mask;
+ int nlMiddle, nl;
+ FbStip stip, bits;
+ int remain;
+ int dstS;
+ int firstlen;
+ int rot0, rot;
+ int nDst;
+
+ /*
+ * Do not read past the end of the buffer!
+ */
+ srcEnd = srcLine + height * srcStride;
+
+ srcLine += srcX >> FB_STIP_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dstX &= FB_MASK;
+ rot0 = FbFirst24Rot (dstX);
+
+ FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask);
+
+ dstS = (dstX + 23) / 24;
+ firstlen = FbStip24Len - dstS;
+
+ nDst = nlMiddle;
+ if (leftMask)
+ nDst++;
+ dstStride -= nDst;
+
+ /* opaque copy */
+ if (bgand == 0 && fgand == 0)
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX,firstlen, stip);
+ if (leftMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = (*dst & ~leftMask) | (FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot))
+ & leftMask);
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ mask = fbStipple24Bits[rot>>3][stip];
+ *dst = FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot));
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ if (rightMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = (*dst & ~rightMask) | (FbOpaqueStipple (mask,
+ FbRot24(fgxor, rot),
+ FbRot24(bgxor, rot))
+ & rightMask);
+ }
+ dst += dstStride;
+ src += srcStride;
+ }
+ }
+ /* transparent copy */
+ else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0)
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX, firstlen, stip);
+ if (leftMask)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
+ *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
+ }
+ dst++;
+ fbNextStipBits (rot, stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot>>3][stip];
+ *dst = (*dst & ~mask) | (FbRot24(fgxor,rot) & mask);
+ }
+ dst++;
+ fbNextStipBits (rot, stip);
+ }
+ if (rightMask)
+ {
+ if (stip)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip] & rightMask;
+ *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
+ }
+ }
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ while (height--)
+ {
+ rot = rot0;
+ src = srcLine;
+ srcLine += srcStride;
+ fbInitStipBits (srcX, firstlen, stip);
+ if (leftMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRopMask (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot),
+ leftMask);
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRop (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot));
+ dst++;
+ fbNextStipBits(rot,stip);
+ }
+ if (rightMask)
+ {
+ mask = fbStipple24Bits[rot >> 3][stip];
+ *dst = FbStippleRRopMask (*dst, mask,
+ FbRot24(fgand, rot),
+ FbRot24(fgxor, rot),
+ FbRot24(bgand, rot),
+ FbRot24(bgxor, rot),
+ rightMask);
+ }
+ dst += dstStride;
+ }
+ }
+}
+#endif
+
+/*
+ * Not very efficient, but simple -- copy a single plane
+ * from an N bit image to a 1 bit image
+ */
+
+void
+fbBltPlane (FbBits *src,
+ FbStride srcStride,
+ int srcX,
+ int srcBpp,
+
+ FbStip *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbStip fgand,
+ FbStip fgxor,
+ FbStip bgand,
+ FbStip bgxor,
+ Pixel planeMask)
+{
+ FbBits *s;
+ FbBits pm;
+ FbBits srcMask;
+ FbBits srcMaskFirst;
+ FbBits srcMask0 = 0;
+ FbBits srcBits;
+
+ FbStip dstBits;
+ FbStip *d;
+ FbStip dstMask;
+ FbStip dstMaskFirst;
+ FbStip dstUnion;
+ int w;
+ int wt;
+ int rot0;
+
+ if (!width)
+ return;
+
+ src += srcX >> FB_SHIFT;
+ srcX &= FB_MASK;
+
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ w = width / srcBpp;
+
+ pm = fbReplicatePixel (planeMask, srcBpp);
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ {
+ int w = 24;
+
+ rot0 = FbFirst24Rot (srcX);
+ if (srcX + w > FB_UNIT)
+ w = FB_UNIT - srcX;
+ srcMaskFirst = FbRot24(pm,rot0) & FbBitsMask(srcX,w);
+ }
+ else
+#endif
+ {
+ rot0 = 0;
+ srcMaskFirst = pm & FbBitsMask(srcX, srcBpp);
+ srcMask0 = pm & FbBitsMask(0, srcBpp);
+ }
+
+ dstMaskFirst = FbStipMask(dstX,1);
+ while (height--)
+ {
+ d = dst;
+ dst += dstStride;
+ s = src;
+ src += srcStride;
+
+ srcMask = srcMaskFirst;
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ srcMask0 = FbRot24(pm,rot0) & FbBitsMask(0, srcBpp);
+#endif
+ srcBits = *s++;
+
+ dstMask = dstMaskFirst;
+ dstUnion = 0;
+ dstBits = 0;
+
+ wt = w;
+
+ while (wt--)
+ {
+ if (!srcMask)
+ {
+ srcBits = *s++;
+#ifdef FB_24BIT
+ if (srcBpp == 24)
+ srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0,24);
+#endif
+ srcMask = srcMask0;
+ }
+ if (!dstMask)
+ {
+ *d = FbStippleRRopMask(*d, dstBits,
+ fgand, fgxor, bgand, bgxor,
+ dstUnion);
+ d++;
+ dstMask = FbStipMask(0,1);
+ dstUnion = 0;
+ dstBits = 0;
+ }
+ if (srcBits & srcMask)
+ dstBits |= dstMask;
+ dstUnion |= dstMask;
+ if (srcBpp == FB_UNIT)
+ srcMask = 0;
+ else
+ srcMask = FbScrRight(srcMask,srcBpp);
+ dstMask = FbStipRight(dstMask,1);
+ }
+ if (dstUnion)
+ *d = FbStippleRRopMask(*d,dstBits,
+ fgand, fgxor, bgand, bgxor,
+ dstUnion);
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/fb/fbbstore.c b/nx-X11/programs/Xserver/fb/fbbstore.c
new file mode 100644
index 000000000..75f6084c0
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbbstore.c
@@ -0,0 +1,65 @@
+/*
+ * Id: fbbstore.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbSaveAreas(PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ fbCopyWindowProc (&pWin->drawable,
+ &pPixmap->drawable,
+ 0,
+ RegionRects(prgnSave),
+ RegionNumRects(prgnSave),
+ xorg, yorg,
+ FALSE,
+ FALSE,
+ 0,0);
+}
+
+void
+fbRestoreAreas(PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ fbCopyWindowProc (&pPixmap->drawable,
+ &pWin->drawable,
+ 0,
+ RegionRects(prgnRestore),
+ RegionNumRects(prgnRestore),
+ -xorg, -yorg,
+ FALSE,
+ FALSE,
+ 0,0);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbcmap.c b/nx-X11/programs/Xserver/fb/fbcmap.c
new file mode 100644
index 000000000..ec8ddff4f
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbcmap.c
@@ -0,0 +1,671 @@
+/* $XConsortium: fbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "fb.h"
+
+#ifndef XFree86Server
+ColormapPtr FbInstalledMaps[MAXSCREENS];
+
+int
+fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+ *pmaps = FbInstalledMaps[pScreen->myNum]->mid;
+ return (1);
+}
+
+
+void
+fbInstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr oldpmap = FbInstalledMaps[index];
+
+ if(pmap != oldpmap)
+ {
+ /* Uninstall pInstalledMap. No hardware changes required, just
+ * notify all interested parties. */
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ FbInstalledMaps[index] = pmap;
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+ }
+}
+
+void
+fbUninstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr curpmap = FbInstalledMaps[index];
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+void
+fbResolveColor(unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual)
+{
+ int shift = 16 - pVisual->bitsPerRGBValue;
+ unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class | DynamicClass) == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else
+ {
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+fbInitializeColormap(ColormapPtr pmap)
+{
+ register unsigned i;
+ register VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+ if (pVisual->class == TrueColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((i * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->green[i].co.local.green =
+ ((((i * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->blue[i].co.local.blue =
+ ((((i * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticColor)
+ {
+ unsigned n;
+ unsigned r, g, b;
+ unsigned red, green, blue;
+
+ for (n = 0; n*n*n < pVisual->ColormapEntries; n++)
+ ;
+ n--;
+ i = 0;
+ for (r = 0; r < n; r++)
+ {
+ red = (((r * 65535 / (n - 1)) >> shift) * 65535) / lim;
+ for (g = 0; g < n; g++)
+ {
+ green = (((g * 65535 / (n - 1)) >> shift) * 65535) / lim;
+ for (b = 0; b < n; b++)
+ {
+ blue = (((b * 65535 / (n - 1)) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.red = red;
+ pmap->red[i].co.local.green = green;
+ pmap->red[i].co.local.blue = blue;
+ i++;
+ }
+ }
+ }
+ n = pVisual->ColormapEntries - i;
+ for (r = 0; r < n; r++)
+ {
+ red = (((r * 65535 / (n - 1)) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.red = red;
+ pmap->red[i].co.local.green = red;
+ pmap->red[i].co.local.blue = red;
+ i++;
+ }
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
+ * 65535) / lim;
+ pmap->red[i].co.local.green = pmap->red[i].co.local.red;
+ pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
+ }
+ }
+ return TRUE;
+}
+
+/* When simulating DirectColor on PseudoColor hardware, multiple
+ entries of the colormap must be updated
+ */
+
+#define AddElement(mask) { \
+ pixel = red | green | blue; \
+ for (i = 0; i < nresult; i++) \
+ if (outdefs[i].pixel == pixel) \
+ break; \
+ if (i == nresult) \
+ { \
+ nresult++; \
+ outdefs[i].pixel = pixel; \
+ outdefs[i].flags = 0; \
+ } \
+ outdefs[i].flags |= (mask); \
+ outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
+ outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
+ outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
+}
+
+int
+fbExpandDirectColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ register int red, green, blue;
+ int maxred, maxgreen, maxblue;
+ int stepred, stepgreen, stepblue;
+ VisualPtr pVisual;
+ register int pixel;
+ register int nresult;
+ register int i;
+
+ pVisual = pmap->pVisual;
+
+ stepred = 1 << pVisual->offsetRed;
+ stepgreen = 1 << pVisual->offsetGreen;
+ stepblue = 1 << pVisual->offsetBlue;
+ maxred = pVisual->redMask;
+ maxgreen = pVisual->greenMask;
+ maxblue = pVisual->blueMask;
+ nresult = 0;
+ for (;ndef--; indefs++)
+ {
+ if (indefs->flags & DoRed)
+ {
+ red = indefs->pixel & pVisual->redMask;
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoRed)
+ }
+ }
+ }
+ if (indefs->flags & DoGreen)
+ {
+ green = indefs->pixel & pVisual->greenMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoGreen)
+ }
+ }
+ }
+ if (indefs->flags & DoBlue)
+ {
+ blue = indefs->pixel & pVisual->blueMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ AddElement (DoBlue)
+ }
+ }
+ }
+ }
+ return nresult;
+}
+
+Bool
+fbCreateDefColormap(ScreenPtr pScreen)
+{
+ unsigned short zero = 0, ones = 0xFFFF;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ Pixel wp, bp;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
+ 0)
+ != Success)
+ return FALSE;
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+extern int defaultColorVisualClass;
+
+#define _RZ(d) ((d + 2) / 3)
+#define _RS(d) 0
+#define _RM(d) ((1 << _RZ(d)) - 1)
+#define _GZ(d) ((d - _RZ(d) + 1) / 2)
+#define _GS(d) _RZ(d)
+#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
+#define _BZ(d) (d - _RZ(d) - _GZ(d))
+#define _BS(d) (_RZ(d) + _GZ(d))
+#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
+#define _CE(d) (1 << _RZ(d))
+
+#define MAX_PSEUDO_DEPTH 10 /* largest DAC size I know */
+
+#define StaticGrayMask (1 << StaticGray)
+#define GrayScaleMask (1 << GrayScale)
+#define StaticColorMask (1 << StaticColor)
+#define PseudoColorMask (1 << PseudoColor)
+#define TrueColorMask (1 << TrueColor)
+#define DirectColorMask (1 << DirectColor)
+
+#define ALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask|\
+ TrueColorMask|\
+ DirectColorMask)
+
+#define LARGE_VISUALS (TrueColorMask|\
+ DirectColorMask)
+
+typedef struct _fbVisuals {
+ struct _fbVisuals *next;
+ int depth;
+ int bitsPerRGB;
+ int visuals;
+ int count;
+ Pixel redMask, greenMask, blueMask;
+} fbVisualsRec, *fbVisualsPtr;
+
+static const int fbVisualPriority[] = {
+ PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray
+};
+
+#define NUM_PRIORITY 6
+
+static fbVisualsPtr fbVisuals;
+
+static int
+popCount (int i)
+{
+ int count;
+
+ count = (i >> 1) & 033333333333;
+ count = i - count - ((count >> 1) & 033333333333);
+ count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
+ return count;
+}
+
+/*
+ * Distance to least significant one bit
+ */
+static int
+maskShift (Pixel p)
+{
+ int s;
+
+ if (!p) return 0;
+ s = 0;
+ while (!(p & 1))
+ {
+ s++;
+ p >>= 1;
+ }
+ return s;
+}
+
+Bool
+fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB,
+ Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+ fbVisualsPtr new, *prev, v;
+
+ new = (fbVisualsPtr) malloc (sizeof *new);
+ if (!new)
+ return FALSE;
+ if (!redMask || !greenMask || !blueMask)
+ {
+ redMask = _RM(depth);
+ greenMask = _GM(depth);
+ blueMask = _BM(depth);
+ }
+ new->next = 0;
+ new->depth = depth;
+ new->visuals = visuals;
+ new->bitsPerRGB = bitsPerRGB;
+ new->redMask = redMask;
+ new->greenMask = greenMask;
+ new->blueMask = blueMask;
+ new->count = popCount (visuals);
+ for (prev = &fbVisuals; (v = *prev); prev = &v->next);
+ *prev = new;
+ return TRUE;
+}
+
+Bool
+fbHasVisualTypes (int depth)
+{
+ fbVisualsPtr v;
+
+ for (v = fbVisuals; v; v = v->next)
+ if (v->depth == depth)
+ return TRUE;
+ return FALSE;
+}
+
+Bool
+fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
+{
+ return fbSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
+ _RM(depth), _GM(depth), _BM(depth));
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which coorespond to
+ * the set which can be used with this version of fb.
+ */
+
+Bool
+fbInitVisuals (VisualPtr *visualp,
+ DepthPtr *depthp,
+ int *nvisualp,
+ int *ndepthp,
+ int *rootDepthp,
+ VisualID *defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB)
+{
+ int i, j = 0, k;
+ VisualPtr visual;
+ DepthPtr depth;
+ VisualID *vid;
+ int d, b;
+ int f;
+ int ndepth, nvisual;
+ int nvtype;
+ int vtype;
+ fbVisualsPtr visuals, nextVisuals;
+
+ /* none specified, we'll guess from pixmap formats */
+ if (!fbVisuals)
+ {
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ b = screenInfo.formats[f].bitsPerPixel;
+ if (sizes & (1 << (b - 1)))
+ {
+ if (d > MAX_PSEUDO_DEPTH)
+ vtype = LARGE_VISUALS;
+ else if (d == 1)
+ vtype = StaticGrayMask;
+ else
+ vtype = ALL_VISUALS;
+ }
+ else
+ vtype = 0;
+ if (!fbSetVisualTypes (d, vtype, bitsPerRGB))
+ return FALSE;
+ }
+ }
+ nvisual = 0;
+ ndepth = 0;
+ for (visuals = fbVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ ndepth++;
+ nvisual += visuals->count;
+ }
+ depth = (DepthPtr) malloc (ndepth * sizeof (DepthRec));
+ visual = (VisualPtr) malloc (nvisual * sizeof (VisualRec));
+ if (!depth || !visual)
+ {
+ free (depth);
+ free (visual);
+ return FALSE;
+ }
+ *depthp = depth;
+ *visualp = visual;
+ *ndepthp = ndepth;
+ *nvisualp = nvisual;
+ for (visuals = fbVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ d = visuals->depth;
+ vtype = visuals->visuals;
+ nvtype = visuals->count;
+ vid = NULL;
+ if (nvtype)
+ {
+ vid = (VisualID *) malloc (nvtype * sizeof (VisualID));
+ if (!vid)
+ return FALSE;
+ }
+ depth->depth = d;
+ depth->numVids = nvtype;
+ depth->vids = vid;
+ depth++;
+ for (i = 0; i < NUM_PRIORITY; i++) {
+ if (! (vtype & (1 << fbVisualPriority[i])))
+ continue;
+ visual->class = fbVisualPriority[i];
+ visual->bitsPerRGBValue = visuals->bitsPerRGB;
+ visual->ColormapEntries = 1 << d;
+ visual->nplanes = d;
+ visual->vid = *vid = FakeClientID (0);
+ switch (visual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ case StaticColor:
+ visual->redMask = 0;
+ visual->greenMask = 0;
+ visual->blueMask = 0;
+ visual->offsetRed = 0;
+ visual->offsetGreen = 0;
+ visual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ visual->ColormapEntries = _CE(d);
+ visual->redMask = visuals->redMask;
+ visual->greenMask = visuals->greenMask;
+ visual->blueMask = visuals->blueMask;
+ visual->offsetRed = maskShift (visuals->redMask);
+ visual->offsetGreen = maskShift (visuals->greenMask);
+ visual->offsetBlue = maskShift (visuals->blueMask);
+ }
+ vid++;
+ visual++;
+ }
+ free (visuals);
+ }
+ fbVisuals = NULL;
+ visual = *visualp;
+ depth = *depthp;
+ for (i = 0; i < ndepth; i++)
+ {
+ if (*rootDepthp && *rootDepthp != depth[i].depth)
+ continue;
+ for (j = 0; j < depth[i].numVids; j++)
+ {
+ for (k = 0; k < nvisual; k++)
+ if (visual[k].vid == depth[i].vids[j])
+ break;
+ if (k == nvisual)
+ continue;
+ if (defaultColorVisualClass < 0 ||
+ visual[k].class == defaultColorVisualClass)
+ break;
+ }
+ if (j != depth[i].numVids)
+ break;
+ }
+ if (i == ndepth) {
+ for (i = 0; i < ndepth; i++)
+ {
+ if (depth[i].numVids)
+ break;
+ }
+ if (i == ndepth)
+ return FALSE;
+ j = 0;
+ }
+ *rootDepthp = depth[i].depth;
+ *defaultVisp = depth[i].vids[j];
+ return TRUE;
+}
+#else
+
+#include "micmap.h"
+
+int
+fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ return miListInstalledColormaps(pScreen, pmaps);
+}
+
+void
+fbInstallColormap(ColormapPtr pmap)
+{
+ miInstallColormap(pmap);
+}
+
+void
+fbUninstallColormap(ColormapPtr pmap)
+{
+ miUninstallColormap(pmap);
+}
+
+void
+fbResolveColor(unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual)
+{
+ miResolveColor(pred, pgreen, pblue, pVisual);
+}
+
+Bool
+fbInitializeColormap(ColormapPtr pmap)
+{
+ return miInitializeColormap(pmap);
+}
+
+int
+fbExpandDirectColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ return miExpandDirectColors(pmap, ndef, indefs, outdefs);
+}
+
+Bool
+fbCreateDefColormap(ScreenPtr pScreen)
+{
+ return miCreateDefColormap(pScreen);
+}
+
+void
+fbClearVisualTypes(void)
+{
+ miClearVisualTypes();
+}
+
+Bool
+fbSetVisualTypes (int depth, int visuals, int bitsPerRGB)
+{
+ return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which coorespond to
+ * the set which can be used with this version of fb.
+ */
+
+Bool
+fbInitVisuals (VisualPtr *visualp,
+ DepthPtr *depthp,
+ int *nvisualp,
+ int *ndepthp,
+ int *rootDepthp,
+ VisualID *defaultVisp,
+ unsigned long sizes,
+ int bitsPerRGB)
+{
+ return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB, -1);
+}
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbcompose.c b/nx-X11/programs/Xserver/fb/fbcompose.c
new file mode 100644
index 000000000..3f4e6ec20
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbcompose.c
@@ -0,0 +1,3628 @@
+/*
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * 2005 Lars Knoll & Zack Rusin, Trolltech
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#ifdef RENDER
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "fbpict.h"
+
+#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+
+#define SCANLINE_BUFFER_LENGTH 2048
+
+typedef FASTCALL void (*fetchProc)(const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed);
+
+/*
+ * All of the fetch functions
+ */
+
+static FASTCALL void
+fbFetch_a8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ memcpy(buffer, (const CARD32 *)bits + x, width*sizeof(CARD32));
+}
+
+static FASTCALL void
+fbFetch_x8r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD32 *pixel = (const CARD32 *)bits + x;
+ const CARD32 *end = pixel + width;
+ while (pixel < end) {
+ *buffer++ = *pixel++ | 0xff000000;
+ }
+}
+
+static FASTCALL void
+fbFetch_a8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD32 *pixel = (CARD32 *)bits + x;
+ const CARD32 *end = pixel + width;
+ while (pixel < end) {
+ *buffer++ = ((*pixel & 0xff00ff00) |
+ ((*pixel >> 16) & 0xff) |
+ ((*pixel & 0xff) << 16));
+ ++pixel;
+ }
+}
+
+static FASTCALL void
+fbFetch_x8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD32 *pixel = (CARD32 *)bits + x;
+ const CARD32 *end = pixel + width;
+ while (pixel < end) {
+ *buffer++ = 0xff000000 |
+ ((*pixel & 0x0000ff00) |
+ ((*pixel >> 16) & 0xff) |
+ ((*pixel & 0xff) << 16));
+ ++pixel;
+ }
+}
+
+static FASTCALL void
+fbFetch_r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + 3*x;
+ const CARD8 *end = pixel + 3*width;
+ while (pixel < end) {
+ CARD32 b = Fetch24(pixel) | 0xff000000;
+ pixel += 3;
+ *buffer++ = b;
+ }
+}
+
+static FASTCALL void
+fbFetch_b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + 3*x;
+ const CARD8 *end = pixel + 3*width;
+ while (pixel < end) {
+ CARD32 b = 0xff000000;
+#if IMAGE_BYTE_ORDER == MSBFirst
+ b |= (*pixel++);
+ b |= (*pixel++ << 8);
+ b |= (*pixel++ << 16);
+#else
+ b |= (*pixel++ << 16);
+ b |= (*pixel++ << 8);
+ b |= (*pixel++);
+#endif
+ }
+}
+
+static FASTCALL void
+fbFetch_r5g6b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r = (((p) << 3) & 0xf8) |
+ (((p) << 5) & 0xfc00) |
+ (((p) << 8) & 0xf80000);
+ r |= (r >> 5) & 0x70007;
+ r |= (r >> 6) & 0x300;
+ *buffer++ = 0xff000000 | r;
+ }
+}
+
+static FASTCALL void
+fbFetch_b5g6r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ b = ((p & 0xf800) | ((p & 0xe000) >> 5)) >> 8;
+ g = ((p & 0x07e0) | ((p & 0x0600) >> 6)) << 5;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b, a;
+
+ a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
+ r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
+ *buffer++ = (a | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_x1r5g5b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ r = ((p & 0x7c00) | ((p & 0x7000) >> 5)) << 9;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ b = ((p & 0x001c) | ((p & 0x001f) << 5)) >> 2;
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b, a;
+
+ a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
+ b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+ *buffer++ = (a | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_x1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
+ g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
+ r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b, a;
+
+ a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
+ r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ b = ((p & 0x000f) | ((p & 0x000f) << 4));
+ *buffer++ = (a | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_x4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ b = ((p & 0x000f) | ((p & 0x000f) << 4));
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b, a;
+
+ a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
+ b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ r = ((p & 0x000f) | ((p & 0x000f) << 4));
+ *buffer++ = (a | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_x4b4g4r4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD16 *pixel = (const CARD16 *)bits + x;
+ const CARD16 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ b = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
+ g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
+ r = ((p & 0x000f) | ((p & 0x000f) << 4));
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ *buffer++ = (*pixel++) << 24;
+ }
+}
+
+static FASTCALL void
+fbFetch_r3g3b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ r = ((p & 0xe0) | ((p & 0xe0) >> 3) | ((p & 0xc0) >> 6)) << 16;
+ g = ((p & 0x1c) | ((p & 0x18) >> 3) | ((p & 0x1c) << 3)) << 8;
+ b = (((p & 0x03) ) |
+ ((p & 0x03) << 2) |
+ ((p & 0x03) << 4) |
+ ((p & 0x03) << 6));
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_b2g3r3 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 r,g,b;
+
+ b = (((p & 0xc0) ) |
+ ((p & 0xc0) >> 2) |
+ ((p & 0xc0) >> 4) |
+ ((p & 0xc0) >> 6));
+ g = ((p & 0x38) | ((p & 0x38) >> 3) | ((p & 0x30) << 2)) << 8;
+ r = (((p & 0x07) ) |
+ ((p & 0x07) << 3) |
+ ((p & 0x06) << 6)) << 16;
+ *buffer++ = (0xff000000 | r | g | b);
+ }
+}
+
+static FASTCALL void
+fbFetch_a2r2g2b2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 a,r,g,b;
+
+ a = ((p & 0xc0) * 0x55) << 18;
+ r = ((p & 0x30) * 0x55) << 12;
+ g = ((p & 0x0c) * 0x55) << 6;
+ b = ((p & 0x03) * 0x55);
+ *buffer++ = a|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_a2b2g2r2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ CARD32 a,r,g,b;
+
+ a = ((p & 0xc0) * 0x55) << 18;
+ b = ((p & 0x30) * 0x55) >> 6;
+ g = ((p & 0x0c) * 0x55) << 6;
+ r = ((p & 0x03) * 0x55) << 16;
+ *buffer++ = a|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_c8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ const CARD8 *pixel = (const CARD8 *)bits + x;
+ const CARD8 *end = pixel + width;
+ while (pixel < end) {
+ CARD32 p = *pixel++;
+ *buffer++ = indexed->rgba[p];
+ }
+}
+
+#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
+#else
+#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
+#endif
+
+static FASTCALL void
+fbFetch_a4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+
+ p |= p << 4;
+ *buffer++ = p << 24;
+ }
+}
+
+static FASTCALL void
+fbFetch_r1g2b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+ CARD32 r,g,b;
+
+ r = ((p & 0x8) * 0xff) << 13;
+ g = ((p & 0x6) * 0x55) << 7;
+ b = ((p & 0x1) * 0xff);
+ *buffer++ = 0xff000000|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_b1g2r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+ CARD32 r,g,b;
+
+ b = ((p & 0x8) * 0xff) >> 3;
+ g = ((p & 0x6) * 0x55) << 7;
+ r = ((p & 0x1) * 0xff) << 16;
+ *buffer++ = 0xff000000|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_a1r1g1b1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+ CARD32 a,r,g,b;
+
+ a = ((p & 0x8) * 0xff) << 21;
+ r = ((p & 0x4) * 0xff) << 14;
+ g = ((p & 0x2) * 0xff) << 7;
+ b = ((p & 0x1) * 0xff);
+ *buffer++ = a|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_a1b1g1r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+ CARD32 a,r,g,b;
+
+ a = ((p & 0x8) * 0xff) << 21;
+ r = ((p & 0x4) * 0xff) >> 3;
+ g = ((p & 0x2) * 0xff) << 7;
+ b = ((p & 0x1) * 0xff) << 16;
+ *buffer++ = a|r|g|b;
+ }
+}
+
+static FASTCALL void
+fbFetch_c4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = Fetch4(bits, i + x);
+
+ *buffer++ = indexed->rgba[p];
+ }
+}
+
+
+static FASTCALL void
+fbFetch_a1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = ((CARD32 *)bits)[(i + x) >> 5];
+ CARD32 a;
+#if BITMAP_BIT_ORDER == MSBFirst
+ a = p >> (0x1f - ((i+x) & 0x1f));
+#else
+ a = p >> ((i+x) & 0x1f);
+#endif
+ a = a & 1;
+ a |= a << 1;
+ a |= a << 2;
+ a |= a << 4;
+ *buffer++ = a << 24;
+ }
+}
+
+static FASTCALL void
+fbFetch_g1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 p = ((CARD32 *)bits)[(i+x) >> 5];
+ CARD32 a;
+#if BITMAP_BIT_ORDER == MSBFirst
+ a = p >> (0x1f - ((i+x) & 0x1f));
+#else
+ a = p >> ((i+x) & 0x1f);
+#endif
+ a = a & 1;
+ *buffer++ = indexed->rgba[a];
+ }
+}
+
+static fetchProc fetchProcForPicture (PicturePtr pict)
+{
+ switch(pict->format) {
+ case PICT_a8r8g8b8: return fbFetch_a8r8g8b8;
+ case PICT_x8r8g8b8: return fbFetch_x8r8g8b8;
+ case PICT_a8b8g8r8: return fbFetch_a8b8g8r8;
+ case PICT_x8b8g8r8: return fbFetch_x8b8g8r8;
+
+ /* 24bpp formats */
+ case PICT_r8g8b8: return fbFetch_r8g8b8;
+ case PICT_b8g8r8: return fbFetch_b8g8r8;
+
+ /* 16bpp formats */
+ case PICT_r5g6b5: return fbFetch_r5g6b5;
+ case PICT_b5g6r5: return fbFetch_b5g6r5;
+
+ case PICT_a1r5g5b5: return fbFetch_a1r5g5b5;
+ case PICT_x1r5g5b5: return fbFetch_x1r5g5b5;
+ case PICT_a1b5g5r5: return fbFetch_a1b5g5r5;
+ case PICT_x1b5g5r5: return fbFetch_x1b5g5r5;
+ case PICT_a4r4g4b4: return fbFetch_a4r4g4b4;
+ case PICT_x4r4g4b4: return fbFetch_x4r4g4b4;
+ case PICT_a4b4g4r4: return fbFetch_a4b4g4r4;
+ case PICT_x4b4g4r4: return fbFetch_x4b4g4r4;
+
+ /* 8bpp formats */
+ case PICT_a8: return fbFetch_a8;
+ case PICT_r3g3b2: return fbFetch_r3g3b2;
+ case PICT_b2g3r3: return fbFetch_b2g3r3;
+ case PICT_a2r2g2b2: return fbFetch_a2r2g2b2;
+ case PICT_a2b2g2r2: return fbFetch_a2b2g2r2;
+ case PICT_c8: return fbFetch_c8;
+ case PICT_g8: return fbFetch_c8;
+
+ /* 4bpp formats */
+ case PICT_a4: return fbFetch_a4;
+ case PICT_r1g2b1: return fbFetch_r1g2b1;
+ case PICT_b1g2r1: return fbFetch_b1g2r1;
+ case PICT_a1r1g1b1: return fbFetch_a1r1g1b1;
+ case PICT_a1b1g1r1: return fbFetch_a1b1g1r1;
+ case PICT_c4: return fbFetch_c4;
+ case PICT_g4: return fbFetch_c4;
+
+ /* 1bpp formats */
+ case PICT_a1: return fbFetch_a1;
+ case PICT_g1: return fbFetch_g1;
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Pixel wise fetching
+ */
+
+typedef FASTCALL CARD32 (*fetchPixelProc)(const FbBits *bits, int offset, miIndexedPtr indexed);
+
+static FASTCALL CARD32
+fbFetchPixel_a8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ return ((CARD32 *)bits)[offset];
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x8r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ return ((CARD32 *)bits)[offset] | 0xff000000;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD32 *)bits)[offset];
+
+ return ((pixel & 0xff000000) |
+ ((pixel >> 16) & 0xff) |
+ (pixel & 0x0000ff00) |
+ ((pixel & 0xff) << 16));
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x8b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD32 *)bits)[offset];
+
+ return ((0xff000000) |
+ ((pixel >> 16) & 0xff) |
+ (pixel & 0x0000ff00) |
+ ((pixel & 0xff) << 16));
+}
+
+static FASTCALL CARD32
+fbFetchPixel_r8g8b8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD8 *pixel = ((CARD8 *) bits) + (offset*3);
+#if IMAGE_BYTE_ORDER == MSBFirst
+ return (0xff000000 |
+ (pixel[0] << 16) |
+ (pixel[1] << 8) |
+ (pixel[2]));
+#else
+ return (0xff000000 |
+ (pixel[2] << 16) |
+ (pixel[1] << 8) |
+ (pixel[0]));
+#endif
+}
+
+static FASTCALL CARD32
+fbFetchPixel_b8g8r8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD8 *pixel = ((CARD8 *) bits) + (offset*3);
+#if IMAGE_BYTE_ORDER == MSBFirst
+ return (0xff000000 |
+ (pixel[2] << 16) |
+ (pixel[1] << 8) |
+ (pixel[0]));
+#else
+ return (0xff000000 |
+ (pixel[0] << 16) |
+ (pixel[1] << 8) |
+ (pixel[2]));
+#endif
+}
+
+static FASTCALL CARD32
+fbFetchPixel_r5g6b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ r = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) << 8;
+ g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_b5g6r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ b = ((pixel & 0xf800) | ((pixel & 0xe000) >> 5)) >> 8;
+ g = ((pixel & 0x07e0) | ((pixel & 0x0600) >> 6)) << 5;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
+ r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+ return (a | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x1r5g5b5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ r = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) << 9;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ b = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) >> 2;
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = (CARD32) ((CARD8) (0 - ((pixel & 0x8000) >> 15))) << 24;
+ b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+ return (a | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x1b5g5r5 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ b = ((pixel & 0x7c00) | ((pixel & 0x7000) >> 5)) >> 7;
+ g = ((pixel & 0x03e0) | ((pixel & 0x0380) >> 5)) << 6;
+ r = ((pixel & 0x001c) | ((pixel & 0x001f) << 5)) << 14;
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+ r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+ return (a | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x4r4g4b4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ r = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ b = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0xf000) | ((pixel & 0xf000) >> 4)) << 16;
+ b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+ return (a | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_x4b4g4r4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD16 *) bits)[offset];
+ CARD32 r,g,b;
+
+ b = ((pixel & 0x0f00) | ((pixel & 0x0f00) >> 4)) << 12;
+ g = ((pixel & 0x00f0) | ((pixel & 0x00f0) >> 4)) << 8;
+ r = ((pixel & 0x000f) | ((pixel & 0x000f) << 4));
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+
+ return pixel << 24;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_r3g3b2 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+ CARD32 r,g,b;
+
+ r = ((pixel & 0xe0) | ((pixel & 0xe0) >> 3) | ((pixel & 0xc0) >> 6)) << 16;
+ g = ((pixel & 0x1c) | ((pixel & 0x18) >> 3) | ((pixel & 0x1c) << 3)) << 8;
+ b = (((pixel & 0x03) ) |
+ ((pixel & 0x03) << 2) |
+ ((pixel & 0x03) << 4) |
+ ((pixel & 0x03) << 6));
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_b2g3r3 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+ CARD32 r,g,b;
+
+ b = (((pixel & 0xc0) ) |
+ ((pixel & 0xc0) >> 2) |
+ ((pixel & 0xc0) >> 4) |
+ ((pixel & 0xc0) >> 6));
+ g = ((pixel & 0x38) | ((pixel & 0x38) >> 3) | ((pixel & 0x30) << 2)) << 8;
+ r = (((pixel & 0x07) ) |
+ ((pixel & 0x07) << 3) |
+ ((pixel & 0x06) << 6)) << 16;
+ return (0xff000000 | r | g | b);
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a2r2g2b2 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0xc0) * 0x55) << 18;
+ r = ((pixel & 0x30) * 0x55) << 12;
+ g = ((pixel & 0x0c) * 0x55) << 6;
+ b = ((pixel & 0x03) * 0x55);
+ return a|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a2b2g2r2 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0xc0) * 0x55) << 18;
+ b = ((pixel & 0x30) * 0x55) >> 6;
+ g = ((pixel & 0x0c) * 0x55) << 6;
+ r = ((pixel & 0x03) * 0x55) << 16;
+ return a|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_c8 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD8 *) bits)[offset];
+ return indexed->rgba[pixel];
+}
+
+#define Fetch8(l,o) (((CARD8 *) (l))[(o) >> 2])
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) & 0xf : Fetch8(l,o) >> 4)
+#else
+#define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf)
+#endif
+
+static FASTCALL CARD32
+fbFetchPixel_a4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+
+ pixel |= pixel << 4;
+ return pixel << 24;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_r1g2b1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+ CARD32 r,g,b;
+
+ r = ((pixel & 0x8) * 0xff) << 13;
+ g = ((pixel & 0x6) * 0x55) << 7;
+ b = ((pixel & 0x1) * 0xff);
+ return 0xff000000|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_b1g2r1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+ CARD32 r,g,b;
+
+ b = ((pixel & 0x8) * 0xff) >> 3;
+ g = ((pixel & 0x6) * 0x55) << 7;
+ r = ((pixel & 0x1) * 0xff) << 16;
+ return 0xff000000|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a1r1g1b1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0x8) * 0xff) << 21;
+ r = ((pixel & 0x4) * 0xff) << 14;
+ g = ((pixel & 0x2) * 0xff) << 7;
+ b = ((pixel & 0x1) * 0xff);
+ return a|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_a1b1g1r1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+ CARD32 a,r,g,b;
+
+ a = ((pixel & 0x8) * 0xff) << 21;
+ r = ((pixel & 0x4) * 0xff) >> 3;
+ g = ((pixel & 0x2) * 0xff) << 7;
+ b = ((pixel & 0x1) * 0xff) << 16;
+ return a|r|g|b;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_c4 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = Fetch4(bits, offset);
+
+ return indexed->rgba[pixel];
+}
+
+
+static FASTCALL CARD32
+fbFetchPixel_a1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD32 *)bits)[offset >> 5];
+ CARD32 a;
+#if BITMAP_BIT_ORDER == MSBFirst
+ a = pixel >> (0x1f - (offset & 0x1f));
+#else
+ a = pixel >> (offset & 0x1f);
+#endif
+ a = a & 1;
+ a |= a << 1;
+ a |= a << 2;
+ a |= a << 4;
+ return a << 24;
+}
+
+static FASTCALL CARD32
+fbFetchPixel_g1 (const FbBits *bits, int offset, miIndexedPtr indexed)
+{
+ CARD32 pixel = ((CARD32 *)bits)[offset >> 5];
+ CARD32 a;
+#if BITMAP_BIT_ORDER == MSBFirst
+ a = pixel >> (0x1f - (offset & 0x1f));
+#else
+ a = pixel >> (offset & 0x1f);
+#endif
+ a = a & 1;
+ return indexed->rgba[a];
+}
+
+static fetchPixelProc fetchPixelProcForPicture (PicturePtr pict)
+{
+ switch(pict->format) {
+ case PICT_a8r8g8b8: return fbFetchPixel_a8r8g8b8;
+ case PICT_x8r8g8b8: return fbFetchPixel_x8r8g8b8;
+ case PICT_a8b8g8r8: return fbFetchPixel_a8b8g8r8;
+ case PICT_x8b8g8r8: return fbFetchPixel_x8b8g8r8;
+
+ /* 24bpp formats */
+ case PICT_r8g8b8: return fbFetchPixel_r8g8b8;
+ case PICT_b8g8r8: return fbFetchPixel_b8g8r8;
+
+ /* 16bpp formats */
+ case PICT_r5g6b5: return fbFetchPixel_r5g6b5;
+ case PICT_b5g6r5: return fbFetchPixel_b5g6r5;
+
+ case PICT_a1r5g5b5: return fbFetchPixel_a1r5g5b5;
+ case PICT_x1r5g5b5: return fbFetchPixel_x1r5g5b5;
+ case PICT_a1b5g5r5: return fbFetchPixel_a1b5g5r5;
+ case PICT_x1b5g5r5: return fbFetchPixel_x1b5g5r5;
+ case PICT_a4r4g4b4: return fbFetchPixel_a4r4g4b4;
+ case PICT_x4r4g4b4: return fbFetchPixel_x4r4g4b4;
+ case PICT_a4b4g4r4: return fbFetchPixel_a4b4g4r4;
+ case PICT_x4b4g4r4: return fbFetchPixel_x4b4g4r4;
+
+ /* 8bpp formats */
+ case PICT_a8: return fbFetchPixel_a8;
+ case PICT_r3g3b2: return fbFetchPixel_r3g3b2;
+ case PICT_b2g3r3: return fbFetchPixel_b2g3r3;
+ case PICT_a2r2g2b2: return fbFetchPixel_a2r2g2b2;
+ case PICT_a2b2g2r2: return fbFetchPixel_a2b2g2r2;
+ case PICT_c8: return fbFetchPixel_c8;
+ case PICT_g8: return fbFetchPixel_c8;
+
+ /* 4bpp formats */
+ case PICT_a4: return fbFetchPixel_a4;
+ case PICT_r1g2b1: return fbFetchPixel_r1g2b1;
+ case PICT_b1g2r1: return fbFetchPixel_b1g2r1;
+ case PICT_a1r1g1b1: return fbFetchPixel_a1r1g1b1;
+ case PICT_a1b1g1r1: return fbFetchPixel_a1b1g1r1;
+ case PICT_c4: return fbFetchPixel_c4;
+ case PICT_g4: return fbFetchPixel_c4;
+
+ /* 1bpp formats */
+ case PICT_a1: return fbFetchPixel_a1;
+ case PICT_g1: return fbFetchPixel_g1;
+ default:
+ return NULL;
+ }
+}
+
+
+
+/*
+ * All the store functions
+ */
+
+typedef FASTCALL void (*storeProc) (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed);
+
+#define Splita(v) CARD32 a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
+#define Split(v) CARD32 r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff
+
+static FASTCALL void
+fbStore_a8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ memcpy(((CARD32 *)bits) + x, values, width*sizeof(CARD32));
+}
+
+static FASTCALL void
+fbStore_x8r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD32 *pixel = (CARD32 *)bits + x;
+ for (i = 0; i < width; ++i)
+ *pixel++ = values[i] & 0xffffff;
+}
+
+static FASTCALL void
+fbStore_a8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD32 *pixel = (CARD32 *)bits + x;
+ for (i = 0; i < width; ++i)
+ *pixel++ = (values[i] & 0xff00ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16);
+}
+
+static FASTCALL void
+fbStore_x8b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD32 *pixel = (CARD32 *)bits + x;
+ for (i = 0; i < width; ++i)
+ *pixel++ = (values[i] & 0x0000ff00) | ((values[i] >> 16) & 0xff) | ((values[i] & 0xff) << 16);
+}
+
+static FASTCALL void
+fbStore_r8g8b8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + 3*x;
+ for (i = 0; i < width; ++i) {
+ Store24(pixel, values[i]);
+ pixel += 3;
+ }
+}
+
+static FASTCALL void
+fbStore_b8g8r8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + 3*x;
+ for (i = 0; i < width; ++i) {
+#if IMAGE_BYTE_ORDER == MSBFirst
+ *pixel++ = Blue(values[i]);
+ *pixel++ = Green(values[i]);
+ *pixel++ = Red(values[i]);
+#else
+ *pixel++ = Red(values[i]);
+ *pixel++ = Green(values[i]);
+ *pixel++ = Blue(values[i]);
+#endif
+ }
+}
+
+static FASTCALL void
+fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = values[i];
+ *pixel++ = ((s >> 3) & 0x001f) |
+ ((s >> 5) & 0x07e0) |
+ ((s >> 8) & 0xf800);
+ }
+}
+
+static FASTCALL void
+fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((b << 8) & 0xf800) |
+ ((g << 3) & 0x07e0) |
+ ((r >> 3) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Splita(values[i]);
+ *pixel++ = (((a << 8) & 0x8000) |
+ ((r << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
+ }
+}
+
+static FASTCALL void
+fbStore_x1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((r << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Splita(values[i]);
+ *pixel++ = (((a << 8) & 0x8000) |
+ ((b << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
+ }
+}
+
+static FASTCALL void
+fbStore_x1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((b << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Splita(values[i]);
+ *pixel++ = (((a << 8) & 0xf000) |
+ ((r << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
+ }
+}
+
+static FASTCALL void
+fbStore_x4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((r << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Splita(values[i]);
+ *pixel++ = (((a << 8) & 0xf000) |
+ ((b << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
+ }
+}
+
+static FASTCALL void
+fbStore_x4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD16 *pixel = ((CARD16 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((b << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ *pixel++ = values[i] >> 24;
+ }
+}
+
+static FASTCALL void
+fbStore_r3g3b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((r ) & 0xe0) |
+ ((g >> 3) & 0x1c) |
+ ((b >> 6) ));
+ }
+}
+
+static FASTCALL void
+fbStore_b2g3r3 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Split(values[i]);
+ *pixel++ = (((b ) & 0xe0) |
+ ((g >> 3) & 0x1c) |
+ ((r >> 6) ));
+ }
+}
+
+static FASTCALL void
+fbStore_a2r2g2b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ Splita(values[i]);
+ *pixel++ = (((a ) & 0xc0) |
+ ((r >> 2) & 0x30) |
+ ((g >> 4) & 0x0c) |
+ ((b >> 6) ));
+ }
+}
+
+static FASTCALL void
+fbStore_c8 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ CARD8 *pixel = ((CARD8 *) bits) + x;
+ for (i = 0; i < width; ++i) {
+ *pixel++ = miIndexToEnt24(indexed,values[i]);
+ }
+}
+
+#define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v))
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
+ (Fetch8(l,o) & 0xf0) | (v) : \
+ (Fetch8(l,o) & 0x0f) | ((v) << 4)))
+#else
+#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
+ (Fetch8(l,o) & 0x0f) | ((v) << 4) : \
+ (Fetch8(l,o) & 0xf0) | (v)))
+#endif
+
+static FASTCALL void
+fbStore_a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ Store4(bits, i + x, values[i]>>28);
+ }
+}
+
+static FASTCALL void
+fbStore_r1g2b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 pixel;
+
+ Split(values[i]);
+ pixel = (((r >> 4) & 0x8) |
+ ((g >> 5) & 0x6) |
+ ((b >> 7) ));
+ Store4(bits, i + x, pixel);
+ }
+}
+
+static FASTCALL void
+fbStore_b1g2r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 pixel;
+
+ Split(values[i]);
+ pixel = (((b >> 4) & 0x8) |
+ ((g >> 5) & 0x6) |
+ ((r >> 7) ));
+ Store4(bits, i + x, pixel);
+ }
+}
+
+static FASTCALL void
+fbStore_a1r1g1b1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 pixel;
+ Splita(values[i]);
+ pixel = (((a >> 4) & 0x8) |
+ ((r >> 5) & 0x4) |
+ ((g >> 6) & 0x2) |
+ ((b >> 7) ));
+ Store4(bits, i + x, pixel);
+ }
+}
+
+static FASTCALL void
+fbStore_a1b1g1r1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 pixel;
+ Splita(values[i]);
+ pixel = (((a >> 4) & 0x8) |
+ ((b >> 5) & 0x4) |
+ ((g >> 6) & 0x2) |
+ ((r >> 7) ));
+ Store4(bits, i + x, pixel);
+ }
+}
+
+static FASTCALL void
+fbStore_c4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 pixel;
+
+ pixel = miIndexToEnt24(indexed, values[i]);
+ Store4(bits, i + x, pixel);
+ }
+}
+
+static FASTCALL void
+fbStore_a1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 *pixel = ((CARD32 *) bits) + ((i+x) >> 5);
+ CARD32 mask = FbStipMask((i+x) & 0x1f, 1);
+
+ CARD32 v = values[i] & 0x80000000 ? mask : 0;
+ *pixel = (*pixel & ~mask) | v;
+ }
+}
+
+static FASTCALL void
+fbStore_g1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 *pixel = ((CARD32 *) bits) + ((i+x) >> 5);
+ CARD32 mask = FbStipMask((i+x) & 0x1f, 1);
+
+ CARD32 v = miIndexToEntY24(indexed,values[i]) ? mask : 0;
+ *pixel = (*pixel & ~mask) | v;
+ }
+}
+
+
+static storeProc storeProcForPicture (PicturePtr pict)
+{
+ switch(pict->format) {
+ case PICT_a8r8g8b8: return fbStore_a8r8g8b8;
+ case PICT_x8r8g8b8: return fbStore_x8r8g8b8;
+ case PICT_a8b8g8r8: return fbStore_a8b8g8r8;
+ case PICT_x8b8g8r8: return fbStore_x8b8g8r8;
+
+ /* 24bpp formats */
+ case PICT_r8g8b8: return fbStore_r8g8b8;
+ case PICT_b8g8r8: return fbStore_b8g8r8;
+
+ /* 16bpp formats */
+ case PICT_r5g6b5: return fbStore_r5g6b5;
+ case PICT_b5g6r5: return fbStore_b5g6r5;
+
+ case PICT_a1r5g5b5: return fbStore_a1r5g5b5;
+ case PICT_x1r5g5b5: return fbStore_x1r5g5b5;
+ case PICT_a1b5g5r5: return fbStore_a1b5g5r5;
+ case PICT_x1b5g5r5: return fbStore_x1b5g5r5;
+ case PICT_a4r4g4b4: return fbStore_a4r4g4b4;
+ case PICT_x4r4g4b4: return fbStore_x4r4g4b4;
+ case PICT_a4b4g4r4: return fbStore_a4b4g4r4;
+ case PICT_x4b4g4r4: return fbStore_x4b4g4r4;
+
+ /* 8bpp formats */
+ case PICT_a8: return fbStore_a8;
+ case PICT_r3g3b2: return fbStore_r3g3b2;
+ case PICT_b2g3r3: return fbStore_b2g3r3;
+ case PICT_a2r2g2b2: return fbStore_a2r2g2b2;
+ case PICT_c8: return fbStore_c8;
+ case PICT_g8: return fbStore_c8;
+
+ /* 4bpp formats */
+ case PICT_a4: return fbStore_a4;
+ case PICT_r1g2b1: return fbStore_r1g2b1;
+ case PICT_b1g2r1: return fbStore_b1g2r1;
+ case PICT_a1r1g1b1: return fbStore_a1r1g1b1;
+ case PICT_a1b1g1r1: return fbStore_a1b1g1r1;
+ case PICT_c4: return fbStore_c4;
+ case PICT_g4: return fbStore_c4;
+
+ /* 1bpp formats */
+ case PICT_a1: return fbStore_a1;
+ case PICT_g1: return fbStore_g1;
+ default:
+ return NULL;
+ }
+}
+
+
+/*
+ * Combine src and mask
+ */
+static FASTCALL void
+fbCombineMaskU (CARD32 *src, const CARD32 *mask, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 a = mask[i] >> 24;
+ CARD32 s = src[i];
+ FbByteMul(s, a);
+ src[i] = s;
+ }
+}
+
+/*
+ * All of the composing functions
+ */
+
+static FASTCALL void
+fbCombineClear (CARD32 *dest, const CARD32 *src, int width)
+{
+ memset(dest, 0, width*sizeof(CARD32));
+}
+
+static FASTCALL void
+fbCombineSrcU (CARD32 *dest, const CARD32 *src, int width)
+{
+ memcpy(dest, src, width*sizeof(CARD32));
+}
+
+
+static FASTCALL void
+fbCombineOverU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 ia = Alpha(~s);
+
+ FbByteMulAdd(d, ia, s);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineOverReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 ia = Alpha(~dest[i]);
+ FbByteMulAdd(s, ia, d);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineInU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 a = Alpha(dest[i]);
+ FbByteMul(s, a);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineInReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD32 a = Alpha(src[i]);
+ FbByteMul(d, a);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineOutU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 a = Alpha(~dest[i]);
+ FbByteMul(s, a);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineOutReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD32 a = Alpha(~src[i]);
+ FbByteMul(d, a);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineAtopU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 dest_a = Alpha(d);
+ CARD32 src_ia = Alpha(~s);
+
+ FbByteAddMul(s, dest_a, d, src_ia);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 src_a = Alpha(s);
+ CARD32 dest_ia = Alpha(~d);
+
+ FbByteAddMul(s, dest_ia, d, src_a);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineXorU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 src_ia = Alpha(~s);
+ CARD32 dest_ia = Alpha(~d);
+
+ FbByteAddMul(s, dest_ia, d, src_ia);
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineAddU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ FbByteAdd(d, s);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineSaturateU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD16 sa, da;
+
+ sa = s >> 24;
+ da = ~d >> 24;
+ if (sa > da)
+ {
+ sa = FbIntDiv(da, sa);
+ FbByteMul(s, sa);
+ }
+ FbByteAdd(d, s);
+ dest[i] = d;
+ }
+}
+
+/*
+ * All of the disjoint composing functions
+
+ The four entries in the first column indicate what source contributions
+ come from each of the four areas of the picture -- areas covered by neither
+ A nor B, areas covered only by A, areas covered only by B and finally
+ areas covered by both A and B.
+
+ Disjoint Conjoint
+ Fa Fb Fa Fb
+(0,0,0,0) 0 0 0 0
+(0,A,0,A) 1 0 1 0
+(0,0,B,B) 0 1 0 1
+(0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
+(0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
+(0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
+(0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
+(0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
+(0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
+(0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
+(0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
+(0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
+
+ */
+
+#define CombineAOut 1
+#define CombineAIn 2
+#define CombineBOut 4
+#define CombineBIn 8
+
+#define CombineClear 0
+#define CombineA (CombineAOut|CombineAIn)
+#define CombineB (CombineBOut|CombineBIn)
+#define CombineAOver (CombineAOut|CombineBOut|CombineAIn)
+#define CombineBOver (CombineAOut|CombineBOut|CombineBIn)
+#define CombineAAtop (CombineBOut|CombineAIn)
+#define CombineBAtop (CombineAOut|CombineBIn)
+#define CombineXor (CombineAOut|CombineBOut)
+
+/* portion covered by a but not b */
+static INLINE CARD8
+fbCombineDisjointOutPart (CARD8 a, CARD8 b)
+{
+ /* min (1, (1-b) / a) */
+
+ b = ~b; /* 1 - b */
+ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
+ return 0xff; /* 1 */
+ return FbIntDiv(b,a); /* (1-b) / a */
+}
+
+/* portion covered by both a and b */
+static INLINE CARD8
+fbCombineDisjointInPart (CARD8 a, CARD8 b)
+{
+ /* max (1-(1-b)/a,0) */
+ /* = - min ((1-b)/a - 1, 0) */
+ /* = 1 - min (1, (1-b)/a) */
+
+ b = ~b; /* 1 - b */
+ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
+ return 0; /* 1 - 1 */
+ return ~FbIntDiv(b,a); /* 1 - (1-b) / a */
+}
+
+static FASTCALL void
+fbCombineDisjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 m,n,o,p;
+ CARD16 Fa, Fb, t, u, v;
+ CARD8 sa = s >> 24;
+ CARD8 da = d >> 24;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ Fa = fbCombineDisjointOutPart (sa, da);
+ break;
+ case CombineAIn:
+ Fa = fbCombineDisjointInPart (sa, da);
+ break;
+ case CombineA:
+ Fa = 0xff;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ Fb = fbCombineDisjointOutPart (da, sa);
+ break;
+ case CombineBIn:
+ Fb = fbCombineDisjointInPart (da, sa);
+ break;
+ case CombineB:
+ Fb = 0xff;
+ break;
+ }
+ m = FbGen (s,d,0,Fa,Fb,t, u, v);
+ n = FbGen (s,d,8,Fa,Fb,t, u, v);
+ o = FbGen (s,d,16,Fa,Fb,t, u, v);
+ p = FbGen (s,d,24,Fa,Fb,t, u, v);
+ s = m|n|o|p;
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineDisjointOverU (CARD32 *dest, const CARD32 *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD16 a = s >> 24;
+
+ if (a != 0x00)
+ {
+ if (a != 0xff)
+ {
+ CARD32 d = dest[i];
+ a = fbCombineDisjointOutPart (d >> 24, a);
+ FbByteMulAdd(d, a, s);
+ s = d;
+ }
+ dest[i] = s;
+ }
+ }
+}
+
+static FASTCALL void
+fbCombineDisjointInU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAIn);
+}
+
+static FASTCALL void
+fbCombineDisjointInReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBIn);
+}
+
+static FASTCALL void
+fbCombineDisjointOutU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAOut);
+}
+
+static FASTCALL void
+fbCombineDisjointOutReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBOut);
+}
+
+static FASTCALL void
+fbCombineDisjointAtopU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAAtop);
+}
+
+static FASTCALL void
+fbCombineDisjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBAtop);
+}
+
+static FASTCALL void
+fbCombineDisjointXorU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineXor);
+}
+
+/* portion covered by a but not b */
+static INLINE CARD8
+fbCombineConjointOutPart (CARD8 a, CARD8 b)
+{
+ /* max (1-b/a,0) */
+ /* = 1-min(b/a,1) */
+
+ /* min (1, (1-b) / a) */
+
+ if (b >= a) /* b >= a -> b/a >= 1 */
+ return 0x00; /* 0 */
+ return ~FbIntDiv(b,a); /* 1 - b/a */
+}
+
+/* portion covered by both a and b */
+static INLINE CARD8
+fbCombineConjointInPart (CARD8 a, CARD8 b)
+{
+ /* min (1,b/a) */
+
+ if (b >= a) /* b >= a -> b/a >= 1 */
+ return 0xff; /* 1 */
+ return FbIntDiv(b,a); /* b/a */
+}
+
+static FASTCALL void
+fbCombineConjointGeneralU (CARD32 *dest, const CARD32 *src, int width, CARD8 combine)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ CARD32 m,n,o,p;
+ CARD16 Fa, Fb, t, u, v;
+ CARD8 sa = s >> 24;
+ CARD8 da = d >> 24;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ Fa = fbCombineConjointOutPart (sa, da);
+ break;
+ case CombineAIn:
+ Fa = fbCombineConjointInPart (sa, da);
+ break;
+ case CombineA:
+ Fa = 0xff;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ Fb = fbCombineConjointOutPart (da, sa);
+ break;
+ case CombineBIn:
+ Fb = fbCombineConjointInPart (da, sa);
+ break;
+ case CombineB:
+ Fb = 0xff;
+ break;
+ }
+ m = FbGen (s,d,0,Fa,Fb,t, u, v);
+ n = FbGen (s,d,8,Fa,Fb,t, u, v);
+ o = FbGen (s,d,16,Fa,Fb,t, u, v);
+ p = FbGen (s,d,24,Fa,Fb,t, u, v);
+ s = m|n|o|p;
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineConjointOverU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAOver);
+}
+
+
+static FASTCALL void
+fbCombineConjointOverReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBOver);
+}
+
+
+static FASTCALL void
+fbCombineConjointInU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAIn);
+}
+
+
+static FASTCALL void
+fbCombineConjointInReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBIn);
+}
+
+static FASTCALL void
+fbCombineConjointOutU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAOut);
+}
+
+static FASTCALL void
+fbCombineConjointOutReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBOut);
+}
+
+static FASTCALL void
+fbCombineConjointAtopU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAAtop);
+}
+
+static FASTCALL void
+fbCombineConjointAtopReverseU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBAtop);
+}
+
+static FASTCALL void
+fbCombineConjointXorU (CARD32 *dest, const CARD32 *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineXor);
+}
+
+static CombineFuncU fbCombineFuncU[] = {
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineOverU,
+ fbCombineOverReverseU,
+ fbCombineInU,
+ fbCombineInReverseU,
+ fbCombineOutU,
+ fbCombineOutReverseU,
+ fbCombineAtopU,
+ fbCombineAtopReverseU,
+ fbCombineXorU,
+ fbCombineAddU,
+ fbCombineSaturateU,
+ NULL,
+ NULL,
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineDisjointOverU,
+ fbCombineSaturateU, /* DisjointOverReverse */
+ fbCombineDisjointInU,
+ fbCombineDisjointInReverseU,
+ fbCombineDisjointOutU,
+ fbCombineDisjointOutReverseU,
+ fbCombineDisjointAtopU,
+ fbCombineDisjointAtopReverseU,
+ fbCombineDisjointXorU,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineConjointOverU,
+ fbCombineConjointOverReverseU,
+ fbCombineConjointInU,
+ fbCombineConjointInReverseU,
+ fbCombineConjointOutU,
+ fbCombineConjointOutReverseU,
+ fbCombineConjointAtopU,
+ fbCombineConjointAtopReverseU,
+ fbCombineConjointXorU,
+};
+
+static FASTCALL void
+fbCombineMaskC (CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 a = mask[i];
+
+ CARD32 x;
+ CARD16 xa;
+
+ if (!a)
+ {
+ src[i] = 0;
+ continue;
+ }
+
+ x = src[i];
+ if (a == 0xffffffff)
+ {
+ x = x >> 24;
+ x |= x << 8;
+ x |= x << 16;
+ mask[i] = x;
+ continue;
+ }
+
+ xa = x >> 24;
+ FbByteMulC(x, a);
+ src[i] = x;
+ FbByteMul(a, xa);
+ mask[i] = a;
+ }
+}
+
+static FASTCALL void
+fbCombineMaskValueC (CARD32 *src, const CARD32 *mask, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 a = mask[i];
+ CARD32 x;
+
+ if (!a)
+ {
+ src[i] = 0;
+ continue;
+ }
+
+ if (a == 0xffffffff)
+ continue;
+
+ x = src[i];
+ FbByteMulC(x, a);
+ src[i] = x;
+ }
+}
+
+
+static FASTCALL void
+fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ CARD32 a = mask[i];
+ CARD32 x;
+
+ if (!a)
+ continue;
+
+ x = src[i] >> 24;
+ if (x == 0xff)
+ continue;
+ if (a == 0xffffffff)
+ {
+ x = x >> 24;
+ x |= x << 8;
+ x |= x << 16;
+ mask[i] = x;
+ continue;
+ }
+
+ FbByteMul(a, x);
+ mask[i] = a;
+ }
+}
+
+static FASTCALL void
+fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ memset(dest, 0, width*sizeof(CARD32));
+}
+
+static FASTCALL void
+fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineMaskValueC(src, mask, width);
+ memcpy(dest, src, width*sizeof(CARD32));
+}
+
+static FASTCALL void
+fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 a = ~mask[i];
+
+ if (a != 0xffffffff)
+ {
+ if (a)
+ {
+ CARD32 d = dest[i];
+ FbByteMulAddC(d, a, s);
+ s = d;
+ }
+ dest[i] = s;
+ }
+ }
+}
+
+static FASTCALL void
+fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskValueC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD32 a = ~d >> 24;
+
+ if (a)
+ {
+ CARD32 s = src[i];
+ if (a != 0xff)
+ {
+ FbByteMulAdd(s, a, d);
+ }
+ dest[i] = s;
+ }
+ }
+}
+
+static FASTCALL void
+fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskValueC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD16 a = d >> 24;
+ CARD32 s = 0;
+ if (a)
+ {
+ s = src[i];
+ if (a != 0xff)
+ {
+ FbByteMul(s, a);
+ }
+ }
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskAlphaC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 a = mask[i];
+
+ if (a != 0xffffffff)
+ {
+ CARD32 d = 0;
+ if (a)
+ {
+ d = dest[i];
+ FbByteMulC(d, a);
+ }
+ dest[i] = d;
+ }
+ }
+}
+
+static FASTCALL void
+fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskValueC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD16 a = ~d >> 24;
+ CARD32 s = 0;
+ if (a)
+ {
+ s = src[i];
+ if (a != 0xff)
+ {
+ FbByteMul(s, a);
+ }
+ }
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskAlphaC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 a = ~mask[i];
+
+ if (a != 0xffffffff)
+ {
+ CARD32 d = 0;
+ if (a)
+ {
+ d = dest[i];
+ FbByteMulC(d, a);
+ }
+ dest[i] = d;
+ }
+ }
+}
+
+static FASTCALL void
+fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD32 s = src[i];
+ CARD32 ad = ~mask[i];
+ CARD16 as = d >> 24;
+ FbByteAddMulC(d, ad, s, as);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+
+ CARD32 d = dest[i];
+ CARD32 s = src[i];
+ CARD32 ad = mask[i];
+ CARD16 as = ~d >> 24;
+ FbByteAddMulC(d, ad, s, as);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 d = dest[i];
+ CARD32 s = src[i];
+ CARD32 ad = ~mask[i];
+ CARD16 as = ~d >> 24;
+ FbByteAddMulC(d, ad, s, as);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskValueC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 s = src[i];
+ CARD32 d = dest[i];
+ FbByteAdd(d, s);
+ dest[i] = d;
+ }
+}
+
+static FASTCALL void
+fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 s, d;
+ CARD16 sa, sr, sg, sb, da;
+ CARD16 t, u, v;
+ CARD32 m,n,o,p;
+
+ d = dest[i];
+ s = src[i];
+ sa = (mask[i] >> 24);
+ sr = (mask[i] >> 16) & 0xff;
+ sg = (mask[i] >> 8) & 0xff;
+ sb = (mask[i] ) & 0xff;
+ da = ~d >> 24;
+
+ if (sb <= da)
+ m = FbAdd(s,d,0,t);
+ else
+ m = FbGen (s, d, 0, (da << 8) / sb, 0xff, t, u, v);
+
+ if (sg <= da)
+ n = FbAdd(s,d,8,t);
+ else
+ n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v);
+
+ if (sr <= da)
+ o = FbAdd(s,d,16,t);
+ else
+ o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v);
+
+ if (sa <= da)
+ p = FbAdd(s,d,24,t);
+ else
+ p = FbGen (s, d, 24, (da << 8) / sa, 0xff, t, u, v);
+
+ dest[i] = m|n|o|p;
+ }
+}
+
+static FASTCALL void
+fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 s, d;
+ CARD32 m,n,o,p;
+ CARD32 Fa, Fb;
+ CARD16 t, u, v;
+ CARD32 sa;
+ CARD8 da;
+
+ s = src[i];
+ sa = mask[i];
+ d = dest[i];
+ da = d >> 24;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da);
+ n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8;
+ o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16;
+ p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24;
+ Fa = m|n|o|p;
+ break;
+ case CombineAIn:
+ m = fbCombineDisjointInPart ((CARD8) (sa >> 0), da);
+ n = fbCombineDisjointInPart ((CARD8) (sa >> 8), da) << 8;
+ o = fbCombineDisjointInPart ((CARD8) (sa >> 16), da) << 16;
+ p = fbCombineDisjointInPart ((CARD8) (sa >> 24), da) << 24;
+ Fa = m|n|o|p;
+ break;
+ case CombineA:
+ Fa = 0xffffffff;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ m = fbCombineDisjointOutPart (da, (CARD8) (sa >> 0));
+ n = fbCombineDisjointOutPart (da, (CARD8) (sa >> 8)) << 8;
+ o = fbCombineDisjointOutPart (da, (CARD8) (sa >> 16)) << 16;
+ p = fbCombineDisjointOutPart (da, (CARD8) (sa >> 24)) << 24;
+ Fb = m|n|o|p;
+ break;
+ case CombineBIn:
+ m = fbCombineDisjointInPart (da, (CARD8) (sa >> 0));
+ n = fbCombineDisjointInPart (da, (CARD8) (sa >> 8)) << 8;
+ o = fbCombineDisjointInPart (da, (CARD8) (sa >> 16)) << 16;
+ p = fbCombineDisjointInPart (da, (CARD8) (sa >> 24)) << 24;
+ Fb = m|n|o|p;
+ break;
+ case CombineB:
+ Fb = 0xffffffff;
+ break;
+ }
+ m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v);
+ n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v);
+ o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v);
+ p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v);
+ s = m|n|o|p;
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineDisjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOver);
+}
+
+static FASTCALL void
+fbCombineDisjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAIn);
+}
+
+static FASTCALL void
+fbCombineDisjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBIn);
+}
+
+static FASTCALL void
+fbCombineDisjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut);
+}
+
+static FASTCALL void
+fbCombineDisjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBOut);
+}
+
+static FASTCALL void
+fbCombineDisjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAAtop);
+}
+
+static FASTCALL void
+fbCombineDisjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBAtop);
+}
+
+static FASTCALL void
+fbCombineDisjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineXor);
+}
+
+static FASTCALL void
+fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
+{
+ int i;
+ fbCombineMaskC(src, mask, width);
+ for (i = 0; i < width; ++i) {
+ CARD32 s, d;
+ CARD32 m,n,o,p;
+ CARD32 Fa, Fb;
+ CARD16 t, u, v;
+ CARD32 sa;
+ CARD8 da;
+
+ s = src[i];
+ sa = mask[i];
+ d = dest[i];
+ da = d >> 24;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da);
+ n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8;
+ o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16;
+ p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24;
+ Fa = m|n|o|p;
+ break;
+ case CombineAIn:
+ m = fbCombineConjointInPart ((CARD8) (sa >> 0), da);
+ n = fbCombineConjointInPart ((CARD8) (sa >> 8), da) << 8;
+ o = fbCombineConjointInPart ((CARD8) (sa >> 16), da) << 16;
+ p = fbCombineConjointInPart ((CARD8) (sa >> 24), da) << 24;
+ Fa = m|n|o|p;
+ break;
+ case CombineA:
+ Fa = 0xffffffff;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ m = fbCombineConjointOutPart (da, (CARD8) (sa >> 0));
+ n = fbCombineConjointOutPart (da, (CARD8) (sa >> 8)) << 8;
+ o = fbCombineConjointOutPart (da, (CARD8) (sa >> 16)) << 16;
+ p = fbCombineConjointOutPart (da, (CARD8) (sa >> 24)) << 24;
+ Fb = m|n|o|p;
+ break;
+ case CombineBIn:
+ m = fbCombineConjointInPart (da, (CARD8) (sa >> 0));
+ n = fbCombineConjointInPart (da, (CARD8) (sa >> 8)) << 8;
+ o = fbCombineConjointInPart (da, (CARD8) (sa >> 16)) << 16;
+ p = fbCombineConjointInPart (da, (CARD8) (sa >> 24)) << 24;
+ Fb = m|n|o|p;
+ break;
+ case CombineB:
+ Fb = 0xffffffff;
+ break;
+ }
+ m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t, u, v);
+ n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t, u, v);
+ o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t, u, v);
+ p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t, u, v);
+ s = m|n|o|p;
+ dest[i] = s;
+ }
+}
+
+static FASTCALL void
+fbCombineConjointOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAOver);
+}
+
+static FASTCALL void
+fbCombineConjointOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver);
+}
+
+static FASTCALL void
+fbCombineConjointInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAIn);
+}
+
+static FASTCALL void
+fbCombineConjointInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBIn);
+}
+
+static FASTCALL void
+fbCombineConjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAOut);
+}
+
+static FASTCALL void
+fbCombineConjointOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBOut);
+}
+
+static FASTCALL void
+fbCombineConjointAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAAtop);
+}
+
+static FASTCALL void
+fbCombineConjointAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBAtop);
+}
+
+static FASTCALL void
+fbCombineConjointXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineXor);
+}
+
+static CombineFuncC fbCombineFuncC[] = {
+ fbCombineClearC,
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineOverC,
+ fbCombineOverReverseC,
+ fbCombineInC,
+ fbCombineInReverseC,
+ fbCombineOutC,
+ fbCombineOutReverseC,
+ fbCombineAtopC,
+ fbCombineAtopReverseC,
+ fbCombineXorC,
+ fbCombineAddC,
+ fbCombineSaturateC,
+ NULL,
+ NULL,
+ fbCombineClearC, /* 0x10 */
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineDisjointOverC,
+ fbCombineSaturateC, /* DisjointOverReverse */
+ fbCombineDisjointInC,
+ fbCombineDisjointInReverseC,
+ fbCombineDisjointOutC,
+ fbCombineDisjointOutReverseC,
+ fbCombineDisjointAtopC,
+ fbCombineDisjointAtopReverseC,
+ fbCombineDisjointXorC, /* 0x1b */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ fbCombineClearC,
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineConjointOverC,
+ fbCombineConjointOverReverseC,
+ fbCombineConjointInC,
+ fbCombineConjointInReverseC,
+ fbCombineConjointOutC,
+ fbCombineConjointOutReverseC,
+ fbCombineConjointAtopC,
+ fbCombineConjointAtopReverseC,
+ fbCombineConjointXorC,
+};
+
+
+FbComposeFunctions composeFunctions = {
+ fbCombineFuncU,
+ fbCombineFuncC,
+ fbCombineMaskU
+};
+
+
+static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ FbBits *bits;
+ FbStride stride;
+ int bpp;
+ int xoff, yoff;
+ CARD32 color;
+ CARD32 *end;
+ fetchPixelProc fetch = fetchPixelProcForPicture(pict);
+ miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+
+ fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+ bits += yoff*stride + (xoff*bpp >> FB_SHIFT);
+
+ color = fetch(bits, 0, indexed);
+
+ end = buffer + width;
+ while (buffer < end)
+ *buffer++ = color;
+}
+
+static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ FbBits *bits;
+ FbStride stride;
+ int bpp;
+ int xoff, yoff;
+ fetchProc fetch = fetchProcForPicture(pict);
+ miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+
+ fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+ x += xoff;
+ y += yoff;
+
+ bits += y*stride;
+
+ fetch(bits, x, width, buffer, indexed);
+}
+
+#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
+#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\
+ ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
+
+
+static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
+{
+ int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
+
+ /* calculate the actual offset. */
+ if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
+ if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
+ ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
+ ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
+
+ } else if (spread == RepeatReflect) {
+ const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
+ ipos = ipos % limit;
+ ipos = ipos < 0 ? limit + ipos : ipos;
+ ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
+
+ } else if (spread == RepeatPad) {
+ if (ipos < 0)
+ ipos = 0;
+ else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
+ ipos = PICT_GRADIENT_STOPTABLE_SIZE-1;
+ } else { /* RepeatNone */
+ return 0;
+ }
+ }
+
+ assert(ipos >= 0);
+ assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
+
+ return pGradient->linear.colorTable[ipos];
+}
+
+static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ SourcePictPtr pGradient = pict->pSourcePict;
+ CARD32 *end = buffer + width;
+
+ if (pGradient->type == SourcePictTypeSolidFill) {
+ register CARD32 color = pGradient->solidFill.color;
+ while (buffer < end) {
+ *buffer++ = color;
+ }
+ } else if (pGradient->type == SourcePictTypeLinear) {
+ PictVector v, unit;
+ xFixed_32_32 l;
+ xFixed_48_16 dx, dy, a, b, off;
+
+ v.vector[0] = IntToxFixed(x);
+ v.vector[1] = IntToxFixed(y);
+ v.vector[2] = xFixed1;
+ if (pict->transform) {
+ if (!PictureTransformPoint3d (pict->transform, &v))
+ return;
+ unit.vector[0] = pict->transform->matrix[0][0];
+ unit.vector[1] = pict->transform->matrix[1][0];
+ unit.vector[2] = pict->transform->matrix[2][0];
+ } else {
+ unit.vector[0] = xFixed1;
+ unit.vector[1] = 0;
+ unit.vector[2] = 0;
+ }
+
+ dx = pGradient->linear.p2.x - pGradient->linear.p1.x;
+ dy = pGradient->linear.p2.y - pGradient->linear.p1.y;
+ l = dx*dx + dy*dy;
+ if (l != 0) {
+ a = (dx << 32) / l;
+ b = (dy << 32) / l;
+ off = (-a*pGradient->linear.p1.x - b*pGradient->linear.p1.y)>>16;
+ }
+ if (l == 0 || (unit.vector[2] == 0 && v.vector[2] == xFixed1)) {
+ xFixed_48_16 inc, t;
+ /* affine transformation only */
+ if (l == 0) {
+ t = 0;
+ inc = 0;
+ } else {
+ t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
+ inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
+ }
+ while (buffer < end) {
+ *buffer++ = gradientPixel(pGradient, t, pict->repeatType);
+ t += inc;
+ }
+ } else {
+ /* projective transformation */
+ while (buffer < end) {
+ xFixed_48_16 t;
+ if (v.vector[2] == 0) {
+ t = 0;
+ } else {
+ xFixed_48_16 x, y;
+ x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
+ y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
+ t = ((a*x + b*y) >> 16) + off;
+ }
+ *buffer++ = gradientPixel(pGradient, t, pict->repeatType);
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+ } else {
+ /* radial or conical */
+ Bool affine = TRUE;
+ double cx = 1.;
+ double cy = 0.;
+ double cz = 0.;
+ double rx = x;
+ double ry = y;
+ double rz = 1.;
+
+ if (pict->transform) {
+ PictVector v;
+ v.vector[0] = IntToxFixed(x);
+ v.vector[1] = IntToxFixed(y);
+ v.vector[2] = xFixed1;
+ if (!PictureTransformPoint3d (pict->transform, &v))
+ return;
+
+ cx = pict->transform->matrix[0][0]/65536.;
+ cy = pict->transform->matrix[1][0]/65536.;
+ cz = pict->transform->matrix[2][0]/65536.;
+ rx = v.vector[0]/65536.;
+ ry = v.vector[1]/65536.;
+ rz = v.vector[2]/65536.;
+ affine = pict->transform->matrix[2][0] == 0 && v.vector[2] == xFixed1;
+ }
+
+ if (pGradient->type == SourcePictTypeRadial) {
+ if (affine) {
+ rx -= pGradient->radial.fx;
+ ry -= pGradient->radial.fy;
+
+ while (buffer < end) {
+ double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
+ double c = -(rx*rx + ry*ry);
+ double det = (b * b) - (4 * pGradient->radial.a * c);
+ double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+ *buffer = gradientPixel(pGradient,
+ (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
+ pict->repeatType);
+ ++buffer;
+ rx += cx;
+ ry += cy;
+ }
+ } else {
+ while (buffer < end) {
+ double x, y;
+ double b, c, det, s;
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+ x -= pGradient->radial.fx;
+ y -= pGradient->radial.fy;
+ b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
+ c = -(x*x + y*y);
+ det = (b * b) - (4 * pGradient->radial.a * c);
+ s = (-b + sqrt(det))/(2. * pGradient->radial.a);
+ *buffer = gradientPixel(pGradient,
+ (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
+ pict->repeatType);
+ ++buffer;
+ rx += cx;
+ ry += cy;
+ rz += cz;
+ }
+ }
+ } else /* SourcePictTypeConical */ {
+ double a = pGradient->conical.angle/(180.*65536);
+ if (affine) {
+ rx -= pGradient->conical.center.x/65536.;
+ ry -= pGradient->conical.center.y/65536.;
+
+ while (buffer < end) {
+ double angle = atan2(ry, rx) + a;
+ *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+ pict->repeatType);
+ ++buffer;
+ rx += cx;
+ ry += cy;
+ }
+ } else {
+
+ while (buffer < end) {
+ double x, y, angle;
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+ x -= pGradient->conical.center.x/65536.;
+ y -= pGradient->conical.center.y/65536.;
+ angle = atan2(y, x) + a;
+ *buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
+ pict->repeatType);
+ ++buffer;
+ rx += cx;
+ ry += cy;
+ rz += cz;
+ }
+ }
+ }
+ }
+}
+
+
+
+static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ FbBits *bits;
+ FbStride stride;
+ int bpp;
+ int xoff, yoff;
+ fetchPixelProc fetch;
+ PictVector v;
+ PictVector unit;
+ int i;
+ BoxRec box;
+ miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+ Bool affine = TRUE;
+
+ fetch = fetchPixelProcForPicture(pict);
+
+ fbGetDrawable(pict->pDrawable, bits, stride, bpp, xoff, yoff);
+ x += xoff;
+ y += yoff;
+
+ v.vector[0] = IntToxFixed(x);
+ v.vector[1] = IntToxFixed(y);
+ v.vector[2] = xFixed1;
+
+ /* when using convolution filters one might get here without a transform */
+ if (pict->transform) {
+ if (!PictureTransformPoint3d (pict->transform, &v))
+ return;
+ unit.vector[0] = pict->transform->matrix[0][0];
+ unit.vector[1] = pict->transform->matrix[1][0];
+ unit.vector[2] = pict->transform->matrix[2][0];
+ affine = v.vector[2] == xFixed1 && unit.vector[2] == 0;
+ } else {
+ unit.vector[0] = xFixed1;
+ unit.vector[1] = 0;
+ unit.vector[2] = 0;
+ }
+
+ if (pict->filter == PictFilterNearest)
+ {
+ if (pict->repeatType == RepeatNormal) {
+ if (RegionNumRects(pict->pCompositeClip) == 1) {
+ box = pict->pCompositeClip->extents;
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (!affine) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ } else {
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (!affine) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ if (RegionContainsPoint(pict->pCompositeClip, x, y, &box))
+ buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ else
+ buffer[i] = 0;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+ } else {
+ if (RegionNumRects(pict->pCompositeClip) == 1) {
+ box = pict->pCompositeClip->extents;
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (!affine) {
+ y = DIV(v.vector[1],v.vector[2]);
+ x = DIV(v.vector[0],v.vector[2]);
+ } else {
+ y = v.vector[1]>>16;
+ x = v.vector[0]>>16;
+ }
+ buffer[i] = ((x < box.x1) | (x >= box.x2) | (y < box.y1) | (y >= box.y2)) ?
+ 0 : fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ } else {
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ if (!affine) {
+ y = DIV(v.vector[1],v.vector[2]);
+ x = DIV(v.vector[0],v.vector[2]);
+ } else {
+ y = v.vector[1]>>16;
+ x = v.vector[0]>>16;
+ }
+ if (RegionContainsPoint(pict->pCompositeClip, x, y, &box))
+ buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
+ else
+ buffer[i] = 0;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+ }
+ } else if (pict->filter == PictFilterBilinear) {
+ if (pict->repeatType == RepeatNormal) {
+ if (RegionNumRects(pict->pCompositeClip) == 1) {
+ box = pict->pCompositeClip->extents;
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+
+ tl = fetch(b, x1 + pict->pDrawable->x, indexed);
+ tr = fetch(b, x2 + pict->pDrawable->x, indexed);
+ b = bits + (y2 + pict->pDrawable->y)*stride;
+ bl = fetch(b, x1 + pict->pDrawable->x, indexed);
+ br = fetch(b, x2 + pict->pDrawable->x, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ } else {
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+
+ tl = RegionContainsPoint(pict->pCompositeClip, x1, y1, &box)
+ ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
+ tr = RegionContainsPoint(pict->pCompositeClip, x2, y1, &box)
+ ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
+ b = bits + (y2 + pict->pDrawable->y)*stride;
+ bl = RegionContainsPoint(pict->pCompositeClip, x1, y2, &box)
+ ? fetch(b, x1 + pict->pDrawable->x, indexed) : 0;
+ br = RegionContainsPoint(pict->pCompositeClip, x2, y2, &box)
+ ? fetch(b, x2 + pict->pDrawable->x, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+ } else {
+ if (RegionNumRects(pict->pCompositeClip) == 1) {
+ box = pict->pCompositeClip->extents;
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ Bool x1_out, x2_out, y1_out, y2_out;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+ x_off = x1 + pict->pDrawable->x;
+
+ x1_out = (x1 < box.x1) | (x1 >= box.x2);
+ x2_out = (x2 < box.x1) | (x2 >= box.x2);
+ y1_out = (y1 < box.y1) | (y1 >= box.y2);
+ y2_out = (y2 < box.y1) | (y2 >= box.y2);
+
+ tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
+ tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
+ b += stride;
+ bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
+ br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ } else {
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + pict->pDrawable->y)*stride;
+ x_off = x1 + pict->pDrawable->x;
+
+ tl = RegionContainsPoint(pict->pCompositeClip, x1, y1, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ tr = RegionContainsPoint(pict->pCompositeClip, x2, y1, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+ b += stride;
+ bl = RegionContainsPoint(pict->pCompositeClip, x1, y2, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ br = RegionContainsPoint(pict->pCompositeClip, x2, y2, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ buffer[i] = r;
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+ }
+ } else if (pict->filter == PictFilterConvolution) {
+ xFixed *params = pict->filter_params;
+ INT32 cwidth = xFixedToInt(params[0]);
+ INT32 cheight = xFixedToInt(params[1]);
+ int xoff = params[0] >> 1;
+ int yoff = params[1] >> 1;
+ params += 2;
+ for (i = 0; i < width; ++i) {
+ if (!v.vector[2]) {
+ buffer[i] = 0;
+ } else {
+ int x1, x2, y1, y2, x, y;
+ INT32 srtot, sgtot, sbtot, satot;
+ xFixed *p = params;
+
+ if (!affine) {
+ xFixed_48_16 tmp;
+ tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
+ x1 = xFixedToInt(tmp);
+ tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
+ y1 = xFixedToInt(tmp);
+ } else {
+ x1 = xFixedToInt(v.vector[0] - xoff);
+ y1 = xFixedToInt(v.vector[1] - yoff);
+ }
+ x2 = x1 + cwidth;
+ y2 = y1 + cheight;
+
+ srtot = sgtot = sbtot = satot = 0;
+
+ for (y = y1; y < y2; y++) {
+ int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
+ for (x = x1; x < x2; x++) {
+ if (*p) {
+ int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
+ if (RegionContainsPoint(pict->pCompositeClip, tx, ty, &box)) {
+ FbBits *b = bits + (ty + pict->pDrawable->y)*stride;
+ CARD32 c = fetch(b, tx + pict->pDrawable->x, indexed);
+
+ srtot += Red(c) * *p;
+ sgtot += Green(c) * *p;
+ sbtot += Blue(c) * *p;
+ satot += Alpha(c) * *p;
+ }
+ }
+ p++;
+ }
+ }
+
+ if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+ if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+ if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+ if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+
+ buffer[i] = ((satot << 24) |
+ (srtot << 16) |
+ (sgtot << 8) |
+ (sbtot ));
+ }
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
+ }
+}
+
+
+static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ int i;
+ CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
+ CARD32 *alpha_buffer = _alpha_buffer;
+
+ if (!pict->alphaMap) {
+ fbFetchTransformed(pict, x, y, width, buffer);
+ return;
+ }
+ if (width > SCANLINE_BUFFER_LENGTH)
+ alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
+
+ fbFetchTransformed(pict, x, y, width, buffer);
+ fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer);
+ for (i = 0; i < width; ++i) {
+ int a = alpha_buffer[i]>>24;
+ buffer[i] = (a << 24)
+ | (div_255(Red(buffer[i]) * a) << 16)
+ | (div_255(Green(buffer[i]) * a) << 8)
+ | (div_255(Blue(buffer[i]) * a));
+ }
+
+ if (alpha_buffer != _alpha_buffer)
+ free(alpha_buffer);
+}
+
+static void fbStore(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ FbBits *bits;
+ FbStride stride;
+ int bpp;
+ int xoff, yoff;
+ storeProc store = storeProcForPicture(pict);
+ miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+
+ fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+ x += xoff;
+ y += yoff;
+
+ bits += y*stride;
+ store(bits, buffer, x, width, indexed);
+}
+
+static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+{
+ FbBits *bits, *alpha_bits;
+ FbStride stride, astride;
+ int bpp, abpp;
+ int xoff, yoff;
+ int ax, ay;
+ storeProc store;
+ storeProc astore;
+ miIndexedPtr indexed = (miIndexedPtr) pict->pFormat->index.devPrivate;
+ miIndexedPtr aindexed;
+
+ if (!pict->alphaMap) {
+ fbStore(pict, x, y, width, buffer);
+ return;
+ }
+
+ store = storeProcForPicture(pict);
+ astore = storeProcForPicture(pict->alphaMap);
+ aindexed = (miIndexedPtr) pict->alphaMap->pFormat->index.devPrivate;
+
+ ax = x;
+ ay = y;
+
+ fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+ x += xoff;
+ y += yoff;
+ fbGetDrawable (pict->alphaMap->pDrawable, alpha_bits, astride, abpp, xoff, yoff);
+ ax += xoff;
+ ay += yoff;
+
+ bits += y*stride;
+ alpha_bits += (ay - pict->alphaOrigin.y)*astride;
+
+
+ store(bits, buffer, x, width, indexed);
+ astore(alpha_bits, buffer, ax - pict->alphaOrigin.x, width, aindexed);
+}
+
+typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
+typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *);
+
+static void
+fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
+{
+ CARD32 *src_buffer = scanline_buffer;
+ CARD32 *dest_buffer = src_buffer + data->width;
+ int i;
+ scanStoreProc store;
+ scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
+
+ if (data->op == PictOpClear)
+ fetchSrc = NULL;
+ else if (!data->src->pDrawable) {
+ if (data->src->pSourcePict)
+ fetchSrc = fbFetchSourcePict;
+ } else if (data->src->alphaMap)
+ fetchSrc = fbFetchExternalAlpha;
+ else if (data->src->repeatType == RepeatNormal &&
+ data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
+ fetchSrc = fbFetchSolid;
+ else if (!data->src->transform && data->src->filter != PictFilterConvolution)
+ fetchSrc = fbFetch;
+ else
+ fetchSrc = fbFetchTransformed;
+
+ if (data->mask && data->op != PictOpClear) {
+ if (!data->mask->pDrawable) {
+ if (data->mask->pSourcePict)
+ fetchMask = fbFetchSourcePict;
+ } else if (data->mask->alphaMap)
+ fetchMask = fbFetchExternalAlpha;
+ else if (data->mask->repeatType == RepeatNormal
+ && data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
+ fetchMask = fbFetchSolid;
+ else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
+ fetchMask = fbFetch;
+ else
+ fetchMask = fbFetchTransformed;
+ } else {
+ fetchMask = NULL;
+ }
+
+ if (data->dest->alphaMap) {
+ fetchDest = fbFetchExternalAlpha;
+ store = fbStoreExternalAlpha;
+ } else {
+ fetchDest = fbFetch;
+ store = fbStore;
+ }
+ if (data->op == PictOpClear || data->op == PictOpSrc)
+ fetchDest = NULL;
+
+ if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) {
+ CARD32 *mask_buffer = dest_buffer + data->width;
+ CombineFuncC compose = composeFunctions.combineC[data->op];
+ if (!compose)
+ return;
+
+ for (i = 0; i < data->height; ++i)
+ {
+ /* fill first half of scanline with source */
+ fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
+ fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer);
+
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+
+ /* blend */
+ compose(dest_buffer, src_buffer, mask_buffer, data->width);
+
+ /* write back */
+ store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+ }
+ } else {
+
+ CombineFuncU compose = composeFunctions.combineU[data->op];
+ if (!compose)
+ return;
+
+ if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
+ fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
+ if (fetchMask) {
+ fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer);
+ composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
+ }
+ fetchSrc = NULL;
+ fetchMask = NULL;
+ }
+
+ for (i = 0; i < data->height; ++i)
+ {
+ /* fill first half of scanline with source */
+ if (fetchSrc) {
+ fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
+
+ /* add in mask */
+ if (fetchMask) {
+ fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
+ composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
+ }
+ }
+
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+
+ /* blend */
+ compose(dest_buffer, src_buffer, data->width);
+
+ /* write back */
+ store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
+ }
+ }
+}
+
+void
+fbCompositeGeneral (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ int n;
+ BoxPtr pbox;
+ Bool srcRepeat = FALSE;
+ Bool maskRepeat = FALSE;
+ int w, h;
+ CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3];
+ CARD32 *scanline_buffer = _scanline_buffer;
+ FbComposeData compose_data;
+
+ if (pSrc->pDrawable)
+ srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
+ && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
+
+ if (pMask && pMask->pDrawable)
+ maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
+ && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
+
+ if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
+ op = PictOpSrc;
+
+ if (!miComputeCompositeRegion (&region,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height))
+ return;
+
+ compose_data.op = op;
+ compose_data.src = pSrc;
+ compose_data.mask = pMask;
+ compose_data.dest = pDst;
+ if (width > SCANLINE_BUFFER_LENGTH)
+ scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
+
+ n = RegionNumRects (&region);
+ pbox = RegionRects (&region);
+ while (n--)
+ {
+ h = pbox->y2 - pbox->y1;
+ compose_data.ySrc = pbox->y1 - yDst + ySrc;
+ compose_data.yMask = pbox->y1 - yDst + yMask;
+ compose_data.yDest = pbox->y1;
+ while (h)
+ {
+ compose_data.height = h;
+ w = pbox->x2 - pbox->x1;
+ compose_data.xSrc = pbox->x1 - xDst + xSrc;
+ compose_data.xMask = pbox->x1 - xDst + xMask;
+ compose_data.xDest = pbox->x1;
+ if (maskRepeat)
+ {
+ compose_data.yMask = mod (compose_data.yMask, pMask->pDrawable->height);
+ if (compose_data.height > pMask->pDrawable->height - compose_data.yMask)
+ compose_data.height = pMask->pDrawable->height - compose_data.yMask;
+ }
+ if (srcRepeat)
+ {
+ compose_data.ySrc = mod (compose_data.ySrc, pSrc->pDrawable->height);
+ if (compose_data.height > pSrc->pDrawable->height - compose_data.ySrc)
+ compose_data.height = pSrc->pDrawable->height - compose_data.ySrc;
+ }
+ while (w)
+ {
+ compose_data.width = w;
+ if (maskRepeat)
+ {
+ compose_data.xMask = mod (compose_data.xMask, pMask->pDrawable->width);
+ if (compose_data.width > pMask->pDrawable->width - compose_data.xMask)
+ compose_data.width = pMask->pDrawable->width - compose_data.xMask;
+ }
+ if (srcRepeat)
+ {
+ compose_data.xSrc = mod (compose_data.xSrc, pSrc->pDrawable->width);
+ if (compose_data.width > pSrc->pDrawable->width - compose_data.xSrc)
+ compose_data.width = pSrc->pDrawable->width - compose_data.xSrc;
+ }
+ fbCompositeRect(&compose_data, scanline_buffer);
+ w -= compose_data.width;
+ compose_data.xSrc += compose_data.width;
+ compose_data.xMask += compose_data.width;
+ compose_data.xDest += compose_data.width;
+ }
+ h -= compose_data.height;
+ compose_data.ySrc += compose_data.height;
+ compose_data.yMask += compose_data.height;
+ compose_data.yDest += compose_data.height;
+ }
+ pbox++;
+ }
+ RegionUninit(&region);
+
+ if (scanline_buffer != _scanline_buffer)
+ free(scanline_buffer);
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbcopy.c b/nx-X11/programs/Xserver/fb/fbcopy.c
new file mode 100644
index 000000000..7a1dbb5aa
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbcopy.c
@@ -0,0 +1,636 @@
+/*
+ * Id: fbcopy.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+void
+fbCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ CARD8 alu = pGC ? pGC->alu : GXcopy;
+ FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ while (nbox--)
+ {
+ fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff) * srcBpp,
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ alu,
+ pm,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ pbox++;
+ }
+}
+
+void
+fbCopy1toN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ while (nbox--)
+ {
+ if (dstBpp == 1)
+ {
+ fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff) * srcBpp,
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ FbOpaqueStipple1Rop(pGC->alu,
+ pGC->fgPixel,pGC->bgPixel),
+ pPriv->pm,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ }
+ else
+ {
+ fbBltOne ((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
+ srcStride*(FB_UNIT/FB_STIP_UNIT),
+ (pbox->x1 + dx + srcXoff),
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+ dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ pPriv->and, pPriv->xor,
+ pPriv->bgand, pPriv->bgxor);
+ }
+ pbox++;
+ }
+}
+
+void
+fbCopyNto1 (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+
+ while (nbox--)
+ {
+ if (pDstDrawable->bitsPerPixel == 1)
+ {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetStipDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff) * srcBpp,
+ srcBpp,
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * srcBpp,
+ (pbox->y2 - pbox->y1),
+
+ (FbStip) pPriv->and, (FbStip) pPriv->xor,
+ (FbStip) pPriv->bgand, (FbStip) pPriv->bgxor,
+ bitplane);
+ }
+ else
+ {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ FbStip *tmp;
+ FbStride tmpStride;
+ int width, height;
+
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
+ tmp = malloc (tmpStride * height * sizeof (FbStip));
+ if (!tmp)
+ return;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ fbBltPlane (src + (pbox->y1+ dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff) * srcBpp,
+ srcBpp,
+
+ tmp,
+ tmpStride,
+ 0,
+
+ width * srcBpp,
+ height,
+
+ fbAndStip(GXcopy,FB_ALLONES,FB_ALLONES),
+ fbXorStip(GXcopy,FB_ALLONES,FB_ALLONES),
+ fbAndStip(GXcopy,0,FB_ALLONES),
+ fbXorStip(GXcopy,0,FB_ALLONES),
+ bitplane);
+ fbBltOne (tmp,
+ tmpStride,
+ 0,
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+ dstBpp,
+
+ width * dstBpp,
+ height,
+
+ pPriv->and, pPriv->xor,
+ pPriv->bgand, pPriv->bgxor);
+ free (tmp);
+ }
+ pbox++;
+ }
+}
+
+void
+fbCopyRegion (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ int careful;
+ Bool reverse;
+ Bool upsidedown;
+ BoxPtr pbox;
+ int nbox;
+ BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
+
+ pbox = RegionRects(pDstRegion);
+ nbox = RegionNumRects(pDstRegion);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrcDrawable == pDstDrawable) ||
+ ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
+ (pDstDrawable->type == DRAWABLE_WINDOW)));
+
+ pboxNew1 = NULL;
+ pboxNew2 = NULL;
+ if (careful && dy < 0)
+ {
+ upsidedown = TRUE;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ upsidedown = FALSE;
+ }
+
+ if (careful && dx < 0)
+ {
+ /* walk source right to left */
+ if (dy <= 0)
+ reverse = TRUE;
+ else
+ reverse = FALSE;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew2)
+ {
+ if (pboxNew1)
+ free(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ reverse = FALSE;
+ }
+
+ (*copyProc) (pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ pbox,
+ nbox,
+ dx, dy,
+ reverse, upsidedown, bitPlane, closure);
+
+ if (pboxNew1)
+ free (pboxNew1);
+ if (pboxNew2)
+ free (pboxNew2);
+}
+
+RegionPtr
+fbDoCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ fbCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+ RegionPtr prgnExposed = NULL;
+ RegionRec rgnDst;
+ int dx;
+ int dy;
+ int numRects;
+ int box_x1;
+ int box_y1;
+ int box_x2;
+ int box_y2;
+ Bool fastSrc = FALSE; /* for fast clipping with pixmap source */
+ Bool fastDst = FALSE; /* for fast clipping with one rect dest */
+ Bool fastExpose = FALSE; /* for fast exposures with pixmap source */
+
+ /* Short cut for unmapped windows */
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr)pDstDrawable)->realized)
+ {
+ return NULL;
+ }
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, xIn, yIn, widthSrc, heightSrc);
+ }
+
+ /* Compute source clip region */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = fbGetCompositeClip(pGC);
+ else
+ fastSrc = TRUE;
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ /*
+ * XFree86 DDX empties the border clip when the
+ * VT is inactive, make sure the region isn't empty
+ */
+ if (!((WindowPtr) pSrcDrawable)->parent &&
+ RegionNotEmpty(
+ &((WindowPtr) pSrcDrawable)->borderClip))
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastSrc = TRUE;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = fbGetCompositeClip(pGC);
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ xIn += pSrcDrawable->x;
+ yIn += pSrcDrawable->y;
+
+ xOut += pDstDrawable->x;
+ yOut += pDstDrawable->y;
+
+ box_x1 = xIn;
+ box_y1 = yIn;
+ box_x2 = xIn + widthSrc;
+ box_y2 = yIn + heightSrc;
+
+ dx = xIn - xOut;
+ dy = yIn - yOut;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastSrc)
+ {
+ RegionPtr cclip;
+
+ fastExpose = TRUE;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (box_x1 < pSrcDrawable->x)
+ {
+ box_x1 = pSrcDrawable->x;
+ fastExpose = FALSE;
+ }
+ if (box_y1 < pSrcDrawable->y)
+ {
+ box_y1 = pSrcDrawable->y;
+ fastExpose = FALSE;
+ }
+ if (box_x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ box_x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = FALSE;
+ }
+ if (box_y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ box_y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = FALSE;
+ }
+
+ /* Translate and clip the dst to the destination composite clip */
+ box_x1 -= dx;
+ box_x2 -= dx;
+ box_y1 -= dy;
+ box_y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = fbGetCompositeClip(pGC);
+ if (RegionNumRects(cclip) == 1)
+ {
+ BoxPtr pBox = RegionRects(cclip);
+
+ if (box_x1 < pBox->x1) box_x1 = pBox->x1;
+ if (box_x2 > pBox->x2) box_x2 = pBox->x2;
+ if (box_y1 < pBox->y1) box_y1 = pBox->y1;
+ if (box_y2 > pBox->y2) box_y2 = pBox->y2;
+ fastDst = TRUE;
+ }
+ }
+
+ /* Check to see if the region is empty */
+ if (box_x1 >= box_x2 || box_y1 >= box_y2)
+ {
+ RegionNull(&rgnDst);
+ }
+ else
+ {
+ BoxRec box;
+ box.x1 = box_x1;
+ box.y1 = box_y1;
+ box.x2 = box_x2;
+ box.y2 = box_y2;
+ RegionInit(&rgnDst, &box, 1);
+ }
+
+ /* Clip against complex source if needed */
+ if (!fastSrc)
+ {
+ RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip);
+ RegionTranslate(&rgnDst, -dx, -dy);
+ }
+
+ /* Clip against complex dest if needed */
+ if (!fastDst)
+ {
+ RegionIntersect(&rgnDst, &rgnDst,
+ fbGetCompositeClip(pGC));
+ }
+
+ /* Do bit blitting */
+ numRects = RegionNumRects(&rgnDst);
+ if (numRects && widthSrc && heightSrc)
+ fbCopyRegion (pSrcDrawable, pDstDrawable, pGC,
+ &rgnDst, dx, dy, copyProc, bitPlane, closure);
+
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose && pGC->fExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ xIn - pSrcDrawable->x,
+ yIn - pSrcDrawable->y,
+ widthSrc, heightSrc,
+ xOut - pDstDrawable->x,
+ yOut - pDstDrawable->y,
+ (unsigned long) bitPlane);
+ RegionUninit(&rgnDst);
+ if (freeSrcClip)
+ RegionDestroy(prgnSrcClip);
+ fbValidateDrawable (pDstDrawable);
+ return prgnExposed;
+}
+
+RegionPtr
+fbCopyArea (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut)
+{
+ fbCopyProc copy;
+
+#ifdef FB_24_32BIT
+ if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
+ copy = fb24_32CopyMtoN;
+ else
+#endif
+ copy = fbCopyNtoN;
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
+}
+
+RegionPtr
+fbCopyPlane (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ unsigned long bitplane)
+{
+ if (pSrcDrawable->bitsPerPixel > 1)
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ xIn, yIn, widthSrc, heightSrc,
+ xOut, yOut, fbCopyNto1, (Pixel) bitplane, 0);
+ else if (bitplane & 1)
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, fbCopy1toN,
+ (Pixel) bitplane, 0);
+ else
+ return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ xIn, yIn,
+ widthSrc,
+ heightSrc,
+ xOut, yOut, bitplane);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbedge.c b/nx-X11/programs/Xserver/fb/fbedge.c
new file mode 100644
index 000000000..66dcdc35f
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbedge.c
@@ -0,0 +1,314 @@
+/*
+ * $Id: fbedge.c,v 1.5 2005/10/03 10:20:29 anholt Exp $
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include <string.h>
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#ifdef RENDER
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "renderedge.h"
+#include "fbpict.h"
+
+/*
+ * 4 bit alpha
+ */
+
+#define N_BITS 4
+#define rasterizeEdges fbRasterizeEdges4
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define Shift4(o) ((o) << 2)
+#else
+#define Shift4(o) ((1-(o)) << 2)
+#endif
+
+#define Get4(x,o) (((x) >> Shift4(o)) & 0xf)
+#define Put4(x,o,v) (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o)))
+
+#define DefineAlpha(line,x) \
+ CARD8 *__ap = (CARD8 *) line + ((x) >> 1); \
+ int __ao = (x) & 1
+
+#define StepAlpha ((__ap += __ao), (__ao ^= 1))
+
+#define AddAlpha(a) { \
+ CARD8 __o = *__ap; \
+ CARD8 __a = (a) + Get4(__o, __ao); \
+ *__ap = Put4 (__o, __ao, __a | (0 - ((__a) >> 4))); \
+}
+
+#include "fbedgeimp.h"
+
+#undef AddAlpha
+#undef StepAlpha
+#undef DefineAlpha
+#undef rasterizeEdges
+#undef N_BITS
+
+
+/*
+ * 1 bit alpha
+ */
+
+#define N_BITS 1
+#define rasterizeEdges fbRasterizeEdges1
+
+#include "fbedgeimp.h"
+
+#undef rasterizeEdges
+#undef N_BITS
+
+/*
+ * 8 bit alpha
+ */
+
+static INLINE CARD8
+clip255 (int x)
+{
+ if (x > 255) return 255;
+ return x;
+}
+
+static INLINE void
+add_saturate_8 (CARD8 *buf, int value, int length)
+{
+ while (length--)
+ {
+ *buf = clip255 (*buf + value);
+ buf++;
+ }
+}
+
+/*
+ * We want to detect the case where we add the same value to a long
+ * span of pixels. The triangles on the end are filled in while we
+ * count how many sub-pixel scanlines contribute to the middle section.
+ *
+ * +--------------------------+
+ * fill_height =| \ /
+ * +------------------+
+ * |================|
+ * fill_start fill_end
+ */
+static void
+fbRasterizeEdges8 (FbBits *buf,
+ int width,
+ int stride,
+ RenderEdge *l,
+ RenderEdge *r,
+ xFixed t,
+ xFixed b)
+{
+ xFixed y = t;
+ FbBits *line;
+ int fill_start = -1, fill_end = -1;
+ int fill_size = 0;
+
+ line = buf + xFixedToInt (y) * stride;
+
+ for (;;)
+ {
+ CARD8 *ap = (CARD8 *) line;
+ xFixed lx, rx;
+ int lxi, rxi;
+
+ /* clip X */
+ lx = l->x;
+ if (lx < 0)
+ lx = 0;
+ rx = r->x;
+ if (xFixedToInt (rx) >= width)
+ rx = IntToxFixed (width);
+
+ /* Skip empty (or backwards) sections */
+ if (rx > lx)
+ {
+ int lxs, rxs;
+
+ /* Find pixel bounds for span. */
+ lxi = xFixedToInt (lx);
+ rxi = xFixedToInt (rx);
+
+ /* Sample coverage for edge pixels */
+ lxs = RenderSamplesX (lx, 8);
+ rxs = RenderSamplesX (rx, 8);
+
+ /* Add coverage across row */
+ if (lxi == rxi)
+ {
+ ap[lxi] = clip255 (ap[lxi] + rxs - lxs);
+ }
+ else
+ {
+ ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs);
+
+ /* Move forward so that lxi/rxi is the pixel span */
+ lxi++;
+
+ /* Don't bother trying to optimize the fill unless
+ * the span is longer than 4 pixels. */
+ if (rxi - lxi > 4)
+ {
+ if (fill_start < 0)
+ {
+ fill_start = lxi;
+ fill_end = rxi;
+ fill_size++;
+ }
+ else
+ {
+ if (lxi >= fill_end || rxi < fill_start)
+ {
+ /* We're beyond what we saved, just fill it */
+ add_saturate_8 (ap + fill_start,
+ fill_size * N_X_FRAC(8),
+ fill_end - fill_start);
+ fill_start = lxi;
+ fill_end = rxi;
+ fill_size = 1;
+ }
+ else
+ {
+ /* Update fill_start */
+ if (lxi > fill_start)
+ {
+ add_saturate_8 (ap + fill_start,
+ fill_size * N_X_FRAC(8),
+ lxi - fill_start);
+ fill_start = lxi;
+ }
+ else if (lxi < fill_start)
+ {
+ add_saturate_8 (ap + lxi, N_X_FRAC(8),
+ fill_start - lxi);
+ }
+
+ /* Update fill_end */
+ if (rxi < fill_end)
+ {
+ add_saturate_8 (ap + rxi,
+ fill_size * N_X_FRAC(8),
+ fill_end - rxi);
+ fill_end = rxi;
+ }
+ else if (fill_end < rxi)
+ {
+ add_saturate_8 (ap + fill_end,
+ N_X_FRAC(8),
+ rxi - fill_end);
+ }
+ fill_size++;
+ }
+ }
+ }
+ else
+ {
+ add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
+ }
+
+ /* Do not add in a 0 alpha here. This check is
+ * necessary to avoid a buffer overrun, (when rx
+ * is exactly on a pixel boundary). */
+ if (rxs)
+ ap[rxi] = clip255 (ap[rxi] + rxs);
+ }
+ }
+
+ if (y == b) {
+ /* We're done, make sure we clean up any remaining fill. */
+ if (fill_start != fill_end) {
+ if (fill_size == N_Y_FRAC(8))
+ {
+ memset (ap + fill_start, 0xff, fill_end - fill_start);
+ }
+ else
+ {
+ add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
+ fill_end - fill_start);
+ }
+ }
+ break;
+ }
+
+ if (xFixedFrac (y) != Y_FRAC_LAST(8))
+ {
+ RenderEdgeStepSmall (l);
+ RenderEdgeStepSmall (r);
+ y += STEP_Y_SMALL(8);
+ }
+ else
+ {
+ RenderEdgeStepBig (l);
+ RenderEdgeStepBig (r);
+ y += STEP_Y_BIG(8);
+ if (fill_start != fill_end)
+ {
+ if (fill_size == N_Y_FRAC(8))
+ {
+ memset (ap + fill_start, 0xff, fill_end - fill_start);
+ }
+ else
+ {
+ add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
+ fill_end - fill_start);
+ }
+ fill_start = fill_end = -1;
+ fill_size = 0;
+ }
+ line += stride;
+ }
+ }
+}
+
+void
+fbRasterizeEdges (FbBits *buf,
+ int bpp,
+ int width,
+ int stride,
+ RenderEdge *l,
+ RenderEdge *r,
+ xFixed t,
+ xFixed b)
+{
+ switch (bpp) {
+ case 1:
+ fbRasterizeEdges1 (buf, width, stride, l, r, t, b);
+ break;
+ case 4:
+ fbRasterizeEdges4 (buf, width, stride, l, r, t, b);
+ break;
+ case 8:
+ fbRasterizeEdges8 (buf, width, stride, l, r, t, b);
+ break;
+ }
+}
+
+#endif /* RENDER */
diff --git a/nx-X11/programs/Xserver/fb/fbedgeimp.h b/nx-X11/programs/Xserver/fb/fbedgeimp.h
new file mode 100644
index 000000000..6b363d7ce
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbedgeimp.h
@@ -0,0 +1,143 @@
+/*
+ * $Id: fbedgeimp.h,v 1.4 2005/08/30 03:05:21 anholt Exp $
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef rasterizeSpan
+#endif
+
+static void
+rasterizeEdges (FbBits *buf,
+ int width,
+ int stride,
+ RenderEdge *l,
+ RenderEdge *r,
+ xFixed t,
+ xFixed b)
+{
+ xFixed y = t;
+ FbBits *line;
+
+ line = buf + xFixedToInt (y) * stride;
+
+ for (;;)
+ {
+ xFixed lx, rx;
+ int lxi, rxi;
+
+ /* clip X */
+ lx = l->x;
+ if (lx < 0)
+ lx = 0;
+ rx = r->x;
+ if (xFixedToInt (rx) >= width)
+ rx = IntToxFixed (width);
+
+ /* Skip empty (or backwards) sections */
+ if (rx > lx)
+ {
+
+ /* Find pixel bounds for span */
+ lxi = xFixedToInt (lx);
+ rxi = xFixedToInt (rx);
+
+#if N_BITS == 1
+ {
+ FbBits *a = line;
+ FbBits startmask, endmask;
+ int nmiddle;
+ int width = rxi - lxi;
+ int x = lxi;
+
+ a += x >> FB_SHIFT;
+ x &= FB_MASK;
+
+ FbMaskBits (x, width, startmask, nmiddle, endmask);
+ if (startmask)
+ *a++ |= startmask;
+ while (nmiddle--)
+ *a++ = FB_ALLONES;
+ if (endmask)
+ *a |= endmask;
+ }
+#else
+ {
+ DefineAlpha(line,lxi);
+ int lxs, rxs;
+
+ /* Sample coverage for edge pixels */
+ lxs = RenderSamplesX (lx, N_BITS);
+ rxs = RenderSamplesX (rx, N_BITS);
+
+ /* Add coverage across row */
+ if (lxi == rxi)
+ {
+ AddAlpha (rxs - lxs);
+ }
+ else
+ {
+ int xi;
+
+ AddAlpha (N_X_FRAC(N_BITS) - lxs);
+ StepAlpha;
+ for (xi = lxi + 1; xi < rxi; xi++)
+ {
+ AddAlpha (N_X_FRAC(N_BITS));
+ StepAlpha;
+ }
+ /* Do not add in a 0 alpha here. This check is necessary
+ * to avoid a buffer overrun when rx is exactly on a pixel
+ * boundary.
+ */
+ if (rxs != 0)
+ AddAlpha (rxs);
+ }
+ }
+#endif
+ }
+
+ if (y == b)
+ break;
+
+#if N_BITS > 1
+ if (xFixedFrac (y) != Y_FRAC_LAST(N_BITS))
+ {
+ RenderEdgeStepSmall (l);
+ RenderEdgeStepSmall (r);
+ y += STEP_Y_SMALL(N_BITS);
+ }
+ else
+#endif
+ {
+ RenderEdgeStepBig (l);
+ RenderEdgeStepBig (r);
+ y += STEP_Y_BIG(N_BITS);
+ line += stride;
+ }
+ }
+}
+
+#undef rasterizeSpan
diff --git a/nx-X11/programs/Xserver/fb/fbfill.c b/nx-X11/programs/Xserver/fb/fbfill.c
new file mode 100644
index 000000000..2d1d163f6
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbfill.c
@@ -0,0 +1,215 @@
+/*
+ * Id: fbfill.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ fbSolid (dst + (y + dstYoff) * dstStride,
+ dstStride,
+ (x + dstXoff) * dstBpp,
+ dstBpp,
+ width * dstBpp, height,
+ pPriv->and, pPriv->xor);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled: {
+ PixmapPtr pStip = pGC->stipple;
+ int stipWidth = pStip->drawable.width;
+ int stipHeight = pStip->drawable.height;
+
+ if (dstBpp == 1)
+ {
+ int alu;
+ FbBits *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff; /* XXX assumed to be zero */
+
+ if (pGC->fillStyle == FillStippled)
+ alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
+ else
+ alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
+ fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
+ fbTile (dst + (y + dstYoff) * dstStride,
+ dstStride,
+ x + dstXoff,
+ width, height,
+ stip,
+ stipStride,
+ stipWidth,
+ stipHeight,
+ alu,
+ pPriv->pm,
+ dstBpp,
+
+ (pGC->patOrg.x + pDrawable->x + dstXoff),
+ pGC->patOrg.y + pDrawable->y - y);
+ }
+ else
+ {
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff; /* XXX assumed to be zero */
+ FbBits fgand, fgxor, bgand, bgxor;
+
+ fgand = pPriv->and;
+ fgxor = pPriv->xor;
+ if (pGC->fillStyle == FillStippled)
+ {
+ bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
+ bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
+ }
+ else
+ {
+ bgand = pPriv->bgand;
+ bgxor = pPriv->bgxor;
+ }
+
+ fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
+ fbStipple (dst + (y + dstYoff) * dstStride,
+ dstStride,
+ (x + dstXoff) * dstBpp,
+ dstBpp,
+ width * dstBpp, height,
+ stip,
+ stipStride,
+ stipWidth,
+ stipHeight,
+ pPriv->evenStipple,
+ fgand, fgxor,
+ bgand, bgxor,
+ pGC->patOrg.x + pDrawable->x + dstXoff,
+ pGC->patOrg.y + pDrawable->y - y);
+ }
+ break;
+ }
+ case FillTiled: {
+ PixmapPtr pTile = pGC->tile.pixmap;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+ int tileWidth;
+ int tileHeight;
+ _X_UNUSED int tileXoff, tileYoff; /* XXX assumed to be zero */
+
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ fbTile (dst + (y + dstYoff) * dstStride,
+ dstStride,
+ (x + dstXoff) * dstBpp,
+ width * dstBpp, height,
+ tile,
+ tileStride,
+ tileWidth * tileBpp,
+ tileHeight,
+ pGC->alu,
+ pPriv->pm,
+ dstBpp,
+ (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
+ pGC->patOrg.y + pDrawable->y - y);
+ break;
+ }
+ }
+ fbValidateDrawable (pDrawable);
+}
+
+void
+fbSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ FbBits and,
+ FbBits xor)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ BoxPtr pbox;
+ int nbox;
+ int partX1, partX2, partY1, partY2;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
+ nbox--;
+ pbox++)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < x1)
+ partX1 = x1;
+
+ partX2 = pbox->x2;
+ if (partX2 > x2)
+ partX2 = x2;
+
+ if (partX2 <= partX1)
+ continue;
+
+ partY1 = pbox->y1;
+ if (partY1 < y1)
+ partY1 = y1;
+
+ partY2 = pbox->y2;
+ if (partY2 > y2)
+ partY2 = y2;
+
+ if (partY2 <= partY1)
+ continue;
+
+ fbSolid (dst + (partY1 + dstYoff) * dstStride,
+ dstStride,
+ (partX1 + dstXoff) * dstBpp,
+ dstBpp,
+
+ (partX2 - partX1) * dstBpp,
+ (partY2 - partY1),
+ and, xor);
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbfillrect.c b/nx-X11/programs/Xserver/fb/fbfillrect.c
new file mode 100644
index 000000000..2a19fa7d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbfillrect.c
@@ -0,0 +1,114 @@
+/*
+ * Id: fbfillrect.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prect)
+{
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ register BoxPtr pbox;
+ BoxPtr pextent;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1, fullY2;
+ int partX1, partX2, partY1, partY2;
+ int xorg, yorg;
+ int n;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ pextent = RegionExtents(pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (nrect--)
+ {
+ fullX1 = prect->x + xorg;
+ fullY1 = prect->y + yorg;
+ fullX2 = fullX1 + (int) prect->width;
+ fullY2 = fullY1 + (int) prect->height;
+ prect++;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullY1 < extentY1)
+ fullY1 = extentY1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullY2 > extentY2)
+ fullY2 = extentY2;
+
+ if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
+ continue;
+ n = RegionNumRects (pClip);
+ if (n == 1)
+ {
+ fbFill (pDrawable,
+ pGC,
+ fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
+ }
+ else
+ {
+ pbox = RegionRects(pClip);
+ /*
+ * clip the rectangle to each box in the clip region
+ * this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partY1 = pbox->y1;
+ if (partY1 < fullY1)
+ partY1 = fullY1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ partY2 = pbox->y2;
+ if (partY2 > fullY2)
+ partY2 = fullY2;
+
+ pbox++;
+
+ if (partX1 < partX2 && partY1 < partY2)
+ fbFill (pDrawable, pGC,
+ partX1, partY1,
+ partX2 - partX1, partY2 - partY1);
+ }
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbfillsp.c b/nx-X11/programs/Xserver/fb/fbfillsp.c
new file mode 100644
index 000000000..ca9fdbb0a
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbfillsp.c
@@ -0,0 +1,102 @@
+/*
+ * Id: fbfillsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbFillSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ int partX1, partX2;
+
+ pextent = RegionExtents(pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (n--)
+ {
+ fullX1 = ppt->x;
+ fullY1 = ppt->y;
+ fullX2 = fullX1 + (int) *pwidth;
+ ppt++;
+ pwidth++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ nbox = RegionNumRects (pClip);
+ if (nbox == 1)
+ {
+ fbFill (pDrawable,
+ pGC,
+ fullX1, fullY1, fullX2-fullX1, 1);
+ }
+ else
+ {
+ pbox = RegionRects(pClip);
+ while(nbox--)
+ {
+ if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ if (partX2 > partX1)
+ {
+ fbFill (pDrawable, pGC,
+ partX1, fullY1,
+ partX2 - partX1, 1);
+ }
+ }
+ pbox++;
+ }
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbgc.c b/nx-X11/programs/Xserver/fb/fbgc.c
new file mode 100644
index 000000000..437bc5df3
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbgc.c
@@ -0,0 +1,314 @@
+/*
+ * Id: fbgc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+const GCFuncs fbGCFuncs = {
+ fbValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+const GCOps fbGCOps = {
+ fbFillSpans,
+ fbSetSpans,
+ fbPutImage,
+ fbCopyArea,
+ fbCopyPlane,
+ fbPolyPoint,
+ fbPolyLine,
+ fbPolySegment,
+ fbPolyRectangle,
+ fbPolyArc,
+ miFillPolygon,
+ fbPolyFillRect,
+ fbPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ fbImageGlyphBlt,
+ fbPolyGlyphBlt,
+ fbPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+Bool
+fbCreateGC(GCPtr pGC)
+{
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ pGC->ops = (GCOps *) &fbGCOps;
+ pGC->funcs = (GCFuncs *) &fbGCFuncs;
+
+ /* fb wants to translate before scan conversion */
+ pGC->miTranslate = 1;
+
+ fbGetRotatedPixmap(pGC) = 0;
+ fbGetExpose(pGC) = 1;
+ fbGetFreeCompClip(pGC) = 0;
+ fbGetCompositeClip(pGC) = 0;
+ fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
+ return TRUE;
+}
+
+/*
+ * Pad pixmap to FB_UNIT bits wide
+ */
+void
+fbPadPixmap (PixmapPtr pPixmap)
+{
+ int width;
+ FbBits *bits;
+ FbBits b;
+ FbBits mask;
+ int height;
+ int w;
+
+ width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
+ bits = pPixmap->devPrivate.ptr;
+ height = pPixmap->drawable.height;
+ mask = FbBitsMask (0, width);
+ while (height--)
+ {
+ b = *bits & mask;
+ w = width;
+ while (w < FB_UNIT)
+ {
+ b = b | FbScrRight(b, w);
+ w <<= 1;
+ }
+ *bits++ = b;
+ }
+}
+
+/*
+ * Verify that 'bits' repeats every 'len' bits
+ */
+static Bool
+fbBitsRepeat (FbBits bits, int len, int width)
+{
+ FbBits mask = FbBitsMask(0, len);
+ FbBits orig = bits & mask;
+ int i;
+
+ if (width > FB_UNIT)
+ width = FB_UNIT;
+ for (i = 0; i < width / len; i++)
+ {
+ if ((bits & mask) != orig)
+ return FALSE;
+ bits = FbScrLeft(bits,len);
+ }
+ return TRUE;
+}
+
+/*
+ * Check whether an entire bitmap line is a repetition of
+ * the first 'len' bits
+ */
+static Bool
+fbLineRepeat (FbBits *bits, int len, int width)
+{
+ FbBits first = bits[0];
+
+ if (!fbBitsRepeat (first, len, width))
+ return FALSE;
+ width = (width + FB_UNIT-1) >> FB_SHIFT;
+ bits++;
+ while (--width)
+ if (*bits != first)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * The even stipple code wants the first FB_UNIT/bpp bits on
+ * each scanline to represent the entire stipple
+ */
+static Bool
+fbCanEvenStipple (PixmapPtr pStipple, int bpp)
+{
+ int len = FB_UNIT / bpp;
+ FbBits *bits;
+ int stride;
+ int stip_bpp;
+ _X_UNUSED int stipXoff, stipYoff;
+ int h;
+
+ /* can't even stipple 24bpp drawables */
+ if ((bpp & (bpp-1)) != 0)
+ return FALSE;
+ /* make sure the stipple width is a multiple of the even stipple width */
+ if (pStipple->drawable.width % len != 0)
+ return FALSE;
+ fbGetDrawable (&pStipple->drawable, bits, stride, stip_bpp, stipXoff, stipYoff);
+ h = pStipple->drawable.height;
+ /* check to see that the stipple repeats horizontally */
+ while (h--)
+ {
+ if (!fbLineRepeat (bits, len, pStipple->drawable.width))
+ return FALSE;
+ bits += stride;
+ }
+ return TRUE;
+}
+
+void
+fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ FbBits mask;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+ pPriv->oneRect = RegionNumRects(fbGetCompositeClip(pGC)) == 1;
+ }
+
+#ifdef FB_24_32BIT
+ if (pPriv->bpp != pDrawable->bitsPerPixel)
+ {
+ changes |= GCStipple|GCForeground|GCBackground|GCPlaneMask;
+ pPriv->bpp = pDrawable->bitsPerPixel;
+ }
+ if ((changes & GCTile) && fbGetRotatedPixmap(pGC))
+ {
+ (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
+ fbGetRotatedPixmap(pGC) = 0;
+ }
+
+ if (pGC->fillStyle == FillTiled)
+ {
+ PixmapPtr pOldTile, pNewTile;
+
+ pOldTile = pGC->tile.pixmap;
+ if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
+ {
+ pNewTile = fbGetRotatedPixmap(pGC);
+ if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
+ {
+ if (pNewTile)
+ (*pGC->pScreen->DestroyPixmap) (pNewTile);
+ pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel);
+ }
+ if (pNewTile)
+ {
+ fbGetRotatedPixmap(pGC) = pOldTile;
+ pGC->tile.pixmap = pNewTile;
+ changes |= GCTile;
+ }
+ }
+ }
+#endif
+ if (changes & GCTile)
+ {
+ if (!pGC->tileIsPixel &&
+ FbEvenTile (pGC->tile.pixmap->drawable.width *
+ pDrawable->bitsPerPixel))
+ fbPadPixmap (pGC->tile.pixmap);
+ }
+ if (changes & GCStipple)
+ {
+ pPriv->evenStipple = FALSE;
+
+ if (pGC->stipple) {
+
+ /* can we do an even stipple ?? */
+ if (FbEvenStip (pGC->stipple->drawable.width,
+ pDrawable->bitsPerPixel) &&
+ (fbCanEvenStipple (pGC->stipple, pDrawable->bitsPerPixel)))
+ pPriv->evenStipple = TRUE;
+
+ if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel < FB_UNIT)
+ fbPadPixmap (pGC->stipple);
+ }
+ }
+ /*
+ * Recompute reduced rop values
+ */
+ if (changes & (GCForeground|GCBackground|GCPlaneMask|GCFunction))
+ {
+ int s;
+ FbBits depthMask;
+
+ mask = FbFullMask(pDrawable->bitsPerPixel);
+ depthMask = FbFullMask(pDrawable->depth);
+
+ pPriv->fg = pGC->fgPixel & mask;
+ pPriv->bg = pGC->bgPixel & mask;
+
+ if ((pGC->planemask & depthMask) == depthMask)
+ pPriv->pm = mask;
+ else
+ pPriv->pm = pGC->planemask & mask;
+
+ s = pDrawable->bitsPerPixel;
+ while (s < FB_UNIT)
+ {
+ pPriv->fg |= pPriv->fg << s;
+ pPriv->bg |= pPriv->bg << s;
+ pPriv->pm |= pPriv->pm << s;
+ s <<= 1;
+ }
+ pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
+ pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
+ pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
+ pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
+ }
+ if (changes & GCDashList)
+ {
+ unsigned short n = pGC->numInDashList;
+ unsigned char *dash = pGC->dash;
+ unsigned int dashLength = 0;
+
+ while (n--)
+ dashLength += (unsigned int ) *dash++;
+ pPriv->dashLength = dashLength;
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbgetsp.c b/nx-X11/programs/Xserver/fb/fbgetsp.c
new file mode 100644
index 000000000..f77ea8c52
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbgetsp.c
@@ -0,0 +1,87 @@
+/*
+ * Id: fbgetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart)
+{
+ FbBits *src, *dst;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ int xoff;
+
+ /*
+ * XFree86 DDX empties the root borderClip when the VT is
+ * switched away; this checks for that case
+ */
+ if (!fbDrawableEnabled(pDrawable))
+ return;
+
+#ifdef FB_24_32BIT
+ if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
+ {
+ fb24_32GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pchardstStart);
+ return;
+ }
+#endif
+
+ fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+
+ while (nspans--)
+ {
+ xoff = (int) (((long) pchardstStart) & (FB_MASK >> 3));
+ dst = (FbBits *) (pchardstStart - xoff);
+ xoff <<= 3;
+ fbBlt (src + (ppt->y + srcYoff) * srcStride, srcStride,
+ (ppt->x + srcXoff) * srcBpp,
+
+ dst,
+ 1,
+ xoff,
+
+ *pwidth * srcBpp,
+ 1,
+
+ GXcopy,
+ FB_ALLONES,
+ srcBpp,
+
+ FALSE,
+ FALSE);
+ pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbglyph.c b/nx-X11/programs/Xserver/fb/fbglyph.c
new file mode 100644
index 000000000..6ff90e54a
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbglyph.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+
+#define dummyScreen screenInfo.screens[0]
+
+Bool
+fbGlyphIn (RegionPtr pRegion,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ BoxRec box;
+ BoxPtr pExtents = RegionExtents(pRegion);
+
+ /*
+ * Check extents by hand to avoid 16 bit overflows
+ */
+ if (x < (int) pExtents->x1)
+ return FALSE;
+ if ((int) pExtents->x2 < x + width)
+ return FALSE;
+ if (y < (int) pExtents->y1)
+ return FALSE;
+ if ((int) pExtents->y2 < y + height)
+ return FALSE;
+ box.x1 = x;
+ box.x2 = x + width;
+ box.y1 = y;
+ box.y2 = y + height;
+ return RegionContainsRect(pRegion, &box) == rgnIN;
+}
+
+#ifdef FB_24BIT
+#ifndef FBNOPIXADDR
+
+#define WRITE1(d,n,fg) ((d)[n] = (CARD8) fg)
+#define WRITE2(d,n,fg) (*(CARD16 *) &(d[n]) = (CARD16) fg)
+#define WRITE4(d,n,fg) (*(CARD32 *) &(d[n]) = (CARD32) fg)
+#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst
+#define WRITE8(d) (*(FbBits *) &(d[0]) = fg)
+#else
+#define WRITE8(d) WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB)
+#endif
+
+/*
+ * This is a bit tricky, but it's brief. Write 12 bytes worth
+ * of dest, which is four pixels, at a time. This gives constant
+ * code for each pattern as they're always aligned the same
+ *
+ * a b c d a b c d a b c d bytes
+ * A B C A B C A B C A B C pixels
+ *
+ * f0 f1 f2
+ * A B C A B C A B C A B C pixels LSB
+ * C A B C A B C A B C A B pixels MSB
+ *
+ * LSB MSB
+ * A f0 f1
+ * B f1 f2
+ * C f2 f0
+ * A B f0 f2
+ * B C f1 f0
+ * C A f2 f1
+ * A B C A f0 f1
+ * B C A B f1 f2
+ * C A B C f2 f0
+ */
+
+#undef _A
+#undef _B
+#undef _C
+#undef _AB
+#undef _BC
+#undef _CA
+#undef _ABCA
+#undef _BCAB
+#undef _CABC
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define _A f1
+#define _B f2
+#define _C f0
+#define _AB f2
+#define _BC f0
+#define _CA f1
+#define _ABCA f1
+#define _BCAB f2
+#define _CABC f0
+#define CASE(a,b,c,d) ((a << 3) | (b << 2) | (c << 1) | d)
+#else
+#define _A f0
+#define _B f1
+#define _C f2
+#define _AB f0
+#define _BC f1
+#define _CA f2
+#define _ABCA f0
+#define _BCAB f1
+#define _CABC f2
+#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3))
+#endif
+
+void
+fbGlyph24 (FbBits *dstBits,
+ FbStride dstStride,
+ int dstBpp,
+ FbStip *stipple,
+ FbBits fg,
+ int x,
+ int height)
+{
+ int lshift;
+ FbStip bits;
+ CARD8 *dstLine;
+ CARD8 *dst;
+ FbStip f0, f1, f2;
+ int n;
+ int shift;
+
+ f0 = fg;
+ f1 = FbRot24(f0,16);
+ f2 = FbRot24(f0,8);
+
+ dstLine = (CARD8 *) dstBits;
+ dstLine += (x & ~3) * 3;
+ dstStride *= (sizeof (FbBits) / sizeof (CARD8));
+ shift = x & 3;
+ lshift = 4 - shift;
+ while (height--)
+ {
+ bits = *stipple++;
+ n = lshift;
+ dst = dstLine;
+ while (bits)
+ {
+ switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
+ case CASE(0,0,0,0):
+ break;
+ case CASE(1,0,0,0):
+ WRITE2(dst,0,_AB);
+ WRITE1(dst,2,_C);
+ break;
+ case CASE(0,1,0,0):
+ WRITE1(dst,3,_A);
+ WRITE2(dst,4,_BC);
+ break;
+ case CASE(1,1,0,0):
+ WRITE4(dst,0,_ABCA);
+ WRITE2(dst,4,_BC);
+ break;
+ case CASE(0,0,1,0):
+ WRITE2(dst,6,_AB);
+ WRITE1(dst,8,_C);
+ break;
+ case CASE(1,0,1,0):
+ WRITE2(dst,0,_AB);
+ WRITE1(dst,2,_C);
+
+ WRITE2(dst,6,_AB);
+ WRITE1(dst,8,_C);
+ break;
+ case CASE(0,1,1,0):
+ WRITE1(dst,3,_A);
+ WRITE4(dst,4,_BCAB);
+ WRITE1(dst,8,_C);
+ break;
+ case CASE(1,1,1,0):
+ WRITE8(dst);
+ WRITE1(dst,8,_C);
+ break;
+ case CASE(0,0,0,1):
+ WRITE1(dst,9,_A);
+ WRITE2(dst,10,_BC);
+ break;
+ case CASE(1,0,0,1):
+ WRITE2(dst,0,_AB);
+ WRITE1(dst,2,_C);
+
+ WRITE1(dst,9,_A);
+ WRITE2(dst,10,_BC);
+ break;
+ case CASE(0,1,0,1):
+ WRITE1(dst,3,_A);
+ WRITE2(dst,4,_BC);
+
+ WRITE1(dst,9,_A);
+ WRITE2(dst,10,_BC);
+ break;
+ case CASE(1,1,0,1):
+ WRITE4(dst,0,_ABCA);
+ WRITE2(dst,4,_BC);
+
+ WRITE1(dst,9,_A);
+ WRITE2(dst,10,_BC);
+ break;
+ case CASE(0,0,1,1):
+ WRITE2(dst,6,_AB);
+ WRITE4(dst,8,_CABC);
+ break;
+ case CASE(1,0,1,1):
+ WRITE2(dst,0,_AB);
+ WRITE1(dst,2,_C);
+
+ WRITE2(dst,6,_AB);
+ WRITE4(dst,8,_CABC);
+ break;
+ case CASE(0,1,1,1):
+ WRITE1(dst,3,_A);
+ WRITE4(dst,4,_BCAB);
+ WRITE4(dst,8,_CABC);
+ break;
+ case CASE(1,1,1,1):
+ WRITE8(dst);
+ WRITE4(dst,8,_CABC);
+ break;
+ }
+ bits = FbStipLeft (bits, n);
+ n = 4;
+ dst += 12;
+ }
+ dstLine += dstStride;
+ }
+}
+#endif
+#endif
+
+void
+fbPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void * pglyphBase)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gx, gy;
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+#ifndef FBNOPIXADDR
+ void (*glyph) (FbBits *,
+ FbStride,
+ int,
+ FbStip *,
+ FbBits,
+ int,
+ int);
+ FbBits *dst = 0;
+ FbStride dstStride = 0;
+ int dstBpp = 0;
+ int dstXoff = 0, dstYoff = 0;
+
+ glyph = 0;
+ if (pGC->fillStyle == FillSolid && pPriv->and == 0)
+ {
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ switch (dstBpp) {
+ case 8: glyph = fbGlyph8; break;
+ case 16: glyph = fbGlyph16; break;
+#ifdef FB_24BIT
+ case 24: glyph = fbGlyph24; break;
+#endif
+ case 32: glyph = fbGlyph32; break;
+ }
+ }
+#endif
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+#ifndef FBNOPIXADDR
+ if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ (*glyph) (dst + (gy + dstYoff) * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->xor,
+ gx + dstXoff,
+ gHeight);
+ }
+ else
+#endif
+ {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPushImage (pDrawable,
+ pGC,
+
+ (FbStip *) pglyph,
+ gStride,
+ 0,
+
+ gx,
+ gy,
+ gWidth, gHeight);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+
+void
+fbImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ void * pglyphBase)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ CharInfoPtr *ppci;
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+ Bool opaque;
+ int n;
+ int gx, gy;
+#ifndef FBNOPIXADDR
+ void (*glyph) (FbBits *,
+ FbStride,
+ int,
+ FbStip *,
+ FbBits,
+ int,
+ int);
+ FbBits *dst = 0;
+ FbStride dstStride = 0;
+ int dstBpp = 0;
+ int dstXoff = 0, dstYoff = 0;
+
+ glyph = 0;
+ if (pPriv->and == 0)
+ {
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ switch (dstBpp) {
+ case 8: glyph = fbGlyph8; break;
+ case 16: glyph = fbGlyph16; break;
+#ifdef FB_24BIT
+ case 24: glyph = fbGlyph24; break;
+#endif
+ case 32: glyph = fbGlyph32; break;
+ }
+ }
+#endif
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ if (TERMINALFONT (pGC->font)
+#ifndef FBNOPIXADDR
+ && !glyph
+#endif
+ )
+ {
+ opaque = TRUE;
+ }
+ else
+ {
+ int xBack, widthBack;
+ int yBack, heightBack;
+
+ ppci = ppciInit;
+ n = nglyph;
+ widthBack = 0;
+ while (n--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0)
+ {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT(pGC->font);
+ heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ fbSolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ xBack,
+ yBack,
+ xBack + widthBack,
+ yBack + heightBack,
+ fbAnd(GXcopy,pPriv->bg,pPriv->pm),
+ fbXor(GXcopy,pPriv->bg,pPriv->pm));
+ opaque = FALSE;
+ }
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+#ifndef FBNOPIXADDR
+ if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ (*glyph) (dst + (gy + dstYoff) * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->fg,
+ gx + dstXoff,
+ gHeight);
+ }
+ else
+#endif
+ {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pPriv->fg,
+ pPriv->bg,
+ pPriv->pm,
+ GXcopy,
+ opaque,
+
+ gx,
+ gy,
+ gWidth, gHeight,
+
+ (FbStip *) pglyph,
+ gStride,
+ 0);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbimage.c b/nx-X11/programs/Xserver/fb/fbimage.c
new file mode 100644
index 000000000..9894faf02
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbimage.c
@@ -0,0 +1,364 @@
+/*
+ * Id: fbimage.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "fb.h"
+
+void
+fbPutImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ unsigned long i;
+ FbStride srcStride;
+ FbStip *src = (FbStip *) pImage;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ switch (format)
+ {
+ case XYBitmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pPriv->fg,
+ pPriv->bg,
+ pPriv->pm,
+ pGC->alu,
+ TRUE,
+ x, y, w, h,
+ src,
+ srcStride,
+ leftPad);
+ break;
+ case XYPixmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
+ for (i = 1 << (pDrawable->depth - 1); i; i >>= 1)
+ {
+ if (i & pGC->planemask)
+ {
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ FB_ALLONES,
+ 0,
+ fbReplicatePixel (i, pDrawable->bitsPerPixel),
+ pGC->alu,
+ TRUE,
+ x, y, w, h,
+ src,
+ srcStride,
+ leftPad);
+ src += srcStride * h;
+ }
+ }
+ break;
+ case ZPixmap:
+#ifdef FB_24_32BIT
+ if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
+ {
+ srcStride = PixmapBytePad(w, pDrawable->depth);
+ fb24_32PutZImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pGC->alu,
+ (FbBits) pGC->planemask,
+ x, y, w, h,
+ (CARD8 *) pImage,
+ srcStride);
+ }
+ else
+#endif
+ {
+ srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip);
+ fbPutZImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pGC->alu,
+ pPriv->pm,
+ x, y, w, h,
+ src, srcStride);
+ }
+ }
+}
+
+void
+fbPutZImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int alu,
+ FbBits pm,
+ int x,
+ int y,
+ int width,
+ int height,
+ FbStip *src,
+ FbStride srcStride)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ for (nbox = RegionNumRects (pClip),
+ pbox = RegionRects(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fbBltStip (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) * dstBpp,
+
+ dst + (y1 + dstYoff) * dstStride,
+ dstStride,
+ (x1 + dstXoff) * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ alu,
+ pm,
+ dstBpp);
+ }
+}
+
+void
+fbPutXYImage (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ FbBits fg,
+ FbBits bg,
+ FbBits pm,
+ int alu,
+ Bool opaque,
+
+ int x,
+ int y,
+ int width,
+ int height,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+ FbBits fgand = 0, fgxor = 0, bgand = 0, bgxor = 0;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ if (dstBpp == 1)
+ {
+ if (opaque)
+ alu = FbOpaqueStipple1Rop(alu,fg,bg);
+ else
+ alu = FbStipple1Rop(alu,fg);
+ }
+ else
+ {
+ fgand = fbAnd(alu,fg,pm);
+ fgxor = fbXor(alu,fg,pm);
+ if (opaque)
+ {
+ bgand = fbAnd(alu,bg,pm);
+ bgxor = fbXor(alu,bg,pm);
+ }
+ else
+ {
+ bgand = fbAnd(GXnoop,(FbBits)0,FB_ALLONES);
+ bgxor = fbXor(GXnoop,(FbBits)0,FB_ALLONES);
+ }
+ }
+
+ for (nbox = RegionNumRects (pClip),
+ pbox = RegionRects(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ if (dstBpp == 1)
+ {
+ fbBltStip (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) + srcX,
+
+ (FbStip *) (dst + (y1 + dstYoff) * dstStride),
+ FbBitsStrideToStipStride(dstStride),
+ (x1 + dstXoff) * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ alu,
+ pm,
+ dstBpp);
+ }
+ else
+ {
+ fbBltOne (src + (y1 - y) * srcStride,
+ srcStride,
+ (x1 - x) + srcX,
+
+ dst + (y1 + dstYoff) * dstStride,
+ dstStride,
+ (x1 + dstXoff) * dstBpp,
+ dstBpp,
+
+ (x2 - x1) * dstBpp,
+ (y2 - y1),
+
+ fgand, fgxor, bgand, bgxor);
+ }
+ }
+}
+
+void
+fbGetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d)
+{
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbStip *dst;
+ FbStride dstStride;
+
+ /*
+ * XFree86 DDX empties the root borderClip when the VT is
+ * switched away; this checks for that case
+ */
+ if (!fbDrawableEnabled(pDrawable))
+ return;
+
+#ifdef FB_24_32BIT
+ if (format == ZPixmap &&
+ pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth))
+ {
+ fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ return;
+ }
+#endif
+
+ fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ dst = (FbStip *) d;
+ if (format == ZPixmap || srcBpp == 1)
+ {
+ FbBits pm;
+
+ pm = fbReplicatePixel (planeMask, srcBpp);
+ dstStride = PixmapBytePad(w, pDrawable->depth);
+ if (pm != FB_ALLONES)
+ memset (d, 0, dstStride * h);
+ dstStride /= sizeof (FbStip);
+ fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride),
+ FbBitsStrideToStipStride(srcStride),
+ (x + srcXoff) * srcBpp,
+
+ dst,
+ dstStride,
+ 0,
+
+ w * srcBpp, h,
+
+ GXcopy,
+ pm,
+ srcBpp);
+ }
+ else
+ {
+ dstStride = BitmapBytePad(w) / sizeof (FbStip);
+ fbBltPlane (src + (y + srcYoff) * srcStride,
+ srcStride,
+ (x + srcXoff) * srcBpp,
+ srcBpp,
+
+ dst,
+ dstStride,
+ 0,
+
+ w * srcBpp, h,
+
+ fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
+ fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
+ fbAndStip(GXcopy,0,FB_STIP_ALLONES),
+ fbXorStip(GXcopy,0,FB_STIP_ALLONES),
+ planeMask);
+ }
+}
diff --git a/nx-X11/programs/Xserver/fb/fbline.c b/nx-X11/programs/Xserver/fb/fbline.c
new file mode 100644
index 000000000..fa80573e2
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbline.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbZeroLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ int x1, y1, x2, y2;
+ int x, y;
+ int dashOffset;
+
+ x = pDrawable->x;
+ y = pDrawable->y;
+ x1 = ppt->x;
+ y1 = ppt->y;
+ dashOffset = pGC->dashOffset;
+ while (--npt)
+ {
+ ++ppt;
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ fbSegment (pDrawable, pGC, x1 + x, y1 + y,
+ x2 + x, y2 + y,
+ npt == 1 && pGC->capStyle != CapNotLast,
+ &dashOffset);
+ x1 = x2;
+ y1 = y2;
+ }
+}
+
+void
+fbZeroSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSegs)
+{
+ int dashOffset;
+ int x, y;
+ Bool drawLast = pGC->capStyle != CapNotLast;
+
+ x = pDrawable->x;
+ y = pDrawable->y;
+ while (nseg--)
+ {
+ dashOffset = pGC->dashOffset;
+ fbSegment (pDrawable, pGC,
+ pSegs->x1 + x, pSegs->y1 + y,
+ pSegs->x2 + x, pSegs->y2 + y,
+ drawLast,
+ &dashOffset);
+ pSegs++;
+ }
+}
+
+void
+fbFixCoordModePrevious (int npt,
+ DDXPointPtr ppt)
+{
+ int x, y;
+
+ x = ppt->x;
+ y = ppt->y;
+ npt--;
+ while (npt--)
+ {
+ ppt++;
+ x = (ppt->x += x);
+ y = (ppt->y += y);
+ }
+}
+
+void
+fbPolyLine (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt);
+
+ if (pGC->lineWidth == 0)
+ {
+ line = fbZeroLine;
+#ifndef FBNOPIXADDR
+ if (pGC->fillStyle == FillSolid &&
+ pGC->lineStyle == LineSolid &&
+ RegionNumRects (fbGetCompositeClip(pGC)) == 1)
+ {
+ switch (pDrawable->bitsPerPixel) {
+ case 8: line = fbPolyline8; break;
+ case 16: line = fbPolyline16; break;
+#ifdef FB_24BIT
+ case 24: line = fbPolyline24; break;
+#endif
+ case 32: line = fbPolyline32; break;
+ }
+ }
+#endif
+ }
+ else
+ {
+ if (pGC->lineStyle != LineSolid)
+ line = miWideDash;
+ else
+ line = miWideLine;
+ }
+ (*line) (pDrawable, pGC, mode, npt, ppt);
+}
+
+void
+fbPolySegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pseg)
+{
+ void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pseg);
+
+ if (pGC->lineWidth == 0)
+ {
+ seg = fbZeroSegment;
+#ifndef FBNOPIXADDR
+ if (pGC->fillStyle == FillSolid &&
+ pGC->lineStyle == LineSolid &&
+ RegionNumRects (fbGetCompositeClip(pGC)) == 1)
+ {
+ switch (pDrawable->bitsPerPixel) {
+ case 8: seg = fbPolySegment8; break;
+ case 16: seg = fbPolySegment16; break;
+#ifdef FB_24BIT
+ case 24: seg = fbPolySegment24; break;
+#endif
+ case 32: seg = fbPolySegment32; break;
+ }
+ }
+#endif
+ }
+ else
+ {
+ seg = miPolySegment;
+ }
+ (*seg) (pDrawable, pGC, nseg, pseg);
+}
diff --git a/nx-X11/programs/Xserver/fb/fboverlay.c b/nx-X11/programs/Xserver/fb/fboverlay.c
new file mode 100644
index 000000000..6e0bbf252
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fboverlay.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+#include "fboverlay.h"
+
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+
+int fbOverlayGeneration;
+int fbOverlayScreenPrivateIndex = -1;
+
+int fbOverlayGetScreenPrivateIndex(void)
+{
+ return fbOverlayScreenPrivateIndex;
+}
+
+/*
+ * Replace this if you want something supporting
+ * multiple overlays with the same depth
+ */
+Bool
+fbOverlayCreateWindow(WindowPtr pWin)
+{
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
+ int i;
+ PixmapPtr pPixmap;
+
+ if (pWin->drawable.class != InputOutput)
+ return TRUE;
+
+#ifdef FB_SCREEN_PRIVATE
+ if (pWin->drawable.bitsPerPixel == 32)
+ pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
+#endif
+
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ pPixmap = pScrPriv->layer[i].u.run.pixmap;
+ if (pWin->drawable.depth == pPixmap->drawable.depth)
+ {
+ pWin->devPrivates[fbWinPrivateIndex].ptr = (void *) pPixmap;
+ /*
+ * Make sure layer keys are written correctly by
+ * having non-root layers set to full while the
+ * root layer is set to empty. This will cause
+ * all of the layers to get painted when the root
+ * is mapped
+ */
+ if (!pWin->parent)
+ {
+ RegionEmpty(
+ &pScrPriv->layer[i].u.run.region);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+Bool
+fbOverlayCloseScreen (ScreenPtr pScreen)
+{
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ int i;
+
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ (*pScreen->DestroyPixmap)(pScrPriv->layer[i].u.run.pixmap);
+ RegionUninit(&pScrPriv->layer[i].u.run.region);
+ }
+ return TRUE;
+}
+
+/*
+ * Return layer containing this window
+ */
+int
+fbOverlayWindowLayer(WindowPtr pWin)
+{
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
+ int i;
+
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ if (pWin->devPrivates[fbWinPrivateIndex].ptr ==
+ (void *) pScrPriv->layer[i].u.run.pixmap)
+ return i;
+ return 0;
+}
+
+Bool
+fbOverlayCreateScreenResources(ScreenPtr pScreen)
+{
+ int i;
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ PixmapPtr pPixmap;
+ void * pbits;
+ int width;
+ int depth;
+ BoxRec box;
+
+ if (!miCreateScreenResources(pScreen))
+ return FALSE;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ pbits = pScrPriv->layer[i].u.init.pbits;
+ width = pScrPriv->layer[i].u.init.width;
+ depth = pScrPriv->layer[i].u.init.depth;
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
+ if (!pPixmap)
+ return FALSE;
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
+ pScreen->height, depth,
+ BitsPerPixel(depth),
+ PixmapBytePad(width, depth),
+ pbits))
+ return FALSE;
+ pScrPriv->layer[i].u.run.pixmap = pPixmap;
+ RegionInit(&pScrPriv->layer[i].u.run.region, &box, 0);
+ }
+ pScreen->devPrivate = pScrPriv->layer[0].u.run.pixmap;
+ return TRUE;
+}
+
+void
+fbOverlayPaintKey (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ CARD32 pixel,
+ int layer)
+{
+ fbFillRegionSolid (pDrawable, pRegion, 0,
+ fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
+}
+
+/*
+ * Track visible region for each layer
+ */
+void
+fbOverlayUpdateLayerRegion (ScreenPtr pScreen,
+ int layer,
+ RegionPtr prgn)
+{
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ int i;
+ RegionRec rgnNew;
+
+ if (!prgn || !RegionNotEmpty(prgn))
+ return;
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ if (i == layer)
+ {
+ /* add new piece to this fb */
+ RegionUnion(
+ &pScrPriv->layer[i].u.run.region,
+ &pScrPriv->layer[i].u.run.region,
+ prgn);
+ }
+ else if (RegionNotEmpty(
+ &pScrPriv->layer[i].u.run.region))
+ {
+ /* paint new piece with chroma key */
+ RegionNull(&rgnNew);
+ RegionIntersect(
+ &rgnNew,
+ prgn,
+ &pScrPriv->layer[i].u.run.region);
+ (*pScrPriv->PaintKey) (&pScrPriv->layer[i].u.run.pixmap->drawable,
+ &rgnNew,
+ pScrPriv->layer[i].key,
+ i);
+ RegionUninit(&rgnNew);
+ /* remove piece from other fbs */
+ RegionSubtract(
+ &pScrPriv->layer[i].u.run.region,
+ &pScrPriv->layer[i].u.run.region,
+ prgn);
+ }
+ }
+}
+
+/*
+ * Copy only areas in each layer containing real bits
+ */
+void
+fbOverlayCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pWin->drawable.pScreen);
+ RegionRec rgnDst;
+ int dx, dy;
+ int i;
+ RegionRec layerRgn[FB_OVERLAY_MAX];
+ PixmapPtr pPixmap;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+
+ /*
+ * Clip to existing bits
+ */
+ RegionTranslate(prgnSrc, -dx, -dy);
+ RegionNull(&rgnDst);
+ RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
+ RegionTranslate(&rgnDst, dx, dy);
+ /*
+ * Compute the portion of each fb affected by this copy
+ */
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ RegionNull(&layerRgn[i]);
+ RegionIntersect(&layerRgn[i], &rgnDst,
+ &pScrPriv->layer[i].u.run.region);
+ if (RegionNotEmpty(&layerRgn[i]))
+ {
+ RegionTranslate(&layerRgn[i], -dx, -dy);
+ pPixmap = pScrPriv->layer[i].u.run.pixmap;
+ fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+ 0,
+ &layerRgn[i], dx, dy, pScrPriv->CopyWindow, 0,
+ (void *)(long) i);
+ }
+ }
+ /*
+ * Update regions
+ */
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ if (RegionNotEmpty(&layerRgn[i]))
+ fbOverlayUpdateLayerRegion (pScreen, i, &layerRgn[i]);
+
+ RegionUninit(&layerRgn[i]);
+ }
+ RegionUninit(&rgnDst);
+}
+
+void
+fbOverlayWindowExposures (WindowPtr pWin,
+ RegionPtr prgn,
+ RegionPtr other_exposed)
+{
+ fbOverlayUpdateLayerRegion (pWin->drawable.pScreen,
+ fbOverlayWindowLayer (pWin),
+ prgn);
+ miWindowExposures(pWin, prgn, other_exposed);
+}
+
+void
+fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ if (what == PW_BORDER)
+ fbOverlayUpdateLayerRegion (pWin->drawable.pScreen,
+ fbOverlayWindowLayer (pWin),
+ pRegion);
+ fbPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+fbOverlaySetupScreen(ScreenPtr pScreen,
+ void * pbits1,
+ void * pbits2,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width1,
+ int width2,
+ int bpp1,
+ int bpp2)
+{
+ return fbSetupScreen (pScreen,
+ pbits1,
+ xsize,
+ ysize,
+ dpix,
+ dpiy,
+ width1,
+ bpp1);
+}
+
+static Bool
+fb24_32OverlayCreateScreenResources(ScreenPtr pScreen)
+{
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ int pitch;
+ Bool retval;
+ int i;
+
+ if((retval = fbOverlayCreateScreenResources(pScreen))) {
+ for (i = 0; i < pScrPriv->nlayers; i++)
+ {
+ /* fix the screen pixmap */
+ PixmapPtr pPix = (PixmapPtr) pScrPriv->layer[i].u.run.pixmap;
+ if (pPix->drawable.bitsPerPixel == 32) {
+ pPix->drawable.bitsPerPixel = 24;
+ pitch = BitmapBytePad(pPix->drawable.width * 24);
+ pPix->devKind = pitch;
+ }
+ }
+ }
+
+ return retval;
+}
+
+Bool
+fbOverlayFinishScreenInit(ScreenPtr pScreen,
+ void * pbits1,
+ void * pbits2,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width1,
+ int width2,
+ int bpp1,
+ int bpp2,
+ int depth1,
+ int depth2)
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int bpp = 0, imagebpp = 32;
+ VisualID defaultVisual;
+ FbOverlayScrPrivPtr pScrPriv;
+
+ if (fbOverlayGeneration != serverGeneration)
+ {
+ fbOverlayScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ fbOverlayGeneration = serverGeneration;
+ }
+
+ pScrPriv = malloc (sizeof (FbOverlayScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+#ifdef FB_24_32BIT
+ if (bpp1 == 32 || bpp2 == 32)
+ bpp = 32;
+ else if (bpp1 == 24 || bpp2 == 24)
+ bpp = 24;
+
+ if (bpp == 24)
+ {
+ int f;
+
+ imagebpp = 32;
+ /*
+ * Check to see if we're advertising a 24bpp image format,
+ * in which case windows will use it in preference to a 32 bit
+ * format.
+ */
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ if (screenInfo.formats[f].bitsPerPixel == 24)
+ {
+ imagebpp = 24;
+ break;
+ }
+ }
+ }
+#endif
+#ifdef FB_SCREEN_PRIVATE
+ if (imagebpp == 32)
+ {
+ fbGetScreenPrivate(pScreen)->win32bpp = bpp;
+ fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
+ }
+ else
+ {
+ fbGetScreenPrivate(pScreen)->win32bpp = 32;
+ fbGetScreenPrivate(pScreen)->pix32bpp = 32;
+ }
+#endif
+
+ if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &depth1,
+ &defaultVisual, ((unsigned long)1<<(bpp1-1)) |
+ ((unsigned long)1<<(bpp2-1)), 8))
+ return FALSE;
+ if (! miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0,
+ depth1, ndepths, depths,
+ defaultVisual, nvisuals, visuals
+#ifdef FB_OLD_MISCREENINIT
+ , (miBSFuncPtr) 0
+#endif
+ ))
+ return FALSE;
+ /* MI thinks there's no frame buffer */
+#ifdef MITSHM
+ ShmRegisterFbFuncs(pScreen);
+#endif
+ pScreen->minInstalledCmaps = 1;
+ pScreen->maxInstalledCmaps = 2;
+
+ pScrPriv->nlayers = 2;
+ pScrPriv->PaintKey = fbOverlayPaintKey;
+ pScrPriv->CopyWindow = fbCopyWindowProc;
+ pScrPriv->layer[0].u.init.pbits = pbits1;
+ pScrPriv->layer[0].u.init.width = width1;
+ pScrPriv->layer[0].u.init.depth = depth1;
+
+ pScrPriv->layer[1].u.init.pbits = pbits2;
+ pScrPriv->layer[1].u.init.width = width2;
+ pScrPriv->layer[1].u.init.depth = depth2;
+
+ pScreen->devPrivates[fbOverlayScreenPrivateIndex].ptr = (void *) pScrPriv;
+
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = fbOverlayCloseScreen;
+ pScreen->CreateScreenResources = fbOverlayCreateScreenResources;
+ pScreen->CreateWindow = fbOverlayCreateWindow;
+ pScreen->WindowExposures = fbOverlayWindowExposures;
+ pScreen->CopyWindow = fbOverlayCopyWindow;
+ pScreen->PaintWindowBorder = fbOverlayPaintWindow;
+#ifdef FB_24_32BIT
+ if (bpp == 24 && imagebpp == 32)
+ {
+ pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
+ pScreen->CreateScreenResources = fb24_32OverlayCreateScreenResources;
+ }
+#endif
+
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/fb/fboverlay.h b/nx-X11/programs/Xserver/fb/fboverlay.h
new file mode 100644
index 000000000..2bb8b176a
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fboverlay.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _FBOVERLAY_H_
+#define _FBOVERLAY_H_
+
+extern int fbOverlayGeneration;
+extern int fbOverlayScreenPrivateIndex; /* XXX should be static */
+extern int fbOverlayGetScreenPrivateIndex(void);
+
+#ifndef FB_OVERLAY_MAX
+#define FB_OVERLAY_MAX 2
+#endif
+
+typedef void (*fbOverlayPaintKeyProc) (DrawablePtr, RegionPtr, CARD32, int);
+
+typedef struct _fbOverlayLayer {
+ union {
+ struct {
+ void * pbits;
+ int width;
+ int depth;
+ } init;
+ struct {
+ PixmapPtr pixmap;
+ RegionRec region;
+ } run;
+ } u;
+ CARD32 key; /* special pixel value */
+} FbOverlayLayer;
+
+typedef struct _fbOverlayScrPriv {
+ int nlayers;
+ fbOverlayPaintKeyProc PaintKey;
+ fbCopyProc CopyWindow;
+ FbOverlayLayer layer[FB_OVERLAY_MAX];
+} FbOverlayScrPrivRec, *FbOverlayScrPrivPtr;
+
+#define fbOverlayGetScrPriv(s) \
+ ((fbOverlayGetScreenPrivateIndex() != -1) ? \
+ (s)->devPrivates[fbOverlayGetScreenPrivateIndex()].ptr : NULL)
+Bool
+fbOverlayCreateWindow(WindowPtr pWin);
+
+Bool
+fbOverlayCloseScreen (ScreenPtr pScreen);
+
+int
+fbOverlayWindowLayer(WindowPtr pWin);
+
+Bool
+fbOverlayCreateScreenResources(ScreenPtr pScreen);
+
+void
+fbOverlayPaintKey (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ CARD32 pixel,
+ int layer);
+void
+fbOverlayUpdateLayerRegion (ScreenPtr pScreen,
+ int layer,
+ RegionPtr prgn);
+
+
+void
+fbOverlayCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+void
+fbOverlayWindowExposures (WindowPtr pWin,
+ RegionPtr prgn,
+ RegionPtr other_exposed);
+
+void
+fbOverlayPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+
+
+Bool
+fbOverlaySetupScreen(ScreenPtr pScreen,
+ void * pbits1,
+ void * pbits2,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width1,
+ int width2,
+ int bpp1,
+ int bpp2);
+
+Bool
+fbOverlayFinishScreenInit(ScreenPtr pScreen,
+ void * pbits1,
+ void * pbits2,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width1,
+ int width2,
+ int bpp1,
+ int bpp2,
+ int depth1,
+ int depth2);
+
+#endif /* _FBOVERLAY_H_ */
diff --git a/nx-X11/programs/Xserver/fb/fbpict.c b/nx-X11/programs/Xserver/fb/fbpict.c
new file mode 100644
index 000000000..214ed5a4c
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbpict.c
@@ -0,0 +1,1225 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "fb.h"
+
+#ifdef RENDER
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "fbpict.h"
+
+typedef void (*CompositeFunc) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+CARD32
+fbOver (CARD32 x, CARD32 y)
+{
+ CARD16 a = ~x >> 24;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ m = FbOverU(x,y,0,a,t);
+ n = FbOverU(x,y,8,a,t);
+ o = FbOverU(x,y,16,a,t);
+ p = FbOverU(x,y,24,a,t);
+ return m|n|o|p;
+}
+
+CARD32
+fbOver24 (CARD32 x, CARD32 y)
+{
+ CARD16 a = ~x >> 24;
+ CARD16 t;
+ CARD32 m,n,o;
+
+ m = FbOverU(x,y,0,a,t);
+ n = FbOverU(x,y,8,a,t);
+ o = FbOverU(x,y,16,a,t);
+ return m|n|o;
+}
+
+CARD32
+fbIn (CARD32 x, CARD8 y)
+{
+ CARD16 a = y;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ m = FbInU(x,0,a,t);
+ n = FbInU(x,8,a,t);
+ o = FbInU(x,16,a,t);
+ p = FbInU(x,24,a,t);
+ return m|n|o|p;
+}
+
+/*
+ * Naming convention:
+ *
+ * opSRCxMASKxDST
+ */
+
+void
+fbCompositeSolidMask_nx8x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD32 *dstLine, *dst, d, dstMask;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ *dst = src & dstMask;
+ else
+ *dst = fbOver (src, *dst) & dstMask;
+ }
+ else if (m)
+ {
+ d = fbIn (src, m);
+ *dst = fbOver (d, *dst) & dstMask;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8888x8888C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD32 *dstLine, *dst, d, dstMask;
+ CARD32 *maskLine, *mask, ma;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 m, n, o, p;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ ma = *mask++;
+ if (ma == 0xffffffff)
+ {
+ if (srca == 0xff)
+ *dst = src & dstMask;
+ else
+ *dst = fbOver (src, *dst) & dstMask;
+ }
+ else if (ma)
+ {
+ d = *dst;
+#define FbInOverC(src,srca,msk,dst,i,result) { \
+ CARD16 __a = FbGet8(msk,i); \
+ CARD32 __t, __ta; \
+ CARD32 __i; \
+ __t = FbIntMult (FbGet8(src,i), __a,__i); \
+ __ta = (CARD8) ~FbIntMult (srca, __a,__i); \
+ __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
+ __t = (CARD32) (CARD8) (__t | (-(__t >> 8))); \
+ result = __t << (i); \
+}
+ FbInOverC (src, srca, ma, d, 0, m);
+ FbInOverC (src, srca, ma, d, 8, n);
+ FbInOverC (src, srca, ma, d, 16, o);
+ FbInOverC (src, srca, ma, d, 24, p);
+ *dst = m|n|o|p;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD8 *dstLine, *dst;
+ CARD32 d;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ d = src;
+ else
+ {
+ d = Fetch24(dst);
+ d = fbOver24 (src, d);
+ }
+ Store24(dst,d);
+ }
+ else if (m)
+ {
+ d = fbOver24 (fbIn(src,m), Fetch24(dst));
+ Store24(dst,d);
+ }
+ dst += 3;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD8 *maskLine, *mask, m;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = *mask++;
+ if (m == 0xff)
+ {
+ if (srca == 0xff)
+ d = src;
+ else
+ {
+ d = *dst;
+ d = fbOver24 (src, cvt0565to8888(d));
+ }
+ *dst = cvt8888to0565(d);
+ }
+ else if (m)
+ {
+ d = *dst;
+ d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSolidMask_nx8888x0565C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD16 src16;
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *maskLine, *mask, ma;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 m, n, o;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ srca = src >> 24;
+ if (src == 0)
+ return;
+
+ src16 = cvt8888to0565(src);
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ ma = *mask++;
+ if (ma == 0xffffffff)
+ {
+ if (srca == 0xff)
+ {
+ *dst = src16;
+ }
+ else
+ {
+ d = *dst;
+ d = fbOver24 (src, cvt0565to8888(d));
+ *dst = cvt8888to0565(d);
+ }
+ }
+ else if (ma)
+ {
+ d = *dst;
+ d = cvt0565to8888(d);
+ FbInOverC (src, srca, ma, d, 0, m);
+ FbInOverC (src, srca, ma, d, 8, n);
+ FbInOverC (src, srca, ma, d, 16, o);
+ d = m|n|o;
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst, dstMask;
+ CARD32 *srcLine, *src, s;
+ FbStride dstStride, srcStride;
+ CARD8 a;
+ CARD16 w;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+
+ dstMask = FbFullMask (pDst->pDrawable->depth);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a == 0xff)
+ *dst = s & dstMask;
+ else if (a)
+ *dst = fbOver (s, *dst) & dstMask;
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *srcLine, *src, s;
+ CARD8 a;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a)
+ {
+ if (a == 0xff)
+ d = s;
+ else
+ d = fbOver24 (s, Fetch24(dst));
+ Store24(dst,d);
+ }
+ dst += 3;
+ }
+ }
+}
+
+void
+fbCompositeSrc_8888x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD16 *dstLine, *dst;
+ CARD32 d;
+ CARD32 *srcLine, *src, s;
+ CARD8 a;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ a = s >> 24;
+ if (a)
+ {
+ if (a == 0xff)
+ d = s;
+ else
+ {
+ d = *dst;
+ d = fbOver24 (s, cvt0565to8888(d));
+ }
+ *dst = cvt8888to0565(d);
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrc_0565x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD16 *dstLine, *dst;
+ CARD16 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ *dst++ = *src++;
+ }
+}
+
+void
+fbCompositeSrcAdd_8000x8000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ CARD8 s, d;
+ CARD16 t;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ if (s)
+ {
+ if (s != 0xff)
+ {
+ d = *dst;
+ t = d + s;
+ s = t | (0 - (t >> 8));
+ }
+ *dst = s;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrcAdd_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst;
+ CARD32 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ CARD32 s, d;
+ CARD16 t;
+ CARD32 m,n,o,p;
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w--)
+ {
+ s = *src++;
+ if (s)
+ {
+ if (s != 0xffffffff)
+ {
+ d = *dst;
+ if (d)
+ {
+ m = FbAdd(s,d,0,t);
+ n = FbAdd(s,d,8,t);
+ o = FbAdd(s,d,16,t);
+ p = FbAdd(s,d,24,t);
+ s = m|n|o|p;
+ }
+ }
+ *dst = s;
+ }
+ dst++;
+ }
+ }
+}
+
+void
+fbCompositeSrcAdd_1000x1000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ FbBits *dstBits, *srcBits;
+ FbStride dstStride, srcStride;
+ int dstBpp, srcBpp;
+ int dstXoff, dstYoff;
+ int srcXoff, srcYoff;
+
+ fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
+
+ fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+
+ fbBlt (srcBits + srcStride * (ySrc + srcYoff),
+ srcStride,
+ xSrc + srcXoff,
+
+ dstBits + dstStride * (yDst + dstYoff),
+ dstStride,
+ xDst + dstXoff,
+
+ width,
+ height,
+
+ GXor,
+ FB_ALLONES,
+ srcBpp,
+
+ FALSE,
+ FALSE);
+}
+
+void
+fbCompositeSolidMask_nx1xn (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ FbBits *dstBits;
+ FbStip *maskBits;
+ FbStride dstStride, maskStride;
+ int dstBpp, maskBpp;
+ int dstXoff, dstYoff;
+ int maskXoff, maskYoff;
+ FbBits src;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ if ((src & 0xff000000) != 0xff000000)
+ {
+ fbCompositeGeneral (op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ return;
+ }
+ fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
+ fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
+
+ switch (dstBpp) {
+ case 32:
+ break;
+ case 24:
+ break;
+ case 16:
+ src = cvt8888to0565(src);
+ break;
+ }
+
+ src = fbReplicatePixel (src, dstBpp);
+
+ fbBltOne (maskBits + maskStride * (yMask + maskYoff),
+ maskStride,
+ xMask + maskXoff,
+
+ dstBits + dstStride * (yDst + dstYoff),
+ dstStride,
+ (xDst + dstXoff) * dstBpp,
+ dstBpp,
+
+ width * dstBpp,
+ height,
+
+ 0x0,
+ src,
+ FB_ALLONES,
+ 0x0);
+}
+
+# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+
+void
+fbComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ int n;
+ BoxPtr pbox;
+ CompositeFunc func = NULL;
+ Bool srcRepeat = pSrc->pDrawable && pSrc->repeat == RepeatNormal;
+ Bool maskRepeat = FALSE;
+ Bool srcAlphaMap = pSrc->alphaMap != 0;
+ Bool maskAlphaMap = FALSE;
+ Bool dstAlphaMap = pDst->alphaMap != 0;
+ int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
+ int w, h, w_this, h_this;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ if (pSrc->pDrawable) {
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ }
+ if (pMask && pMask->pDrawable)
+ {
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+ maskRepeat = pMask->repeat == RepeatNormal;
+ maskAlphaMap = pMask->alphaMap != 0;
+ }
+
+ if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
+ && !pSrc->transform && !(pMask && pMask->transform)
+ && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
+ && (pSrc->filter != PictFilterConvolution)
+ && (!pMask || pMask->filter != PictFilterConvolution))
+ switch (op) {
+ case PictOpSrc:
+ break;
+ case PictOpOver:
+ if (pMask)
+ {
+ if (srcRepeat &&
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1)
+ {
+ srcRepeat = FALSE;
+ if (PICT_FORMAT_COLOR(pSrc->format)) {
+ switch (pMask->format) {
+ case PICT_a8:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ func = fbCompositeSolidMask_nx8x0565;
+ break;
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ func = fbCompositeSolidMask_nx8x0888;
+ break;
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx8x8888;
+ break;
+ }
+ break;
+ case PICT_a8r8g8b8:
+ if (pMask->componentAlpha) {
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ func = fbCompositeSolidMask_nx8888x8888C;
+ break;
+ case PICT_r5g6b5:
+ func = fbCompositeSolidMask_nx8888x0565C;
+ break;
+ }
+ }
+ break;
+ case PICT_a8b8g8r8:
+ if (pMask->componentAlpha) {
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx8888x8888C;
+ break;
+ case PICT_b5g6r5:
+ func = fbCompositeSolidMask_nx8888x0565C;
+ break;
+ }
+ }
+ break;
+ case PICT_a1:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSolidMask_nx1xn;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ else /* has mask and non-repeating source */
+ {
+ if (pSrc->pDrawable == pMask->pDrawable &&
+ xSrc == xMask && ySrc == yMask &&
+ !pMask->componentAlpha)
+ {
+ /* source == mask: non-premultiplied data */
+ switch (pSrc->format) {
+ case PICT_x8b8g8r8:
+ switch (pMask->format) {
+ case PICT_a8r8g8b8:
+ case PICT_a8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ break;
+ case PICT_r5g6b5:
+ break;
+ }
+ break;
+ }
+ break;
+ case PICT_x8r8g8b8:
+ switch (pMask->format) {
+ case PICT_a8r8g8b8:
+ case PICT_a8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ break;
+ case PICT_r5g6b5:
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ else
+ {
+ /* non-repeating source, repeating mask => translucent window */
+ if (maskRepeat &&
+ pMask->pDrawable->width == 1 &&
+ pMask->pDrawable->height == 1)
+ {
+ if (pSrc->format == PICT_x8r8g8b8 &&
+ pDst->format == PICT_x8r8g8b8 &&
+ pMask->format == PICT_a8)
+ {
+ }
+ }
+ }
+ }
+ }
+ else /* no mask */
+ {
+ if (srcRepeat &&
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1)
+ {
+ /* no mask and repeating source */
+ switch (pSrc->format) {
+ case PICT_a8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ break;
+ case PICT_r5g6b5:
+ break;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (pSrc->format) {
+ case PICT_a8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ func = fbCompositeSrc_8888x8888;
+ break;
+ case PICT_r8g8b8:
+ func = fbCompositeSrc_8888x0888;
+ break;
+ case PICT_r5g6b5:
+ func = fbCompositeSrc_8888x0565;
+ break;
+ }
+ break;
+ case PICT_x8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ break;
+ }
+ case PICT_x8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ break;
+ }
+ break;
+ case PICT_a8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ func = fbCompositeSrc_8888x8888;
+ break;
+ case PICT_b8g8r8:
+ func = fbCompositeSrc_8888x0888;
+ break;
+ case PICT_b5g6r5:
+ func = fbCompositeSrc_8888x0565;
+ break;
+ }
+ break;
+ case PICT_r5g6b5:
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ func = fbCompositeSrc_0565x0565;
+ break;
+ }
+ break;
+ case PICT_b5g6r5:
+ switch (pDst->format) {
+ case PICT_b5g6r5:
+ func = fbCompositeSrc_0565x0565;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ break;
+ case PictOpAdd:
+ if (pMask == 0)
+ {
+ switch (pSrc->format) {
+ case PICT_a8r8g8b8:
+ switch (pDst->format) {
+ case PICT_a8r8g8b8:
+ func = fbCompositeSrcAdd_8888x8888;
+ break;
+ }
+ break;
+ case PICT_a8b8g8r8:
+ switch (pDst->format) {
+ case PICT_a8b8g8r8:
+ func = fbCompositeSrcAdd_8888x8888;
+ break;
+ }
+ break;
+ case PICT_a8:
+ switch (pDst->format) {
+ case PICT_a8:
+ func = fbCompositeSrcAdd_8000x8000;
+ break;
+ }
+ break;
+ case PICT_a1:
+ switch (pDst->format) {
+ case PICT_a1:
+ func = fbCompositeSrcAdd_1000x1000;
+ break;
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ if (!func) {
+ /* no fast path, use the general code */
+ fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
+ return;
+ }
+
+ if (!miComputeCompositeRegion (&region,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height))
+ return;
+
+ n = RegionNumRects (&region);
+ pbox = RegionRects (&region);
+ while (n--)
+ {
+ h = pbox->y2 - pbox->y1;
+ y_src = pbox->y1 - yDst + ySrc;
+ y_msk = pbox->y1 - yDst + yMask;
+ y_dst = pbox->y1;
+ while (h)
+ {
+ h_this = h;
+ w = pbox->x2 - pbox->x1;
+ x_src = pbox->x1 - xDst + xSrc;
+ x_msk = pbox->x1 - xDst + xMask;
+ x_dst = pbox->x1;
+ if (maskRepeat)
+ {
+ y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
+ if (h_this > pMask->pDrawable->height - y_msk)
+ h_this = pMask->pDrawable->height - y_msk;
+ y_msk += pMask->pDrawable->y;
+ }
+ if (srcRepeat)
+ {
+ y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
+ if (h_this > pSrc->pDrawable->height - y_src)
+ h_this = pSrc->pDrawable->height - y_src;
+ y_src += pSrc->pDrawable->y;
+ }
+ while (w)
+ {
+ w_this = w;
+ if (maskRepeat)
+ {
+ x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
+ if (w_this > pMask->pDrawable->width - x_msk)
+ w_this = pMask->pDrawable->width - x_msk;
+ x_msk += pMask->pDrawable->x;
+ }
+ if (srcRepeat)
+ {
+ x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
+ if (w_this > pSrc->pDrawable->width - x_src)
+ w_this = pSrc->pDrawable->width - x_src;
+ x_src += pSrc->pDrawable->x;
+ }
+ (*func) (op, pSrc, pMask, pDst,
+ x_src, y_src, x_msk, y_msk, x_dst, y_dst,
+ w_this, h_this);
+ w -= w_this;
+ x_src += w_this;
+ x_msk += w_this;
+ x_dst += w_this;
+ }
+ h -= h_this;
+ y_src += h_this;
+ y_msk += h_this;
+ y_dst += h_this;
+ }
+ pbox++;
+ }
+ RegionUninit(&region);
+}
+
+#endif /* RENDER */
+
+Bool
+fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+
+#ifdef RENDER
+
+ PictureScreenPtr ps;
+
+ if (!miPictureInit (pScreen, formats, nformats))
+ return FALSE;
+ ps = GetPictureScreen(pScreen);
+ ps->Composite = fbComposite;
+ ps->Glyphs = miGlyphs;
+ ps->CompositeRects = miCompositeRects;
+ ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
+ ps->AddTraps = fbAddTraps;
+ ps->AddTriangles = fbAddTriangles;
+
+#endif /* RENDER */
+
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/fb/fbpict.h b/nx-X11/programs/Xserver/fb/fbpict.h
new file mode 100644
index 000000000..78d280707
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbpict.h
@@ -0,0 +1,610 @@
+/*
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _FBPICT_H_
+#define _FBPICT_H_
+
+#include "renderedge.h"
+
+#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
+#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
+
+#define FbGet8(v,i) ((CARD16) (CARD8) ((v) >> i))
+
+/*
+ * There are two ways of handling alpha -- either as a single unified value or
+ * a separate value for each component, hence each macro must have two
+ * versions. The unified alpha version has a 'U' at the end of the name,
+ * the component version has a 'C'. Similarly, functions which deal with
+ * this difference will have two versions using the same convention.
+ */
+
+#define FbOverU(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),(a),(t)) + FbGet8(x,i),\
+ (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+#define FbOverC(x,y,i,a,t) ((t) = FbIntMult(FbGet8(y,i),FbGet8(a,i),(t)) + FbGet8(x,i),\
+ (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+#define FbInU(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),(a),(t)) << (i))
+
+#define FbInC(x,i,a,t) ((CARD32) FbIntMult(FbGet8(x,i),FbGet8(a,i),(t)) << (i))
+
+#define FbGen(x,y,i,ax,ay,t,u,v) ((t) = (FbIntMult(FbGet8(y,i),ay,(u)) + \
+ FbIntMult(FbGet8(x,i),ax,(v))),\
+ (CARD32) ((CARD8) ((t) | \
+ (0 - ((t) >> 8)))) << (i))
+
+#define FbAdd(x,y,i,t) ((t) = FbGet8(x,i) + FbGet8(y,i), \
+ (CARD32) ((CARD8) ((t) | (0 - ((t) >> 8)))) << (i))
+
+
+#define Alpha(x) ((x) >> 24)
+#define Red(x) (((x) >> 16) & 0xff)
+#define Green(x) (((x) >> 8) & 0xff)
+#define Blue(x) ((x) & 0xff)
+
+#define fbComposeGetSolid(pict, bits, fmt) { \
+ FbBits *__bits__; \
+ FbStride __stride__; \
+ int __bpp__; \
+ _X_UNUSED int __xoff__,__yoff__; \
+\
+ fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
+ switch (__bpp__) { \
+ case 32: \
+ (bits) = *(CARD32 *) __bits__; \
+ break; \
+ case 24: \
+ (bits) = Fetch24 ((CARD8 *) __bits__); \
+ break; \
+ case 16: \
+ (bits) = *(CARD16 *) __bits__; \
+ (bits) = cvt0565to8888(bits); \
+ break; \
+ default: \
+ return; \
+ } \
+ /* If necessary, convert RGB <--> BGR. */ \
+ if (PICT_FORMAT_TYPE((pict)->format) != PICT_FORMAT_TYPE(fmt)) \
+ { \
+ (bits) = (((bits) & 0xff000000) | \
+ (((bits) & 0x00ff0000) >> 16) | \
+ (((bits) & 0x0000ff00) >> 0) | \
+ (((bits) & 0x000000ff) << 16)); \
+ } \
+ /* manage missing src alpha */ \
+ if ((pict)->pFormat->direct.alphaMask == 0) \
+ (bits) |= 0xff000000; \
+}
+
+#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
+ FbBits *__bits__; \
+ FbStride __stride__; \
+ int __bpp__; \
+ int __xoff__,__yoff__; \
+\
+ fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
+ (stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
+ (line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \
+}
+#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
+ (((s) >> 5) & 0x07e0) | \
+ (((s) >> 8) & 0xf800))
+#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
+ ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define Fetch24(a) ((unsigned long) (a) & 1 ? \
+ ((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
+ ((*((CARD16 *) (a)) << 8) | *((a)+2)))
+#define Store24(a,v) ((unsigned long) (a) & 1 ? \
+ ((*(a) = (CARD8) ((v) >> 16)), \
+ (*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
+ ((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
+ (*((a)+2) = (CARD8) (v))))
+#else
+#define Fetch24(a) ((unsigned long) (a) & 1 ? \
+ ((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
+ ((*((CARD16 *) (a))) | (*((a)+2) << 16)))
+#define Store24(a,v) ((unsigned long) (a) & 1 ? \
+ ((*(a) = (CARD8) (v)), \
+ (*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
+ ((*((CARD16 *) (a)) = (CARD16) (v)),\
+ (*((a)+2) = (CARD8) ((v) >> 16))))
+#endif
+
+/*
+ The methods below use some tricks to be able to do two color
+ components at the same time.
+*/
+
+/*
+ x_c = (x_c * a) / 255
+*/
+#define FbByteMul(x, a) do { \
+ CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
+ t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
+ t &= 0xff00ff; \
+ \
+ x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
+ x = (x + ((x >> 8) & 0xff00ff)); \
+ x &= 0xff00ff00; \
+ x += t; \
+ } while (0)
+
+/*
+ x_c = (x_c * a) / 255 + y
+*/
+#define FbByteMulAdd(x, a, y) do { \
+ CARD32 t = ((x & 0xff00ff) * a) + 0x800080; \
+ t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
+ t &= 0xff00ff; \
+ t += y & 0xff00ff; \
+ t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ t &= 0xff00ff; \
+ \
+ x = (((x >> 8) & 0xff00ff) * a) + 0x800080; \
+ x = (x + ((x >> 8) & 0xff00ff)) >> 8; \
+ x &= 0xff00ff; \
+ x += (y >> 8) & 0xff00ff; \
+ x |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ x &= 0xff00ff; \
+ x <<= 8; \
+ x += t; \
+ } while (0)
+
+/*
+ x_c = (x_c * a + y_c * b) / 255
+*/
+#define FbByteAddMul(x, a, y, b) do { \
+ CARD32 t; \
+ CARD32 r = (x >> 24) * a + (y >> 24) * b + 0x80; \
+ r += (r >> 8); \
+ r >>= 8; \
+ \
+ t = (x & 0xff00) * a + (y & 0xff00) * b; \
+ t += (t >> 8) + 0x8000; \
+ t >>= 16; \
+ \
+ t |= r << 16; \
+ t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ t &= 0xff00ff; \
+ t <<= 8; \
+ \
+ r = ((x >> 16) & 0xff) * a + ((y >> 16) & 0xff) * b + 0x80; \
+ r += (r >> 8); \
+ r >>= 8; \
+ \
+ x = (x & 0xff) * a + (y & 0xff) * b + 0x80; \
+ x += (x >> 8); \
+ x >>= 8; \
+ x |= r << 16; \
+ x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
+ x &= 0xff00ff; \
+ x |= t; \
+} while (0)
+
+/*
+ x_c = (x_c * a + y_c *b) / 256
+*/
+#define FbByteAddMul_256(x, a, y, b) do { \
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; \
+ t >>= 8; \
+ t &= 0xff00ff; \
+ \
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; \
+ x &= 0xff00ff00; \
+ x += t; \
+} while (0)
+/*
+ x_c = (x_c * a_c) / 255
+*/
+#define FbByteMulC(x, a) do { \
+ CARD32 t; \
+ CARD32 r = (x & 0xff) * (a & 0xff); \
+ r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
+ r += 0x800080; \
+ r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
+ r &= 0xff00ff; \
+ \
+ x >>= 8; \
+ t = (x & 0xff) * ((a >> 8) & 0xff); \
+ t |= (x & 0xff0000) * (a >> 24); \
+ t += 0x800080; \
+ t = t + ((t >> 8) & 0xff00ff); \
+ x = r | (t & 0xff00ff00); \
+ \
+ } while (0)
+
+/*
+ x_c = (x_c * a) / 255 + y
+*/
+#define FbByteMulAddC(x, a, y) do { \
+ CARD32 t; \
+ CARD32 r = (x & 0xff) * (a & 0xff); \
+ r |= (x & 0xff0000) * ((a >> 16) & 0xff); \
+ r += 0x800080; \
+ r = (r + ((r >> 8) & 0xff00ff)) >> 8; \
+ r &= 0xff00ff; \
+ r += y & 0xff00ff; \
+ r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
+ r &= 0xff00ff; \
+ \
+ x >>= 8; \
+ t = (x & 0xff) * ((a >> 8) & 0xff); \
+ t |= (x & 0xff0000) * (a >> 24); \
+ t += 0x800080; \
+ t = (t + ((t >> 8) & 0xff00ff)) >> 8; \
+ t &= 0xff00ff; \
+ t += (y >> 8) & 0xff00ff; \
+ t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ t &= 0xff00ff; \
+ x = r | (t << 8); \
+ } while (0)
+
+/*
+ x_c = (x_c * a_c + y_c * b) / 255
+*/
+#define FbByteAddMulC(x, a, y, b) do { \
+ CARD32 t; \
+ CARD32 r = (x >> 24) * (a >> 24) + (y >> 24) * b; \
+ r += (r >> 8) + 0x80; \
+ r >>= 8; \
+ \
+ t = (x & 0xff00) * ((a >> 8) & 0xff) + (y & 0xff00) * b; \
+ t += (t >> 8) + 0x8000; \
+ t >>= 16; \
+ \
+ t |= r << 16; \
+ t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ t &= 0xff00ff; \
+ t <<= 8; \
+ \
+ r = ((x >> 16) & 0xff) * ((a >> 16) & 0xff) + ((y >> 16) & 0xff) * b + 0x80; \
+ r += (r >> 8); \
+ r >>= 8; \
+ \
+ x = (x & 0xff) * (a & 0xff) + (y & 0xff) * b + 0x80; \
+ x += (x >> 8); \
+ x >>= 8; \
+ x |= r << 16; \
+ x |= 0x1000100 - ((x >> 8) & 0xff00ff); \
+ x &= 0xff00ff; \
+ x |= t; \
+ } while (0)
+
+/*
+ x_c = min(x_c + y_c, 255)
+*/
+#define FbByteAdd(x, y) do { \
+ CARD32 t; \
+ CARD32 r = (x & 0xff00ff) + (y & 0xff00ff); \
+ r |= 0x1000100 - ((r >> 8) & 0xff00ff); \
+ r &= 0xff00ff; \
+ \
+ t = ((x >> 8) & 0xff00ff) + ((y >> 8) & 0xff00ff); \
+ t |= 0x1000100 - ((t >> 8) & 0xff00ff); \
+ r |= (t & 0xff00ff) << 8; \
+ x = r; \
+ } while (0)
+
+#define div_255(x) (((x) + 0x80 + (((x) + 0x80) >> 8)) >> 8)
+
+#if defined(__i386__) && defined(__GNUC__)
+#define FASTCALL __attribute__((regparm(3)))
+#else
+#define FASTCALL
+#endif
+
+#if defined(__GNUC__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+
+typedef struct _FbComposeData {
+ CARD8 op;
+ PicturePtr src;
+ PicturePtr mask;
+ PicturePtr dest;
+ INT16 xSrc;
+ INT16 ySrc;
+ INT16 xMask;
+ INT16 yMask;
+ INT16 xDest;
+ INT16 yDest;
+ CARD16 width;
+ CARD16 height;
+} FbComposeData;
+
+typedef FASTCALL void (*CombineMaskU) (CARD32 *src, const CARD32 *mask, int width);
+typedef FASTCALL void (*CombineFuncU) (CARD32 *dest, const CARD32 *src, int width);
+typedef FASTCALL void (*CombineFuncC) (CARD32 *dest, CARD32 *src, CARD32 *mask, int width);
+
+typedef struct _FbComposeFunctions {
+ CombineFuncU *combineU;
+ CombineFuncC *combineC;
+ CombineMaskU combineMaskU;
+} FbComposeFunctions;
+
+/* fbcompose.c */
+
+void
+fbCompositeGeneral (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+
+/* fbedge.c */
+void
+fbRasterizeEdges (FbBits *buf,
+ int bpp,
+ int width,
+ int stride,
+ RenderEdge *l,
+ RenderEdge *r,
+ xFixed t,
+ xFixed b);
+
+/* fbpict.c */
+CARD32
+fbOver (CARD32 x, CARD32 y);
+
+CARD32
+fbOver24 (CARD32 x, CARD32 y);
+
+CARD32
+fbIn (CARD32 x, CARD8 y);
+
+void
+fbCompositeSolidMask_nx8x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSolidMask_nx8x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSolidMask_nx8888x8888C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSolidMask_nx8x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSolidMask_nx8888x0565C (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrc_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrc_8888x0888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrc_8888x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrc_0565x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrcAdd_8000x8000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrcAdd_8888x8888 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSrcAdd_1000x1000 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbCompositeSolidMask_nx1xn (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+fbComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+/* fbtrap.c */
+
+void
+fbAddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+void
+fbRasterizeTrapezoid (PicturePtr alpha,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off);
+
+void
+fbAddTriangles (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
+#endif /* _FBPICT_H_ */
diff --git a/nx-X11/programs/Xserver/fb/fbpixmap.c b/nx-X11/programs/Xserver/fb/fbpixmap.c
new file mode 100644
index 000000000..5f24433e3
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbpixmap.c
@@ -0,0 +1,390 @@
+/*
+ * Id: fbpixmap.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+PixmapPtr
+fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
+ unsigned usage_hint)
+{
+ PixmapPtr pPixmap;
+ size_t datasize;
+ size_t paddedWidth;
+ int adjust;
+ int base;
+
+ paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
+ if (paddedWidth / 4 > 32767 || height > 32767)
+ return NullPixmap;
+ datasize = height * paddedWidth;
+#ifdef PIXPRIV
+ base = pScreen->totalPixmapSize;
+#else
+ base = sizeof (PixmapRec);
+#endif
+ adjust = 0;
+ if (base & 7)
+ adjust = 8 - (base & 7);
+ datasize += adjust;
+#ifdef FB_DEBUG
+ datasize += 2 * paddedWidth;
+#endif
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bpp;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = (void *) ((char *)pPixmap + base + adjust);
+#ifdef FB_DEBUG
+ pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth);
+ fbInitializeDrawable (&pPixmap->drawable);
+#endif
+
+#ifdef COMPOSITE
+ pPixmap->screen_x = 0;
+ pPixmap->screen_y = 0;
+#endif
+ pPixmap->usage_hint = usage_hint;
+
+ return pPixmap;
+}
+
+PixmapPtr
+fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
+{
+ int bpp;
+ bpp = BitsPerPixel (depth);
+#ifdef FB_SCREEN_PRIVATE
+ if (bpp == 32 && depth <= 24)
+ bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
+#endif
+ return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint);
+}
+
+Bool
+fbDestroyPixmap (PixmapPtr pPixmap)
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ free(pPixmap);
+ return TRUE;
+}
+
+#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) \
+{ \
+ if ((reg)->data->numRects == (reg)->data->size) \
+ { \
+ RegionRectAlloc(reg, 1); \
+ fr = RegionBoxptr(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if(r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if(r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+fbPixmapToRegion(PixmapPtr pPix)
+{
+ register RegionPtr pReg;
+ FbBits *pw, w;
+ register int ib;
+ int width, h, base, rx1 = 0, crects;
+ FbBits *pwLineEnd;
+ int irectPrevStart, irectLineStart;
+ register BoxPtr prectO, prectN;
+ BoxPtr FirstRect, rects, prectLineStart;
+ Bool fInBox, fSame;
+ register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1);
+ FbBits *pwLine;
+ int nWidth;
+
+ pReg = RegionCreate(NULL, 1);
+ if(!pReg)
+ return NullRegion;
+ FirstRect = RegionBoxptr(pReg);
+ rects = FirstRect;
+
+ pwLine = (FbBits *) pPix->devPrivate.ptr;
+ nWidth = pPix->devKind >> (FB_SHIFT-3);
+
+ width = pPix->drawable.width;
+ pReg->extents.x1 = width - 1;
+ pReg->extents.x2 = 0;
+ irectPrevStart = -1;
+ for(h = 0; h < pPix->drawable.height; h++)
+ {
+ pw = pwLine;
+ pwLine += nWidth;
+ irectLineStart = rects - FirstRect;
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if(*pw & mask0)
+ {
+ fInBox = TRUE;
+ rx1 = 0;
+ }
+ else
+ fInBox = FALSE;
+ /* Process all words which are fully in the pixmap */
+ pwLineEnd = pw + (width >> FB_SHIFT);
+ for (base = 0; pw < pwLineEnd; base += FB_UNIT)
+ {
+ w = *pw++;
+ if (fInBox)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for(ib = 0; ib < FB_UNIT; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ if(width & FB_MASK)
+ {
+ /* Process final partial word on line */
+ w = *pw++;
+ for(ib = 0; ib < (width & FB_MASK); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = FbScrLeft(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + (width & FB_MASK), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ fSame = FALSE;
+ if(irectPrevStart != -1)
+ {
+ crects = irectLineStart - irectPrevStart;
+ if(crects == ((rects - FirstRect) - irectLineStart))
+ {
+ prectO = FirstRect + irectPrevStart;
+ prectN = prectLineStart = FirstRect + irectLineStart;
+ fSame = TRUE;
+ while(prectO < prectLineStart)
+ {
+ if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
+ {
+ fSame = FALSE;
+ break;
+ }
+ prectO++;
+ prectN++;
+ }
+ if (fSame)
+ {
+ prectO = FirstRect + irectPrevStart;
+ while(prectO < prectLineStart)
+ {
+ prectO->y2 += 1;
+ prectO++;
+ }
+ rects -= crects;
+ pReg->data->numRects -= crects;
+ }
+ }
+ }
+ if(!fSame)
+ irectPrevStart = irectLineStart;
+ }
+ if (!pReg->data->numRects)
+ pReg->extents.x1 = pReg->extents.x2 = 0;
+ else
+ {
+ pReg->extents.y1 = RegionBoxptr(pReg)->y1;
+ pReg->extents.y2 = RegionEnd(pReg)->y2;
+ if (pReg->data->numRects == 1)
+ {
+ free(pReg->data);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ }
+#ifdef DEBUG
+ if (!RegionIsValid(pReg))
+ FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
+#endif
+ return(pReg);
+}
+
+#ifdef FB_DEBUG
+
+#ifndef WIN32
+#include <stdio.h>
+#else
+#include <dbg.h>
+#endif
+
+static Bool
+fbValidateBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ {
+ if (*bits != data)
+ {
+#ifdef WIN32
+ NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)",
+ bits, *bits, data));
+#else
+ fprintf (stderr, "fbValidateBits failed\n");
+#endif
+ return FALSE;
+ }
+ bits++;
+ }
+}
+
+void
+fbValidateDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+ int xoff, yoff;
+ int height;
+ Bool failed;
+
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable);
+ fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ if (!fbValidateBits (first, stride, FB_HEAD_BITS) ||
+ !fbValidateBits (last, stride, FB_TAIL_BITS))
+ fbInitializeDrawable(pDrawable);
+}
+
+void
+fbSetBits (FbStip *bits, int stride, FbStip data)
+{
+ while (stride--)
+ *bits++ = data;
+}
+
+void
+fbInitializeDrawable (DrawablePtr pDrawable)
+{
+ FbStip *bits, *first, *last;
+ int stride, bpp;
+ int xoff, yoff;
+
+ fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff);
+ first = bits - stride;
+ last = bits + stride * pDrawable->height;
+ fbSetBits (first, stride, FB_HEAD_BITS);
+ fbSetBits (last, stride, FB_TAIL_BITS);
+}
+#endif /* FB_DEBUG */
diff --git a/nx-X11/programs/Xserver/fb/fbpoint.c b/nx-X11/programs/Xserver/fb/fbpoint.c
new file mode 100644
index 000000000..719dcfbb4
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbpoint.c
@@ -0,0 +1,163 @@
+/*
+ * Id: fbpoint.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+typedef void (*FbDots) (FbBits *dst,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits and,
+ FbBits xor);
+
+void
+fbDots (FbBits *dstOrig,
+ FbStride dstStride,
+ int dstBpp,
+ BoxPtr pBox,
+ xPoint *pts,
+ int npt,
+ int xorg,
+ int yorg,
+ int xoff,
+ int yoff,
+ FbBits andOrig,
+ FbBits xorOrig)
+{
+ FbStip *dst = (FbStip *) dstOrig;
+ int x1, y1, x2, y2;
+ int x, y;
+ FbStip *d;
+ FbStip and = andOrig;
+ FbStip xor = xorOrig;
+
+ dstStride = FbBitsStrideToStipStride (dstStride);
+ x1 = pBox->x1;
+ y1 = pBox->y1;
+ x2 = pBox->x2;
+ y2 = pBox->y2;
+ while (npt--)
+ {
+ x = pts->x + xorg;
+ y = pts->y + yorg;
+ pts++;
+ if (x1 <= x && x < x2 && y1 <= y && y < y2)
+ {
+ x = (x + xoff) * dstBpp;
+ d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT);
+ x &= FB_STIP_MASK;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ {
+ FbStip leftMask, rightMask;
+ int n, rot;
+ FbStip andT, xorT;
+
+ rot = FbFirst24Rot (x);
+ andT = FbRot24Stip(and,rot);
+ xorT = FbRot24Stip(xor,rot);
+ FbMaskStip (x, 24, leftMask, n, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ andT = FbNext24Stip(andT);
+ xorT = FbNext24Stip(xorT);
+ d++;
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop(*d, andT, xorT, rightMask);
+ }
+ else
+#endif
+ {
+ FbStip mask;
+ mask = FbStipMask(x, dstBpp);
+ *d = FbDoMaskRRop (*d, and, xor, mask);
+ }
+ }
+ }
+}
+
+void
+fbPolyPoint (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nptInit,
+ xPoint *pptInit)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbDots dots;
+ FbBits and, xor;
+ xPoint *ppt;
+ int npt;
+ BoxPtr pBox;
+ int nBox;
+
+ /* make pointlist origin relative */
+ ppt = pptInit;
+ npt = nptInit;
+ if (mode == CoordModePrevious)
+ {
+ npt--;
+ while(npt--)
+ {
+ ppt++;
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ }
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ and = pPriv->and;
+ xor = pPriv->xor;
+ dots = fbDots;
+#ifndef FBNOPIXADDR
+ switch (dstBpp) {
+ case 8: dots = fbDots8; break;
+ case 16: dots = fbDots16; break;
+#ifdef FB_24BIT
+ case 24: dots = fbDots24; break;
+#endif
+ case 32: dots = fbDots32; break;
+ }
+#endif
+ for (nBox = RegionNumRects (pClip), pBox = RegionRects (pClip);
+ nBox--; pBox++)
+ (*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit,
+ pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbpush.c b/nx-X11/programs/Xserver/fb/fbpush.c
new file mode 100644
index 000000000..6979b6f1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbpush.c
@@ -0,0 +1,246 @@
+/*
+ * Id: fbpush.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbPushPattern (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+
+ int width,
+ int height)
+{
+ FbStip *s, bitsMask, bitsMask0, bits;
+ int xspan;
+ int w;
+ int lenspan;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+
+ bitsMask0 = FbStipMask (srcX, 1);
+
+ while (height--)
+ {
+ bitsMask = bitsMask0;
+ w = width;
+ s = src;
+ src += srcStride;
+ bits = *s++;
+ xspan = x;
+ while (w)
+ {
+ if (bits & bitsMask)
+ {
+ lenspan = 0;
+ do
+ {
+ lenspan++;
+ if (lenspan == w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = *s++;
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (bits & bitsMask);
+ fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
+ xspan += lenspan;
+ w -= lenspan;
+ }
+ else
+ {
+ do
+ {
+ w--;
+ xspan++;
+ if (!w)
+ break;
+ bitsMask = FbStipRight (bitsMask, 1);
+ if (!bitsMask)
+ {
+ bits = *s++;
+ bitsMask = FbBitsMask(0,1);
+ }
+ } while (!(bits & bitsMask));
+ }
+ }
+ y++;
+ }
+}
+
+void
+fbPushFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+
+ if (pGC->fillStyle == FillSolid)
+ {
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int dstX;
+ int dstWidth;
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst = dst + (y + dstYoff) * dstStride;
+ dstX = (x + dstXoff) * dstBpp;
+ dstWidth = width * dstBpp;
+ if (dstBpp == 1)
+ {
+ fbBltStip (src,
+ srcStride,
+ srcX,
+
+ (FbStip *) dst,
+ FbBitsStrideToStipStride (dstStride),
+ dstX,
+
+ dstWidth,
+ height,
+
+ FbStipple1Rop(pGC->alu,pGC->fgPixel),
+ pPriv->pm,
+ dstBpp);
+ }
+ else
+ {
+ fbBltOne (src,
+ srcStride,
+ srcX,
+
+ dst,
+ dstStride,
+ dstX,
+ dstBpp,
+
+ dstWidth,
+ height,
+
+ pPriv->and, pPriv->xor,
+ fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
+ fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
+ }
+ }
+ else
+ {
+ fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
+ x, y, width, height);
+ }
+}
+
+void
+fbPushImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+
+ FbStip *src,
+ FbStride srcStride,
+ int srcX,
+
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+ int nbox;
+ BoxPtr pbox;
+ int x1, y1, x2, y2;
+
+ for (nbox = RegionNumRects (pClip),
+ pbox = RegionRects(pClip);
+ nbox--;
+ pbox++)
+ {
+ x1 = x;
+ y1 = y;
+ x2 = x + width;
+ y2 = y + height;
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+ fbPushFill (pDrawable,
+ pGC,
+
+ src + (y1 - y) * srcStride,
+ srcStride,
+ srcX + (x1 - x),
+
+ x1,
+ y1,
+ x2 - x1,
+ y2 - y1);
+ }
+}
+
+void
+fbPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff; /* Assumed to be zero */
+
+ fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
+
+ fbPushImage (pDrawable, pGC,
+ stip, stipStride, 0,
+ xOrg, yOrg, dx, dy);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbrop.h b/nx-X11/programs/Xserver/fb/fbrop.h
new file mode 100644
index 000000000..f3768a265
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbrop.h
@@ -0,0 +1,138 @@
+/*
+ * Id: fbrop.h,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _FBROP_H_
+#define _FBROP_H_
+
+typedef struct _mergeRopBits {
+ FbBits ca1, cx1, ca2, cx2;
+} FbMergeRopRec, *FbMergeRopPtr;
+
+extern const FbMergeRopRec FbMergeRopBits[16];
+
+#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2;
+#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx;
+
+#define FbInitializeMergeRop(alu,pm) {\
+ const FbMergeRopRec *_bits; \
+ _bits = &FbMergeRopBits[alu]; \
+ _ca1 = _bits->ca1 & pm; \
+ _cx1 = _bits->cx1 | ~pm; \
+ _ca2 = _bits->ca2 & pm; \
+ _cx2 = _bits->cx2 & pm; \
+}
+
+#define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \
+ (((alu) >> 1 & 5) == ((alu) & 5)))
+
+#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
+
+/* AND has higher precedence than XOR */
+
+#define FbDoMergeRop(src, dst) \
+ (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
+
+#define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2)
+
+#define FbDoMaskMergeRop(src, dst, mask) \
+ (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
+
+#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \
+ FbBits __xor = ((src) & _ca2) ^ _cx2; \
+ FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
+}
+
+#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \
+ FbBits __xor = ((src) & _ca2) ^ _cx2; \
+ FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
+}
+
+#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
+
+#define FbDoMaskRRop(dst, and, xor, mask) \
+ (((dst) & ((and) | ~(mask))) ^ (xor & mask))
+
+/*
+ * Take a single bit (0 or 1) and generate a full mask
+ */
+#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1))
+
+#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
+ (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
+
+#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
+ (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
+ ~(pm))
+
+#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits)
+
+#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits)
+
+#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip)
+
+#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip)
+
+/*
+ * Stippling operations;
+ */
+
+extern const FbBits fbStipple16Bits[256]; /* half of table */
+#define FbStipple16Bits(b) \
+ (fbStipple16Bits[(b)&0xff] | fbStipple16Bits[(b) >> 8] << FB_HALFUNIT)
+extern const FbBits fbStipple8Bits[256];
+extern const FbBits fbStipple4Bits[16];
+extern const FbBits fbStipple2Bits[4];
+extern const FbBits fbStipple1Bits[2];
+extern const FbBits *const fbStippleTable[];
+
+#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
+ (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
+
+#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
+ (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
+
+#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
+ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
+ FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
+}
+
+#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
+ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
+ FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
+}
+
+#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
+
+/*
+ * Compute rop for using tile code for 1-bit dest stipples; modifies
+ * existing rop to flip depending on pixel values
+ */
+#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
+
+#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \
+ (FbStipple1RopPick(alu,bg) << 2))
+
+#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4)
+
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbscreen.c b/nx-X11/programs/Xserver/fb/fbscreen.c
new file mode 100644
index 000000000..b0e6d9a6b
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbscreen.c
@@ -0,0 +1,300 @@
+/* $XdotOrg: xc/programs/Xserver/fb/fbscreen.c,v 1.6 2005/07/03 07:01:23 daniels Exp $
+ * Id: fbscreen.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+Bool
+fbCloseScreen (ScreenPtr pScreen)
+{
+ int d;
+ DepthPtr depths = pScreen->allowedDepths;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ free (depths[d].vids);
+ free (depths);
+ free (pScreen->visuals);
+ free (pScreen->devPrivate);
+#ifdef FB_SCREEN_PRIVATE
+ free (pScreen->devPrivates[fbScreenPrivateIndex].ptr);
+#endif
+ return TRUE;
+}
+
+Bool
+fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return (TRUE);
+}
+
+Bool
+fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return (TRUE);
+}
+
+void
+fbQueryBestSize (int class,
+ unsigned short *width, unsigned short *height,
+ ScreenPtr pScreen)
+{
+ unsigned short w;
+
+ switch (class) {
+ case CursorShape:
+ if (*width > pScreen->width)
+ *width = pScreen->width;
+ if (*height > pScreen->height)
+ *height = pScreen->height;
+ break;
+ case TileShape:
+ case StippleShape:
+ w = *width;
+ if ((w & (w - 1)) && w < FB_UNIT)
+ {
+ for (w = 1; w < *width; w <<= 1)
+ ;
+ *width = w;
+ }
+ }
+}
+
+#ifndef FB_OLD_SCREEN
+PixmapPtr
+_fbGetWindowPixmap (WindowPtr pWindow)
+{
+ return fbGetWindowPixmap (pWindow);
+}
+
+void
+_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+#ifdef FB_NO_WINDOW_PIXMAPS
+ FatalError ("Attempted to set window pixmap without fb support\n");
+#else
+ pWindow->devPrivates[fbWinPrivateIndex].ptr = (void *) pPixmap;
+#endif
+}
+#endif
+
+Bool
+fbSetupScreen(ScreenPtr pScreen,
+ void * pbits, /* pointer to screen bitmap */
+ int xsize, /* in pixels */
+ int ysize,
+ int dpix, /* dots per inch */
+ int dpiy,
+ int width, /* pixel width of frame buffer */
+ int bpp) /* bits per pixel for screen */
+{
+ if (!fbAllocatePrivates(pScreen, (int *) 0))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = fbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = fbGetImage;
+ pScreen->GetSpans = fbGetSpans;
+ pScreen->CreateWindow = fbCreateWindow;
+ pScreen->DestroyWindow = fbDestroyWindow;
+ pScreen->PositionWindow = fbPositionWindow;
+ pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
+ pScreen->RealizeWindow = fbMapWindow;
+ pScreen->UnrealizeWindow = fbUnmapWindow;
+ pScreen->PaintWindowBackground = fbPaintWindow;
+ pScreen->PaintWindowBorder = fbPaintWindow;
+ pScreen->CopyWindow = fbCopyWindow;
+ pScreen->CreatePixmap = fbCreatePixmap;
+ pScreen->DestroyPixmap = fbDestroyPixmap;
+ pScreen->RealizeFont = fbRealizeFont;
+ pScreen->UnrealizeFont = fbUnrealizeFont;
+ pScreen->CreateGC = fbCreateGC;
+ pScreen->CreateColormap = fbInitializeColormap;
+ pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
+ pScreen->InstallColormap = fbInstallColormap;
+ pScreen->UninstallColormap = fbUninstallColormap;
+ pScreen->ListInstalledColormaps = fbListInstalledColormaps;
+ pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
+ pScreen->ResolveColor = fbResolveColor;
+ pScreen->BitmapToRegion = fbPixmapToRegion;
+
+#ifndef FB_OLD_SCREEN
+ pScreen->GetWindowPixmap = _fbGetWindowPixmap;
+ pScreen->SetWindowPixmap = _fbSetWindowPixmap;
+
+ pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas;
+ pScreen->BackingStoreFuncs.SetClipmaskRgn = 0;
+ pScreen->BackingStoreFuncs.GetImagePixmap = 0;
+ pScreen->BackingStoreFuncs.GetSpansPixmap = 0;
+#endif
+
+ return TRUE;
+}
+
+Bool
+fbFinishScreenInit(ScreenPtr pScreen,
+ void * pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp)
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+ int imagebpp = bpp;
+
+#ifdef FB_DEBUG
+ int stride;
+
+ ysize -= 2;
+ stride = (width * bpp) / 8;
+ fbSetBits ((FbStip *) pbits,
+ stride / sizeof (FbStip), FB_HEAD_BITS);
+ pbits = (void *) ((char *) pbits + stride);
+ fbSetBits ((FbStip *) ((char *) pbits + stride * ysize),
+ stride / sizeof (FbStip), FB_TAIL_BITS);
+#endif
+ /*
+ * By default, a 24bpp screen will use 32bpp images, this avoids
+ * problems with many applications which just can't handle packed
+ * pixels. If you want real 24bit images, include a 24bpp
+ * format in the pixmap formats
+ */
+#ifdef FB_24_32BIT
+ if (bpp == 24)
+ {
+ int f;
+
+ imagebpp = 32;
+ /*
+ * Check to see if we're advertising a 24bpp image format,
+ * in which case windows will use it in preference to a 32 bit
+ * format.
+ */
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ if (screenInfo.formats[f].bitsPerPixel == 24)
+ {
+ imagebpp = 24;
+ break;
+ }
+ }
+ }
+#endif
+#ifdef FB_SCREEN_PRIVATE
+ if (imagebpp == 32)
+ {
+ fbGetScreenPrivate(pScreen)->win32bpp = bpp;
+ fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
+ }
+ else
+ {
+ fbGetScreenPrivate(pScreen)->win32bpp = 32;
+ fbGetScreenPrivate(pScreen)->pix32bpp = 32;
+ }
+#endif
+ rootdepth = 0;
+ if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(imagebpp-1)), 8))
+ return FALSE;
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals
+#ifdef FB_OLD_MISCREENINIT
+ , (miBSFuncPtr) 0
+#endif
+ ))
+ return FALSE;
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = fbCloseScreen;
+#ifdef FB_24_32BIT
+ if (bpp == 24 && imagebpp == 32)
+ {
+ pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
+ pScreen->CreateScreenResources = fb24_32CreateScreenResources;
+ }
+#endif
+#if 0
+ /* leave backing store initialization to the enclosing code so
+ * it can choose the correct order of wrappers
+ */
+ /* init backing store here so we can overwrite CloseScreen without stepping
+ * on the backing store wrapped version */
+ fbInitializeBackingStore (pScreen);
+#endif
+ return TRUE;
+}
+
+/* dts * (inch/dot) * (25.4 mm / inch) = mm */
+Bool
+fbScreenInit(ScreenPtr pScreen,
+ void * pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp)
+{
+ if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
+ return FALSE;
+ if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
+ width, bpp))
+ return FALSE;
+ return TRUE;
+}
+
+
+#ifdef FB_OLD_SCREEN
+const miBSFuncRec fbBSFuncRec = {
+ fbSaveAreas,
+ fbRestoreAreas,
+ (void (*)(GCPtr, RegionPtr)) 0,
+ (PixmapPtr (*)(void)) 0,
+ (PixmapPtr (*)(void)) 0,
+};
+#endif
+
+#if 0
+void
+fbInitializeBackingStore (ScreenPtr pScreen)
+{
+#ifdef FB_OLD_SCREEN
+ miInitializeBackingStore (pScreen, (miBSFuncRec *) &fbBSFuncRec);
+#else
+ miInitializeBackingStore (pScreen);
+#endif
+}
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbseg.c b/nx-X11/programs/Xserver/fb/fbseg.c
new file mode 100644
index 000000000..db3240e1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbseg.c
@@ -0,0 +1,728 @@
+/*
+ * Id: fbseg.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+#include "miline.h"
+
+#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \
+ ((dir < 0) ? FbStipLeft(mask,bpp) : \
+ FbStipRight(mask,bpp)))
+
+void
+fbBresSolid (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = (FbStip) pPriv->and;
+ FbStip xor = (FbStip) pPriv->xor;
+ FbStip mask, mask0;
+ FbStip bits;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * dstBpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, dstBpp);
+ mask = FbStipRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ if (axis == X_AXIS)
+ {
+ bits = 0;
+ while (len--)
+ {
+ bits |= mask;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ bits = 0;
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ bits = 0;
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ if (bits)
+ *dst = FbDoMaskRRop (*dst, and, xor, bits);
+ }
+ else
+ {
+ while (len--)
+ {
+ *dst = FbDoMaskRRop (*dst, and, xor, mask);
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ }
+}
+
+void
+fbBresDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = (FbStip) pPriv->and;
+ FbStip xor = (FbStip) pPriv->xor;
+ FbStip bgand = (FbStip) pPriv->bgand;
+ FbStip bgxor = (FbStip) pPriv->bgxor;
+ FbStip mask, mask0;
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+
+ FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
+
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * dstBpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, dstBpp);
+ mask = FbStipRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ while (len--)
+ {
+ if (even)
+ *dst = FbDoMaskRRop (*dst, and, xor, mask);
+ else if (doOdd)
+ *dst = FbDoMaskRRop (*dst, bgand, bgxor, mask);
+ if (axis == X_AXIS)
+ {
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+}
+
+void
+fbBresFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ while (len--)
+ {
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+}
+
+static void
+fbSetFg (DrawablePtr pDrawable,
+ GCPtr pGC,
+ Pixel fg)
+{
+ if (fg != pGC->fgPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *) &fg, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+}
+
+void
+fbBresFillDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+ Bool doBg;
+ Pixel fg, bg;
+
+ fg = pGC->fgPixel;
+ bg = pGC->bgPixel;
+
+ /* whether to fill the odd dashes */
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ /* whether to switch fg to bg when filling odd dashes */
+ doBg = doOdd && (pGC->fillStyle == FillSolid ||
+ pGC->fillStyle == FillStippled);
+
+ /* compute current dash position */
+ FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
+
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (doBg)
+ {
+ if (even)
+ fbSetFg (pDrawable, pGC, fg);
+ else
+ fbSetFg (pDrawable, pGC, bg);
+ }
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+ if (doBg)
+ fbSetFg (pDrawable, pGC, fg);
+}
+
+#ifdef FB_24BIT
+static void
+fbBresSolid24RRop (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = pPriv->and;
+ FbStip xor = pPriv->xor;
+ FbStip leftMask, rightMask;
+ int nl;
+ FbStip *d;
+ int x;
+ int rot;
+ FbStip andT, xorT;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ d = dst + (x1 >> FB_STIP_SHIFT);
+ x = x1 & FB_STIP_MASK;
+ rot = FbFirst24Rot (x);
+ andT = FbRot24Stip(and,rot);
+ xorT = FbRot24Stip(xor,rot);
+ FbMaskStip (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ d++;
+ andT = FbNext24Stip (andT);
+ xorT = FbNext24Stip (xorT);
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop (*d, andT, xorT, rightMask);
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+}
+
+static void
+fbBresDash24RRop (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip andT, xorT;
+ FbStip fgand = pPriv->and;
+ FbStip fgxor = pPriv->xor;
+ FbStip bgand = pPriv->bgand;
+ FbStip bgxor = pPriv->bgxor;
+ FbStip leftMask, rightMask;
+ int nl;
+ FbStip *d;
+ int x;
+ int rot;
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+
+ /* compute current dash position */
+ FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
+
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (even)
+ {
+ andT = fgand;
+ xorT = fgxor;
+ }
+ else
+ {
+ andT = bgand;
+ xorT = bgxor;
+ }
+ d = dst + (x1 >> FB_STIP_SHIFT);
+ x = x1 & FB_STIP_MASK;
+ rot = FbFirst24Rot (x);
+ andT = FbRot24Stip (andT, rot);
+ xorT = FbRot24Stip (xorT, rot);
+ FbMaskStip (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ *d = FbDoMaskRRop (*d, andT, xorT, leftMask);
+ d++;
+ andT = FbNext24Stip (andT);
+ xorT = FbNext24Stip (xorT);
+ }
+ if (rightMask)
+ *d = FbDoMaskRRop (*d, andT, xorT, rightMask);
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+}
+#endif
+
+/*
+ * For drivers that want to bail drawing some lines, this
+ * function takes care of selecting the appropriate rasterizer
+ * based on the contents of the specified GC.
+ */
+
+FbBres *
+fbSelectBres (DrawablePtr pDrawable,
+ GCPtr pGC)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ int dstBpp = pDrawable->bitsPerPixel;
+ FbBres * bres;
+
+ if (pGC->lineStyle == LineSolid)
+ {
+ bres = fbBresFill;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresSolid;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresSolid24RRop;
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0)
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresSolid8; break;
+ case 16: bres = fbBresSolid16; break;
+#ifdef FB_24BIT
+ case 24: bres = fbBresSolid24; break;
+#endif
+ case 32: bres = fbBresSolid32; break;
+ }
+ }
+#endif
+ }
+ }
+ else
+ {
+ bres = fbBresFillDash;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresDash;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresDash24RRop;
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0 &&
+ (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0))
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresDash8; break;
+ case 16: bres = fbBresDash16; break;
+#ifdef FB_24BIT
+ case 24: bres = fbBresDash24; break;
+#endif
+ case 32: bres = fbBresDash32; break;
+ }
+ }
+#endif
+ }
+ }
+ return bres;
+}
+
+void
+fbBres (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ (*fbSelectBres (pDrawable, pGC)) (pDrawable, pGC, dashOffset,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e3, len);
+}
+
+void
+fbSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Bool drawLast,
+ int *dashOffset)
+{
+ FbBres * bres;
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nBox;
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2, e3; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ int dashoff;
+ int doff;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ nBox = RegionNumRects (pClip);
+ pBox = RegionRects (pClip);
+
+ bres = fbSelectBres (pDrawable, pGC);
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ len = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ len = ady;
+ }
+
+ FIXUP_ERROR (e, octant, bias);
+
+ /*
+ * Adjust error terms to compare against zero
+ */
+ e3 = e2 - e1;
+ e = e - e1;
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ if (drawLast)
+ len++;
+ dashoff = *dashOffset;
+ *dashOffset = dashoff + len;
+ while(nBox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pBox);
+ OUTCODES(oc2, x2, y2, pBox);
+ if ((oc1 | oc2) == 0)
+ {
+ (*bres) (pDrawable, pGC, dashoff,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e3, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pBox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
+ pBox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pBox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+ if (clip2 != 0 || drawLast)
+ len++;
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ doff = dashoff;
+ err = e;
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ {
+ doff += clipdx;
+ err += e3 * clipdy + e1 * clipdx;
+ }
+ else
+ {
+ doff += clipdy;
+ err += e3 * clipdx + e1 * clipdy;
+ }
+ }
+ (*bres) (pDrawable, pGC, doff,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e3, len);
+ }
+ pBox++;
+ }
+ } /* while (nBox--) */
+}
diff --git a/nx-X11/programs/Xserver/fb/fbsetsp.c b/nx-X11/programs/Xserver/fb/fbsetsp.c
new file mode 100644
index 000000000..4b3db1eda
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbsetsp.c
@@ -0,0 +1,103 @@
+/*
+ * Id: fbsetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbSetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ FbBits *dst, *d, *s;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ BoxPtr pbox;
+ int n;
+ int xoff;
+ int x1, x2;
+
+#ifdef FB_24_32BIT
+ if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
+ {
+ fb24_32SetSpans (pDrawable, pGC, src, ppt, pwidth, nspans, fSorted);
+ return;
+ }
+#endif
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ while (nspans--)
+ {
+ d = dst + (ppt->y + dstYoff) * dstStride;
+ xoff = (int) (((long) src) & (FB_MASK >> 3));
+ s = (FbBits *) (src - xoff);
+ xoff <<= 3;
+ n = RegionNumRects(pClip);
+ pbox = RegionRects (pClip);
+ while (n--)
+ {
+ if (pbox->y1 > ppt->y)
+ break;
+ if (pbox->y2 > ppt->y)
+ {
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ if (pbox->x1 > x1)
+ x1 = pbox->x1;
+ if (pbox->x2 < x2)
+ x2 = pbox->x2;
+ if (x1 < x2)
+ fbBlt ((FbBits *) s,
+ 0,
+ (x1 - ppt->x) * dstBpp + xoff,
+ d,
+ dstStride,
+ (x1 + dstXoff) * dstBpp,
+
+ (x2 - x1) * dstBpp,
+ 1,
+ pGC->alu,
+ pPriv->pm,
+ dstBpp,
+
+ FALSE,
+ FALSE);
+ }
+ }
+ src += PixmapBytePad (*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+ fbValidateDrawable (pDrawable);
+}
+
diff --git a/nx-X11/programs/Xserver/fb/fbsolid.c b/nx-X11/programs/Xserver/fb/fbsolid.c
new file mode 100644
index 000000000..99e479f49
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbsolid.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FbSelectPart(xor,o,t) xor
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+void
+fbSolid (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int bpp,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor)
+{
+ FbBits startmask, endmask;
+ int n, nmiddle;
+ int startbyte, endbyte;
+
+#ifdef FB_24BIT
+ if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
+ {
+ fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
+ return;
+ }
+#endif
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
+ nmiddle, endmask, endbyte);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+ while (height--)
+ {
+ if (startmask)
+ {
+ FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor);
+ dst += dstStride;
+ }
+}
+
+#ifdef FB_24BIT
+void
+fbSolid24 (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits and,
+ FbBits xor)
+{
+ FbBits startmask, endmask;
+ FbBits xor0 = 0, xor1 = 0, xor2 = 0;
+ FbBits and0 = 0, and1 = 0, and2 = 0;
+ FbBits xorS = 0, andS = 0, xorE = 0, andE = 0;
+ int n, nmiddle;
+ int rotS, rot;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ /*
+ * Rotate pixel values this far across the word to align on
+ * screen pixel boundaries
+ */
+ rot = FbFirst24Rot (dstX);
+ FbMaskBits (dstX, width, startmask, nmiddle, endmask);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ /*
+ * Precompute rotated versions of the rasterop values
+ */
+ rotS = rot;
+ xor = FbRot24(xor,rotS);
+ and = FbRot24(and,rotS);
+ if (startmask)
+ {
+ xorS = xor;
+ andS = and;
+ xor = FbNext24Pix(xor);
+ and = FbNext24Pix(and);
+ }
+
+ if (nmiddle)
+ {
+ xor0 = xor;
+ and0 = and;
+ xor1 = FbNext24Pix(xor0);
+ and1 = FbNext24Pix(and0);
+ xor2 = FbNext24Pix(xor1);
+ and2 = FbNext24Pix(and1);
+ }
+
+ if (endmask)
+ {
+ switch (nmiddle % 3) {
+ case 0:
+ xorE = xor;
+ andE = and;
+ break;
+ case 1:
+ xorE = xor1;
+ andE = and1;
+ break;
+ case 2:
+ xorE = xor2;
+ andE = and2;
+ break;
+ }
+ }
+
+ while (height--)
+ {
+ if (startmask)
+ {
+ *dst = FbDoMaskRRop(*dst, andS, xorS, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and0)
+ {
+ while (n >= 3)
+ {
+ *dst++ = xor0;
+ *dst++ = xor1;
+ *dst++ = xor2;
+ n -= 3;
+ }
+ if (n)
+ {
+ *dst++ = xor0;
+ n--;
+ if (n)
+ {
+ *dst++ = xor1;
+ }
+ }
+ }
+ else
+ {
+ while (n >= 3)
+ {
+ *dst = FbDoRRop (*dst, and0, xor0);
+ dst++;
+ *dst = FbDoRRop (*dst, and1, xor1);
+ dst++;
+ *dst = FbDoRRop (*dst, and2, xor2);
+ dst++;
+ n -= 3;
+ }
+ if (n)
+ {
+ *dst = FbDoRRop (*dst, and0, xor0);
+ dst++;
+ n--;
+ if (n)
+ {
+ *dst = FbDoRRop (*dst, and1, xor1);
+ dst++;
+ }
+ }
+ }
+ if (endmask)
+ *dst = FbDoMaskRRop (*dst, andE, xorE, endmask);
+ dst += dstStride;
+ }
+}
+#endif
diff --git a/nx-X11/programs/Xserver/fb/fbstipple.c b/nx-X11/programs/Xserver/fb/fbstipple.c
new file mode 100644
index 000000000..486fa2030
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbstipple.c
@@ -0,0 +1,315 @@
+/*
+ * Id: fbstipple.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#ifndef FBNOPIXADDR
+/*
+ * This is a slight abuse of the preprocessor to generate repetitive
+ * code, the idea is to generate code for each case of a copy-mode
+ * transparent stipple
+ */
+#define LaneCases1(c,a) case c: \
+ while (n--) { (void)FbLaneCase(c,a); a++; } \
+ break
+#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
+#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
+#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
+#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
+#define LaneCases32(c,a) LaneCases16(c,a); LaneCases16(c+16,a)
+#define LaneCases64(c,a) LaneCases32(c,a); LaneCases32(c+32,a)
+#define LaneCases128(c,a) LaneCases64(c,a); LaneCases64(c+64,a)
+#define LaneCases256(c,a) LaneCases128(c,a); LaneCases128(c+128,a)
+
+#if FB_SHIFT == 6
+#define LaneCases(a) LaneCases256(0,a)
+#endif
+
+#if FB_SHIFT == 5
+#define LaneCases(a) LaneCases16(0,a)
+#endif
+
+/*
+ * Repeat a transparent stipple across a scanline n times
+ */
+
+void
+fbTransparentSpan (FbBits *dst,
+ FbBits stip,
+ FbBits fgxor,
+ int n)
+{
+ FbStip s;
+
+ s = ((FbStip) (stip ) & 0x01);
+ s |= ((FbStip) (stip >> 8) & 0x02);
+ s |= ((FbStip) (stip >> 16) & 0x04);
+ s |= ((FbStip) (stip >> 24) & 0x08);
+#if FB_SHIFT > 5
+ s |= ((FbStip) (stip >> 32) & 0x10);
+ s |= ((FbStip) (stip >> 40) & 0x20);
+ s |= ((FbStip) (stip >> 48) & 0x40);
+ s |= ((FbStip) (stip >> 56) & 0x80);
+#endif
+ switch (s) {
+ LaneCases(dst);
+ }
+}
+#endif
+
+void
+fbEvenStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ FbBits startmask, endmask;
+ FbBits mask, and, xor;
+ int nmiddle, n;
+ FbStip *s, *stipEnd, bits;
+ int rot, stipX, stipY;
+ int pixelsPerDst;
+ const FbBits *fbBits;
+ Bool transparent;
+ int startbyte, endbyte;
+
+ /*
+ * Check for a transparent stipple (stencil)
+ */
+ transparent = FALSE;
+ if (dstBpp >= 8 &&
+ fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
+ transparent = TRUE;
+
+ pixelsPerDst = FB_UNIT / dstBpp;
+ /*
+ * Adjust dest pointers
+ */
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes (dstX, width, fgand == 0 && bgand == 0,
+ startmask, startbyte, nmiddle, endmask, endbyte);
+
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ xRot *= dstBpp;
+ /*
+ * Compute stip start scanline and rotation parameters
+ */
+ stipEnd = stip + stipStride * stipHeight;
+ modulus (- yRot, stipHeight, stipY);
+ s = stip + stipStride * stipY;
+ modulus (- xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ fbBits = 0; /* unused */
+ if (pixelsPerDst <= 8)
+ fbBits = fbStippleTable[pixelsPerDst];
+
+ while (height--)
+ {
+ /*
+ * Extract stipple bits for this scanline;
+ */
+ bits = *s;
+ s += stipStride;
+ if (s == stipEnd)
+ s = stip;
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits,16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
+ /*
+ * Rotate into position and compute reduced rop values
+ */
+ mask = FbRotLeft(mask, rot);
+ and = (fgand & mask) | (bgand & ~mask);
+ xor = (fgxor & mask) | (bgxor & ~mask);
+
+#ifndef FBNOPIXADDR
+ if (transparent)
+ {
+ if (startmask)
+ {
+ fbTransparentSpan(dst, mask&startmask, fgxor, 1);
+ dst++;
+ }
+ fbTransparentSpan (dst, mask, fgxor, nmiddle);
+ dst += nmiddle;
+ if (endmask)
+ fbTransparentSpan(dst, mask&endmask, fgxor, 1);
+ }
+ else
+#endif
+ {
+ /*
+ * Fill scanline
+ */
+ if (startmask)
+ {
+ FbDoLeftMaskByteRRop (dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ {
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ }
+ dst += dstStride;
+ }
+}
+
+void
+fbOddStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus (- yRot, stipHeight, stipY);
+ modulus (dstX / dstBpp - xRot, stipWidth, stipX);
+ y = 0;
+ while (height)
+ {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp)
+ {
+ w = (stipWidth - sx) * dstBpp;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBltOne (stip + stipY * stipStride,
+ stipStride,
+ sx,
+
+ dst + y * dstStride,
+ dstStride,
+ x,
+ dstBpp,
+
+ w, h,
+
+ fgand, fgxor, bgand, bgxor);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+}
+
+void
+fbStipple (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+ int dstBpp,
+
+ int width,
+ int height,
+
+ FbStip *stip,
+ FbStride stipStride,
+ int stipWidth,
+ int stipHeight,
+ Bool even,
+
+ FbBits fgand,
+ FbBits fgxor,
+ FbBits bgand,
+ FbBits bgxor,
+
+ int xRot,
+ int yRot)
+{
+ if (even)
+ fbEvenStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+ else
+ fbOddStipple (dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipWidth, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbtile.c b/nx-X11/programs/Xserver/fb/fbtile.c
new file mode 100644
index 000000000..0d0cfe174
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbtile.c
@@ -0,0 +1,203 @@
+/*
+ * Id: fbtile.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+/*
+ * Accelerated tile fill -- tile width is a power of two not greater
+ * than FB_UNIT
+ */
+
+void
+fbEvenTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int xRot,
+ int yRot)
+{
+ FbBits *t, *tileEnd, bits;
+ FbBits startmask, endmask;
+ FbBits and, xor;
+ int n, nmiddle;
+ int tileX, tileY;
+ int rot;
+ int startbyte, endbyte;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
+ startmask, startbyte, nmiddle, endmask, endbyte);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ /*
+ * Compute tile start scanline and rotation parameters
+ */
+ tileEnd = tile + tileHeight;
+ modulus (- yRot, tileHeight, tileY);
+ t = tile + tileY;
+ modulus (- xRot, FB_UNIT, tileX);
+ rot = tileX;
+
+ while (height--)
+ {
+
+ /*
+ * Pick up bits for this scanline
+ */
+ bits = *t++;
+ if (t == tileEnd) t = tile;
+ bits = FbRotLeft(bits,rot);
+ and = fbAnd(alu,bits,pm);
+ xor = fbXor(alu,bits,pm);
+
+ if (startmask)
+ {
+ FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ *dst++ = xor;
+ else
+ while (n--)
+ {
+ *dst = FbDoRRop (*dst, and, xor);
+ dst++;
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ dst += dstStride;
+ }
+}
+
+void
+fbOddTile(FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot)
+{
+ int tileX, tileY;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus (- yRot, tileHeight, tileY);
+ y = 0;
+ while (height)
+ {
+ h = tileHeight - tileY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ modulus (dstX - xRot, tileWidth, tileX);
+ while (widthTmp)
+ {
+ w = tileWidth - tileX;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBlt (tile + tileY * tileStride,
+ tileStride,
+ tileX,
+
+ dst + y * dstStride,
+ dstStride,
+ x,
+
+ w, h,
+ alu,
+ pm,
+ bpp,
+
+ FALSE,
+ FALSE);
+ x += w;
+ tileX = 0;
+ }
+ y += h;
+ tileY = 0;
+ }
+}
+
+void
+fbTile (FbBits *dst,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ FbBits *tile,
+ FbStride tileStride,
+ int tileWidth,
+ int tileHeight,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ int xRot,
+ int yRot)
+{
+ if (FbEvenTile (tileWidth))
+ fbEvenTile (dst, dstStride, dstX, width, height,
+ tile, tileHeight,
+ alu, pm, xRot, yRot);
+ else
+ fbOddTile (dst, dstStride, dstX, width, height,
+ tile, tileStride, tileWidth, tileHeight,
+ alu, pm, bpp, xRot, yRot);
+}
diff --git a/nx-X11/programs/Xserver/fb/fbtrap.c b/nx-X11/programs/Xserver/fb/fbtrap.c
new file mode 100644
index 000000000..c9951b00d
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbtrap.c
@@ -0,0 +1,240 @@
+/*
+ * $Id: fbtrap.c,v 1.5 2005/07/03 07:01:23 daniels Exp $
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+#ifdef RENDER
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "renderedge.h"
+#include "fbpict.h"
+
+void
+fbAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ FbBits *buf;
+ int bpp;
+ int width;
+ int stride;
+ int height;
+ int pxoff, pyoff;
+
+ xFixed x_off_fixed;
+ xFixed y_off_fixed;
+ RenderEdge l, r;
+ xFixed t, b;
+
+ fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
+
+ width = pPicture->pDrawable->width;
+ height = pPicture->pDrawable->height;
+ x_off += pxoff;
+ y_off += pyoff;
+
+ x_off_fixed = IntToxFixed(y_off);
+ y_off_fixed = IntToxFixed(y_off);
+
+ while (ntrap--)
+ {
+ t = traps->top.y + y_off_fixed;
+ if (t < 0)
+ t = 0;
+ t = RenderSampleCeilY (t, bpp);
+
+ b = traps->bot.y + y_off_fixed;
+ if (xFixedToInt (b) >= height)
+ b = IntToxFixed (height) - 1;
+ b = RenderSampleFloorY (b, bpp);
+
+ if (b >= t)
+ {
+ /* initialize edge walkers */
+ RenderEdgeInit (&l, bpp, t,
+ traps->top.l + x_off_fixed,
+ traps->top.y + y_off_fixed,
+ traps->bot.l + x_off_fixed,
+ traps->bot.y + y_off_fixed);
+
+ RenderEdgeInit (&r, bpp, t,
+ traps->top.r + x_off_fixed,
+ traps->top.y + y_off_fixed,
+ traps->bot.r + x_off_fixed,
+ traps->bot.y + y_off_fixed);
+
+ fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
+ }
+ traps++;
+ }
+}
+
+void
+fbRasterizeTrapezoid (PicturePtr pPicture,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off)
+{
+ FbBits *buf;
+ int bpp;
+ int width;
+ int stride;
+ int height;
+ int pxoff, pyoff;
+
+ xFixed y_off_fixed;
+ RenderEdge l, r;
+ xFixed t, b;
+
+ if (!xTrapezoidValid (trap))
+ return;
+
+ fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
+
+ width = pPicture->pDrawable->width;
+ height = pPicture->pDrawable->height;
+ x_off += pxoff;
+ y_off += pyoff;
+
+ y_off_fixed = IntToxFixed(y_off);
+ t = trap->top + y_off_fixed;
+ if (t < 0)
+ t = 0;
+ t = RenderSampleCeilY (t, bpp);
+
+ b = trap->bottom + y_off_fixed;
+ if (xFixedToInt (b) >= height)
+ b = IntToxFixed (height) - 1;
+ b = RenderSampleFloorY (b, bpp);
+
+ if (b >= t)
+ {
+ /* initialize edge walkers */
+ RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off);
+ RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off);
+
+ fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
+ }
+}
+
+static int
+_GreaterY (xPointFixed *a, xPointFixed *b)
+{
+ if (a->y == b->y)
+ return a->x > b->x;
+ return a->y > b->y;
+}
+
+/*
+ * Note that the definition of this function is a bit odd because
+ * of the X coordinate space (y increasing downwards).
+ */
+static int
+_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
+{
+ xPointFixed ad, bd;
+
+ ad.x = a->x - ref->x;
+ ad.y = a->y - ref->y;
+ bd.x = b->x - ref->x;
+ bd.y = b->y - ref->y;
+
+ return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
+}
+
+/* FIXME -- this could be made more efficient */
+void
+fbAddTriangles (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntri,
+ xTriangle *tris)
+{
+ xPointFixed *top, *left, *right, *tmp;
+ xTrapezoid trap;
+
+ for (; ntri; ntri--, tris++)
+ {
+ top = &tris->p1;
+ left = &tris->p2;
+ right = &tris->p3;
+ if (_GreaterY (top, left)) {
+ tmp = left; left = top; top = tmp;
+ }
+ if (_GreaterY (top, right)) {
+ tmp = right; right = top; top = tmp;
+ }
+ if (_Clockwise (top, right, left)) {
+ tmp = right; right = left; left = tmp;
+ }
+
+ /*
+ * Two cases:
+ *
+ * + +
+ * / \ / \
+ * / \ / \
+ * / + + \
+ * / -- -- \
+ * / -- -- \
+ * / --- --- \
+ * +-- --+
+ */
+
+ trap.top = top->y;
+ trap.left.p1 = *top;
+ trap.left.p2 = *left;
+ trap.right.p1 = *top;
+ trap.right.p2 = *right;
+ if (right->y < left->y)
+ trap.bottom = right->y;
+ else
+ trap.bottom = left->y;
+ fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
+ if (right->y < left->y)
+ {
+ trap.top = right->y;
+ trap.bottom = left->y;
+ trap.right.p1 = *right;
+ trap.right.p2 = *left;
+ }
+ else
+ {
+ trap.top = left->y;
+ trap.bottom = right->y;
+ trap.left.p1 = *left;
+ trap.left.p2 = *right;
+ }
+ fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
+ }
+}
+
+#endif /* RENDER */
diff --git a/nx-X11/programs/Xserver/fb/fbutil.c b/nx-X11/programs/Xserver/fb/fbutil.c
new file mode 100644
index 000000000..4be0f233c
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbutil.c
@@ -0,0 +1,364 @@
+/*
+ * Id: fbutil.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "fb.h"
+
+FbBits
+fbReplicatePixel (Pixel p, int bpp)
+{
+ FbBits b = p;
+
+ b &= FbFullMask (bpp);
+ while (bpp < FB_UNIT)
+ {
+ b |= b << bpp;
+ bpp <<= 1;
+ }
+ return b;
+}
+
+void
+fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp)
+{
+ FbBits and, xor;
+
+ switch (rop)
+ {
+ default:
+ case GXclear: /* 0 0 0 0 */
+ and = 0;
+ xor = 0;
+ break;
+ case GXand: /* 0 0 0 1 */
+ and = fg;
+ xor = 0;
+ break;
+ case GXandReverse: /* 0 0 1 0 */
+ and = fg;
+ xor = fg;
+ break;
+ case GXcopy: /* 0 0 1 1 */
+ and = 0;
+ xor = fg;
+ break;
+ case GXandInverted: /* 0 1 0 0 */
+ and = ~fg;
+ xor = 0;
+ break;
+ case GXnoop: /* 0 1 0 1 */
+ and = FB_ALLONES;
+ xor = 0;
+ break;
+ case GXxor: /* 0 1 1 0 */
+ and = FB_ALLONES;
+ xor = fg;
+ break;
+ case GXor: /* 0 1 1 1 */
+ and = ~fg;
+ xor = fg;
+ break;
+ case GXnor: /* 1 0 0 0 */
+ and = ~fg;
+ xor = ~fg;
+ break;
+ case GXequiv: /* 1 0 0 1 */
+ and = FB_ALLONES;
+ xor = ~fg;
+ break;
+ case GXinvert: /* 1 0 1 0 */
+ and = FB_ALLONES;
+ xor = FB_ALLONES;
+ break;
+ case GXorReverse: /* 1 0 1 1 */
+ and = ~fg;
+ xor = FB_ALLONES;
+ break;
+ case GXcopyInverted: /* 1 1 0 0 */
+ and = 0;
+ xor = ~fg;
+ break;
+ case GXorInverted: /* 1 1 0 1 */
+ and = fg;
+ xor = ~fg;
+ break;
+ case GXnand: /* 1 1 1 0 */
+ and = fg;
+ xor = FB_ALLONES;
+ break;
+ case GXset: /* 1 1 1 1 */
+ and = 0;
+ xor = FB_ALLONES;
+ break;
+ }
+ and |= ~pm;
+ xor &= pm;
+ *andp = and;
+ *xorp = xor;
+}
+
+#define O 0
+#define I FB_ALLONES
+
+const FbMergeRopRec FbMergeRopBits[16] = {
+ { O,O,O,O }, /* clear 0x0 0 */
+ { I,O,O,O }, /* and 0x1 src AND dst */
+ { I,O,I,O }, /* andReverse 0x2 src AND NOT dst */
+ { O,O,I,O }, /* copy 0x3 src */
+ { I,I,O,O }, /* andInverted 0x4 NOT src AND dst */
+ { O,I,O,O }, /* noop 0x5 dst */
+ { O,I,I,O }, /* xor 0x6 src XOR dst */
+ { I,I,I,O }, /* or 0x7 src OR dst */
+ { I,I,I,I }, /* nor 0x8 NOT src AND NOT dst */
+ { O,I,I,I }, /* equiv 0x9 NOT src XOR dst */
+ { O,I,O,I }, /* invert 0xa NOT dst */
+ { I,I,O,I }, /* orReverse 0xb src OR NOT dst */
+ { O,O,I,I }, /* copyInverted 0xc NOT src */
+ { I,O,I,I }, /* orInverted 0xd NOT src OR dst */
+ { I,O,O,I }, /* nand 0xe NOT src OR NOT dst */
+ { O,O,O,I }, /* set 0xf 1 */
+};
+
+/*
+ * Stipple masks are independent of bit/byte order as long
+ * as bitorder == byteorder. FB doesn't handle the case
+ * where these differ
+ */
+#define BitsMask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \
+ (FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK)))
+
+#define Mask(x,w) BitsMask((x)*(w),(w))
+
+
+#define SelMask(b,n,w) ((((b) >> n) & 1) * Mask(n,w))
+
+#define C1(b,w) \
+ (SelMask(b,0,w))
+
+#define C2(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w))
+
+#define C4(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w) | \
+ SelMask(b,2,w) | \
+ SelMask(b,3,w))
+
+#define C8(b,w) \
+ (SelMask(b,0,w) | \
+ SelMask(b,1,w) | \
+ SelMask(b,2,w) | \
+ SelMask(b,3,w) | \
+ SelMask(b,4,w) | \
+ SelMask(b,5,w) | \
+ SelMask(b,6,w) | \
+ SelMask(b,7,w))
+
+#if FB_UNIT == 16
+#define fbStipple16Bits 0
+#define fbStipple8Bits 0
+const FbBits fbStipple4Bits[16] = {
+ C4( 0,4), C4( 1,4), C4( 2,4), C4( 3,4), C4( 4,4), C4( 5,4),
+ C4( 6,4), C4( 7,4), C4( 8,4), C4( 9,4), C4( 10,4), C4( 11,4),
+ C4( 12,4), C4( 13,4), C4( 14,4), C4( 15,4),};
+const FbBits fbStipple2Bits[4] = {
+ C2( 0,8), C2( 1,8), C2( 2,8), C2( 3,8),
+};
+const FbBits fbStipple1Bits[2] = {
+ C1( 0,16), C1( 1,16),
+};
+#endif
+#if FB_UNIT == 32
+#define fbStipple16Bits 0
+const FbBits fbStipple8Bits[256] = {
+ C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4),
+ C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4),
+ C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4),
+ C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4),
+ C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4),
+ C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4),
+ C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4),
+ C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4),
+ C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4),
+ C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4),
+ C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4),
+ C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4),
+ C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4),
+ C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4),
+ C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4),
+ C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4),
+ C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4),
+ C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4),
+ C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4),
+ C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4),
+ C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4),
+ C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4),
+ C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4),
+ C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4),
+ C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4),
+ C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4),
+ C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4),
+ C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4),
+ C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4),
+ C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4),
+ C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4),
+ C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4),
+ C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4),
+ C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4),
+ C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4),
+ C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4),
+ C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4),
+ C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4),
+ C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4),
+ C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4),
+ C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4),
+ C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4),
+ C8(252,4), C8(253,4), C8(254,4), C8(255,4),
+};
+const FbBits fbStipple4Bits[16] = {
+ C4( 0,8), C4( 1,8), C4( 2,8), C4( 3,8), C4( 4,8), C4( 5,8),
+ C4( 6,8), C4( 7,8), C4( 8,8), C4( 9,8), C4( 10,8), C4( 11,8),
+ C4( 12,8), C4( 13,8), C4( 14,8), C4( 15,8),};
+const FbBits fbStipple2Bits[4] = {
+ C2( 0,16), C2( 1,16), C2( 2,16), C2( 3,16),
+};
+const FbBits fbStipple1Bits[2] = {
+ C1( 0,32), C1( 1,32),
+};
+#endif
+#if FB_UNIT == 64
+const FbBits fbStipple16Bits[256] = {
+ C8( 0,4), C8( 1,4), C8( 2,4), C8( 3,4), C8( 4,4), C8( 5,4),
+ C8( 6,4), C8( 7,4), C8( 8,4), C8( 9,4), C8( 10,4), C8( 11,4),
+ C8( 12,4), C8( 13,4), C8( 14,4), C8( 15,4), C8( 16,4), C8( 17,4),
+ C8( 18,4), C8( 19,4), C8( 20,4), C8( 21,4), C8( 22,4), C8( 23,4),
+ C8( 24,4), C8( 25,4), C8( 26,4), C8( 27,4), C8( 28,4), C8( 29,4),
+ C8( 30,4), C8( 31,4), C8( 32,4), C8( 33,4), C8( 34,4), C8( 35,4),
+ C8( 36,4), C8( 37,4), C8( 38,4), C8( 39,4), C8( 40,4), C8( 41,4),
+ C8( 42,4), C8( 43,4), C8( 44,4), C8( 45,4), C8( 46,4), C8( 47,4),
+ C8( 48,4), C8( 49,4), C8( 50,4), C8( 51,4), C8( 52,4), C8( 53,4),
+ C8( 54,4), C8( 55,4), C8( 56,4), C8( 57,4), C8( 58,4), C8( 59,4),
+ C8( 60,4), C8( 61,4), C8( 62,4), C8( 63,4), C8( 64,4), C8( 65,4),
+ C8( 66,4), C8( 67,4), C8( 68,4), C8( 69,4), C8( 70,4), C8( 71,4),
+ C8( 72,4), C8( 73,4), C8( 74,4), C8( 75,4), C8( 76,4), C8( 77,4),
+ C8( 78,4), C8( 79,4), C8( 80,4), C8( 81,4), C8( 82,4), C8( 83,4),
+ C8( 84,4), C8( 85,4), C8( 86,4), C8( 87,4), C8( 88,4), C8( 89,4),
+ C8( 90,4), C8( 91,4), C8( 92,4), C8( 93,4), C8( 94,4), C8( 95,4),
+ C8( 96,4), C8( 97,4), C8( 98,4), C8( 99,4), C8(100,4), C8(101,4),
+ C8(102,4), C8(103,4), C8(104,4), C8(105,4), C8(106,4), C8(107,4),
+ C8(108,4), C8(109,4), C8(110,4), C8(111,4), C8(112,4), C8(113,4),
+ C8(114,4), C8(115,4), C8(116,4), C8(117,4), C8(118,4), C8(119,4),
+ C8(120,4), C8(121,4), C8(122,4), C8(123,4), C8(124,4), C8(125,4),
+ C8(126,4), C8(127,4), C8(128,4), C8(129,4), C8(130,4), C8(131,4),
+ C8(132,4), C8(133,4), C8(134,4), C8(135,4), C8(136,4), C8(137,4),
+ C8(138,4), C8(139,4), C8(140,4), C8(141,4), C8(142,4), C8(143,4),
+ C8(144,4), C8(145,4), C8(146,4), C8(147,4), C8(148,4), C8(149,4),
+ C8(150,4), C8(151,4), C8(152,4), C8(153,4), C8(154,4), C8(155,4),
+ C8(156,4), C8(157,4), C8(158,4), C8(159,4), C8(160,4), C8(161,4),
+ C8(162,4), C8(163,4), C8(164,4), C8(165,4), C8(166,4), C8(167,4),
+ C8(168,4), C8(169,4), C8(170,4), C8(171,4), C8(172,4), C8(173,4),
+ C8(174,4), C8(175,4), C8(176,4), C8(177,4), C8(178,4), C8(179,4),
+ C8(180,4), C8(181,4), C8(182,4), C8(183,4), C8(184,4), C8(185,4),
+ C8(186,4), C8(187,4), C8(188,4), C8(189,4), C8(190,4), C8(191,4),
+ C8(192,4), C8(193,4), C8(194,4), C8(195,4), C8(196,4), C8(197,4),
+ C8(198,4), C8(199,4), C8(200,4), C8(201,4), C8(202,4), C8(203,4),
+ C8(204,4), C8(205,4), C8(206,4), C8(207,4), C8(208,4), C8(209,4),
+ C8(210,4), C8(211,4), C8(212,4), C8(213,4), C8(214,4), C8(215,4),
+ C8(216,4), C8(217,4), C8(218,4), C8(219,4), C8(220,4), C8(221,4),
+ C8(222,4), C8(223,4), C8(224,4), C8(225,4), C8(226,4), C8(227,4),
+ C8(228,4), C8(229,4), C8(230,4), C8(231,4), C8(232,4), C8(233,4),
+ C8(234,4), C8(235,4), C8(236,4), C8(237,4), C8(238,4), C8(239,4),
+ C8(240,4), C8(241,4), C8(242,4), C8(243,4), C8(244,4), C8(245,4),
+ C8(246,4), C8(247,4), C8(248,4), C8(249,4), C8(250,4), C8(251,4),
+ C8(252,4), C8(253,4), C8(254,4), C8(255,4),
+};
+const FbBits fbStipple8Bits[256] = {
+ C8( 0,8), C8( 1,8), C8( 2,8), C8( 3,8), C8( 4,8), C8( 5,8),
+ C8( 6,8), C8( 7,8), C8( 8,8), C8( 9,8), C8( 10,8), C8( 11,8),
+ C8( 12,8), C8( 13,8), C8( 14,8), C8( 15,8), C8( 16,8), C8( 17,8),
+ C8( 18,8), C8( 19,8), C8( 20,8), C8( 21,8), C8( 22,8), C8( 23,8),
+ C8( 24,8), C8( 25,8), C8( 26,8), C8( 27,8), C8( 28,8), C8( 29,8),
+ C8( 30,8), C8( 31,8), C8( 32,8), C8( 33,8), C8( 34,8), C8( 35,8),
+ C8( 36,8), C8( 37,8), C8( 38,8), C8( 39,8), C8( 40,8), C8( 41,8),
+ C8( 42,8), C8( 43,8), C8( 44,8), C8( 45,8), C8( 46,8), C8( 47,8),
+ C8( 48,8), C8( 49,8), C8( 50,8), C8( 51,8), C8( 52,8), C8( 53,8),
+ C8( 54,8), C8( 55,8), C8( 56,8), C8( 57,8), C8( 58,8), C8( 59,8),
+ C8( 60,8), C8( 61,8), C8( 62,8), C8( 63,8), C8( 64,8), C8( 65,8),
+ C8( 66,8), C8( 67,8), C8( 68,8), C8( 69,8), C8( 70,8), C8( 71,8),
+ C8( 72,8), C8( 73,8), C8( 74,8), C8( 75,8), C8( 76,8), C8( 77,8),
+ C8( 78,8), C8( 79,8), C8( 80,8), C8( 81,8), C8( 82,8), C8( 83,8),
+ C8( 84,8), C8( 85,8), C8( 86,8), C8( 87,8), C8( 88,8), C8( 89,8),
+ C8( 90,8), C8( 91,8), C8( 92,8), C8( 93,8), C8( 94,8), C8( 95,8),
+ C8( 96,8), C8( 97,8), C8( 98,8), C8( 99,8), C8(100,8), C8(101,8),
+ C8(102,8), C8(103,8), C8(104,8), C8(105,8), C8(106,8), C8(107,8),
+ C8(108,8), C8(109,8), C8(110,8), C8(111,8), C8(112,8), C8(113,8),
+ C8(114,8), C8(115,8), C8(116,8), C8(117,8), C8(118,8), C8(119,8),
+ C8(120,8), C8(121,8), C8(122,8), C8(123,8), C8(124,8), C8(125,8),
+ C8(126,8), C8(127,8), C8(128,8), C8(129,8), C8(130,8), C8(131,8),
+ C8(132,8), C8(133,8), C8(134,8), C8(135,8), C8(136,8), C8(137,8),
+ C8(138,8), C8(139,8), C8(140,8), C8(141,8), C8(142,8), C8(143,8),
+ C8(144,8), C8(145,8), C8(146,8), C8(147,8), C8(148,8), C8(149,8),
+ C8(150,8), C8(151,8), C8(152,8), C8(153,8), C8(154,8), C8(155,8),
+ C8(156,8), C8(157,8), C8(158,8), C8(159,8), C8(160,8), C8(161,8),
+ C8(162,8), C8(163,8), C8(164,8), C8(165,8), C8(166,8), C8(167,8),
+ C8(168,8), C8(169,8), C8(170,8), C8(171,8), C8(172,8), C8(173,8),
+ C8(174,8), C8(175,8), C8(176,8), C8(177,8), C8(178,8), C8(179,8),
+ C8(180,8), C8(181,8), C8(182,8), C8(183,8), C8(184,8), C8(185,8),
+ C8(186,8), C8(187,8), C8(188,8), C8(189,8), C8(190,8), C8(191,8),
+ C8(192,8), C8(193,8), C8(194,8), C8(195,8), C8(196,8), C8(197,8),
+ C8(198,8), C8(199,8), C8(200,8), C8(201,8), C8(202,8), C8(203,8),
+ C8(204,8), C8(205,8), C8(206,8), C8(207,8), C8(208,8), C8(209,8),
+ C8(210,8), C8(211,8), C8(212,8), C8(213,8), C8(214,8), C8(215,8),
+ C8(216,8), C8(217,8), C8(218,8), C8(219,8), C8(220,8), C8(221,8),
+ C8(222,8), C8(223,8), C8(224,8), C8(225,8), C8(226,8), C8(227,8),
+ C8(228,8), C8(229,8), C8(230,8), C8(231,8), C8(232,8), C8(233,8),
+ C8(234,8), C8(235,8), C8(236,8), C8(237,8), C8(238,8), C8(239,8),
+ C8(240,8), C8(241,8), C8(242,8), C8(243,8), C8(244,8), C8(245,8),
+ C8(246,8), C8(247,8), C8(248,8), C8(249,8), C8(250,8), C8(251,8),
+ C8(252,8), C8(253,8), C8(254,8), C8(255,8),
+};
+const FbBits fbStipple4Bits[16] = {
+ C4( 0,16), C4( 1,16), C4( 2,16), C4( 3,16), C4( 4,16), C4( 5,16),
+ C4( 6,16), C4( 7,16), C4( 8,16), C4( 9,16), C4( 10,16), C4( 11,16),
+ C4( 12,16), C4( 13,16), C4( 14,16), C4( 15,16),};
+const FbBits fbStipple2Bits[4] = {
+ C2( 0,32), C2( 1,32), C2( 2,32), C2( 3,32),
+};
+#define fbStipple1Bits 0
+#endif
+const FbBits * const fbStippleTable[] = {
+ 0,
+ fbStipple1Bits,
+ fbStipple2Bits,
+ 0,
+ fbStipple4Bits,
+ 0,
+ 0,
+ 0,
+ fbStipple8Bits,
+};
diff --git a/nx-X11/programs/Xserver/fb/fbwindow.c b/nx-X11/programs/Xserver/fb/fbwindow.c
new file mode 100644
index 000000000..c4e28de5b
--- /dev/null
+++ b/nx-X11/programs/Xserver/fb/fbwindow.c
@@ -0,0 +1,349 @@
+/*
+ * Id: fbwindow.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+Bool
+fbCreateWindow(WindowPtr pWin)
+{
+#ifndef FB_NO_WINDOW_PIXMAPS
+ pWin->devPrivates[fbWinPrivateIndex].ptr =
+ (void *) fbGetScreenPixmap(pWin->drawable.pScreen);
+#endif
+#ifdef FB_SCREEN_PRIVATE
+ if (pWin->drawable.bitsPerPixel == 32)
+ pWin->drawable.bitsPerPixel = fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
+#endif
+ return TRUE;
+}
+
+Bool
+fbDestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+fbMapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+Bool
+fbPositionWindow(WindowPtr pWin, int x, int y)
+{
+ return TRUE;
+}
+
+Bool
+fbUnmapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+void
+fbCopyWindowProc (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ while (nbox--)
+ {
+ fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (pbox->x1 + dx + srcXoff) * srcBpp,
+
+ dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+
+ (pbox->x2 - pbox->x1) * dstBpp,
+ (pbox->y2 - pbox->y1),
+
+ GXcopy,
+ FB_ALLONES,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+ pbox++;
+ }
+}
+
+void
+fbCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ RegionRec rgnDst;
+ int dx, dy;
+
+ PixmapPtr pPixmap = fbGetWindowPixmap (pWin);
+ DrawablePtr pDrawable = &pPixmap->drawable;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ RegionTranslate(prgnSrc, -dx, -dy);
+
+ RegionNull(&rgnDst);
+
+ RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
+
+#ifdef COMPOSITE
+ if (pPixmap->screen_x || pPixmap->screen_y)
+ RegionTranslate(&rgnDst,
+ -pPixmap->screen_x, -pPixmap->screen_y);
+#endif
+
+ fbCopyRegion (pDrawable, pDrawable,
+ 0,
+ &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
+
+ RegionUninit(&rgnDst);
+ fbValidateDrawable (&pWin->drawable);
+}
+
+Bool
+fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
+{
+ PixmapPtr pPixmap;
+
+ if (mask & CWBackPixmap)
+ {
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pPixmap = pWin->background.pixmap;
+#ifdef FB_24_32BIT
+ if (pPixmap->drawable.bitsPerPixel != pWin->drawable.bitsPerPixel)
+ {
+ pPixmap = fb24_32ReformatTile (pPixmap,
+ pWin->drawable.bitsPerPixel);
+ if (pPixmap)
+ {
+ (*pWin->drawable.pScreen->DestroyPixmap) (pWin->background.pixmap);
+ pWin->background.pixmap = pPixmap;
+ }
+ }
+#endif
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ fbPadPixmap (pPixmap);
+ }
+ }
+ if (mask & CWBorderPixmap)
+ {
+ if (pWin->borderIsPixel == FALSE)
+ {
+ pPixmap = pWin->border.pixmap;
+#ifdef FB_24_32BIT
+ if (pPixmap->drawable.bitsPerPixel !=
+ pWin->drawable.bitsPerPixel)
+ {
+ pPixmap = fb24_32ReformatTile (pPixmap,
+ pWin->drawable.bitsPerPixel);
+ if (pPixmap)
+ {
+ (*pWin->drawable.pScreen->DestroyPixmap) (pWin->border.pixmap);
+ pWin->border.pixmap = pPixmap;
+ }
+ }
+#endif
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ fbPadPixmap (pPixmap);
+ }
+ }
+ return TRUE;
+}
+
+void
+fbFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ FbBits and,
+ FbBits xor)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int n = RegionNumRects(pRegion);
+ BoxPtr pbox = RegionRects(pRegion);
+
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ while (n--)
+ {
+ fbSolid (dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+ dstBpp,
+ (pbox->x2 - pbox->x1) * dstBpp,
+ pbox->y2 - pbox->y1,
+ and, xor);
+ fbValidateDrawable (pDrawable);
+ pbox++;
+ }
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+void
+fbFillRegionTiled (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ PixmapPtr pTile)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbBits *tile;
+ FbStride tileStride;
+ int tileBpp;
+ _X_UNUSED int tileXoff, tileYoff; /* XXX assumed to be zero */
+ int tileWidth, tileHeight;
+ int n = RegionNumRects(pRegion);
+ BoxPtr pbox = RegionRects(pRegion);
+ int xRot = pDrawable->x;
+ int yRot = pDrawable->y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ {
+ int index = pDrawable->pScreen->myNum;
+ if(&screenInfo.screens[index]->root->drawable == pDrawable)
+ {
+ xRot -= panoramiXdataPtr[index].x;
+ yRot -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ xRot += dstXoff;
+ yRot += dstYoff;
+
+ while (n--)
+ {
+ fbTile (dst + (pbox->y1 + dstYoff) * dstStride,
+ dstStride,
+ (pbox->x1 + dstXoff) * dstBpp,
+ (pbox->x2 - pbox->x1) * dstBpp,
+ pbox->y2 - pbox->y1,
+ tile,
+ tileStride,
+ tileWidth * dstBpp,
+ tileHeight,
+ GXcopy,
+ FB_ALLONES,
+ dstBpp,
+ xRot * dstBpp,
+ yRot - (pbox->y1 + dstYoff));
+ pbox++;
+ }
+}
+
+void
+fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ WindowPtr pBgWin;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ break;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ break;
+ case BackgroundPixmap:
+ fbFillRegionTiled (&pWin->drawable,
+ pRegion,
+ pWin->background.pixmap);
+ break;
+ case BackgroundPixel:
+ fbFillRegionSolid (&pWin->drawable,
+ pRegion,
+ 0,
+ fbReplicatePixel (pWin->background.pixel,
+ pWin->drawable.bitsPerPixel));
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ fbFillRegionSolid (&pWin->drawable,
+ pRegion,
+ 0,
+ fbReplicatePixel (pWin->border.pixel,
+ pWin->drawable.bitsPerPixel));
+ }
+ else
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+
+ fbFillRegionTiled (&pBgWin->drawable,
+ pRegion,
+ pWin->border.pixmap);
+ }
+ break;
+ }
+ fbValidateDrawable (&pWin->drawable);
+}
diff --git a/nx-X11/programs/Xserver/fix-miregion b/nx-X11/programs/Xserver/fix-miregion
new file mode 100755
index 000000000..fc502bbfd
--- /dev/null
+++ b/nx-X11/programs/Xserver/fix-miregion
@@ -0,0 +1,29 @@
+#!/bin/sh
+sed -i \
+-e 's/miRegionCreate\b/RegionCreate/g' \
+-e 's/miRegionInit\b/RegionInit/g' \
+-e 's/miRegionDestroy\b/RegionDestroy/g' \
+-e 's/miRegionUninit\b/RegionUninit/g' \
+-e 's/miRegionCopy\b/RegionCopy/g' \
+-e 's/miIntersect\b/RegionIntersect/g' \
+-e 's/miUnion\b/RegionUnion/g' \
+-e 's/miRegionAppend\b/RegionAppend/g' \
+-e 's/miRegionValidate\b/RegionValidate/g' \
+-e 's/miRectsToRegion\b/RegionFromRects/g' \
+-e 's/miSubtract\b/RegionSubtract/g' \
+-e 's/miInverse\b/RegionInverse/g' \
+-e 's/miRectIn\b/RegionContainsRect/g' \
+-e 's/miTranslateRegion\b/RegionTranslate/g' \
+-e 's/miRegionReset\b/RegionReset/g' \
+-e 's/miRegionBreak\b/RegionBreak/g' \
+-e 's/miPointInRegion\b/RegionContainsPoint/g' \
+-e 's/miRegionEqual\b/RegionEqual/g' \
+-e 's/miRegionNotEmpty\b/RegionNotEmpty/g' \
+-e 's/miRegionEmpty\b/RegionEmpty/g' \
+-e 's/miRegionExtents\b/RegionExtents/g' \
+-e 's/miPrintRegion\b/RegionPrint/g' \
+-e 's/miRectAlloc\b/RegionRectAlloc/g' \
+-e 's/miValidRegion\b/RegionIsValid/g' \
+-e 's/miRegionBroken\b/RegionBroken/g' \
+-e 's/miClipSpans\b/RegionClipSpans/g' \
+"$@"
diff --git a/nx-X11/programs/Xserver/fix-miregion-private b/nx-X11/programs/Xserver/fix-miregion-private
new file mode 100755
index 000000000..ebc24fac0
--- /dev/null
+++ b/nx-X11/programs/Xserver/fix-miregion-private
@@ -0,0 +1,14 @@
+#!/bin/sh
+sed -i \
+-e 's/miEmptyBox\b/RegionEmptyBox/g' \
+-e 's/miEmptyData\b/RegionEmptyData/g' \
+-e 's/miBrokenData\b/RegionBrokenData/g' \
+-e 's/miBrokenRegion\b/RegionBrokenRegion/g' \
+-e 's/miCoalesce\b/RegionCoalesce/g' \
+-e 's/miAppendNonO\b/RegionAppendNonO/g' \
+-e 's/miRegionOp\b/RegionOp/g' \
+-e 's/miSetExtents\b/RegionSetExtents/g' \
+-e 's/miIntersectO\b/RegionIntersectO/g' \
+-e 's/miUnionO\b/RegionUnionO/g' \
+-e 's/miSubtractO\b/RegionSubtractO/g' \
+"$@"
diff --git a/nx-X11/programs/Xserver/fix-region b/nx-X11/programs/Xserver/fix-region
new file mode 100755
index 000000000..61fe6e0fb
--- /dev/null
+++ b/nx-X11/programs/Xserver/fix-region
@@ -0,0 +1,40 @@
+#!/bin/sh
+sed -i \
+ -e 's/REGION_NIL\b/RegionNil/g' \
+ -e 's/REGION_NAR\b/RegionNar/g' \
+ -e 's/REGION_NUM_RECTS\b/RegionNumRects/g' \
+ -e 's/REGION_SIZE\b/RegionSize/g' \
+ -e 's/REGION_RECTS\b/RegionRects/g' \
+ -e 's/REGION_BOXPTR\b/RegionBoxptr/g' \
+ -e 's/REGION_BOX\b/RegionBox/g' \
+ -e 's/REGION_TOP\b/RegionTop/g' \
+ -e 's/REGION_END\b/RegionEnd/g' \
+ -e 's/REGION_SZOF\b/RegionSizeof/g' \
+ -e 's/REGION_CREATE *([^,]*, */RegionCreate(/g' \
+ -e 's/REGION_COPY *([^,]*, */RegionCopy(/g' \
+ -e 's/REGION_DESTROY *([^,]*, */RegionDestroy(/g' \
+ -e 's/REGION_INTERSECT *([^,]*, */RegionIntersect(/g' \
+ -e 's/REGION_UNION *([^,]*, */RegionUnion(/g' \
+ -e 's/REGION_SUBTRACT *([^,]*, */RegionSubtract(/g' \
+ -e 's/REGION_INVERSE *([^,]*, */RegionInverse(/g' \
+ -e 's/REGION_TRANSLATE *([^,]*, */RegionTranslate(/g' \
+ -e 's/RECT_IN_REGION *([^,]*, */RegionContainsRect(/g' \
+ -e 's/POINT_IN_REGION *([^,]*, */RegionContainsPoint(/g' \
+ -e 's/REGION_EQUAL *([^,]*, */RegionEqual(/g' \
+ -e 's/REGION_APPEND *([^,]*, */RegionAppend(/g' \
+ -e 's/REGION_VALIDATE *([^,]*, */RegionValidate(/g' \
+ -e 's/BITMAP_TO_REGION\b/BitmapToRegion/g' \
+ -e 's/RECTS_TO_REGION *([^,]*, */RegionFromRects(/g' \
+ -e 's/REGION_BREAK *([^,]*, */RegionBreak(/g' \
+ -e 's/REGION_INIT *([^,]*, */RegionInit(/g' \
+ -e 's/REGION_UNINIT *([^,]*, */RegionUninit(/g' \
+ -e 's/REGION_RESET *([^,]*, */RegionReset(/g' \
+ -e 's/REGION_NOTEMPTY *([^,]*, */RegionNotEmpty(/g' \
+ -e 's/REGION_BROKEN *([^,]*, */RegionBroken(/g' \
+ -e 's/REGION_EMPTY *([^,]*, */RegionEmpty(/g' \
+ -e 's/REGION_EXTENTS *([^,]*, */RegionExtents(/g' \
+ -e 's/REGION_NUM_RECTS *([^,]*, */RegionNumRects(/g' \
+ -e 's/REGION_RECTS *([^,]*, */RegionRects(/g' \
+ -e 's/REGION_NULL *([^,]*, */RegionNull(/g' \
+ -e 's/REGION_NULL$/RegionNull/g' \
+ "$@"
diff --git a/nx-X11/programs/Xserver/hw/nxagent/.gitignore b/nx-X11/programs/Xserver/hw/nxagent/.gitignore
new file mode 100644
index 000000000..256534b63
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/.gitignore
@@ -0,0 +1,3 @@
+miinitext.c
+stubs.c
+xpstubs.c
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
new file mode 100644
index 000000000..af8b62810
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -0,0 +1,136 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright (c) 1995 X Consortium
+
+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 THE X CONSORTIUM 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 X Consortium 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 X Consortium.
+
+*/
+
+#ifndef __Agent_H__
+#define __Agent_H__
+
+/*
+ * Machines with a 64 bit library interface and a 32 bit
+ * server require name changes to protect the guilty.
+ */
+
+#ifdef _XSERVER64
+#define _XSERVER64_tmp
+#undef _XSERVER64
+typedef unsigned long XID64;
+typedef unsigned long Mask64;
+typedef unsigned long Atom64;
+typedef unsigned long VisualID64;
+typedef unsigned long Time64;
+#define XID XID64
+#define Mask Mask64
+#define Atom Atom64
+#define VisualID VisualID64
+#define Time Time64
+typedef XID Window64;
+typedef XID Drawable64;
+typedef XID Font64;
+typedef XID Pixmap64;
+typedef XID Cursor64;
+typedef XID Colormap64;
+typedef XID GContext64;
+typedef XID KeySym64;
+#define Window Window64
+#define Drawable Drawable64
+#define Font Font64
+#define Pixmap Pixmap64
+#define Cursor Cursor64
+#define Colormap Colormap64
+#define GContext GContext64
+#define KeySym KeySym64
+
+#define XlibAtom Atom64
+#define XlibWindow Window64
+#define XlibPixmap Pixmap64
+#define XlibFont Font64
+#define XlibKeySym KeySym64
+#define XlibXID XID64
+
+#else /*_XSERVER64*/
+
+#define XlibAtom Atom
+#define XlibWindow Window
+#define XlibPixmap Pixmap
+#define XlibFont Font
+#define XlibKeySym KeySym
+#define XlibXID XID
+
+#endif /*_XSERVER64*/
+
+#define NX_TRANS_SOCKET
+#define GC XlibGC
+#include <nx-X11/Xlib.h>
+#include <X11/extensions/shape.h>
+#undef GC
+
+#ifdef _XSERVER64_tmp
+#define _XSERVER64
+#undef _XSERVER64_tmp
+#undef XID
+#undef Mask
+#undef Atom
+#undef VisualID
+#undef Time
+#undef Window
+#undef Drawable
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef KeySym
+#endif /*_XSERVER64_tmp*/
+
+#endif /* __Agent_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
new file mode 100644
index 000000000..5db7e0110
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -0,0 +1,2613 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef __sun
+#include <strings.h>
+#endif
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "globals.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "servermd.h"
+#include "opaque.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Args.h"
+#include "Options.h"
+#include "Binder.h"
+#include "Trap.h"
+#include "Screen.h"
+#include "Image.h"
+#ifdef RENDER
+#include "Render.h"
+#endif
+#include "Handlers.h"
+#include "Error.h"
+#include "Reconnect.h"
+#include "Utils.h"
+
+/*
+ * NX includes and definitions.
+ */
+
+#include "compext/Compext.h"
+#include <nx/NXpack.h>
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef WATCH
+
+#ifdef WATCH
+
+#include "unistd.h"
+
+#endif
+
+#ifdef PANORAMIX
+ #define PANORAMIX_DISABLED_COND (noPanoramiXExtension || PanoramiXExtensionDisabledHack)
+#else
+ #define PANORAMIX_DISABLED_COND TRUE
+#endif
+
+#ifdef RANDR
+ #define RRXINERAMA_DISABLED_COND noRRXineramaExtension
+#else
+ #define RRXINERAMA_DISABLED_COND TRUE
+#endif
+
+/*
+ * Define this to force the dispatcher
+ * to always use the dumb scheduler.
+ */
+
+#undef DISABLE_SMART_SCHEDULE
+
+int nxagentUserDefinedFontPath = 0;
+
+/*
+ * From X11/ImUtil.c.
+ */
+
+extern int _XGetBitsPerPixel(Display *dpy, int depth);
+
+extern char dispatchExceptionAtReset;
+
+extern const char *__progname;
+
+char nxagentDisplayName[1024];
+Bool nxagentSynchronize = False;
+
+char nxagentShadowDisplayName[1024] = {0};
+
+char nxagentWindowName[256];
+char nxagentDialogName[256];
+char nxagentSessionId[256] = {0};
+char *nxagentOptionFile;
+
+Bool nxagentFullGeneration = False;
+int nxagentDefaultClass = TrueColor;
+Bool nxagentUserDefaultClass = False;
+int nxagentDefaultDepth;
+Bool nxagentUserDefaultDepth = False;
+struct UserGeometry nxagentUserGeometry = {0, 0, 0, 0, 0};
+Bool nxagentUserBorderWidth = False;
+int nxagentNumScreens = 0;
+Bool nxagentDoDirectColormaps = False;
+Window nxagentParentWindow = 0;
+Bool nxagentIpaq = False;
+
+int nxagentLockDeferLevel = 0;
+
+Bool nxagentResizeDesktopAtStartup = False;
+
+Bool nxagentUseNXTrans = False;
+Bool nxagentForceNXTrans = False;
+
+int nxagentMaxAllowedResets = 0;
+
+char *nxagentKeyboard = NULL;
+
+Bool nxagentOnce = True;
+
+int nxagentRemoteMajor = -1;
+
+static void nxagentParseOptionString(char*);
+
+/*
+ * Get the caption to be used for helper dialogs
+ * from agent's window name passed as parameter.
+ */
+
+static int nxagentGetDialogName(void);
+
+char nxagentVerbose = 0;
+
+char *nxagentKeystrokeFile = NULL;
+
+int ddxProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Ensure that the options are set to their defaults.
+ */
+
+ static Bool resetOptions = True;
+
+ if (resetOptions == True)
+ {
+ char *envOptions = NULL;
+ char *envDisplay = NULL;
+ int j;
+
+ nxagentInitOptions();
+
+ resetOptions = False;
+
+ /*
+ * Ensure the correct order of options evaluation:
+ * the environment first, then those included in
+ * the options file and, last, the command line
+ * options.
+ */
+
+ envDisplay = getenv("DISPLAY");
+
+ if (envDisplay != NULL && strlen(envDisplay) == 0)
+ {
+ envDisplay = NULL;
+ }
+
+ for (j = 0; j < argc; j++)
+ {
+ if ((!strcmp(argv[j], "-display")) && (j + 1 < argc))
+ {
+ envOptions = malloc(strlen(argv[j + 1]) + 1);
+
+ if (envOptions != NULL)
+ {
+ envOptions = strcpy(envOptions, argv[j + 1]);
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+ }
+ #endif
+
+ break;
+ }
+ }
+
+ if ((envOptions == NULL) && (envDisplay != NULL))
+ {
+ envOptions = malloc(strlen(envDisplay) + 1);
+
+ if (envOptions != NULL)
+ {
+ envOptions = strcpy(envOptions, envDisplay);
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+ }
+ #endif
+ }
+
+ if (envOptions != NULL)
+ {
+ nxagentParseOptionString(envOptions);
+
+ free(envOptions);
+ }
+
+ for (j = 0; j < argc; j++)
+ {
+ if ((!strcmp(argv[j], "-options") || !strcmp(argv[j], "-option")) && j + 1 < argc)
+ {
+ if (nxagentOptionFile)
+ {
+ nxagentOptionFile = (char *) realloc(nxagentOptionFile, strlen(argv[j + 1]) + 1);
+ }
+ else
+ {
+ nxagentOptionFile = (char *) malloc(strlen(argv[j + 1]) +1);
+ }
+
+ if (nxagentOptionFile != NULL)
+ {
+ nxagentOptionFile = strcpy(nxagentOptionFile, argv[j + 1]);
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+ }
+ #endif
+
+ break;
+ }
+ }
+
+ if (nxagentOptionFile)
+ {
+ nxagentProcessOptionsFile();
+ }
+ }
+
+ if (!strcmp(argv[i], "-B"))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ddxProcessArgument: Checking the NX binder option.\n");
+ #endif
+
+ if (nxagentCheckBinder(argc, argv, i) > 0)
+ {
+ /*
+ * We are going to run the agent with the
+ * 'binder' option. Go straight to the
+ * proxy loop.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "ddxProcessArgument: Entering the NX proxy binder loop.\n");
+ #endif
+
+ nxagentBinderLoop();
+
+ /*
+ * This will make an exit.
+ */
+
+ nxagentBinderExit(0);
+ }
+ else
+ {
+ /*
+ * Exit with an error.
+ */
+
+ nxagentBinderExit(1);
+ }
+ }
+
+ if (!strcmp(argv[i], "-display"))
+ {
+ if (++i < argc)
+ {
+ strncpy(nxagentDisplayName, argv[i], 1023);
+
+ nxagentDisplayName[1023] = '\0';
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-id"))
+ {
+ if (++i < argc)
+ {
+ strncpy(nxagentSessionId, argv[i], 255);
+
+ *(nxagentSessionId + 255) = '\0';
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ /*
+ * This had to be '-options' since the beginning
+ * but was '-option' by mistake. Now we have to
+ * handle the backward compatibility.
+ */
+
+ if (!strcmp(argv[i], "-options") || !strcmp(argv[i], "-option"))
+ {
+ if (++i < argc)
+ {
+ int size;
+
+ if (nxagentOptionFile != NULL)
+ {
+ free(nxagentOptionFile);
+
+ nxagentOptionFile = NULL;
+ }
+
+ if ((size = strlen(argv[i])) < 1024)
+ {
+ if ((nxagentOptionFile = malloc(size + 1)) == NULL)
+ {
+ FatalError("malloc failed");
+ }
+
+ strncpy(nxagentOptionFile, argv[i], size);
+
+ nxagentOptionFile[size] = '\0';
+ }
+ else
+ {
+ /*
+ * It is useless to store the file name
+ * that has just been truncated.
+ */
+
+ #ifdef WARNING
+ fprintf(stderr, "ddxProcessArgument: WARNING! Option file name "
+ "too long. It will be ignored.\n");
+ #endif
+ }
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-sync")) {
+ nxagentSynchronize = True;
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-full")) {
+ nxagentFullGeneration = True;
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-class")) {
+ if (++i < argc) {
+ if (!strcmp(argv[i], "StaticGray")) {
+ nxagentDefaultClass = StaticGray;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "GrayScale")) {
+ nxagentDefaultClass = GrayScale;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "StaticColor")) {
+ nxagentDefaultClass = StaticColor;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "PseudoColor")) {
+ nxagentDefaultClass = PseudoColor;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "TrueColor")) {
+ nxagentDefaultClass = TrueColor;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "DirectColor")) {
+ nxagentDefaultClass = DirectColor;
+ nxagentUserDefaultClass = True;
+ return 2;
+ }
+ }
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-cc")) {
+ if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultClass) == 1) {
+ if (nxagentDefaultClass >= 0 && nxagentDefaultClass <= 5) {
+ nxagentUserDefaultClass = True;
+ /* lex the OS layer process it as well, so return 0 */
+ }
+ }
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-depth")) {
+ if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultDepth) == 1) {
+ if (nxagentDefaultDepth > 0) {
+ nxagentUserDefaultDepth = True;
+ return 2;
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * These options are now useless and are
+ * parsed only for compatibility with
+ * older versions.
+ */
+
+ if (!strcmp(argv[i], "-fast") ||
+ !strcmp(argv[i], "-slow") ||
+ !strcmp(argv[i], "-hint") ||
+ !strcmp(argv[i], "-sss"))
+ {
+ fprintf(stderr, "Warning: Ignoring deprecated command line option '%s'.\n",
+ argv[i]);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-backingstore"))
+ {
+ if (++i < argc)
+ {
+ if (!strcmp(argv[i], "0"))
+ {
+ nxagentChangeOption(BackingStore, BackingStoreNever);
+ }
+ else
+ {
+ nxagentChangeOption(BackingStore, BackingStoreForce);
+ }
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-streaming"))
+ {
+ if (++i < argc)
+ {
+ if (!strcmp(argv[i], "0"))
+ {
+ nxagentChangeOption(Streaming, 0);
+ }
+ else
+ {
+ nxagentChangeOption(Streaming, 1);
+ }
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-defer"))
+ {
+ int level;
+
+ if (++i < argc &&
+ sscanf(argv[i], "%i", &level) == 1 &&
+ level >= 0 && level <= 2)
+ {
+ if (nxagentOption(Shadow) == 0)
+ {
+ nxagentChangeOption(DeferLevel, level);
+
+ /*
+ * The defer level set with the command
+ * line is not changed when the session
+ * is resumed.
+ */
+
+ nxagentLockDeferLevel = 1;
+ }
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-irlimit"))
+ {
+ int limit;
+
+ if (++i < argc &&
+ sscanf(argv[i], "%i", &limit) == 1)
+ {
+ nxagentChangeOption(ImageRateLimit, limit);
+
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-tile"))
+ {
+ int width;
+ int height;
+
+ if (++i < argc &&
+ sscanf(argv[i], "%ix%i", &width, &height) == 2 &&
+ width >= 32 && height >= 32)
+ {
+ nxagentChangeOption(TileWidth, width);
+ nxagentChangeOption(TileHeight, height);
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (strcmp(argv[i], "-fp") == 0)
+ {
+ if(++i < argc)
+ {
+
+ #ifdef TEST
+ fprintf(stderr, "ddxProcessArgument: User defined font path [%s].\n", argv[i]);
+ #endif
+
+ nxagentUserDefinedFontPath = 1;
+
+ defaultFontPath = argv[i];
+ }
+ else
+ {
+ UseMsg();
+ }
+ }
+
+ if (!strcmp(argv[i], "-geometry"))
+ {
+ if (++i < argc)
+ {
+ if (!strcmp(argv[i],"fullscreen"))
+ {
+ nxagentChangeOption(Fullscreen, True);
+
+ nxagentChangeOption(AllScreens, True);
+ }
+ else if (!strcmp(argv[i],"ipaq"))
+ {
+ nxagentChangeOption(Fullscreen, True);
+
+ nxagentChangeOption(AllScreens, True);
+
+ nxagentIpaq = True;
+ }
+ else
+ {
+ if (nxagentUserGeometry.flag == 0)
+ {
+ nxagentUserGeometry.flag = XParseGeometry(argv[i],
+ &nxagentUserGeometry.X,
+ &nxagentUserGeometry.Y,
+ &nxagentUserGeometry.Width,
+ &nxagentUserGeometry.Height);
+ }
+ }
+
+ if (nxagentUserGeometry.flag || (nxagentOption(Fullscreen) == 1)) return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-bw"))
+ {
+ int BorderWidth;
+
+ if (++i < argc && sscanf(argv[i], "%i", &BorderWidth) == 1)
+ {
+ nxagentChangeOption(BorderWidth, BorderWidth);
+
+ if (nxagentOption(BorderWidth) >= 0)
+ {
+ nxagentUserBorderWidth = True;
+
+ return 2;
+ }
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-name"))
+ {
+ if (++i < argc)
+ {
+ strncpy(nxagentWindowName, argv[i], 255);
+
+ *(nxagentWindowName + 255) = '\0';
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-scrns")) {
+ if (++i < argc && sscanf(argv[i], "%i", &nxagentNumScreens) == 1) {
+ if (nxagentNumScreens > 0) {
+ if (nxagentNumScreens > MAXSCREENS) {
+ ErrorF("Maximum number of screens is %d.\n", MAXSCREENS);
+ nxagentNumScreens = MAXSCREENS;
+ }
+ return 2;
+ }
+ }
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-install")) {
+ nxagentDoDirectColormaps = True;
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-parent")) {
+ if (++i < argc) {
+ nxagentParentWindow = (XID) strtol (argv[i], (char**)NULL, 0);
+ return 2;
+ }
+ }
+
+ if (!strcmp(argv[i], "-forcenx")) {
+ nxagentForceNXTrans = True;
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-norootlessexit")) {
+ nxagentChangeOption(NoRootlessExit, True);
+ return 1;
+ }
+
+
+ if (!strcmp(argv[i], "-noonce"))
+ {
+ nxagentOnce = False;
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-kbtype") ||
+ !strcmp(argv[i], "-keyboard"))
+ {
+ if (++i < argc)
+ {
+ int size;
+
+ if (nxagentKeyboard != NULL)
+ {
+ free(nxagentKeyboard);
+
+ nxagentKeyboard = NULL;
+ }
+
+ if ((size = strlen(argv[i])) < 256)
+ {
+ if ((nxagentKeyboard = malloc(size + 1)) == NULL)
+ {
+ FatalError("malloc failed");
+ }
+
+ strncpy(nxagentKeyboard, argv[i], size);
+
+ nxagentKeyboard[size] = '\0';
+ }
+ #ifdef WARNING
+ else
+ {
+ /*
+ * it is useless to remember a kbtype
+ * option that has just been truncated.
+ */
+
+ fprintf(stderr, "ddxProcessArgument: WARNING! Option [%s] too long. "
+ "It will be ignored.\n", argv[i]);
+ }
+ #endif
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-extensions"))
+ {
+ return 1;
+ }
+
+ #ifdef RENDER
+ if (!strcmp(argv[i], "-norender"))
+ {
+ nxagentRenderEnable = False;
+
+ return 1;
+ }
+ #endif
+
+ if (!strcmp(argv[i], "-nocomposite"))
+ {
+ nxagentChangeOption(Composite, 0);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-nodamage"))
+ {
+ nxagentChangeOption(UseDamage, 0);
+
+ return 1;
+ }
+
+ /*
+ * The original -noreset option, disabling
+ * dispatchExceptionAtReset, is the default.
+ * Use this option to restore the original
+ * behaviour.
+ */
+
+ if (!strcmp(argv[i], "-reset"))
+ {
+ nxagentChangeOption(Reset, True);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-persistent"))
+ {
+ nxagentChangeOption(Persistent, True);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-nopersistent"))
+ {
+ nxagentChangeOption(Persistent, False);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-noshmem"))
+ {
+ nxagentChangeOption(SharedMemory, False);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-shmem"))
+ {
+ nxagentChangeOption(SharedMemory, True);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-noignore"))
+ {
+ nxagentChangeOption(DeviceControl, True);
+
+ nxagentChangeOption(DeviceControlUserDefined , True);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-nokbreset"))
+ {
+ nxagentChangeOption(ResetKeyboardAtResume, False);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-noxkblock"))
+ {
+ nxagentChangeOption(InhibitXkb, 0);
+
+ return 1;
+ }
+
+ /*
+ * Enable pseudo-rootless mode.
+ */
+
+ if (!strcmp(argv[i], "-R"))
+ {
+ if (nxagentOption(Binder) == UNDEFINED ||
+ nxagentOption(Desktop) == UNDEFINED ||
+ nxagentOption(Rootless) == UNDEFINED)
+ {
+ nxagentChangeOption(Binder, False);
+ nxagentChangeOption(Desktop, False);
+ nxagentChangeOption(Rootless, True);
+ }
+ return 1;
+ }
+
+ /*
+ * Enable the "desktop" mode. This is
+ * the default.
+ */
+
+ if (!strcmp(argv[i], "-D"))
+ {
+ nxagentChangeOption(Binder, False);
+ nxagentChangeOption(Rootless, False);
+ nxagentChangeOption(Desktop, True);
+
+ return 1;
+ }
+
+ /*
+ * Enable the "shadow" mode.
+ */
+
+ if (!strcmp(argv[i], "-S"))
+ {
+ nxagentChangeOption(Shadow, 1);
+ nxagentChangeOption(DeferLevel, 0);
+ nxagentChangeOption(Persistent, 0);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-shadow"))
+ {
+ if (++i < argc)
+ {
+ strncpy(nxagentShadowDisplayName, argv[i], 1023);
+
+ if (strcmp(nxagentShadowDisplayName, "") == 0)
+ {
+ FatalError("Invalid shadow display option");
+ }
+
+ *(nxagentShadowDisplayName + 1023) = '\0';
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+
+ if (!strcmp(argv[i], "-shadowmode"))
+ {
+ if (++i < argc)
+ {
+ if (!strcmp(argv[i], "0"))
+ {
+ nxagentChangeOption(ViewOnly, 1);
+ }
+ else
+ {
+ nxagentChangeOption(ViewOnly, 0);
+ }
+
+ return 2;
+ }
+
+ return 0;
+ }
+
+ /*
+ * Enable the auto-disconnect timeout.
+ */
+
+ if (!strcmp(argv[i], "-timeout"))
+ {
+ int seconds;
+
+ if (++i < argc && sscanf(argv[i], "%i", &seconds) == 1)
+ {
+ if (seconds >= 0)
+ {
+ if (seconds > 0 && seconds < 60)
+ {
+ seconds = 60;
+ }
+
+ nxagentChangeOption(Timeout, seconds);
+
+ return 2;
+ }
+ }
+
+ return 0;
+ }
+
+ /*
+ * The return value for -query, -broadcast and
+ * -indirect must be 0 to let the dix layer pro-
+ * cess these options.
+ */
+
+ if (!strcmp(argv[i], "-query"))
+
+ {
+ nxagentChangeOption(Desktop, True);
+ nxagentChangeOption(Xdmcp, True);
+
+ nxagentMaxAllowedResets = 0;
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-broadcast"))
+
+ {
+ nxagentChangeOption(Desktop, True);
+ nxagentChangeOption(Xdmcp, True);
+
+ nxagentMaxAllowedResets = 0;
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-indirect"))
+ {
+ nxagentChangeOption(Desktop, True);
+ nxagentChangeOption(Xdmcp, True);
+
+ nxagentMaxAllowedResets = 1;
+
+ return 0;
+ }
+
+ if (!strcmp(argv[i], "-noshpix"))
+ {
+ nxagentChangeOption(SharedPixmaps, False);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-shpix"))
+ {
+ nxagentChangeOption(SharedPixmaps, True);
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-clipboard"))
+ {
+ if ((!strcmp(argv[i+1], "both")) || (!strcmp(argv[i+1], "1")))
+ {
+ nxagentChangeOption(Clipboard, ClipboardBoth);
+ }
+ else if (!strcmp(argv[i+1], "client"))
+ {
+ nxagentChangeOption(Clipboard, ClipboardClient);
+ }
+ else if (!strcmp(argv[i+1], "server"))
+ {
+ nxagentChangeOption(Clipboard, ClipboardServer);
+ }
+ else if ((!strcmp(argv[i+1], "none")) || (!strcmp(argv[i+1], "1")))
+ {
+ nxagentChangeOption(Clipboard, ClipboardNone);
+ }
+ else
+ {
+ nxagentChangeOption(Clipboard, ClipboardBoth);
+ }
+
+ return 2;
+ }
+
+ if (!strcmp(argv[i], "-bs"))
+ {
+ nxagentChangeOption(BackingStore, BackingStoreNever);
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-verbose"))
+ {
+ nxagentVerbose = 1;
+
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "-keystrokefile"))
+ {
+ if (i + 1 < argc)
+ {
+ if (NULL != (nxagentKeystrokeFile = strdup(argv[i + 1])))
+ {
+ return 2;
+ } else {
+ FatalError("malloc failed");
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * Disable Xinerama (i.e. fake it in Screen.c) if somehow Xinerama support
+ * has been disabled on the cmdline.
+ */
+ if (PANORAMIX_DISABLED_COND && RRXINERAMA_DISABLED_COND)
+ nxagentChangeOption(Xinerama, 0);
+
+ return 0;
+}
+
+static void nxagentParseOptions(char *name, char *value)
+{
+ int size, argc;
+
+ char *argv[2] = { NULL, NULL };
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentParseOptions: Processing option '%s' = '%s'.\n",
+ validateString(name), validateString(value));
+ #endif
+
+ if (!strcmp(name, "kbtype") ||
+ !strcmp(name, "keyboard") ||
+ !strcmp(name, "id") ||
+ !strcmp(name, "display") ||
+ !strcmp(name, "clipboard") ||
+ !strcmp(name, "geometry") ||
+ !strcmp(name, "option") ||
+ !strcmp(name, "options") ||
+ !strcmp(name, "shadow") ||
+ !strcmp(name, "shadowmode") ||
+ !strcmp(name, "streaming") ||
+ !strcmp(name, "defer") ||
+ !strcmp(name, "tile"))
+ {
+ argv[1] = value;
+
+ argc = 2;
+ }
+ else if (!strcmp(name, "R") && !strcmp(value, "1"))
+ {
+ argc = 1;
+ }
+ else if (!strcmp(name, "fast") || !strcmp(name, "slow"))
+ {
+ fprintf(stderr, "Warning: Ignoring deprecated option '%s'.\n", name);
+
+ return;
+ }
+ else if (!strcmp(name, "render"))
+ {
+ if (nxagentReconnectTrap == True)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentParseOptions: Ignoring option 'render' at reconnection.\n");
+ #endif
+ }
+ else if (nxagentRenderEnable == UNDEFINED)
+ {
+ if (!strcmp(value, "1"))
+ {
+ nxagentRenderEnable = True;
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentRenderEnable = False;
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'render'.\n",
+ validateString(value));
+ }
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "state"))
+ {
+ setStatePath(value);
+ return;
+ }
+ else if (!strcmp(name, "fullscreen"))
+ {
+ if (nxagentReconnectTrap == True)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentParseOptions: Ignoring option 'fullscreen' at reconnection.\n");
+ #endif
+ }
+ else if (!strcmp(value, "1"))
+ {
+ nxagentChangeOption(Fullscreen, True);
+
+ nxagentChangeOption(AllScreens, True);
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(Fullscreen, False);
+
+ nxagentChangeOption(AllScreens, False);
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'fullscreen'.\n",
+ validateString(value));
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "shpix"))
+ {
+ if (!strcmp(value, "1"))
+ {
+ nxagentChangeOption(SharedPixmaps, True);
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(SharedPixmaps, False);
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shpix'.\n",
+ validateString(value));
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "shmem"))
+ {
+ if (!strcmp(value, "1"))
+ {
+ nxagentChangeOption(SharedMemory, True);
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(SharedMemory, False);
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shmem'.\n",
+ validateString(value));
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "composite"))
+ {
+ if (!strcmp(value, "1"))
+ {
+ nxagentChangeOption(Composite, 1);
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(Composite, 0);
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'composite'.\n",
+ validateString(value));
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "xinerama"))
+ {
+#if !defined(PANORAMIX) && !defined(RANDR)
+ nxagentChangeOption(Xinerama, 0);
+ fprintf(stderr, "Warning: No Xinerama support compiled into %s.\n", __progname);
+ return;
+#else
+ if (PANORAMIX_DISABLED_COND && RRXINERAMA_DISABLED_COND)
+ {
+ nxagentChangeOption(Xinerama, 0);
+ fprintf(stderr, "Warning: XINERAMA extension has been disabled on %s startup.\n", __progname);
+ return;
+ }
+
+ if (!strcmp(value, "1"))
+ {
+ nxagentChangeOption(Xinerama, 1);
+ return;
+ }
+ else if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(Xinerama, 0);
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'xinerama'.\n",
+ validateString(value));
+ }
+ return;
+#endif
+ }
+ else if (!strcmp(name, "resize"))
+ {
+ if (nxagentOption(DesktopResize) == 0 || strcmp(value, "0") == 0)
+ {
+ nxagentResizeDesktopAtStartup = 0;
+ }
+ else if (strcmp(value, "1") == 0)
+ {
+ nxagentResizeDesktopAtStartup = 1;
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'resize'.\n",
+ validateString(value));
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "backingstore"))
+ {
+ if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(BackingStore, BackingStoreNever);
+ }
+ else
+ {
+ nxagentChangeOption(BackingStore, BackingStoreForce);
+ }
+
+ return;
+ }
+ else if (!strcmp(name, "menu"))
+ {
+ if (!strcmp(value, "0"))
+ {
+ nxagentChangeOption(Menu, 0);
+ }
+ else
+ {
+ nxagentChangeOption(Menu, 1);
+ }
+
+ return;
+ }
+ else if (strcmp(name, "shadowuid") == 0)
+ {
+ nxagentShadowUid = atoi(value);
+
+ return;
+ }
+ else if (strcmp(name, "clients") == 0)
+ {
+ strcpy(nxagentClientsLogName, value);
+
+ return;
+ }
+ else if (strcmp(name, "client") == 0)
+ {
+ if (strcmp(value, "winnt") == 0 || strcmp(value, "windows") == 0)
+ {
+ nxagentChangeOption(ClientOs, ClientOsWinnt);
+ }
+ else if (strcmp(value, "linux") == 0)
+ {
+ nxagentChangeOption(ClientOs, ClientOsLinux);
+ }
+ else if (strcmp(value, "solaris") == 0)
+ {
+ nxagentChangeOption(ClientOs, ClientOsSolaris);
+ }
+ else if (strcmp(value, "macosx") == 0)
+ {
+ nxagentChangeOption(ClientOs, ClientOsMac);
+ }
+
+ return;
+ }
+ else if (strcmp(name, "copysize") == 0)
+ {
+ nxagentChangeOption(CopyBufferSize, atoi(value));
+
+ return;
+ }
+ else if (strcmp(name, "clipboard") == 0)
+ {
+ if ((strcmp(value, "both") == 0) || (strcmp(value, "1") == 0))
+ {
+ nxagentChangeOption(Clipboard, ClipboardBoth);
+ }
+ else if (strcmp(value, "client") == 0)
+ {
+ nxagentChangeOption(Clipboard, ClipboardClient);
+ }
+ else if (strcmp(value, "server") == 0)
+ {
+ nxagentChangeOption(Clipboard, ClipboardServer);
+ }
+ else if ((strcmp(value, "none") == 0) || (strcmp(value, "0") == 0))
+ {
+ nxagentChangeOption(Clipboard, ClipboardNone);
+ }
+ else
+ {
+ nxagentChangeOption(Clipboard, ClipboardBoth);
+ }
+ }
+ else if (!strcmp(name, "sleep"))
+ {
+ long sleep_parse = 0;
+
+ errno = 0;
+ sleep_parse = strtol(value, NULL, 10);
+
+ if ((errno) && (0 == sleep_parse))
+ {
+ fprintf(stderr, "nxagentParseOptions: Unable to convert value [%s] of option [%s]. "
+ "Ignoring option.\n",
+ validateString(value), validateString(name));
+
+ return;
+ }
+
+ if ((long) UINT_MAX < sleep_parse)
+ {
+ sleep_parse = UINT_MAX;
+
+ fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] "
+ "out of range, clamped to [%lu].\n",
+ validateString(value), validateString(name), sleep_parse);
+ }
+
+ if (0 > sleep_parse)
+ {
+ sleep_parse = 0;
+
+ fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] "
+ "out of range, clamped to [%lu].\n",
+ validateString(value), validateString(name), sleep_parse);
+ }
+
+ nxagentChangeOption(SleepTime, sleep_parse);
+
+ return;
+ }
+ else if (!strcmp(name, "tolerancechecks"))
+ {
+ if (strcmp(value, "strict") == 0)
+ {
+ nxagentChangeOption(ReconnectTolerance, ToleranceChecksStrict);
+ }
+ else if (strcmp(value, "safe") == 0)
+ {
+ nxagentChangeOption(ReconnectTolerance, ToleranceChecksSafe);
+ }
+ else if (strcmp(value, "risky") == 0)
+ {
+ nxagentChangeOption(ReconnectTolerance, ToleranceChecksRisky);
+ }
+ else if (strcmp(value, "bypass") == 0)
+ {
+ nxagentChangeOption(ReconnectTolerance, ToleranceChecksBypass);
+ }
+ else
+ {
+ /*
+ * Check for a matching integer. Or any integer, really.
+ */
+ long tolerance_parse = 0;
+
+ errno = 0;
+ tolerance_parse = strtol(value, NULL, 10);
+
+ if ((errno) && (0 == tolerance_parse))
+ {
+ fprintf(stderr, "nxagentParseOptions: Unable to convert value [%s] of option [%s]. "
+ "Ignoring option.\n",
+ validateString(value), validateString(name));
+
+ return;
+ }
+
+ if ((long) UINT_MAX < tolerance_parse)
+ {
+ tolerance_parse = UINT_MAX;
+
+ fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] "
+ "out of range, clamped to [%lu].\n",
+ validateString(value), validateString(name), tolerance_parse);
+ }
+
+ if (0 > tolerance_parse)
+ {
+ tolerance_parse = 0;
+
+ fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of option [%s] "
+ "out of range, clamped to [%lu].\n",
+ validateString(value), validateString(name), tolerance_parse);
+ }
+
+ #ifdef TEST
+ switch (tolerance_parse) {
+ case ToleranceChecksStrict:
+ case ToleranceChecksSafe:
+ case ToleranceChecksRisky:
+ case ToleranceChecksBypass:
+ break;
+ default:
+ fprintf(stderr, "nxagentParseOptions: Warning: value [%s] of "
+ "option [%s] unknown, will be mapped to "
+ "\"Bypass\" [%u] value internally.\n",
+ validateString(value), validateString(name),
+ (unsigned int)ToleranceChecksBypass);
+ }
+ #endif
+
+ nxagentChangeOption(ReconnectTolerance, tolerance_parse);
+ }
+
+ return;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentParseOptions: Ignored option [%s] with value [%s].\n",
+ validateString(name), validateString(value));
+ #endif
+
+ return;
+ }
+
+ /*
+ * Before passing the not yet evaluated options
+ * to ddxProcessArgument(), we have to add a dash
+ * as prefix.
+ */
+
+ if ((size = strlen(name) + 1) > 1)
+ {
+ if ((argv[0] = malloc(size + 1)) == NULL)
+ {
+ fprintf(stderr, "Warning: Ignoring option '%s' due to lack of memory.\n",
+ name);
+
+ return;
+ }
+
+ *argv[0] = '-';
+
+ memcpy(argv[0] + 1, name, size);
+ }
+
+ ddxProcessArgument(argc, argv, 0);
+
+ free(argv[0]);
+}
+
+static void nxagentParseOptionString(char *string)
+{
+ char *value = NULL;
+ char *option = NULL;
+ char *delimiter = NULL;
+
+ /*
+ * Remove the port specification.
+ */
+
+ delimiter = rindex(string, ':');
+
+ if (delimiter)
+ {
+ *delimiter = 0;
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Option file doesn't contain a port specification.\n");
+ }
+
+ while ((option = strtok(option ? NULL : string, ",")))
+ {
+ delimiter = rindex(option, '=');
+
+ if (delimiter)
+ {
+ *delimiter = 0;
+ value = delimiter + 1;
+ }
+ else
+ {
+ value = NULL;
+ }
+
+ nxagentParseOptions(option, value);
+ }
+}
+
+void nxagentProcessOptionsFile()
+{
+ FILE *file;
+ char *data;
+
+ int offset;
+ int size;
+
+ int sizeOfFile;
+ int maxFileSize = 1024;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentProcessOptionsFile: Going to process option the file [%s].\n",
+ validateString(nxagentOptionFile));
+ #endif
+
+ /*
+ * Init statePath
+ */
+ setStatePath("");
+
+ if (nxagentOptionFile == NULL)
+ {
+ return;
+ }
+
+ if ((file = fopen(nxagentOptionFile, "r")) == NULL)
+ {
+ fprintf(stderr, "Warning: Couldn't open option file '%s'. Error is '%s'.\n",
+ validateString(nxagentOptionFile), strerror(errno));
+
+ goto nxagentProcessOptionsFileExit;
+ }
+
+ if (fseek(file, 0, SEEK_END) != 0)
+ {
+ fprintf(stderr, "Warning: Couldn't position inside option file '%s'. Error is '%s'.\n",
+ validateString(nxagentOptionFile), strerror(errno));
+
+ goto nxagentProcessOptionsFileClose;
+ }
+
+ if ((sizeOfFile = ftell(file)) == -1)
+ {
+ fprintf(stderr, "Warning: Couldn't get the size of option file '%s'. Error is '%s'.\n",
+ validateString(nxagentOptionFile), strerror(errno));
+
+ goto nxagentProcessOptionsFileClose;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentProcessOptionsFile: Processing option file [%s].\n",
+ validateString(nxagentOptionFile));
+ #endif
+
+ rewind(file);
+
+ if (sizeOfFile > maxFileSize)
+ {
+ fprintf(stderr, "Warning: Maximum file size exceeded for options '%s'.\n",
+ validateString(nxagentOptionFile));
+
+ goto nxagentProcessOptionsFileClose;
+ }
+
+ if ((data = malloc(sizeOfFile + 1)) == NULL)
+ {
+ fprintf(stderr, "Warning: Memory allocation failed processing file '%s'.\n",
+ validateString(nxagentOptionFile));
+
+ goto nxagentProcessOptionsFileClose;
+ }
+
+ offset = 0;
+ size = 0;
+
+ for (;;)
+ {
+ size_t result = fread(data + offset, 1, sizeOfFile, file);
+
+ if (ferror(file) != 0)
+ {
+ fprintf(stderr, "Warning: Error reading the option file '%s'.\n",
+ validateString(nxagentOptionFile));
+
+ goto nxagentProcessOptionsFileFree;
+ }
+
+ size += result;
+ offset += result;
+
+ if (feof(file) != 0 || (size == sizeOfFile))
+ {
+ break;
+ }
+ }
+
+ if (size != sizeOfFile)
+ {
+ fprintf(stderr, "Warning: Premature end of option file '%s' while reading.\n",
+ validateString(nxagentOptionFile));
+
+ goto nxagentProcessOptionsFileFree;
+ }
+
+ /*
+ * Truncate the buffer to the first line.
+ */
+
+ for (offset = 0; (offset < sizeOfFile) && (data[offset] != '\n'); offset++);
+
+ data[offset] = 0;
+
+ nxagentParseOptionString(data);
+
+nxagentProcessOptionsFileFree:
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+
+nxagentProcessOptionsFileClose:
+
+ if (fclose(file) != 0)
+ {
+ fprintf(stderr, "Warning: Couldn't close option file '%s'. Error is '%s'.\n",
+ validateString(nxagentOptionFile), strerror(errno));
+ }
+
+nxagentProcessOptionsFileExit:
+
+ return;
+}
+
+/*
+ * FIXME: Transport initialization, shouldn't depend upon
+ * argv[], because we call it at every reconnection.
+ */
+
+Bool nxagentPostProcessArgs(char* name, Display* dpy, Screen* scr)
+{
+ Bool useNXTrans = False;
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 2.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ if ((nxagentOption(Rootless) == 1) && nxagentOption(Fullscreen) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "WARNING: Ignoring fullscreen option for rootless session.\n");
+ #endif
+
+ nxagentChangeOption(Fullscreen, False);
+ }
+
+ /*
+ * Ensure we have a valid name for children dialogs.
+ */
+
+ nxagentGetDialogName();
+
+ /*
+ * Ensure we have a valid name for window name.
+ */
+
+ if (*nxagentWindowName == '\0')
+ {
+ strncpy(nxagentWindowName, "NX", 255);
+
+ *(nxagentWindowName + 255) = '\0';
+ }
+
+ /*
+ * Note that use of NX packed images as well as
+ * render extension could be later disabled due
+ * to the fact that session is running nested
+ * in a nxagent server.
+ */
+
+ if (nxagentForceNXTrans)
+ {
+ useNXTrans = True;
+ }
+ else if ((strncasecmp(name, "nx/", 3) == 0) ||
+ (strncasecmp(name, "nx:", 3) == 0) ||
+ (strncasecmp(name, "nx,", 3) == 0) ||
+ (strcasecmp(name, "nx") == 0))
+ {
+ useNXTrans = True;
+ }
+
+ if (useNXTrans == True)
+ {
+ unsigned int linkType = LINK_TYPE_NONE;
+
+ unsigned int localMajor = 0;
+ unsigned int localMinor = 0;
+ unsigned int localPatch = 0;
+
+ unsigned int remoteMajor = 0;
+ unsigned int remoteMinor = 0;
+ unsigned int remotePatch = 0;
+
+ int splitTimeout = 0;
+ int motionTimeout = 0;
+
+ int splitMode = 0;
+ int splitSize = 0;
+
+ unsigned int packMethod = PACK_NONE;
+ unsigned int packQuality = 9;
+
+ int dataLevel = 0;
+ int streamLevel = 0;
+ int deltaLevel = 0;
+
+ unsigned int loadCache = 0;
+ unsigned int saveCache = 0;
+ unsigned int startupCache = 0;
+
+ unsigned int enableClient = 0;
+ unsigned int enableServer = 0;
+
+ unsigned int clientSegment = 0;
+ unsigned int serverSegment = 0;
+
+ unsigned int clientSize = 0;
+ unsigned int serverSize = 0;
+
+ if (NXGetControlParameters(dpy, &linkType, &localMajor, &localMinor,
+ &localPatch, &remoteMajor, &remoteMinor, &remotePatch,
+ &splitTimeout, &motionTimeout, &splitMode, &splitSize,
+ &packMethod, &packQuality, &dataLevel, &streamLevel,
+ &deltaLevel, &loadCache, &saveCache, &startupCache) == 0)
+ {
+ fprintf(stderr, "Warning: Failed to get the control parameters.\n");
+ }
+
+ nxagentChangeOption(LinkType, linkType);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPostProcessArgs: Got local version [%d.%d.%d] remote version [%d.%d.%d].\n",
+ localMajor, localMinor, localPatch, remoteMajor, remoteMinor, remotePatch);
+
+ fprintf(stderr, "nxagentPostProcessArgs: Got split timeout [%d] motion timeout [%d].\n",
+ splitTimeout, motionTimeout);
+
+ fprintf(stderr, "nxagentPostProcessArgs: Got split mode [%d] split size [%d].\n",
+ splitMode, splitSize);
+
+ fprintf(stderr, "nxagentPostProcessArgs: Got preferred pack method [%d] and quality [%d].\n",
+ packMethod, packQuality);
+ #endif
+
+ if (remoteMajor < 2)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPostProcessArgs: WARNING! Using backward compatible alpha encoding.\n");
+ #endif
+
+ nxagentAlphaCompat = 1;
+ }
+ else
+ {
+ nxagentAlphaCompat = 0;
+ }
+
+ nxagentRemoteMajor = remoteMajor;
+
+ if (nxagentPackMethod == -1)
+ {
+ nxagentPackMethod = packMethod;
+ }
+
+ if (nxagentPackQuality == -1)
+ {
+ nxagentPackQuality = packQuality;
+ }
+
+ /*
+ * Set the minimum size of images being
+ * streamed.
+ */
+
+ if (nxagentSplitThreshold == -1)
+ {
+ nxagentSplitThreshold = splitSize;
+ }
+
+ /*
+ * Let the remote proxy use the shared memory
+ * extension, if supported by the X server.
+ * The client part is not useful and not impl-
+ * emented. The size of the segment is chosen
+ * by the user. The only purpose of the message
+ * is to reserve the XID that will be used by
+ * the remote.
+ */
+
+ enableClient = 0;
+ enableServer = 1;
+
+ if (NXGetShmemParameters(dpy, &enableClient, &enableServer, &clientSegment,
+ &serverSegment, &clientSize, &serverSize) == 0)
+ {
+ fprintf(stderr, "Warning: Failed to get the shared memory parameters.\n");
+ }
+
+ if (enableServer == 1)
+ {
+ fprintf(stderr, "Info: Using shared memory parameters %d/%d/%d/%dK.\n",
+ nxagentOption(SharedMemory), nxagentOption(SharedPixmaps),
+ enableServer, serverSize / 1024);
+ }
+ else
+ {
+ fprintf(stderr, "Info: Using shared memory parameters %d/%d/0/0K.\n",
+ nxagentOption(SharedMemory), nxagentOption(SharedPixmaps));
+ }
+
+ /*
+ * We don't need the NoExpose events. Block
+ * them at the proxy side.
+ */
+
+ NXSetExposeParameters(nxagentDisplay, 1, 1, 0);
+ }
+ else
+ {
+ /*
+ * We don't have a proxy on the remote side.
+ */
+
+ nxagentChangeOption(LinkType, LINK_TYPE_NONE);
+ }
+
+ /*
+ * Set the lossless and lossy pack methods
+ * based on the user's preferences and the
+ * selected link type.
+ */
+
+ nxagentSetPackMethod();
+
+ /*
+ * If not set, set the defer level and the
+ * synchronization timeout based on the link
+ * type.
+ */
+
+ nxagentSetDeferLevel();
+
+ /*
+ * Also set the display output buffer size.
+ */
+
+ nxagentSetBufferSize();
+
+ /*
+ * Select the preferred scheduler.
+ */
+
+ nxagentSetScheduler();
+
+ /*
+ * Select the buffer coalescence timeout.
+ */
+
+ nxagentSetCoalescence();
+
+ /*
+ * Set the other defaults.
+ */
+
+ if (nxagentOption(Fullscreen) == UNDEFINED)
+ {
+ nxagentChangeOption(Fullscreen, False);
+ }
+
+ if (nxagentOption(AllScreens) == UNDEFINED)
+ {
+ nxagentChangeOption(AllScreens, False);
+ }
+
+ if (nxagentOption(Binder) == UNDEFINED)
+ {
+ nxagentChangeOption(Binder, False);
+ }
+
+ if (nxagentOption(Rootless) == UNDEFINED)
+ {
+ nxagentChangeOption(Rootless, False);
+ }
+
+ if (nxagentOption(Desktop) == UNDEFINED)
+ {
+ nxagentChangeOption(Desktop, True);
+ }
+
+ /*
+ * The enableBackingStore flag is defined
+ * in window.c in the dix.
+ */
+/*
+FIXME: In rootless mode the backing-store support is not functional yet.
+*/
+ if (nxagentOption(Rootless))
+ {
+ enableBackingStore = 0;
+ }
+ else if (nxagentOption(BackingStore) == BackingStoreUndefined ||
+ nxagentOption(BackingStore) == BackingStoreForce)
+ {
+ enableBackingStore = 1;
+ }
+ else if (nxagentOption(BackingStore) == BackingStoreNever)
+ {
+ enableBackingStore = 0;
+ }
+
+ /*
+ * need to check if this was set on the
+ * command line as this has the priority
+ * over the option file.
+ */
+
+ if (nxagentRenderEnable == UNDEFINED)
+ {
+ nxagentRenderEnable = True;
+ }
+
+ if (nxagentRenderEnable == True)
+ {
+ nxagentAlphaEnabled = True;
+ }
+ else
+ {
+ nxagentAlphaEnabled = False;
+ }
+
+ if ((nxagentOption(Rootless) == 1) && nxagentOption(Xdmcp))
+ {
+ FatalError("PANIC! Cannot start a XDMCP session in rootless mode.\n");
+ }
+
+ /*
+ * We enable server reset only for indirect
+ * XDMCP sessions.
+ */
+
+ if (nxagentOption(Reset) == True && nxagentMaxAllowedResets == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPostProcessArgs: Disabling the server reset.\n");
+ #endif
+
+ nxagentChangeOption(Reset, False);
+
+ dispatchExceptionAtReset = 0;
+ }
+
+ /*
+ * We skip server reset by default. This should
+ * be equivalent to passing the -noreset option
+ * to a standard XFree86 server.
+ */
+
+ if (nxagentOption(Reset) == False)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPostProcessArgs: Disabling dispatch of exception at server reset.\n");
+ #endif
+
+ dispatchExceptionAtReset = 0;
+ }
+
+ /*
+ * Check if the user activated the auto-disconect
+ * feature.
+ */
+
+ if (nxagentOption(Timeout) > 0)
+ {
+ fprintf(stderr, "Info: Using auto-disconnect timeout of %d seconds.\n",
+ nxagentOption(Timeout));
+
+ nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+ }
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 3.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#16 1 256 bits (0 KB) -> 12 bits (0 KB) -> 256/1 -> 12/1 = 21.333:1
+#233 A 1 256 bits (0 KB) -> 131 bits (0 KB) -> 256/1 -> 131/1 = 1.954:1
+#245 A 2 512 bits (0 KB) -> 19 bits (0 KB) -> 256/1 -> 10/1 = 26.947:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ return useNXTrans;
+}
+
+void ddxUseMsg()
+{
+ ErrorF("-display string display name of the real server\n");
+ ErrorF("-sync synchronize with the real server\n");
+ ErrorF("-full utilize full regeneration\n");
+ ErrorF("-class string default visual class\n");
+ ErrorF("-depth int default depth\n");
+ ErrorF("-geometry WxH+X+Y window size and position\n");
+ ErrorF("-bw int window border width\n");
+ ErrorF("-name string window name\n");
+ ErrorF("-scrns int number of screens to generate\n");
+ ErrorF("-install install colormaps directly\n");
+
+ ErrorF("The NX system adds the following arguments:\n");
+ ErrorF("-forcenx force use of NX protocol messages assuming communication through nxproxy\n");
+ ErrorF("-timeout int auto-disconnect timeout in seconds (minimum allowed: 60)\n");
+ ErrorF("-norootlessexit don't exit if there are no clients in rootless mode\n");
+#ifdef RENDER
+ ErrorF("-norender disable the use of the render extension\n");
+ ErrorF("-nocomposite disable the use of the composite extension\n");
+#endif
+ ErrorF("-nopersistent disable disconnection/reconnection to the X display on SIGHUP\n");
+ ErrorF("-noshmem disable use of shared memory extension\n");
+ ErrorF("-shmem enable use of shared memory extension\n");
+ ErrorF("-noshpix disable use of shared pixmaps\n");
+ ErrorF("-shpix enable use of shared pixmaps\n");
+ ErrorF("-noignore don't ignore pointer and keyboard configuration changes mandated by clients\n");
+ ErrorF("-nokbreset don't reset keyboard device if the session is resumed\n");
+ ErrorF("-noxkblock always allow applications to change layout through XKEYBOARD\n");
+ ErrorF("-tile WxH size of image tiles (minimum allowed: 32x32)\n");
+ ErrorF("-keystrokefile file file with keyboard shortcut definitions\n");
+ ErrorF("-verbose print more warning and error messages\n");
+ ErrorF("-D enable desktop mode\n");
+ ErrorF("-R enable rootless mode\n");
+ ErrorF("-S enable shadow mode\n");
+ ErrorF("-B enable proxy binding mode\n");
+}
+
+static int nxagentGetDialogName()
+{
+ strcpy(nxagentDialogName, "NX");
+
+ *(nxagentDialogName + 255) = '\0';
+
+ if (*nxagentSessionId != '\0')
+ {
+ int length = strlen(nxagentSessionId);
+
+ strcpy(nxagentDialogName, "NX - ");
+
+ if (length > (MD5_LENGTH * 2 + 1) &&
+ *(nxagentSessionId + (length - (MD5_LENGTH * 2 + 1))) == '-')
+ {
+ strncat(nxagentDialogName, nxagentSessionId, length - (MD5_LENGTH * 2 + 1));
+ }
+ else
+ {
+ strncat(nxagentDialogName, nxagentSessionId, 250);
+ }
+
+ *(nxagentSessionId + 255) = '\0';
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void nxagentSetPackMethod(void)
+{
+ unsigned char supportedMethods[NXNumberOfPackMethods];
+ unsigned int entries = NXNumberOfPackMethods;
+
+ int method;
+
+ if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+ {
+ nxagentChangeOption(Streaming, 0);
+
+ nxagentPackMethod = PACK_NONE;
+ nxagentPackLossless = PACK_NONE;
+
+ nxagentSplitThreshold = 0;
+
+ return;
+ }
+
+ /*
+ * Check if we need to select the lossy
+ * and lossless pack methods based on
+ * the link type.
+ */
+
+ method = nxagentPackMethod;
+
+ if (method == PACK_ADAPTIVE)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPackMethod: Using adaptive mode for image compression.\n");
+ #endif
+
+ nxagentChangeOption(Adaptive, 1);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPackMethod: Not using adaptive mode for image compression.\n");
+ #endif
+
+ nxagentChangeOption(Adaptive, 0);
+ }
+
+ if (method == PACK_LOSSY || method == PACK_ADAPTIVE)
+ {
+ nxagentPackMethod = PACK_JPEG_16M_COLORS;
+ }
+ else if (method == PACK_LOSSLESS)
+ {
+ switch (nxagentOption(LinkType))
+ {
+ case LINK_TYPE_MODEM:
+ case LINK_TYPE_ISDN:
+ case LINK_TYPE_ADSL:
+ case LINK_TYPE_WAN:
+ {
+ nxagentPackMethod = PACK_BITMAP_16M_COLORS;
+
+ break;
+ }
+ case LINK_TYPE_LAN:
+ {
+ nxagentPackMethod = PACK_RLE_16M_COLORS;
+
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "Warning: Unknown link type '%d' while setting the pack method.\n",
+ nxagentOption(LinkType));
+
+ break;
+ }
+ }
+ }
+
+ /*
+ * Query the remote proxy to determine
+ * whether the selected methods are
+ * supported.
+ */
+
+ if (NXGetUnpackParameters(nxagentDisplay, &entries, supportedMethods) == 0 ||
+ entries != NXNumberOfPackMethods)
+ {
+ fprintf(stderr, "Warning: Unable to retrieve the supported pack methods.\n");
+
+ nxagentPackMethod = PACK_NONE;
+ nxagentPackLossless = PACK_NONE;
+ }
+ else
+ {
+ if (nxagentPackMethod == PACK_BITMAP_16M_COLORS ||
+ nxagentPackMethod == PACK_RLE_16M_COLORS ||
+ nxagentPackMethod == PACK_RGB_16M_COLORS ||
+ nxagentPackMethod == PACK_NONE)
+ {
+ nxagentPackLossless = nxagentPackMethod;
+ }
+ else
+ {
+ if (nxagentOption(LinkType) == LINK_TYPE_LAN)
+ {
+ nxagentPackLossless = PACK_RLE_16M_COLORS;
+ }
+ else
+ {
+ nxagentPackLossless = PACK_BITMAP_16M_COLORS;
+ }
+ }
+
+ if (supportedMethods[nxagentPackLossless] == 0)
+ {
+ nxagentPackLossless = PACK_NONE;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPackMethod: Using method [%d] for lossless compression.\n",
+ nxagentPackLossless);
+ #endif
+
+ if (supportedMethods[nxagentPackMethod] == 0)
+ {
+ fprintf(stderr, "Warning: Pack method '%d' not supported by the proxy.\n",
+ nxagentPackMethod);
+
+ fprintf(stderr, "Warning: Replacing with lossless pack method '%d'.\n",
+ nxagentPackLossless);
+
+ nxagentPackMethod = nxagentPackLossless;
+ }
+ }
+
+ if (nxagentPackMethod == nxagentPackLossless)
+ {
+ nxagentPackQuality = 9;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPackMethod: Assuming pack methods [%d] and [%d] with "
+ "quality [%d].\n", nxagentPackMethod, nxagentPackLossless, nxagentPackQuality);
+ #endif
+}
+
+/*
+ * Each defer level adds the following rules to the previous ones:
+ *
+ * Level 0 Eager encoding.
+ *
+ * Level 1 No data is put or copied on pixmaps, marking them always
+ * as corrupted and synchronizing them on demand, i.e. when
+ * a copy area to a window is requested, the source is syn-
+ * chronized before copying it.
+ *
+ * Level 2 The put images over the windows are skipped marking the
+ * destination as corrupted. The same happens for copy area
+ * and composite operations, spreading the corrupted regions
+ * of involved drawables.
+ */
+
+void nxagentSetDeferLevel()
+{
+ int deferLevel;
+ int tileWidth;
+ int tileHeight;
+ int deferTimeout;
+
+ /*
+ * Streaming is only partly implemented
+ * and is not available in this version
+ * of the agent.
+ */
+
+ if (nxagentOption(Streaming) == 1)
+ {
+ fprintf(stderr, "Warning: Streaming of images not available in this agent.\n");
+
+ nxagentChangeOption(Streaming, 0);
+ }
+
+ switch (nxagentOption(LinkType))
+ {
+ case LINK_TYPE_MODEM:
+ {
+ deferLevel = 2;
+
+ tileWidth = 64;
+ tileHeight = 64;
+
+ deferTimeout = 200;
+
+ break;
+ }
+ case LINK_TYPE_ISDN:
+ {
+ deferLevel = 2;
+
+ tileWidth = 64;
+ tileHeight = 64;
+
+ deferTimeout = 200;
+
+ break;
+ }
+ case LINK_TYPE_ADSL:
+ {
+ deferLevel = 2;
+
+ deferTimeout = 200;
+
+ tileWidth = 4096;
+ tileHeight = 4096;
+
+ break;
+ }
+ case LINK_TYPE_WAN:
+ {
+ deferLevel = 1;
+
+ deferTimeout = 200;
+
+ tileWidth = 4096;
+ tileHeight = 4096;
+
+ break;
+ }
+ case LINK_TYPE_NONE:
+ case LINK_TYPE_LAN:
+ {
+ deferLevel = 0;
+
+ deferTimeout = 200;
+
+ tileWidth = 4096;
+ tileHeight = 4096;
+
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "Warning: Unknown link type [%d] processing the defer option.\n",
+ nxagentOption(LinkType));
+
+ deferLevel = 0;
+
+ tileWidth = 64;
+ tileHeight = 64;
+
+ deferTimeout = 200;
+
+ break;
+ }
+ }
+
+ /*
+ * Set the defer timeout.
+ */
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer timeout parameter in shadow mode.\n");
+ #endif
+ }
+ else
+ {
+ nxagentChangeOption(DeferTimeout, deferTimeout);
+ }
+
+ /*
+ * Set the defer level.
+ */
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer parameter in shadow mode.\n");
+ #endif
+ }
+ else if (nxagentOption(DeferLevel) != UNDEFINED)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [defer] option "
+ "with value [%d]. Defer timeout is [%ld] ms.\n", nxagentOption(DeferLevel),
+ nxagentOption(DeferTimeout));
+ #endif
+ }
+ else
+ {
+ nxagentChangeOption(DeferLevel, deferLevel);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Assuming defer level [%d] with timeout of [%ld] ms.\n",
+ nxagentOption(DeferLevel), nxagentOption(DeferTimeout));
+ #endif
+ }
+
+ /*
+ * Set the tile width.
+ */
+
+ if (nxagentOption(TileWidth) != UNDEFINED)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option "
+ "width value [%d].\n", nxagentOption(TileWidth));
+ #endif
+ }
+ else
+ {
+ nxagentChangeOption(TileWidth, tileWidth);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Assuming tile width [%d].\n",
+ nxagentOption(TileWidth));
+ #endif
+ }
+
+ /*
+ * Set the tile height.
+ */
+
+ if (nxagentOption(TileHeight) != UNDEFINED)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option "
+ "height value [%d].\n", nxagentOption(TileHeight));
+ #endif
+ }
+ else
+ {
+ nxagentChangeOption(TileHeight, tileHeight);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDeferLevel: Assuming tile height [%d].\n",
+ nxagentOption(TileHeight));
+ #endif
+ }
+}
+
+void nxagentSetBufferSize()
+{
+ int size;
+
+ switch (nxagentOption(LinkType))
+ {
+ case LINK_TYPE_MODEM:
+ {
+ size = 4096;
+
+ break;
+ }
+ case LINK_TYPE_ISDN:
+ {
+ size = 4096;
+
+ break;
+ }
+ case LINK_TYPE_ADSL:
+ {
+ size = 8192;
+
+ break;
+ }
+ case LINK_TYPE_WAN:
+ {
+ size = 16384;
+
+ break;
+ }
+ case LINK_TYPE_NONE:
+ case LINK_TYPE_LAN:
+ {
+ size = 16384;
+
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "Warning: Unknown link type '%d' while setting the display buffer size.\n",
+ nxagentOption(LinkType));
+
+ size = 16384;
+
+ break;
+ }
+ }
+
+ nxagentChangeOption(DisplayBuffer, size);
+
+ nxagentBuffer = size;
+
+ if (NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer) < 0)
+ {
+ fprintf(stderr, "Warning: Can't set the display buffer size to [%d].\n",
+ nxagentBuffer);
+ }
+}
+
+void nxagentSetScheduler()
+{
+ /*
+ * The smart scheduler is the default.
+ */
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetScheduler: Using the dumb scheduler in shadow mode.\n");
+ #endif
+
+ nxagentDisableTimer();
+ }
+}
+
+void nxagentSetCoalescence()
+{
+ int timeout;
+
+ switch (nxagentOption(LinkType))
+ {
+ case LINK_TYPE_MODEM:
+ {
+ timeout = 50;
+
+ break;
+ }
+ case LINK_TYPE_ISDN:
+ {
+ timeout = 20;
+
+ break;
+ }
+ case LINK_TYPE_ADSL:
+ {
+ timeout = 10;
+
+ break;
+ }
+ case LINK_TYPE_WAN:
+ {
+ timeout = 5;
+
+ break;
+ }
+ case LINK_TYPE_NONE:
+ case LINK_TYPE_LAN:
+ {
+ timeout = 0;
+
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "Warning: Unknown link type '%d' while setting the display coalescence.\n",
+ nxagentOption(LinkType));
+
+ timeout = 0;
+
+ break;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetCoalescence: Using coalescence timeout of [%d] ms.\n",
+ timeout);
+ #endif
+
+ nxagentChangeOption(DisplayCoalescence, timeout);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
new file mode 100644
index 000000000..5192783e5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -0,0 +1,97 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Args_H__
+#define __Args_H__
+
+#define MD5_LENGTH 16
+
+struct UserGeometry{
+ int flag;
+ int X;
+ int Y;
+ unsigned int Width;
+ unsigned int Height;
+};
+
+extern Bool nxagentUseNXTrans;
+
+extern char nxagentSessionId[];
+extern char nxagentDisplayName[];
+extern char nxagentShadowDisplayName[];
+extern char nxagentWindowName[];
+extern char nxagentDialogName[];
+
+extern Bool nxagentSynchronize;
+extern Bool nxagentFullGeneration;
+extern int nxagentDefaultClass;
+extern Bool nxagentUserDefaultClass;
+extern int nxagentDefaultDepth;
+extern Bool nxagentUserDefaultDepth;
+extern int nxagentX;
+extern int nxagentY;
+extern unsigned int nxagentWidth;
+extern unsigned int nxagentHeight;
+extern struct UserGeometry nxagentUserGeometry;
+extern Bool nxagentUserBorderWidth;
+extern int nxagentNumScreens;
+extern Bool nxagentDoDirectColormaps;
+extern Window nxagentParentWindow;
+extern int nxagentMaxAllowedReset;
+extern Bool nxagentResizeDesktopAtStartup;
+extern Bool nxagentIpaq;
+
+extern int nxagentLockDeferLevel;
+
+Bool nxagentPostProcessArgs(char *name, Display *dpy, Screen *scr);
+void nxagentProcessOptionsFile(void);
+
+void nxagentSetPackMethod(void);
+void nxagentSetDeferLevel(void);
+void nxagentSetBufferSize(void);
+void nxagentSetScheduler(void);
+void nxagentSetCoalescence(void);
+
+extern int nxagentUserDefinedFontPath;
+
+extern int nxagentRemoteMajor;
+
+extern char *nxagentKeystrokeFile;
+
+#endif /* __Args_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
new file mode 100644
index 000000000..0784d6c2c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -0,0 +1,796 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include "Xutil.h"
+#include "Xatom.h"
+#include "Xlib.h"
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+#include <nx/NXpack.h>
+
+#include "Atoms.h"
+#include "Args.h"
+#include "Image.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Options.h"
+#include "Agent.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * These values should be moved in
+ * the option repository.
+ */
+
+Bool nxagentWMIsRunning;
+
+static void startWMDetection(void);
+
+static int nxagentInitAtomMap(char **atomNameList, int count, Atom *atomsRet);
+
+#ifdef DEBUG
+static void nxagentPrintAtomMapInfo(char *message);
+#else
+#define nxagentPrintAtomMapInfo(arg)
+#endif
+
+Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
+
+static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
+{
+ "NX_IDENTITY", /* 0 */
+ "WM_PROTOCOLS", /* 1 */
+ "WM_DELETE_WINDOW", /* 2 */
+ "WM_NX_READY", /* 3 */
+ "MCOPGLOBALS", /* 4 */
+ "NX_CUT_BUFFER_SERVER", /* 5 */
+ "TARGETS", /* 6 */
+ "TEXT", /* 7 */
+ "NX_AGENT_SIGNATURE", /* 8 */
+ "NXDARWIN", /* 9 */
+ "CLIPBOARD", /* 10 */
+ "TIMESTAMP", /* 11 */
+ "UTF8_STRING", /* 12 */
+ "_NET_WM_STATE", /* 13 */
+ "_NET_WM_STATE_FULLSCREEN", /* 14 */
+ NULL,
+ NULL
+};
+
+static XErrorHandler previousErrorHandler = NULL;
+
+static void catchAndRedirect(Display* dpy, XErrorEvent* X)
+{
+ if (X -> error_code == BadAccess &&
+ X -> request_code == X_ChangeWindowAttributes &&
+ X -> resourceid == DefaultRootWindow(dpy))
+ {
+ nxagentWMIsRunning = TRUE;
+ }
+ else
+ {
+ previousErrorHandler(dpy, X);
+ }
+}
+
+static void startWMDetection()
+{
+ /*
+ * We are trying to detect if is there any client
+ * that is listening for 'WM' events on the root
+ * window.
+ */
+
+ nxagentWMIsRunning = FALSE;
+
+ previousErrorHandler = XSetErrorHandler((XErrorHandler)&catchAndRedirect);
+
+ /*
+ * After this request we need to Sync with
+ * the X server to be sure we get any error
+ * that is generated.
+ */
+
+ XSelectInput(nxagentDisplay,
+ RootWindow (nxagentDisplay, 0),
+ SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask);
+}
+
+static void finishWMDetection(Bool verbose)
+{
+ XSetErrorHandler(previousErrorHandler);
+
+ if (nxagentWMIsRunning)
+ {
+ if (verbose == 1)
+ {
+ fprintf(stderr, "Info: Detected window manager running.\n");
+ }
+ }
+ else
+ {
+ if (verbose == 1)
+ {
+ fprintf(stderr, "Info: Not found a window manager running.\n");
+ }
+
+ /*
+ * We are not really interested on root window events.
+ */
+
+ XSelectInput(nxagentDisplay, RootWindow (nxagentDisplay, 0), 0);
+ }
+}
+
+void nxagentWMDetect()
+{
+ Bool verbose = False;
+ int windowManagerWasRunning = nxagentWMIsRunning;
+
+ startWMDetection();
+
+ XSync(nxagentDisplay, 0);
+
+ if (windowManagerWasRunning != nxagentWMIsRunning)
+ {
+ verbose = False;
+ }
+
+ finishWMDetection(verbose);
+}
+
+int nxagentInitAtoms(WindowPtr pWin)
+{
+ Atom atom;
+
+ /*
+ * Value of nxagentAtoms[8] is "NX_AGENT_SIGNATURE".
+ *
+ * We don't need to save the atom's value. It will
+ * be checked by other agents to find if they are
+ * run nested.
+ */
+
+ atom = MakeAtom(nxagentAtomNames[8], strlen(nxagentAtomNames[8]), 1);
+
+ if (atom == None)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentInitAtoms: PANIC! Could not create [%s] atom.\n",
+ nxagentAtomNames[8]);
+ #endif
+
+ return -1;
+ }
+
+ return 1;
+}
+
+int nxagentQueryAtoms(ScreenPtr pScreen)
+{
+ int i;
+ static unsigned long atomGeneration = 1;
+
+ int num_of_atoms = NXAGENT_NUMBER_OF_ATOMS;
+ char *names[NXAGENT_NUMBER_OF_ATOMS];
+
+ unsigned long int startingTime = GetTimeInMillis();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentQueryAtoms: Going to create the intern atoms on real display.\n");
+
+ fprintf(stderr, "nxagentQueryAtoms: Starting time is [%ld].\n", startingTime);
+ #endif
+
+ nxagentPrintAtomMapInfo("nxagentQueryAtoms: Entering");
+
+ for (i = 0; i < num_of_atoms; i++)
+ {
+ names[i] = nxagentAtomNames[i];
+
+ nxagentAtoms[i] = None;
+ }
+
+ if (nxagentSessionId[0])
+ {
+ names[num_of_atoms - 1] = nxagentSessionId;
+ }
+ else
+ {
+ num_of_atoms--;
+ }
+
+ startWMDetection();
+
+ nxagentInitAtomMap(names, num_of_atoms, nxagentAtoms);
+
+ /*
+ * We need to be synchronized with the X server
+ * in order to detect the Window Manager, since
+ * after a reset the XInternAtom could be cached
+ * by Xlib.
+ */
+
+ if (atomGeneration != serverGeneration)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentQueryAtoms: The nxagent has been reset with server %ld atom %ld.\n",
+ serverGeneration, atomGeneration);
+
+ fprintf(stderr, "nxagentQueryAtoms: Forcing a sync to detect the window manager.\n");
+ #endif
+
+ atomGeneration = serverGeneration;
+
+ XSync(nxagentDisplay, 0);
+ }
+
+ finishWMDetection(False);
+
+ /*
+ * Value of nxagentAtoms[9] is "NXDARWIN".
+ *
+ * We check if it was created by the NX client.
+ */
+
+ if (nxagentAtoms[9] > nxagentAtoms[0])
+ {
+ nxagentAtoms[9] = None;
+ }
+
+ /*
+ * Value of nxagentAtoms[8] is "NX_AGENT_SIGNATURE".
+ *
+ * This atom is created internally by the agent server at
+ * startup to let other agents determine if they are run
+ * nested. If agent is run nested, in fact, at the time it
+ * will create the NX_AGENT_SIGNATURE atom on the real X
+ * server it will find the existing atom with a value less
+ * than any NX_IDENTITY created but itself.
+ */
+
+ if (nxagentAtoms[8] > nxagentAtoms[0])
+ {
+ nxagentAtoms[8] = None;
+ }
+
+ if (nxagentAtoms[8] != None)
+ {
+ /*
+ * We are running nested in another agent
+ * server.
+ */
+
+ nxagentChangeOption(Nested, 1);
+
+ /*
+ * Avoid the image degradation caused by
+ * multiple lossy encoding.
+ */
+
+ fprintf(stderr, "Warning: Disabling use of lossy encoding in nested mode.\n");
+
+ nxagentPackMethod = nxagentPackLossless;
+ }
+
+ #ifdef TEST
+
+ for (i = 0; i < num_of_atoms; i++)
+ {
+ fprintf(stderr, "nxagentQueryAtoms: Created intern atom [%s] with id [%ld].\n",
+ names[i], nxagentAtoms[i]);
+ }
+
+ #endif
+
+ nxagentChangeOption(DisplayLatency, GetTimeInMillis() - startingTime);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentQueryAtoms: Ending time is [%ld] reference latency is [%d] Ms.\n",
+ GetTimeInMillis(), nxagentOption(DisplayLatency));
+ #endif
+
+ nxagentPrintAtomMapInfo("nxagentQueryAtoms: Exiting");
+
+ return 1;
+}
+
+#define NXAGENT_ATOM_MAP_SIZE_INCREMENT 256
+
+typedef struct {
+ Atom local;
+ Atom remote;
+ const char *string;
+ int length;
+} AtomMap;
+
+static AtomMap *privAtomMap = NULL;
+static unsigned int privAtomMapSize = 0;
+static unsigned int privLastAtom = 0;
+
+static void nxagentExpandCache(void);
+static void nxagentWriteAtom(Atom, Atom, const char*, Bool);
+static AtomMap* nxagentFindAtomByRemoteValue(Atom);
+static AtomMap* nxagentFindAtomByLocalValue(Atom);
+static AtomMap* nxagentFindAtomByName(char*, unsigned);
+
+static void nxagentExpandCache(void)
+{
+ privAtomMapSize += NXAGENT_ATOM_MAP_SIZE_INCREMENT;
+
+ privAtomMap = realloc(privAtomMap, privAtomMapSize * sizeof(AtomMap));
+
+ if (privAtomMap == NULL)
+ {
+ FatalError("nxagentExpandCache: realloc failed\n");
+ }
+}
+
+/*
+ * Check if there is space left on the map
+ * and manage the possible consequent allocation,
+ * then cache the atom-couple.
+ */
+
+static void nxagentWriteAtom(Atom local, Atom remote, const char *string, Bool duplicate)
+{
+ const char *s;
+
+ /*
+ * We could remove this string duplication if
+ * we know for sure that the server will not
+ * reset, since only at reset the dix layer
+ * free all the atom names.
+ */
+
+ if (duplicate)
+ {
+ s = strdup(string);
+
+ #ifdef WARNING
+ if (s == NULL)
+ {
+ fprintf(stderr, "nxagentWriteAtom: Malloc failed.\n");
+ }
+ #endif
+ }
+ else
+ {
+ s = string;
+ }
+
+ if (privLastAtom == privAtomMapSize)
+ {
+ nxagentExpandCache();
+ }
+
+ privAtomMap[privLastAtom].local = local;
+ privAtomMap[privLastAtom].remote = remote;
+ privAtomMap[privLastAtom].string = s;
+ privAtomMap[privLastAtom].length = strlen(s);
+
+ privLastAtom++;
+}
+
+/*
+ * FIXME: We should clean up the atom map
+ * at nxagent reset, in order to cancel
+ * all the local atoms but still mantaining
+ * the Xserver values and the atom names.
+ */
+
+void nxagentResetAtomMap()
+{
+ unsigned i;
+
+ nxagentPrintAtomMapInfo("nxagentResetAtomMap: Entering");
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ privAtomMap[i].local = None;
+ }
+
+ nxagentPrintAtomMapInfo("nxagentResetAtomMap: Exiting");
+}
+
+/*
+ * Init map.
+ * Initializing the atomNameList all in one.
+ */
+
+static int nxagentInitAtomMap(char **atomNameList, int count, Atom *atomsRet)
+{
+ XlibAtom *atom_list;
+ char **name_list;
+ unsigned int i;
+ int ret_value = 0;
+ int list_size = count + privLastAtom;
+
+ nxagentPrintAtomMapInfo("nxagentInitAtomMap: Entering");
+
+ atom_list = malloc((list_size) * sizeof(*atom_list));
+ name_list = malloc((list_size) * sizeof(char*));
+
+ if ((atom_list == NULL) || (name_list == NULL))
+ {
+ FatalError("nxagentInitAtomMap: malloc failed\n");
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ name_list[i] = atomNameList[i];
+ atom_list[i] = None;
+ }
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ name_list[count + i] = (char *)privAtomMap[i].string;
+ atom_list[count + i] = None;
+ }
+
+ /*
+ * Ask X-Server for ours Atoms
+ * ... if successfull cache them too.
+ */
+
+ ret_value = XInternAtoms(nxagentDisplay, name_list, list_size, False, atom_list);
+
+ if (ret_value == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitAtomMap: WARNING! XInternAtoms request failed.\n");
+ #endif
+
+ free(atom_list);
+ free(name_list);
+
+ return 0;
+ }
+
+ for (i = 0; i < list_size; i++)
+ {
+ AtomMap *aMap = nxagentFindAtomByName(name_list[i], strlen(name_list[i]));
+
+ if (aMap == NULL)
+ {
+ Atom local = MakeAtom(name_list[i], strlen(name_list[i]), True);
+
+ if (ValidAtom(local))
+ {
+ nxagentWriteAtom(local, atom_list[i], name_list[i], False);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitAtomMap: WARNING MakeAtom failed.\n");
+ #endif
+ }
+ }
+ else
+ {
+ aMap -> remote = atom_list[i];
+
+ if (i < count && aMap -> local == None)
+ {
+ aMap -> local = MakeAtom(name_list[i], strlen(name_list[i]), True);
+ }
+ }
+
+ if (i < count)
+ {
+ atomsRet[i] = atom_list[i];
+ }
+ }
+
+ free(atom_list);
+ free(name_list);
+
+ nxagentPrintAtomMapInfo("nxagentInitAtomMap: Exiting");
+
+ return 1;
+}
+
+/*
+ * If the nxagent has been resetted,
+ * the local value of the atoms stored
+ * in cache could have the value None,
+ * do not call this function with None.
+ */
+
+static AtomMap* nxagentFindAtomByLocalValue(Atom local)
+{
+ unsigned i;
+
+ if (!ValidAtom(local))
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ if (local == privAtomMap[i].local)
+ {
+ return (privAtomMap + i);
+ }
+ }
+
+ return NULL;
+}
+
+static AtomMap* nxagentFindAtomByRemoteValue(Atom remote)
+{
+ unsigned i;
+
+ if (remote == None || remote == BAD_RESOURCE)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ if (remote == privAtomMap[i].remote)
+ {
+ return (privAtomMap + i);
+ }
+ }
+
+ return NULL;
+}
+
+static AtomMap* nxagentFindAtomByName(char *string, unsigned int length)
+{
+ unsigned i;
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ if ((length == privAtomMap[i].length) &&
+ (strcmp(string, privAtomMap[i].string) == 0))
+ {
+ return (privAtomMap + i);
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Convert local atom's name to X-server value.
+ * Reading them from map, if they have been already cached or
+ * really asking to X-server and caching them.
+ * FIXME: I don't really know if is better to allocate
+ * an automatic variable like ret_value and write it, instead of make all
+ * these return!, perhaps this way the code is a little bit easyer to read.
+ * I think this and the 2 .*Find.* are the only functions to look for performances.
+ */
+
+Atom nxagentMakeAtom(char *string, unsigned int length, Bool Makeit)
+{
+ Atom local;
+ AtomMap *current;
+
+ /*
+ * Surely MakeAtom is faster than
+ * our nxagentFindAtomByName.
+ */
+
+ local = MakeAtom(string, length, Makeit);
+
+ if (!ValidAtom(local))
+ {
+ return None;
+ }
+
+ if (local <= XA_LAST_PREDEFINED)
+ {
+ return local;
+ }
+
+ if ((current = nxagentFindAtomByLocalValue(local)))
+ {
+ /*
+ * Found cached by value.
+ */
+
+ return current->remote;
+ }
+
+ if ((current = nxagentFindAtomByName(string, length)))
+ {
+ /*
+ * Found Cached by name.
+ * It means that nxagent has been resetted,
+ * but not the xserver so we still have cached its atoms.
+ */
+
+ current->local = local;
+
+ return current->remote;
+ }
+
+ /*
+ * We really have to ask Xserver for it.
+ */
+
+ {
+ Atom remote;
+
+ remote = XInternAtom(nxagentDisplay, string, !Makeit);
+
+ if (remote == None)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentMakeAtom: WARNING XInternAtom failed.\n");
+ #endif
+
+ return None;
+ }
+
+ nxagentWriteAtom(local, remote, string, True);
+
+ return remote;
+ }
+}
+
+Atom nxagentLocalToRemoteAtom(Atom local)
+{
+ AtomMap *current;
+ const char *string;
+ Atom remote;
+
+ if (!ValidAtom(local))
+ {
+ return None;
+ }
+
+ if (local <= XA_LAST_PREDEFINED)
+ {
+ return local;
+ }
+
+ if ((current = nxagentFindAtomByLocalValue(local)))
+ {
+ return current->remote;
+ }
+
+ string = NameForAtom(local);
+
+ remote = XInternAtom(nxagentDisplay, string, False);
+
+ if (remote == None)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentLocalToRemoteAtom: WARNING XInternAtom failed.\n");
+ #endif
+
+ return None;
+ }
+
+ nxagentWriteAtom(local, remote, string, True);
+
+ return remote;
+}
+
+Atom nxagentRemoteToLocalAtom(Atom remote)
+{
+ AtomMap *current;
+ char *string;
+ Atom local;
+
+ if (remote == None || remote == BAD_RESOURCE)
+ {
+ return None;
+ }
+
+ if (remote <= XA_LAST_PREDEFINED)
+ {
+ return remote;
+ }
+
+ if ((current = nxagentFindAtomByRemoteValue(remote)))
+ {
+ if (!ValidAtom(current->local))
+ {
+ local = MakeAtom(current->string, current->length, True);
+
+ if (ValidAtom(local))
+ {
+ current->local = local;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING MakeAtom failed.\n");
+ #endif
+
+ current->local = None;
+ }
+ }
+
+ return current->local;
+ }
+
+ if ((string = XGetAtomName(nxagentDisplay, remote)))
+ {
+ local = MakeAtom(string, strlen(string), True);
+
+ if (!ValidAtom(local))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING MakeAtom failed.\n");
+ #endif
+
+ local = None;
+ }
+
+ nxagentWriteAtom(local, remote, string, True);
+
+ XFree(string);
+
+ return local;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING failed to get name from remote atom.\n");
+ #endif
+
+ return None;
+}
+
+#ifdef DEBUG
+
+static void nxagentPrintAtomMapInfo(char *message)
+{
+ unsigned i;
+
+ fprintf(stderr, "--------------- Atom map in context [%s] ----------------------\n", message);
+ fprintf(stderr, "nxagentPrintAtomMapInfo: Map at [%p] size [%d] number of entry [%d] auto increment [%d].\n",
+ (void*) privAtomMap, privLastAtom, privAtomMapSize, NXAGENT_ATOM_MAP_SIZE_INCREMENT);
+
+ for (i = 0; i < privLastAtom; i++)
+ {
+ fprintf(stderr, "[%5.1d] local: %6.1lu - remote: %6.1lu - [%p] %s\n", i,
+ privAtomMap[i].local,
+ privAtomMap[i].remote,
+ privAtomMap[i].string, validateString(privAtomMap[i].string));
+ }
+
+ fprintf(stderr, "---------------------------------------------\n");
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
new file mode 100644
index 000000000..391e06181
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -0,0 +1,73 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Atoms_H__
+#define __Atoms_H__
+
+#include "X.h"
+#include "../../include/window.h"
+#include "screenint.h"
+
+#define NXAGENT_NUMBER_OF_ATOMS 16
+
+extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
+
+extern Bool nxagentWMIsRunning;
+
+/*
+ * Create the required atoms internally
+ * to the agent server.
+ */
+
+int nxagentInitAtoms(WindowPtr pWin);
+
+/*
+ * Query and create all the required atoms
+ * on the remote X server using a single
+ * round trip.
+ */
+
+int nxagentQueryAtoms(ScreenPtr pScreen);
+
+/*
+ * Create the atoms on the remote X server
+ * and cache the couple local-remote atoms.
+ */
+
+Atom nxagentMakeAtom(char *, unsigned, Bool);
+
+/*
+ * Converts local atoms in remote atoms and
+ * viceversa.
+ */
+
+Atom nxagentRemoteToLocalAtom(Atom);
+Atom nxagentLocalToRemoteAtom(Atom);
+
+void nxagentResetAtomMap(void);
+
+void nxagentWMDetect(void);
+
+#endif /* __Atoms_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
new file mode 100644
index 000000000..ae1cd0f25
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -0,0 +1,185 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <nx/NX.h>
+
+#include "Binder.h"
+#include "Options.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int nxagentCheckBinder(int argc, char *argv[], int i)
+{
+ if (++i < argc)
+ {
+ char *display;
+ char *found;
+
+ int port;
+
+ display = argv[i];
+
+ /*
+ * Check if a display specification follows
+ * the -B switch.
+ */
+
+ found = rindex(display, ':');
+
+ if (found == NULL || *(found + 1) == '\0' ||
+ isdigit(*(found + 1)) == 0)
+ {
+ fprintf(stderr, "Error: Can't identify the display port in string '%s'.\n",
+ display);
+
+ return 0;
+ }
+
+ port = atoi(found + 1);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckBinder: Identified agent display port [%d].\n",
+ port);
+ #endif
+
+ /*
+ * The NX options must be specified in the DISPLAY
+ * environment. Check if the display specified on
+ * the command line matches the NX virtual display.
+ */
+
+ display = getenv("DISPLAY");
+
+ if (display == NULL || *display == '\0')
+ {
+ fprintf(stderr, "Error: No DISPLAY environment found.\n");
+
+ return 0;
+ }
+
+ found = rindex(display, ':');
+
+ if (found == NULL || *(found + 1) == '\0' ||
+ isdigit(*(found + 1)) == 0 || atoi(found + 1) != port)
+ {
+ fprintf(stderr, "Error: The NX display doesn't match the agent display :%d.\n",
+ port);
+
+ return 0;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckBinder: Identified NX display port [%d].\n",
+ atoi(found + 1));
+ #endif
+
+ /*
+ * Save the proxy options. They will be later
+ * used to create the transport.
+ */
+
+ nxagentChangeOption(Rootless, False);
+ nxagentChangeOption(Desktop, False);
+ nxagentChangeOption(Binder, True);
+
+ /*
+ * FIXME: This now points to the buffer that was
+ * returned by getenv(). It is to be decided how
+ * to handle the values of type string in the
+ * Options repository.
+ */
+
+ nxagentChangeOption(BinderOptions, display);
+
+ return 2;
+ }
+
+ fprintf(stderr, "Error: No display port specified in command.\n");
+
+ return 0;
+}
+
+int nxagentBinderLoop()
+{
+ struct timeval timeout;
+
+ char *options = nxagentOption(BinderOptions);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBinderLoop: Creating the NX transport.\n");
+ #endif
+
+ if (NXTransCreate(NX_FD_ANY, NX_MODE_CLIENT, options) < 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBinderLoop: PANIC! Error creating the NX transport.\n");
+ #endif
+
+ return -1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBinderLoop: Yielding control to the NX entry point.\n");
+ #endif
+
+ while (NXTransRunning(NX_FD_ANY))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBinderLoop: Going to run a new NX proxy loop.\n");
+ #endif
+
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ NXTransContinue(&timeout);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBinderLoop: Completed execution of the NX loop.\n");
+ #endif
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBinderLoop: Exiting the NX proxy binder loop.\n");
+ #endif
+
+ return 1;
+}
+
+void nxagentBinderExit(int code)
+{
+ NXTransExit(code);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
new file mode 100644
index 000000000..fc6673132
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -0,0 +1,35 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Binder_H__
+#define __Binder_H__
+
+int nxagentCheckBinder(int argc, char *argv[], int i);
+
+int nxagentBinderLoop(void);
+
+void nxagentBinderExit(int code);
+
+#endif /* __Binder_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/BitmapUtils.c b/nx-X11/programs/Xserver/hw/nxagent/BitmapUtils.c
new file mode 100644
index 000000000..b889d2a62
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/BitmapUtils.c
@@ -0,0 +1,118 @@
+/*
+
+Copyright 1990, 1994, 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: Keith Packard, MIT X Consortium
+ */
+
+/*
+ * Derived from libXfont1's utilbitmap.c (available via fontmisc.h).
+ */
+
+/* Utility functions for reformating font bitmaps */
+
+static const unsigned char _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+/*
+ * Invert bit order within each BYTE of an array.
+ */
+void
+nxagentBitOrderInvert(unsigned char *buf, int nbytes)
+{
+ const unsigned char *rev = _reverse_byte;
+
+ for (; --nbytes >= 0; buf++)
+ *buf = rev[*buf];
+}
+
+/*
+ * Invert byte order within each 16-bits of an array.
+ */
+void
+nxagentTwoByteSwap(unsigned char *buf, int nbytes)
+{
+ unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 2, buf += 2)
+ {
+ c = buf[0];
+ buf[0] = buf[1];
+ buf[1] = c;
+ }
+}
+
+/*
+ * Invert byte order within each 32-bits of an array.
+ */
+void
+nxagentFourByteSwap(unsigned char *buf, int nbytes)
+{
+ unsigned char c;
+
+ for (; nbytes > 0; nbytes -= 4, buf += 4)
+ {
+ c = buf[0];
+ buf[0] = buf[3];
+ buf[3] = c;
+ c = buf[1];
+ buf[1] = buf[2];
+ buf[2] = c;
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
new file mode 100644
index 000000000..38d877ed7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -0,0 +1,546 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Used in handling of karma on lost focus.
+ */
+
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+
+#include <nx/NX.h>
+
+#include "Xatom.h"
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "osdep.h"
+
+/*
+ * NX specific includes and definitions.
+ */
+
+#include "Agent.h"
+#include "Args.h"
+#include "Display.h"
+#include "Client.h"
+#include "Dialog.h"
+#include "Handlers.h"
+#include "Events.h"
+#include "Drawable.h"
+#include "Utils.h"
+
+/*
+ * Need to include this after the stub
+ * definition of GC in Agent.h.
+ */
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Returns the last signal delivered
+ * to the process.
+ */
+
+extern int _X11TransSocketCheckSignal(void);
+
+/*
+ * Time in milliseconds of first iteration
+ * through the dispatcher.
+ */
+
+unsigned long nxagentStartTime = -1;
+
+/*
+ * If defined, add a function checking if we
+ * need a null timeout after a client wakeup.
+ */
+
+#undef CHECK_RESTARTED_CLIENTS
+
+#ifdef CHECK_RESTARTED_CLIENTS
+
+void nxagentCheckRestartedClients(struct timeval **timeout);
+
+#endif
+
+/*
+ * Allow attaching private members to the client.
+ */
+
+int nxagentClientPrivateIndex;
+
+/*
+ * The master nxagent holds in nxagentShadowCounter
+ * the number of shadow nxagents connected to itself.
+ */
+
+int nxagentShadowCounter = 0;
+
+void nxagentInitClientPrivates(ClientPtr client)
+{
+ if (nxagentClientPriv(client))
+ {
+ nxagentClientPriv(client) -> clientState = 0;
+ nxagentClientPriv(client) -> clientBytes = 0;
+ nxagentClientPriv(client) -> clientHint = UNKNOWN;
+ }
+}
+
+/*
+ * Guess the running application based on the
+ * properties attached to its main window.
+ */
+
+void nxagentGuessClientHint(ClientPtr client, Atom property, char *data)
+{
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentGuessClientHint: Client [%d] setting property [%s] as [%s].\n",
+ client -> index, validateString(NameForAtom(property)), validateString(data));
+ #endif
+
+ if (nxagentClientPriv(client) -> clientHint == UNKNOWN)
+ {
+ if (property == XA_WM_CLASS)
+ {
+ if (strcmp(data, "nxclient") == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentGuessClientHint: Detected nxclient as [%d].\n", client -> index);
+ #endif
+
+ nxagentClientHint(client) = NXCLIENT_WINDOW;
+ }
+ else if (strstr(data, "java"))
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentGuessClientHint: Detected java as [%d].\n", client -> index);
+ #endif
+
+ nxagentClientHint(client) = JAVA_WINDOW;
+ }
+ }
+ }
+
+ if (nxagentClientPriv(client) -> clientHint == NXCLIENT_WINDOW)
+ {
+ if (property == MakeAtom("WM_WINDOW_ROLE", 14, True) &&
+ strncmp(data, "msgBox", 6) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentGuessClientHint: Detected nxclient dialog as [%d].\n", client -> index);
+ #endif
+
+ nxagentClientHint(client) = NXCLIENT_DIALOG;
+ }
+ }
+}
+
+void nxagentGuessShadowHint(ClientPtr client, Atom property)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGuessShadowHint: Client [%d] setting property [%s].\n",
+ client -> index,
+ validateString(NameForAtom(property)));
+ #endif
+
+ if (nxagentClientPriv(client) -> clientHint == UNKNOWN)
+ {
+ if (strcmp(validateString(NameForAtom(property)), "_NX_SHADOW") == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGuessShadowHint: nxagentShadowCounter [%d].\n",
+ nxagentShadowCounter);
+
+ fprintf(stderr, "nxagentGuessShadowHint: Detected shadow nxagent as client [%d].\n",
+ client -> index);
+
+ #endif
+
+ nxagentClientHint(client) = NXAGENT_SHADOW;
+
+ nxagentShadowCounter++;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGuessShadowHint: nxagentShadowCounter [%d].\n",
+ nxagentShadowCounter);
+ #endif
+
+ /*
+ * From this moment on we ignore the visibility
+ * checks to keep the windows updated.
+ */
+
+ nxagentChangeOption(IgnoreVisibility, 1);
+ }
+ }
+}
+
+void nxagentCheckIfShadowAgent(ClientPtr client)
+{
+
+ if (nxagentClientPriv(client) -> clientHint == NXAGENT_SHADOW)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckIfShadowAgent: nxagentShadowCounter [%d].\n",
+ nxagentShadowCounter);
+
+ fprintf(stderr, "nxagentCheckIfShadowAgent: Shadow nxagent as client [%d] detached.\n",
+ client -> index);
+
+ fprintf(stderr, "nxagentCheckIfShadowAgent: Decreasing nxagentShadowCounter.\n");
+ #endif
+
+ /*
+ * We decrease nxagentShadowCounter.
+ */
+
+ nxagentShadowCounter--;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckIfShadowAgent: nxagentShadowCounter [%d].\n",
+ nxagentShadowCounter);
+ #endif
+
+
+ if (nxagentShadowCounter == 0)
+ {
+ /*
+ * The last shadow nxagent has been detached
+ * from master nxagent.
+ * The master nxagent could do some action
+ * here.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckIfShadowAgent: The last shadow nxagent has been detached.\n");
+ #endif
+
+ nxagentChangeOption(IgnoreVisibility, 0);
+ }
+ }
+}
+
+void nxagentWakeupByReconnect()
+{
+ int i;
+
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWakeupByReconnect: Going to wakeup all clients.\n");
+ #endif
+
+ for (i = 1; i < currentMaxClients; i++)
+ {
+ if (clients[i] != NULL)
+ {
+ nxagentWakeupByReset(clients[i]);
+ }
+ }
+}
+
+void nxagentWakeupByReset(ClientPtr client)
+{
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWakeupByReset: Going to check client id [%d].\n",
+ client -> index);
+ #endif
+
+ if (nxagentNeedWakeup(client))
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWakeupByReset: Going to wakeup client id [%d].\n",
+ client -> index);
+ #endif
+
+ if (client -> index < MAX_CONNECTIONS)
+ {
+ if (nxagentNeedWakeupBySplit(client))
+ {
+ nxagentWakeupBySplit(client);
+ }
+ }
+ }
+
+ if (client -> index < MAX_CONNECTIONS)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWakeupByReset: Going to reset bytes received for client id [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentClientBytes(client) = 0;
+ }
+}
+
+/*
+ * Wait for any event.
+ */
+
+#define WAIT_ALL_EVENTS
+
+#ifndef WAIT_ALL_EVENTS
+
+static Bool nxagentWaitWakeupBySplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+ return (event -> type == ClientMessage &&
+ (event -> xclient.data.l[0] == NXNoSplitNotify ||
+ event -> xclient.data.l[0] == NXStartSplitNotify ||
+ event -> xclient.data.l[0] == NXCommitSplitNotify ||
+ event -> xclient.data.l[0] == NXEndSplitNotify ||
+ event -> xclient.data.l[0] == NXEmptySplitNotify) &&
+ event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+ event -> xclient.format == 32);
+}
+
+#endif
+
+#define USE_FINISH_SPLIT
+
+void nxagentWaitWakeupBySplit(ClientPtr client)
+{
+ #ifdef TEST
+
+ if (nxagentNeedWakeupBySplit(client) == 0)
+ {
+ fprintf(stderr, "++++++nxagentWaitWakeupBySplit: WARNING! The client [%d] is already awake.\n",
+ client -> index);
+ }
+
+ fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Going to wait for the client [%d].\n",
+ client -> index);
+ #endif
+
+ /*
+ * Be sure we intercept an I/O error
+ * as well as an interrupt.
+ */
+
+ #ifdef USE_FINISH_SPLIT
+
+ NXFinishSplit(nxagentDisplay, client -> index);
+
+ #endif
+
+ NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+ for (;;)
+ {
+ /*
+ * Can we handle all the possible events here
+ * or we need to select only the split events?
+ * Handling all the possible events would pre-
+ * empt the queue and make a better use of the
+ * link.
+ */
+
+ #ifdef WAIT_ALL_EVENTS
+
+ nxagentDispatchEvents(NULL);
+
+ #else
+
+ nxagentDispatchEvents(nxagentWaitWakeupBySplitPredicate);
+
+ #endif
+
+ if (nxagentNeedWakeupBySplit(client) == 0 ||
+ NXDisplayError(nxagentDisplay) == 1)
+ {
+ #ifdef TEST
+
+ if (nxagentNeedWakeupBySplit(client) == 0)
+ {
+ fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Client [%d] can now run.\n",
+ client -> index);
+ }
+ else
+ {
+ fprintf(stderr, "++++++nxagentWaitWakeupBySplit: WARNING! Display error "
+ "detected waiting for restart.\n");
+ }
+
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Yielding control to the NX transport.\n");
+ #endif
+
+ nxagentWaitEvents(nxagentDisplay, NULL);
+ }
+}
+
+int nxagentSuspendBySplit(ClientPtr client)
+{
+/*
+FIXME: Should record a serial number for the client, so that
+ the client is not restarted because of an end of split
+ of a previous client with the same index.
+*/
+ if (client -> index < MAX_CONNECTIONS)
+ {
+ if (nxagentNeedWakeup(client) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentSuspendBySplit: Suspending client [%d] with agent sequence [%ld].\n",
+ client -> index, NextRequest(nxagentDisplay) - 1);
+ #endif
+
+ if (client -> clientGone == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentSuspendBySplit: Client [%d] suspended.\n", client -> index);
+ #endif
+
+ IgnoreClient(client);
+ }
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "++++++nxagentSuspendBySplit: WARNING! Client [%d] already ignored with state [%x].\n",
+ client -> index, nxagentClientPriv(client) -> clientState);
+ }
+ #endif
+
+ nxagentClientPriv(client) -> clientState |= SleepingBySplit;
+
+ return 1;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "++++++nxagentSuspendBySplit: WARNING! Invalid client [%d] provided to function.\n",
+ client -> index);
+ #endif
+
+ return -1;
+}
+
+int nxagentWakeupBySplit(ClientPtr client)
+{
+/*
+FIXME: Should record a serial number for the client, so that
+ the client is not restarted because of the end of the
+ split for a previous client with the same index.
+*/
+ if (client -> index < MAX_CONNECTIONS)
+ {
+ nxagentClientPriv(client) -> clientState &= ~SleepingBySplit;
+
+ if (nxagentNeedWakeup(client) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWakeupBySplit: Resuming client [%d] with agent sequence [%ld].\n",
+ client -> index, NextRequest(nxagentDisplay) - 1);
+ #endif
+
+ if (client -> clientGone == 0)
+ {
+ AttendClient(client);
+ }
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "++++++nxagentWakeupBySplit: WARNING! Client [%d] still suspended with state [%x].\n",
+ client -> index, nxagentClientPriv(client) -> clientState);
+ }
+ #endif
+
+ return 1;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "++++++nxagentWakeupBySplit: WARNING! Invalid client [%d] provided to function.\n",
+ client -> index);
+ #endif
+
+ return -1;
+}
+
+#ifdef CHECK_RESTARTED_CLIENTS
+
+void nxagentCheckRestartedClients(struct timeval **timeout)
+{
+ static struct timeval zero;
+
+ int i;
+
+ /*
+ * If any of the restarted clients had requests
+ * in input we'll need to enter the select with
+ * a null timeout, or we will block until any
+ * other client becomes available.
+ */
+
+ for (i = 1; i < currentMaxClients; i++)
+ {
+ if (clients[i] != NULL && clients[i] -> osPrivate != NULL &&
+ nxagentNeedWakeup(clients[i]) == 0)
+ {
+ int fd = ((OsCommPtr) clients[i] -> osPrivate) -> fd;
+
+ if (FD_ISSET(fd, &ClientsWithInput))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentBlockHandler: WARNING! Client [%d] with fd [%d] has input.\n",
+ clients[i] -> index, fd);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBlockHandler: Setting a null timeout with former timeout [%ld] Ms.\n",
+ (*timeout) -> tv_sec * 1000 + (*timeout) -> tv_usec / 1000);
+ #endif
+
+ if (*timeout != NULL)
+ {
+ (*timeout) -> tv_sec = 0;
+ (*timeout) -> tv_usec = 0;
+ }
+ else
+ {
+ zero.tv_sec = 0;
+ zero.tv_usec = 0;
+
+ *timeout = &zero;
+ }
+ }
+ }
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
new file mode 100644
index 000000000..8f4f503ba
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -0,0 +1,128 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Client_H__
+#define __Client_H__
+
+#define MAX_CONNECTIONS 256
+
+/*
+ * The master nxagent holds in nxagentShadowCounter
+ * the number of shadow nxagents connected to itself.
+ */
+
+extern int nxagentShadowCounter;
+
+enum ClientHint
+{
+ UNKNOWN = 0,
+ NXCLIENT_WINDOW,
+ NXCLIENT_DIALOG,
+ NXAGENT_SHADOW,
+ JAVA_WINDOW
+};
+
+typedef struct _PrivClientRec
+{
+ int clientState;
+ long clientBytes;
+ enum ClientHint clientHint;
+
+} PrivClientRec;
+
+extern int nxagentClientPrivateIndex;
+
+#define nxagentClientPriv(pClient) \
+ ((PrivClientRec *)((pClient)->devPrivates[nxagentClientPrivateIndex].ptr))
+
+void nxagentInitClientPrivates(ClientPtr);
+
+#define nxagentClientAddBytes(pClient, size) \
+ (nxagentClientPriv(pClient) -> clientBytes += (size))
+
+#define nxagentClientBytes(pClient) \
+ (nxagentClientPriv(pClient) -> clientBytes)
+
+#define nxagentClientHint(pClient) \
+ (nxagentClientPriv(pClient) -> clientHint)
+
+#define nxagentClientIsDialog(pClient) \
+ (nxagentClientHint(pClient) == NXCLIENT_DIALOG)
+
+/*
+ * The actual reason why the client
+ * is sleeping.
+ */
+
+#define SleepingBySplit 1
+
+#define nxagentNeedWakeup(client) \
+ ((nxagentClientPriv(client) -> \
+ clientState) != 0)
+
+#define nxagentNeedWakeupBySplit(client) \
+ (((nxagentClientPriv(client) -> \
+ clientState) & SleepingBySplit) != 0)
+
+void nxagentGuessClientHint(ClientPtr, Atom, char*);
+
+void nxagentGuessShadowHint(ClientPtr, Atom);
+
+void nxagentCheckIfShadowAgent(ClientPtr);
+
+/*
+ * Suspend or restart the agent's
+ * client.
+ */
+
+int nxagentSuspendBySplit(ClientPtr client);
+int nxagentWakeupBySplit(ClientPtr client);
+
+/*
+ * Wait until the given client is
+ * restarted.
+ */
+
+void nxagentWaitWakeupBySplit(ClientPtr client);
+
+/*
+FIXME: This must be moved to Drawable.h.
+*/
+void nxagentWaitDrawable(DrawablePtr pDrawable);
+
+/*
+ * Wakeup all the sleeping clients.
+ */
+
+void nxagentWakeupByReconnect(void);
+
+/*
+ * Reset the client state before
+ * closing it down.
+ */
+
+void nxagentWakeupByReset(ClientPtr client);
+
+#endif /* __Client_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
new file mode 100644
index 000000000..d26d3524a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -0,0 +1,1677 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "X.h"
+#include "Xproto.h"
+#include "Xatom.h"
+#include "selection.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+
+#include "Windows.h"
+#include "Atoms.h"
+#include "Agent.h"
+#include "Args.h"
+#include "Trap.h"
+#include "Rootless.h"
+#include "Clipboard.h"
+
+#include "gcstruct.h"
+#include "xfixeswire.h"
+#include "X11/include/Xfixes_nxagent.h"
+
+/*
+ * Use asyncronous get property replies.
+ */
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * These are defined in the dispatcher.
+ */
+
+extern int NumCurrentSelections;
+extern Selection *CurrentSelections;
+
+int nxagentLastClipboardClient = -1;
+
+static int agentClipboardStatus;
+static int clientAccum;
+
+Atom serverCutProperty;
+Atom clientCutProperty;
+static Window serverWindow;
+
+static const int nxagentPrimarySelection = 0;
+static const int nxagentClipboardSelection = 1;
+static const int nxagentMaxSelections = 2;
+
+typedef struct _SelectionOwner
+{
+ Atom selection;
+ ClientPtr client;
+ Window window;
+ WindowPtr windowPtr;
+ Time lastTimeChanged;
+
+} SelectionOwner;
+
+static SelectionOwner *lastSelectionOwner;
+static Atom nxagentLastRequestedSelection;
+static Atom nxagentClipboardAtom;
+static Atom nxagentTimestampAtom;
+
+/*
+ * Needed to handle the notify selection event to
+ * be sent to client once the selection property
+ * has been retrieved from the real X server.
+ */
+
+typedef enum
+{
+ SelectionStageNone,
+ SelectionStageQuerySize,
+ SelectionStageWaitSize,
+ SelectionStageQueryData,
+ SelectionStageWaitData
+} ClientSelectionStage;
+
+static WindowPtr lastClientWindowPtr;
+static ClientPtr lastClientClientPtr;
+static Window lastClientRequestor;
+static Atom lastClientProperty;
+static Atom lastClientSelection;
+static Atom lastClientTarget;
+static Time lastClientTime;
+static Time lastClientReqTime;
+static unsigned long lastClientPropertySize;
+
+static ClientSelectionStage lastClientStage;
+
+static Window lastServerRequestor;
+static Atom lastServerProperty;
+static Atom lastServerTarget;
+static Time lastServerTime;
+
+static Atom serverTARGETS;
+static Atom serverTEXT;
+static Atom serverUTF8_STRING;
+static Atom clientTARGETS;
+static Atom clientTEXT;
+static Atom clientCOMPOUND_TEXT;
+static Atom clientUTF8_STRING;
+
+static char szAgentTARGETS[] = "TARGETS";
+static char szAgentTEXT[] = "TEXT";
+static char szAgentCOMPOUND_TEXT[] = "COMPOUND_TEXT";
+static char szAgentUTF8_STRING[] = "UTF8_STRING";
+static char szAgentNX_CUT_BUFFER_CLIENT[] = "NX_CUT_BUFFER_CLIENT";
+
+/*
+ * Save the values queried from X server.
+ */
+
+XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 };
+
+extern Display *nxagentDisplay;
+
+Bool nxagentValidServerTargets(Atom target);
+void nxagentSendSelectionNotify(Atom property);
+void nxagentTransferSelection(int resource);
+void nxagentCollectPropertyEvent(int resource);
+void nxagentResetSelectionOwner(void);
+WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin);
+void nxagentNotifyConvertFailure(ClientPtr client, Window requestor,
+ Atom selection, Atom target, Time time);
+int nxagentSendNotify(xEvent *event);
+
+/*
+ * This is from NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset, long longLength,
+ Bool delete, Atom type, Atom *actualType, int *format,
+ unsigned long *nItems, unsigned long *bytesAfter,
+ unsigned char **propData);
+
+Bool nxagentValidServerTargets(Atom target)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentValidServerTargets: Got called.\n");
+ #endif
+
+ if (target == XA_STRING) return True;
+ if (target == serverTEXT) return True;
+ /* by dimbor */
+ if (target == serverUTF8_STRING) return True;
+
+ return False;
+}
+
+void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
+{
+ int i;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearClipboard: Called with client [%p] window [%p].\n",
+ (void *) pClient, (void *) pWindow);
+ #endif
+
+ /*
+ * Only for PRIMARY and CLIPBOARD selections.
+ */
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ if ((pClient != NULL && lastSelectionOwner[i].client == pClient) ||
+ (pWindow != NULL && lastSelectionOwner[i].windowPtr == pWindow))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentClearClipboard: Resetting state with client [%p] window [%p].\n",
+ (void *) pClient, (void *) pWindow);
+ #endif
+
+ lastSelectionOwner[i].client = NULL;
+ lastSelectionOwner[i].window = None;
+ lastSelectionOwner[i].windowPtr = NULL;
+ lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ lastServerRequestor = None;
+ }
+ }
+
+ if (pWindow == lastClientWindowPtr)
+ {
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+ }
+
+}
+
+void nxagentClearSelection(XEvent *X)
+{
+ int i = 0;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearSelection: Got called.\n");
+ #endif
+
+ if (agentClipboardStatus != 1 ||
+ nxagentOption(Clipboard) == ClipboardServer)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearSelection: SelectionClear event.\n");
+ #endif
+
+ while ((i < nxagentMaxSelections) &&
+ (lastSelectionOwner[i].selection != X->xselectionclear.selection))
+ {
+ i++;
+ }
+
+ if (i < nxagentMaxSelections)
+ {
+ if (lastSelectionOwner[i].client != NULL)
+ {
+ xEvent x;
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionClear;
+ x.u.selectionClear.time = GetTimeInMillis();
+ x.u.selectionClear.window = lastSelectionOwner[i].window;
+ x.u.selectionClear.atom = CurrentSelections[i].selection;
+
+ (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1,
+ NoEventMask, NoEventMask,
+ NullGrab);
+ }
+
+ CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id;
+ CurrentSelections[i].client = NullClient;
+
+ lastSelectionOwner[i].client = NULL;
+ lastSelectionOwner[i].window = None;
+ lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+ }
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+}
+
+void nxagentRequestSelection(XEvent *X)
+{
+ #ifdef DEBUG
+ int result;
+ #endif
+ int i = 0;
+ XSelectionEvent eventSelection;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRequestSelection: Got called.\n");
+ #endif
+
+ if (agentClipboardStatus != 1)
+ {
+ return;
+ }
+
+ if (!nxagentValidServerTargets(X->xselectionrequest.target) ||
+ (lastServerRequestor != None) ||
+ ((X->xselectionrequest.selection != lastSelectionOwner[nxagentPrimarySelection].selection) &&
+ (X->xselectionrequest.selection != lastSelectionOwner[nxagentClipboardSelection].selection)))
+ {
+/*
+FIXME: Do we need this?
+
+ char *strTarget;
+
+ strTarget = XGetAtomName(nxagentDisplay, X->xselectionrequest.target);
+
+ fprintf(stderr, "SelectionRequest event aborting sele=[%s] target=[%s]\n",
+ validateString(NameForAtom(X->xselectionrequest.selection)),
+ validateString(NameForAtom(X->xselectionrequest.target)));
+
+ fprintf(stderr, "SelectionRequest event aborting sele=[%s] ext target=[%s] Atom size is [%d]\n",
+ validateString(NameForAtom(X->xselectionrequest.selection)), strTarget, sizeof(Atom));
+
+ if (strTarget != NULL)
+ {
+ XFree(strTarget);
+ }
+*/
+ memset(&eventSelection, 0, sizeof(XSelectionEvent));
+ eventSelection.property = None;
+
+ if (X->xselectionrequest.target == serverTARGETS)
+ {
+ Atom xa_STRING = XA_STRING;
+ XChangeProperty (nxagentDisplay,
+ X->xselectionrequest.requestor,
+ X->xselectionrequest.property,
+ XInternAtom(nxagentDisplay, "ATOM", 0),
+ sizeof(Atom)*8,
+ PropModeReplace,
+ (unsigned char*)&xa_STRING,
+ 1);
+ eventSelection.property = X->xselectionrequest.property;
+ }
+
+ if (X->xselectionrequest.target == nxagentTimestampAtom)
+ {
+ while ((i < NumCurrentSelections) &&
+ lastSelectionOwner[i].selection != X->xselectionrequest.selection) i++;
+
+ if (i < NumCurrentSelections)
+ {
+ XChangeProperty(nxagentDisplay,
+ X->xselectionrequest.requestor,
+ X->xselectionrequest.property,
+ X->xselectionrequest.target,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &lastSelectionOwner[i].lastTimeChanged,
+ 1);
+ eventSelection.property = X->xselectionrequest.property;
+ }
+ }
+
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = nxagentDisplay;
+ eventSelection.requestor = X->xselectionrequest.requestor;
+ eventSelection.selection = X->xselectionrequest.selection;
+ eventSelection.target = X->xselectionrequest.target;
+ eventSelection.time = X->xselectionrequest.time;
+
+ #ifdef DEBUG
+ result =
+ #endif
+ XSendEvent(nxagentDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+
+ #ifdef DEBUG
+ if (result == BadValue || result == BadWindow)
+ {
+ fprintf(stderr, "nxagentRequestSelection: WARNING! XSendEvent failed.\n");
+ }
+ else
+ {
+ fprintf(stderr, "nxagentRequestSelection: XSendEvent sent to window [0x%lx].\n",
+ eventSelection.requestor);
+ }
+ #endif
+
+ return;
+ }
+
+ /*
+ * This is necessary in nxagentGetClipboardWindow.
+ */
+
+ nxagentLastRequestedSelection = X->xselectionrequest.selection;
+
+ while ((i < nxagentMaxSelections) &&
+ (lastSelectionOwner[i].selection != X->xselectionrequest.selection))
+ {
+ i++;
+ }
+
+ if (i < nxagentMaxSelections)
+ {
+ if ((lastClientWindowPtr != NULL) && (lastSelectionOwner[i].client != NULL))
+ {
+ XConvertSelection(nxagentDisplay, CurrentSelections[i].selection,
+ X->xselectionrequest.target, serverCutProperty,
+ serverWindow, lastClientTime);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRequestSelection: Sent XConvertSelection.\n");
+ #endif
+ }
+ else
+ {
+ if (lastSelectionOwner[i].client != NULL &&
+ nxagentOption(Clipboard) != ClipboardClient)
+ {
+ xEvent x;
+
+ lastServerProperty = X->xselectionrequest.property;
+ lastServerRequestor = X->xselectionrequest.requestor;
+ lastServerTarget = X->xselectionrequest.target;
+
+ /* by dimbor */
+ if (lastServerTarget != XA_STRING)
+ lastServerTarget = serverUTF8_STRING;
+
+ lastServerTime = X->xselectionrequest.time;
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionRequest;
+ x.u.selectionRequest.time = GetTimeInMillis();
+ x.u.selectionRequest.owner = lastSelectionOwner[i].window;
+
+ /*
+ * Fictitious window.
+ */
+
+ x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id;
+
+ /*
+ * Don't send the same window, some programs are
+ * clever and verify cut and paste operations
+ * inside the same window and don't Notify at all.
+ *
+ * x.u.selectionRequest.requestor = lastSelectionOwnerWindow;
+ */
+
+ x.u.selectionRequest.selection = CurrentSelections[i].selection;
+
+ /* by dimbor (idea from zahvatov) */
+ if (X->xselectionrequest.target != XA_STRING)
+ x.u.selectionRequest.target = clientUTF8_STRING;
+ else
+ x.u.selectionRequest.target = XA_STRING;
+
+ x.u.selectionRequest.property = clientCutProperty;
+
+ (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRequestSelection: Executed TryClientEvents with clientCutProperty.\n");
+ #endif
+ }
+ else
+ {
+ /*
+ * Probably we must to send a Notify
+ * to requestor with property None.
+ */
+
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = nxagentDisplay;
+ eventSelection.requestor = X->xselectionrequest.requestor;
+ eventSelection.selection = X->xselectionrequest.selection;
+ eventSelection.target = X->xselectionrequest.target;
+ eventSelection.property = None;
+ eventSelection.time = X->xselectionrequest.time;
+
+ #ifdef DEBUG
+ result =
+ #endif
+ XSendEvent(nxagentDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRequestSelection: Executed XSendEvent with property None.\n");
+ #endif
+ }
+ }
+ }
+}
+
+void nxagentSendSelectionNotify(Atom property)
+{
+ xEvent x;
+
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentSendSelectionNotify: Sending event to client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionNotify;
+
+ x.u.selectionNotify.time = lastClientTime;
+ x.u.selectionNotify.requestor = lastClientRequestor;
+ x.u.selectionNotify.selection = lastClientSelection;
+ x.u.selectionNotify.target = lastClientTarget;
+
+ x.u.selectionNotify.property = property;
+
+ TryClientEvents(lastClientClientPtr, &x, 1, NoEventMask,
+ NoEventMask , NullGrab);
+
+ return;
+}
+
+void nxagentTransferSelection(int resource)
+{
+ int result;
+
+ if (lastClientClientPtr -> index != resource)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: WARNING! Inconsistent resource [%d] with current client [%d].\n",
+ resource, lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ return;
+ }
+
+ switch (lastClientStage)
+ {
+ case SelectionStageQuerySize:
+ {
+ /*
+ * Don't get data yet, just get size. We skip
+ * this stage in current implementation and
+ * go straight to the data.
+ */
+
+ nxagentLastClipboardClient = NXGetCollectPropertyResource(nxagentDisplay);
+
+ if (nxagentLastClipboardClient == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentTransferSelection: WARNING! Asynchronous GetProperty queue full.\n");
+ #endif
+
+ result = -1;
+ }
+ else
+ {
+ result = NXCollectProperty(nxagentDisplay,
+ nxagentLastClipboardClient,
+ serverWindow,
+ serverCutProperty,
+ 0,
+ 0,
+ False,
+ AnyPropertyType);
+ }
+
+ if (result == -1)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: Aborting selection notify procedure for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: Setting stage to [%d] for client [%d].\n",
+ SelectionStageWaitSize, lastClientClientPtr -> index);
+ #endif
+
+ lastClientStage = SelectionStageWaitSize;
+
+ break;
+ }
+ case SelectionStageQueryData:
+ {
+ /*
+ * Request the selection data now.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentTransferSelection: Getting property content from remote server.\n");
+ #endif
+
+ nxagentLastClipboardClient = NXGetCollectPropertyResource(nxagentDisplay);
+
+ if (nxagentLastClipboardClient == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentTransferSelection: WARNING! Asynchronous GetProperty queue full.\n");
+ #endif
+
+ result = -1;
+ }
+ else
+ {
+ result = NXCollectProperty(nxagentDisplay,
+ nxagentLastClipboardClient,
+ serverWindow,
+ serverCutProperty,
+ 0,
+ lastClientPropertySize,
+ False,
+ AnyPropertyType);
+ }
+
+ if (result == -1)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: Aborting selection notify procedure for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: Setting stage to [%d] for client [%d].\n",
+ SelectionStageWaitData, lastClientClientPtr -> index);
+ #endif
+
+ lastClientStage = SelectionStageWaitData;
+
+ break;
+ }
+ default:
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentTransferSelection: WARNING! Inconsistent state [%d] for client [%d].\n",
+ lastClientStage, lastClientClientPtr -> index);
+ #endif
+
+ break;
+ }
+ }
+}
+
+void nxagentCollectPropertyEvent(int resource)
+{
+ Atom atomReturnType;
+ int resultFormat;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ int result;
+
+ /*
+ * We have received the notification so
+ * we can safely retrieve data from the
+ * client structure.
+ */
+
+ result = NXGetCollectedProperty(nxagentDisplay,
+ resource,
+ &atomReturnType,
+ &resultFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
+
+ nxagentLastClipboardClient = -1;
+
+ if (result == 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ if (pszReturnData != NULL)
+ {
+ XFree(pszReturnData);
+ }
+
+ return;
+ }
+
+ if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32)
+ {
+
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Invalid property "
+ "value.\n");
+ #endif
+
+ if (lastClientClientPtr != NULL)
+ {
+ nxagentSendSelectionNotify(None);
+ }
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ if (pszReturnData != NULL)
+ {
+ XFree(pszReturnData);
+ }
+
+ return;
+ }
+
+ switch (lastClientStage)
+ {
+ case SelectionStageWaitSize:
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: Got size notify event for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ if (ulReturnBytesLeft == 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: Aborting selection notify procedure for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ if (pszReturnData != NULL)
+ {
+ free(pszReturnData);
+ }
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCollectPropertyEvent: Got property size from remote server.\n");
+ #endif
+
+ /*
+ * Request the selection data now.
+ */
+
+ lastClientPropertySize = ulReturnBytesLeft;
+ lastClientStage = SelectionStageQueryData;
+
+ nxagentTransferSelection(resource);
+
+ break;
+ }
+ case SelectionStageWaitData:
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: Got data notify event for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ if (ulReturnBytesLeft != 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: Aborting selection notify procedure for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ if (pszReturnData != NULL)
+ {
+ free(pszReturnData);
+ }
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCollectPropertyEvent: Got property content from remote server.\n");
+ #endif
+
+ ChangeWindowProperty(lastClientWindowPtr,
+ lastClientProperty,
+ lastClientTarget,
+ resultFormat, PropModeReplace,
+ ulReturnItems, pszReturnData, 1);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCollectPropertyEvent: Selection property [%s] changed to [%s]\n",
+ validateString(NameForAtom(lastClientProperty)), pszReturnData);
+ #endif
+
+ nxagentSendSelectionNotify(lastClientProperty);
+
+ /*
+ * Enable further requests from clients.
+ */
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ break;
+ }
+ default:
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Inconsistent state [%d] for client [%d].\n",
+ lastClientStage, lastClientClientPtr -> index);
+ #endif
+
+ break;
+ }
+ }
+
+ XFree(pszReturnData);
+ pszReturnData = NULL;
+}
+
+void nxagentNotifySelection(XEvent *X)
+{
+ int result;
+
+ XSelectionEvent eventSelection;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentNotifySelection: Got called.\n");
+ #endif
+
+ if (agentClipboardStatus != 1)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentNotifySelection: SelectionNotify event.\n");
+ #endif
+
+ if (lastClientWindowPtr != NULL)
+ {
+ if ((lastClientStage == SelectionStageNone) && (X->xselection.property == serverCutProperty))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentNotifySelection: Starting selection transferral for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ /*
+ * The state machine is able to work in two phases. In the first
+ * phase we get the size of property data, in the second we get
+ * the actual data. We save a round-trip by requesting a prede-
+ * termined amount of data in a single GetProperty and by discar-
+ * ding the remaining part. This is not the optimal solution (we
+ * could get the remaining part if it doesn't fit in a single
+ * reply) but, at least with text, it should work in most situa-
+ * tions.
+ */
+
+ lastClientStage = SelectionStageQueryData;
+ lastClientPropertySize = 262144;
+
+ nxagentTransferSelection(lastClientClientPtr -> index);
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentNotifySelection: WARNING! Resetting selection transferral for client [%d].\n",
+ lastClientClientPtr -> index);
+ #endif
+
+ nxagentSendSelectionNotify(None);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+ }
+
+ return;
+ }
+ else
+ {
+ int i = 0;
+
+ while ((i < nxagentMaxSelections) && (lastSelectionOwner[i].selection != X->xselection.selection))
+ {
+ i++;
+ }
+
+ if (i < nxagentMaxSelections)
+ {
+ if ((lastSelectionOwner[i].client != NULL) &&
+ (lastSelectionOwner[i].windowPtr != NULL) &&
+ (X->xselection.property == clientCutProperty))
+ {
+ Atom atomReturnType;
+ int resultFormat;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+
+ result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0, 0, False,
+ AnyPropertyType, &atomReturnType, &resultFormat,
+ &ulReturnItems, &ulReturnBytesLeft, &pszReturnData);
+
+ if (result == BadAlloc || result == BadAtom ||
+ result == BadMatch || result == BadValue ||
+ result == BadWindow)
+ {
+ fprintf (stderr, "Client GetProperty failed error =");
+ lastServerProperty = None;
+ switch (result)
+ {
+ case BadAtom:
+ fprintf (stderr, "BadAtom\n");
+ break;
+ case BadValue:
+ fprintf (stderr, "BadValue\n");
+ break;
+ case BadWindow:
+ fprintf (stderr, "BadWindow\n");
+ break;
+ }
+ }
+ else
+ {
+ result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0,
+ ulReturnBytesLeft, False, AnyPropertyType, &atomReturnType,
+ &resultFormat, &ulReturnItems, &ulReturnBytesLeft,
+ &pszReturnData);
+
+ if (result == BadAlloc || result == BadAtom ||
+ result == BadMatch || result == BadValue ||
+ result == BadWindow)
+ {
+ fprintf (stderr, "SelectionNotify - XChangeProperty failed\n");
+
+ lastServerProperty = None;
+ }
+ else
+ {
+ result = XChangeProperty(nxagentDisplay,
+ lastServerRequestor,
+ lastServerProperty,
+ lastServerTarget,
+ 8,
+ PropModeReplace,
+ pszReturnData,
+ ulReturnItems);
+ }
+
+ /*
+ * if (pszReturnData)
+ * {
+ * free(pszReturnData);
+ * pszReturnData=NULL;
+ * }
+ */
+
+ }
+
+ memset(&eventSelection, 0, sizeof(XSelectionEvent));
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = nxagentDisplay;
+ eventSelection.requestor = lastServerRequestor;
+
+ eventSelection.selection = X->xselection.selection;
+
+ /*
+ * eventSelection.target = X->xselection.target;
+ */
+
+ eventSelection.target = lastServerTarget;
+ eventSelection.property = lastServerProperty;
+ eventSelection.time = lastServerTime;
+
+ /*
+ * eventSelection.time = CurrentTime;
+ * eventSelection.time = lastServerTime;
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentNotifySelection: Sending event to requestor.\n");
+ #endif
+
+ result = XSendEvent(nxagentDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+
+ if (result == BadValue || result == BadWindow)
+ {
+ fprintf (stderr, "SelectionRequest - XSendEvent failed\n");
+ }
+
+ lastServerRequestor = None; /* allow further request */
+ }
+ }
+ }
+}
+
+/*
+ * Acquire selection so we don't get selection
+ * requests from real X clients.
+ */
+
+void nxagentResetSelectionOwner()
+{
+ int i;
+
+ if (lastServerRequestor != None)
+ {
+ #ifdef TEST
+ fprintf (stderr, "nxagentResetSelectionOwner: WARNING! Requestor window [0x%lx] already found.\n",
+ lastServerRequestor);
+ #endif
+
+ return;
+ }
+
+ /*
+ * Only for PRIMARY and CLIPBOARD selections.
+ */
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+
+ fprintf (stderr, "nxagentResetSelectionOwner: Reset clipboard state.\n");
+
+ lastSelectionOwner[i].client = NULL;
+ lastSelectionOwner[i].window = None;
+ lastSelectionOwner[i].windowPtr = NULL;
+ lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+ }
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ lastServerRequestor = None;
+
+ return;
+}
+
+void nxagentSetSelectionOwner(Selection *pSelection)
+{
+ int i;
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetSelectionOwner: Got called.\n");
+ #endif
+
+ if (agentClipboardStatus != 1)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetSelectionOwner: Setting selection owner to window [0x%lx].\n",
+ serverWindow);
+ #endif
+
+ #ifdef TEST
+ if (lastServerRequestor != None)
+ {
+ fprintf (stderr, "nxagentSetSelectionOwner: WARNING! Requestor window [0x%lx] already found.\n",
+ lastServerRequestor);
+ }
+ #endif
+
+ /*
+ * Only for PRIMARY and CLIPBOARD selections.
+ */
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ if (pSelection->selection == CurrentSelections[i].selection)
+ {
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+
+ lastSelectionOwner[i].client = pSelection->client;
+ lastSelectionOwner[i].window = pSelection->window;
+ lastSelectionOwner[i].windowPtr = pSelection->pWin;
+ lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+ }
+ }
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ lastServerRequestor = None;
+
+/*
+FIXME
+
+ if (XGetSelectionOwner(nxagentDisplay,pSelection->selection)==serverWindow)
+ {
+ fprintf (stderr, "NXdispatch: SetSelectionOwner OK\n");
+
+ lastSelectionOwnerSelection = pSelection;
+ lastSelectionOwnerClient = pSelection->client;
+ lastSelectionOwnerWindow = pSelection->window;
+ lastSelectionOwnerWindowPtr = pSelection->pWin;
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+
+ lastServerRequestor = None;
+ }
+ else fprintf (stderr, "nxagentSetSelectionOwner: SetSelectionOwner failed\n");
+*/
+}
+
+void nxagentNotifyConvertFailure(ClientPtr client, Window requestor,
+ Atom selection, Atom target, Time time)
+{
+ xEvent x;
+
+/*
+FIXME: Why this pointer can be not a valid
+ client pointer?
+*/
+ if (clients[client -> index] != client)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentNotifyConvertFailure: WARNING! Invalid client pointer.");
+ #endif
+
+ return;
+ }
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionNotify;
+ x.u.selectionNotify.time = time;
+ x.u.selectionNotify.requestor = requestor;
+ x.u.selectionNotify.selection = selection;
+ x.u.selectionNotify.target = target;
+ x.u.selectionNotify.property = None;
+
+ (void) TryClientEvents(client, &x, 1, NoEventMask,
+ NoEventMask , NullGrab);
+}
+
+int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
+ Window requestor, Atom property, Atom target, Time time)
+{
+ const char *strTarget;
+ int i;
+
+ if (agentClipboardStatus != 1 ||
+ nxagentOption(Clipboard) == ClipboardServer)
+ {
+ return 0;
+ }
+
+ /*
+ * There is a client owner on the agent side, let normal stuff happen.
+ */
+
+ /*
+ * Only for PRIMARY and CLIPBOARD selections.
+ */
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ if ((selection == CurrentSelections[i].selection) &&
+ (lastSelectionOwner[i].client != NULL))
+ {
+ return 0;
+ }
+ }
+
+ if (lastClientWindowPtr != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConvertSelection: lastClientWindowPtr != NULL.\n");
+ #endif
+
+ if ((GetTimeInMillis() - lastClientReqTime) > 5000)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentConvertSelection: timeout expired on last request, "
+ "notifying failure to client\n");
+ #endif
+
+ nxagentNotifyConvertFailure(lastClientClientPtr, lastClientRequestor,
+ lastClientSelection, lastClientTarget, lastClientTime);
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentConvertSelection: got request "
+ "before timeout expired on last request, notifying failure to client\n");
+ #endif
+
+ nxagentNotifyConvertFailure(client, requestor, selection, target, time);
+
+ return 1;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentConvertSelection: client [%d] ask for sel [%s] "
+ "on window [%lx] prop [%s] target [%s].\n",
+ client -> index, validateString(NameForAtom(selection)), requestor,
+ validateString(NameForAtom(property)), validateString(NameForAtom(target)));
+ #endif
+
+ strTarget = NameForAtom(target);
+
+ if (strTarget == NULL)
+ {
+ return 1;
+ }
+
+ if (target == clientTARGETS)
+ {
+ Atom xa_STRING[4];
+ xEvent x;
+
+ /* --- Order changed by dimbor (prevent sending COMPOUND_TEXT to client --- */
+ xa_STRING[0] = XA_STRING;
+ xa_STRING[1] = clientUTF8_STRING;
+ xa_STRING[2] = clientTEXT;
+ xa_STRING[3] = clientCOMPOUND_TEXT;
+
+ ChangeWindowProperty(pWin,
+ property,
+ MakeAtom("ATOM", 4, 1),
+ sizeof(Atom)*8,
+ PropModeReplace,
+ 4,
+ &xa_STRING, 1);
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionNotify;
+ x.u.selectionNotify.time = time;
+ x.u.selectionNotify.requestor = requestor;
+ x.u.selectionNotify.selection = selection;
+ x.u.selectionNotify.target = target;
+ x.u.selectionNotify.property = property;
+
+ (void) TryClientEvents(client, &x, 1, NoEventMask,
+ NoEventMask , NullGrab);
+
+ return 1;
+ }
+
+ if (target == MakeAtom("TIMESTAMP", 9, 1))
+ {
+ xEvent x;
+ int i = 0;
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != selection) i++;
+
+ if (i < NumCurrentSelections)
+ {
+ ChangeWindowProperty(pWin,
+ property,
+ target,
+ 32,
+ PropModeReplace,
+ 1,
+ (unsigned char *) &lastSelectionOwner[i].lastTimeChanged,
+ 1);
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionNotify;
+ x.u.selectionNotify.time = time;
+ x.u.selectionNotify.requestor = requestor;
+ x.u.selectionNotify.selection = selection;
+ x.u.selectionNotify.target = target;
+ x.u.selectionNotify.property = property;
+
+ (void) TryClientEvents(client, &x, 1, NoEventMask,
+ NoEventMask , NullGrab);
+
+ return 1;
+
+ }
+ }
+
+ if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < 5000))
+ {
+ /*
+ * The same client made consecutive requests
+ * of clipboard contents with less than 5
+ * seconds time interval between them.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentConvertSelection: Consecutives request from client [%p] selection [%ld] "
+ "elapsed time [%lu] clientAccum [%d]\n", (void *) client, selection,
+ GetTimeInMillis() - lastClientReqTime, clientAccum);
+ #endif
+
+ clientAccum++;
+ }
+ else
+ {
+ if (lastClientClientPtr != client)
+ {
+ clientAccum = 0;
+ }
+ }
+
+ if ((target == clientTEXT) ||
+ (target == XA_STRING) ||
+ (target == clientCOMPOUND_TEXT) ||
+ (target == clientUTF8_STRING))
+ {
+ lastClientWindowPtr = pWin;
+ lastClientStage = SelectionStageNone;
+ lastClientRequestor = requestor;
+ lastClientClientPtr = client;
+ lastClientTime = time;
+ lastClientProperty = property;
+ lastClientSelection = selection;
+ lastClientTarget = target;
+
+ lastClientReqTime = (GetTimeInMillis() - lastClientReqTime) > 5000 ?
+ GetTimeInMillis() : lastClientReqTime;
+
+ if (selection == MakeAtom("CLIPBOARD", 9, 0))
+ {
+ selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+ }
+
+ if (target == clientUTF8_STRING)
+ {
+ XConvertSelection(nxagentDisplay, selection, serverUTF8_STRING, serverCutProperty,
+ serverWindow, CurrentTime);
+ }
+ else
+ {
+ XConvertSelection(nxagentDisplay, selection, XA_STRING, serverCutProperty,
+ serverWindow, CurrentTime);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentConvertSelection: Sent XConvertSelection with target=[%s], property [%s]\n",
+ validateString(NameForAtom(target)), validateString(NameForAtom(property)));
+ #endif
+
+ return 1;
+ }
+ else
+ {
+ xEvent x;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentConvertSelection: Xserver generates a SelectionNotify event "
+ "to the requestor with property None.\n");
+ #endif
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = SelectionNotify;
+ x.u.selectionNotify.time = time;
+ x.u.selectionNotify.requestor = requestor;
+ x.u.selectionNotify.selection = selection;
+ x.u.selectionNotify.target = target;
+ x.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &x, 1, NoEventMask, NoEventMask , NullGrab);
+ return 1;
+ }
+ return 0;
+}
+
+int nxagentSendNotify(xEvent *event)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSendNotify: Got called.\n");
+ #endif
+
+ if (agentClipboardStatus != 1)
+ {
+ return 0;
+ }
+
+ if (event->u.selectionNotify.property == clientCutProperty)
+ {
+ XSelectionEvent x;
+ int result;
+
+ /*
+ * Setup selection notify event to real server.
+ */
+
+ memset(&x, 0, sizeof(XSelectionEvent));
+ x.type = SelectionNotify;
+ x.send_event = True;
+ x.display = nxagentDisplay;
+ x.requestor = serverWindow;
+
+ /*
+ * On real server, the right CLIPBOARD atom is
+ * XInternAtom(nxagentDisplay, "CLIPBOARD", 1).
+ */
+
+ if (event->u.selectionNotify.selection == MakeAtom("CLIPBOARD", 9, 0))
+ {
+ x.selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+ }
+ else
+ {
+ x.selection = event->u.selectionNotify.selection;
+ }
+
+ x.target = event->u.selectionNotify.target;
+ x.property = event->u.selectionNotify.property;
+ x.time = CurrentTime;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSendNotify: Propagating clientCutProperty.\n");
+ #endif
+
+ result = XSendEvent (nxagentDisplay, x.requestor, False,
+ 0L, (XEvent *) &x);
+
+ if (result == BadValue || result == BadWindow)
+ {
+ fprintf (stderr, "nxagentSendNotify: XSendEvent failed.\n");
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin)
+{
+ int i = 0;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetClipboardWindow: Got called.\n");
+ #endif
+
+ while ((i < nxagentMaxSelections) &&
+ (lastSelectionOwner[i].selection != nxagentLastRequestedSelection))
+ {
+ i++;
+ }
+
+ if ((i < nxagentMaxSelections) && (property == clientCutProperty) &&
+ (lastSelectionOwner[i].windowPtr != NULL))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetClipboardWindow: Returning last clipboard owner window.\n");
+ #endif
+
+ return lastSelectionOwner[i].windowPtr;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetClipboardWindow: Returning original target window.\n");
+ #endif
+
+ return pWin;
+ }
+
+}
+
+int nxagentInitClipboard(WindowPtr pWin)
+{
+ int i;
+ Window iWindow = nxagentWindow(pWin);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentInitClipboard: Got called.\n");
+ #endif
+
+ if (lastSelectionOwner != NULL)
+ {
+ free(lastSelectionOwner);
+ lastSelectionOwner = NULL;
+ }
+
+ lastSelectionOwner = (SelectionOwner *) malloc(2 * sizeof(SelectionOwner));
+
+ if (lastSelectionOwner == NULL)
+ {
+ FatalError("nxagentInitClipboard: Failed to allocate memory for the clipboard selections.\n");
+ }
+
+ nxagentClipboardAtom = nxagentAtoms[10]; /* CLIPBOARD */
+ nxagentTimestampAtom = nxagentAtoms[11]; /* TIMESTAMP */
+
+ lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY;
+ lastSelectionOwner[nxagentPrimarySelection].client = NullClient;
+ lastSelectionOwner[nxagentPrimarySelection].window = screenInfo.screens[0]->root->drawable.id;
+ lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL;
+ lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis();
+
+ lastSelectionOwner[nxagentClipboardSelection].selection = nxagentClipboardAtom;
+ lastSelectionOwner[nxagentClipboardSelection].client = NullClient;
+ lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id;
+ lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL;
+ lastSelectionOwner[nxagentClipboardSelection].lastTimeChanged = GetTimeInMillis();
+
+ #ifdef NXAGENT_TIMESTAMP
+ {
+ extern unsigned long startTime;
+
+ fprintf(stderr, "nxagentInitClipboard: Initializing start [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+ #endif
+
+ agentClipboardStatus = 0;
+ serverWindow = iWindow;
+
+ /*
+ * Local property to hold pasted data.
+ */
+
+ serverCutProperty = nxagentAtoms[5]; /* NX_CUT_BUFFER_SERVER */
+ serverTARGETS = nxagentAtoms[6]; /* TARGETS */
+ serverTEXT = nxagentAtoms[7]; /* TEXT */
+ serverUTF8_STRING = nxagentAtoms[12]; /* UTF8_STRING */
+
+ if (serverCutProperty == None)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentInitClipboard: PANIC! Could not create NX_CUT_BUFFER_SERVER atom\n");
+ #endif
+
+ return -1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitClipboard: Setting owner of selection [%s][%d] on window 0x%lx\n",
+ "NX_CUT_BUFFER_SERVER", (int) serverCutProperty, iWindow);
+ #endif
+
+ XSetSelectionOwner(nxagentDisplay, serverCutProperty, iWindow, CurrentTime);
+
+ if (XQueryExtension(nxagentDisplay,
+ "XFIXES",
+ &nxagentXFixesInfo.Opcode,
+ &nxagentXFixesInfo.EventBase,
+ &nxagentXFixesInfo.ErrorBase) == 0)
+ {
+ ErrorF("Unable to initialize XFixes extension.\n");
+ }
+
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitClipboard: Registering for XFixesSelectionNotify events.\n");
+ #endif
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ XFixesSelectSelectionInput(nxagentDisplay, iWindow,
+ lastSelectionOwner[i].selection,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+ }
+
+ nxagentXFixesInfo.Initialized = 1;
+ }
+
+ /*
+ The first paste from CLIPBOARD did not work directly after
+ session start. Removing this code makes it work. It is unsure why
+ it was introduced in the first place so it is possible that we
+ see other effects by leaving out this code.
+
+ Fixes X2Go bug #952, see https://bugs.x2go.org/952 for details .
+
+ if (nxagentSessionId[0])
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitClipboard: setting the ownership of %s to %lx"
+ " and registering for PropertyChangeMask events\n",
+ validateString(XGetAtomName(nxagentDisplay, nxagentAtoms[10])), iWindow);
+ #endif
+
+ XSetSelectionOwner(nxagentDisplay, nxagentAtoms[10], iWindow, CurrentTime);
+ pWin -> eventMask |= PropertyChangeMask;
+ nxagentChangeWindowAttributes(pWin, CWEventMask);
+ }
+ */
+
+ if (nxagentReconnectTrap)
+ {
+ /*
+ * Only for PRIMARY and CLIPBOARD selections.
+ */
+
+ for (i = 0; i < nxagentMaxSelections; i++)
+ {
+ if (lastSelectionOwner[i].client && lastSelectionOwner[i].window)
+ {
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, iWindow, CurrentTime);
+ }
+ }
+ }
+ else
+ {
+ lastSelectionOwner[nxagentPrimarySelection].client = NULL;
+ lastSelectionOwner[nxagentClipboardSelection].client = NULL;
+
+ lastServerRequestor = None;
+
+ lastClientWindowPtr = NULL;
+ lastClientStage = SelectionStageNone;
+ lastClientReqTime = GetTimeInMillis();
+
+ clientCutProperty = MakeAtom(szAgentNX_CUT_BUFFER_CLIENT,
+ strlen(szAgentNX_CUT_BUFFER_CLIENT), 1);
+ clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
+ clientTEXT = MakeAtom(szAgentTEXT, strlen(szAgentTEXT), True);
+ clientCOMPOUND_TEXT = MakeAtom(szAgentCOMPOUND_TEXT, strlen(szAgentCOMPOUND_TEXT), True);
+ clientUTF8_STRING = MakeAtom(szAgentUTF8_STRING, strlen(szAgentUTF8_STRING), True);
+
+ if (clientCutProperty == None)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentInitClipboard: PANIC! "
+ "Could not create NX_CUT_BUFFER_CLIENT atom.\n");
+ #endif
+
+ return -1;
+ }
+ }
+
+ agentClipboardStatus = 1;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentInitClipboard: Clipboard initialization completed.\n");
+ #endif
+
+ #ifdef NXAGENT_TIMESTAMP
+ {
+ extern unsigned long startTime;
+
+ fprintf(stderr, "nxagentInitClipboard: initializing ends [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+ #endif
+
+ return 1;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
new file mode 100644
index 000000000..62fc32fd9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -0,0 +1,69 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Clipboard_H__
+#define __Clipboard_H__
+
+/*
+ * Queried at clipboard initialization.
+ */
+
+typedef struct _XFixesAgentInfo
+{
+ int Opcode;
+ int EventBase;
+ int ErrorBase;
+ int Initialized;
+
+} XFixesAgentInfoRec;
+
+extern XFixesAgentInfoRec nxagentXFixesInfo;
+
+/*
+ * Create the NX_CUT_BUFFER_CLIENT atom and
+ * initialize the required property to exchange
+ * data with the X server.
+ */
+
+extern int nxagentInitClipboard(WindowPtr pWindow);
+
+/*
+ * Called whenever a client or a window is
+ * destroyed to let the clipboard code to
+ * release any pointer to the referenced
+ * structures.
+ */
+
+extern void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow);
+
+extern void nxagentSetSelectionOwner(Selection *pSelection);
+extern int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
+ Window requestor, Atom property, Atom target, Time time);
+
+void nxagentClearSelection();
+void nxagentRequestSelection();
+void nxagentNotifySelection();
+
+#endif /* __Clipboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
new file mode 100644
index 000000000..c21bcbbe7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -0,0 +1,600 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Agent.h"
+
+
+#include "Display.h"
+#include "Screen.h"
+#include "Colormap.h"
+#include "Visual.h"
+#include "Windows.h"
+#include "Args.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+static ColormapPtr InstalledMaps[MAXSCREENS];
+
+static Bool nxagentInstalledDefaultColormap = False;
+
+Bool nxagentReconnectAllColormap(void *p0);
+
+Bool nxagentCreateColormap(ColormapPtr pCmap)
+{
+ VisualPtr pVisual;
+ XColor *colors;
+ int i, ncolors;
+ Pixel red, green, blue;
+ Pixel redInc, greenInc, blueInc;
+
+ Visual *visual;
+ int class;
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "nxagentCreateColormap: Going to create new colormap with "
+ " visual [%lu].\n", pCmap->pVisual);
+ #endif
+
+ pVisual = pCmap->pVisual;
+ ncolors = pVisual->ColormapEntries;
+
+ pCmap->devPriv = (void *)malloc(sizeof(nxagentPrivColormap));
+
+ if (((visual = nxagentVisual(pVisual))) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreateColormap: WARNING: Visual not found. Using default visual.\n");
+ #endif
+
+ visual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ class = nxagentVisuals[nxagentDefaultVisualIndex].class;
+ }
+ else
+ {
+ class = pVisual->class;
+ }
+
+
+ nxagentColormapPriv(pCmap)->colormap =
+ XCreateColormap(nxagentDisplay,
+ nxagentDefaultWindows[pCmap->pScreen->myNum],
+ visual,
+ (class & DynamicClass) ?
+ AllocAll : AllocNone);
+
+ switch (class) {
+ case StaticGray: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].red;
+ pCmap->red[i].co.local.blue = colors[i].red;
+ }
+ free(colors);
+ break;
+
+ case StaticColor: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].green;
+ pCmap->red[i].co.local.blue = colors[i].blue;
+ }
+ free(colors);
+ break;
+
+ case TrueColor: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ red = green = blue = 0L;
+ redInc = lowbit(pVisual->redMask);
+ greenInc = lowbit(pVisual->greenMask);
+ blueInc = lowbit(pVisual->blueMask);
+ for (i = 0; i < ncolors; i++) {
+ colors[i].pixel = red | green | blue;
+ red += redInc;
+ if (red > pVisual->redMask) red = 0L;
+ green += greenInc;
+ if (green > pVisual->greenMask) green = 0L;
+ blue += blueInc;
+ if (blue > pVisual->blueMask) blue = 0L;
+ }
+ XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->green[i].co.local.green = colors[i].green;
+ pCmap->blue[i].co.local.blue = colors[i].blue;
+ }
+ free(colors);
+ break;
+
+ case GrayScale: /* read and write */
+ break;
+
+ case PseudoColor: /* read and write */
+ break;
+
+ case DirectColor: /* read and write */
+ break;
+ }
+
+ return True;
+}
+
+void nxagentDestroyColormap(ColormapPtr pCmap)
+{
+ XFreeColormap(nxagentDisplay, nxagentColormap(pCmap));
+ free(pCmap->devPriv);
+}
+
+#define SEARCH_PREDICATE \
+ (nxagentWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
+
+static int nxagentCountInstalledColormapWindows(WindowPtr pWin, void * ptr)
+{
+ nxagentInstalledColormapWindows *icws = (nxagentInstalledColormapWindows *) ptr;
+
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->numWindows++;
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int nxagentGetInstalledColormapWindows(WindowPtr pWin, void * ptr)
+{
+ nxagentInstalledColormapWindows *icws = (nxagentInstalledColormapWindows *)ptr;
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->windows[icws->index++] = nxagentWindow(pWin);
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static Window *nxagentOldInstalledColormapWindows = NULL;
+static int nxagentNumOldInstalledColormapWindows = 0;
+
+static Bool nxagentSameInstalledColormapWindows(Window *windows, int numWindows)
+{
+ if (nxagentNumOldInstalledColormapWindows != numWindows)
+ return False;
+
+ if (nxagentOldInstalledColormapWindows == windows)
+ return True;
+
+ if (nxagentOldInstalledColormapWindows == NULL || windows == NULL)
+ return False;
+
+ if (memcmp(nxagentOldInstalledColormapWindows, windows,
+ numWindows * sizeof(Window)))
+ return False;
+
+ return True;
+}
+
+void nxagentSetInstalledColormapWindows(ScreenPtr pScreen)
+{
+ nxagentInstalledColormapWindows icws;
+ int numWindows;
+
+ icws.cmapIDs = (Colormap *)malloc(pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ icws.numCmapIDs = nxagentListInstalledColormaps(pScreen, icws.cmapIDs);
+ icws.numWindows = 0;
+ WalkTree(pScreen, nxagentCountInstalledColormapWindows, (void *)&icws);
+ if (icws.numWindows) {
+ icws.windows = (Window *)malloc((icws.numWindows + 1) * sizeof(Window));
+ icws.index = 0;
+ WalkTree(pScreen, nxagentGetInstalledColormapWindows, (void *)&icws);
+ icws.windows[icws.numWindows] = nxagentDefaultWindows[pScreen->myNum];
+ numWindows = icws.numWindows + 1;
+ }
+ else {
+ icws.windows = NULL;
+ numWindows = 0;
+ }
+
+ free(icws.cmapIDs);
+
+ if (!nxagentSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
+ if (nxagentOldInstalledColormapWindows)
+ free(nxagentOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ int i;
+ Window64 *windows = (Window64 *)malloc(numWindows * sizeof(Window64));
+
+ for(i = 0; i < numWindows; ++i)
+ windows[i] = icws.windows[i];
+ XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ windows, numWindows);
+ free(windows);
+ }
+#else
+ XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ icws.windows, numWindows);
+#endif
+
+ nxagentOldInstalledColormapWindows = icws.windows;
+ nxagentNumOldInstalledColormapWindows = icws.numWindows;
+
+#ifdef DUMB_WINDOW_MANAGERS
+ /*
+ This code is for dumb window managers.
+ This will only work with default local visual colormaps.
+ */
+ if (icws.numWindows)
+ {
+ WindowPtr pWin;
+ Visual *visual;
+ ColormapPtr pCmap;
+
+ pWin = nxagentWindowPtr(icws.windows[0]);
+ visual = nxagentVisualFromID(pScreen, wVisual(pWin));
+
+ if (visual == nxagentDefaultVisual(pScreen))
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin),
+ RT_COLORMAP);
+ else
+ pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+
+ if (pCmap != NULL)
+ {
+ XSetWindowColormap(nxagentDisplay,
+ nxagentDefaultWindows[pScreen->myNum],
+ nxagentColormap(pCmap));
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "nxagentSetInstalledColormapWindows: WARNING! "
+ "Window at [%p] has no colormap with class [%d].\n",
+ (void *)pWin, pWin -> drawable.class);
+ }
+ #endif
+ }
+#endif /* DUMB_WINDOW_MANAGERS */
+ }
+ else
+ if (icws.windows) free(icws.windows);
+}
+
+void nxagentSetScreenSaverColormapWindow(ScreenPtr pScreen)
+{
+ if (nxagentOldInstalledColormapWindows)
+ free(nxagentOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ Window64 window;
+
+ window = nxagentScreenSaverWindows[pScreen->myNum];
+ XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ &window, 1);
+ nxagentScreenSaverWindows[pScreen->myNum] = window;
+ }
+#else
+ XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ &nxagentScreenSaverWindows[pScreen->myNum], 1);
+#endif /* _XSERVER64 */
+
+ nxagentOldInstalledColormapWindows = NULL;
+ nxagentNumOldInstalledColormapWindows = 0;
+
+ nxagentDirectUninstallColormaps(pScreen);
+}
+
+void nxagentDirectInstallColormaps(ScreenPtr pScreen)
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!nxagentDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+ if (pCmap)
+ XInstallColormap(nxagentDisplay, nxagentColormap(pCmap));
+ }
+}
+
+void nxagentDirectUninstallColormaps(ScreenPtr pScreen)
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!nxagentDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+ if (pCmap)
+ XUninstallColormap(nxagentDisplay, nxagentColormap(pCmap));
+ }
+}
+
+void nxagentInstallColormap(ColormapPtr pCmap)
+{
+ int index;
+ ColormapPtr pOldCmap;
+
+ index = pCmap->pScreen->myNum;
+ pOldCmap = InstalledMaps[index];
+
+ if(pCmap != pOldCmap)
+ {
+ nxagentDirectUninstallColormaps(pCmap->pScreen);
+
+ /* Uninstall pInstalledMap. Notify all interested parties. */
+ if(pOldCmap != (ColormapPtr)None)
+ WalkTree(pCmap->pScreen, TellLostMap, (void *)&pOldCmap->mid);
+
+ InstalledMaps[index] = pCmap;
+ WalkTree(pCmap->pScreen, TellGainedMap, (void *)&pCmap->mid);
+
+ nxagentSetInstalledColormapWindows(pCmap->pScreen);
+ nxagentDirectInstallColormaps(pCmap->pScreen);
+ }
+}
+
+void nxagentUninstallColormap(ColormapPtr pCmap)
+{
+ int index;
+ ColormapPtr pCurCmap;
+
+ index = pCmap->pScreen->myNum;
+ pCurCmap = InstalledMaps[index];
+
+ if(pCmap == pCurCmap)
+ {
+ if ((unsigned int)pCmap->mid != pCmap->pScreen->defColormap)
+ {
+ pCurCmap = (ColormapPtr)LookupIDByType(pCmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pCmap->pScreen->InstallColormap)(pCurCmap);
+ }
+ }
+}
+
+int nxagentListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds)
+{
+ if (nxagentInstalledDefaultColormap)
+ {
+ *pCmapIds = InstalledMaps[pScreen->myNum]->mid;
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void nxagentStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors)
+{
+ if (pCmap->pVisual->class & DynamicClass)
+#ifdef _XSERVER64
+ {
+ int i;
+ XColor *pColors64 = (XColor *)malloc(nColors * sizeof(XColor) );
+
+ for(i = 0; i < nColors; ++i)
+ {
+ pColors64[i].pixel = pColors[i].pixel;
+ pColors64[i].red = pColors[i].red;
+ pColors64[i].green = pColors[i].green;
+ pColors64[i].blue = pColors[i].blue;
+ pColors64[i].flags = pColors[i].flags;
+ }
+ XStoreColors(nxagentDisplay, nxagentColormap(pCmap), pColors64, nColors);
+ free(pColors64);
+ }
+#else
+ XStoreColors(nxagentDisplay, nxagentColormap(pCmap),
+ (XColor *)pColors, nColors);
+#endif
+}
+
+void nxagentResolveColor(unsigned short *pRed, unsigned short *pGreen,
+ unsigned short *pBlue, VisualPtr pVisual)
+{
+ int shift;
+ unsigned int lim;
+
+ shift = 16 - pVisual->bitsPerRGBValue;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+ {
+ /* rescale to rgb bits */
+ *pRed = ((*pRed >> shift) * 65535) / lim;
+ *pGreen = ((*pGreen >> shift) * 65535) / lim;
+ *pBlue = ((*pBlue >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ unsigned int limg;
+
+ limg = pVisual->ColormapEntries - 1;
+ /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ /* rescale to [0..limN] then [0..65535] then rgb bits */
+ *pRed = ((((((*pRed * (limr + 1)) >> 16) *
+ 65535) / limr) >> shift) * 65535) / lim;
+ *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
+ 65535) / limg) >> shift) * 65535) / lim;
+ *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
+ 65535) / limb) >> shift) * 65535) / lim;
+ }
+}
+
+Bool nxagentCreateDefaultColormap(ScreenPtr pScreen)
+{
+ VisualPtr pVisual;
+ ColormapPtr pCmap;
+ unsigned short zero = 0, ones = 0xFFFF;
+ Pixel wp, bp;
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Searching for the root visual [%lu].\n",
+ pScreen->rootVisual);
+ #endif
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++);
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
+ != Success)
+ return False;
+
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+ (*pScreen->InstallColormap)(pCmap);
+
+ nxagentInstalledDefaultColormap = True;
+
+ return True;
+}
+
+static void nxagentReconnectColormap(void * p0, XID x1, void * p2)
+{
+ ColormapPtr pCmap = (ColormapPtr)p0;
+ Bool* pBool = (Bool*)p2;
+ VisualPtr pVisual;
+
+ #ifdef NXAGENT_RECONNECT_COLORMAP_DEBUG
+ fprintf(stderr, "nxagentReconnectColormap: %p\n", pCmap);
+ #endif
+
+ if (!*pBool || !pCmap)
+ return;
+
+ pVisual = pCmap -> pVisual;
+
+ nxagentColormapPriv(pCmap)->colormap =
+ XCreateColormap(nxagentDisplay,
+ nxagentDefaultWindows[pCmap->pScreen->myNum],
+ nxagentVisual(pVisual),
+ (pVisual->class & DynamicClass) ?
+ AllocAll : AllocNone);
+
+ #ifdef NXAGENT_RECONNECT_COLORMAP_DEBUG
+ fprintf(stderr, "nxagentReconnectColormap: %p - ID %xl\n",
+ pCmap, nxagentColormap(pCmap));
+ #endif
+}
+
+Bool nxagentReconnectAllColormap(void *p0)
+{
+ int cid;
+ Bool success = True;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_COLORMAP_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllColormap\n");
+ #endif
+
+ for (cid = 0; (cid < MAXCLIENTS) && success; cid++)
+ {
+ if (clients[cid] && success)
+ {
+ FindClientResourcesByType(clients[cid], RT_COLORMAP, nxagentReconnectColormap, &success);
+ }
+ }
+
+ return success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
new file mode 100644
index 000000000..fc3c828f9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -0,0 +1,92 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Color_H__
+#define __Color_H__
+
+#define DUMB_WINDOW_MANAGERS
+
+#define MAXCMAPS 1
+#define MINCMAPS 1
+
+typedef struct {
+ Colormap colormap;
+} nxagentPrivColormap;
+
+typedef struct {
+ int numCmapIDs;
+ Colormap *cmapIDs;
+ int numWindows;
+ Window *windows;
+ int index;
+} nxagentInstalledColormapWindows;
+
+#define nxagentColormapPriv(pCmap) \
+ ((nxagentPrivColormap *)((pCmap)->devPriv))
+
+#define nxagentColormap(pCmap) (nxagentColormapPriv(pCmap)->colormap)
+
+#define nxagentPixel(pixel) (pixel)
+
+Bool nxagentCreateColormap(ColormapPtr pCmap);
+
+void nxagentDestroyColormap(ColormapPtr pCmap);
+
+void nxagentSetInstalledColormapWindows(ScreenPtr pScreen);
+
+void nxagentSetScreenSaverColormapWindow(ScreenPtr pScreen);
+
+void nxagentDirectInstallColormaps(ScreenPtr pScreen);
+
+void nxagentDirectUninstallColormaps(ScreenPtr pScreen);
+
+void nxagentInstallColormap(ColormapPtr pCmap);
+
+void nxagentUninstallColormap(ColormapPtr pCmap);
+
+int nxagentListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds);
+
+void nxagentStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors);
+
+void nxagentResolveColor(unsigned short *pRed, unsigned short *pGreen,
+ unsigned short *pBlue, VisualPtr pVisual);
+
+Bool nxagentCreateDefaultColormap(ScreenPtr pScreen);
+
+#endif /* __Color_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
new file mode 100644
index 000000000..bd84c52b0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -0,0 +1,207 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "Agent.h"
+#include "Screen.h"
+#include "Display.h"
+#include "Options.h"
+#include "Windows.h"
+
+#include "X11/include/Xcomposite_nxagent.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Set if the composite extension is supported
+ * by the remote display.
+ */
+
+int nxagentCompositeEnable = UNDEFINED;
+
+void nxagentCompositeExtensionInit()
+{
+ /*
+ * Set the flag only if the initialization
+ * completes.
+ */
+
+ nxagentCompositeEnable = 0;
+
+ if (nxagentOption(Composite) == 1)
+ {
+ int eventBase, errorBase;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositeExtensionInit: Checking if the composite extension is supported.\n");
+ #endif
+
+ if (XCompositeQueryExtension(nxagentDisplay, &eventBase, &errorBase) == 1)
+ {
+ /*
+ * At the moment we don't need to care
+ * the version of the extension.
+ */
+
+ #ifdef TEST
+
+ int major = -1;
+ int minor = -1;
+
+ XCompositeQueryVersion(nxagentDisplay, &major, &minor);
+
+ fprintf(stderr, "nxagentCompositeExtensionInit: The remote display supports version [%d] "
+ "minor [%d].\n", major, minor);
+
+ if (major < 0 || minor < 2)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCompositeExtensionInit: WARNING! Potentially incompatible version "
+ "[%d] minor [%d] detected.\n", major, minor);
+ #endif
+ }
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositeExtensionInit: Enabling the use of the composite extension.\n");
+ #endif
+
+ nxagentCompositeEnable = 1;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentCompositeExtensionInit: Composite extension not supported on this display.\n");
+ }
+ #endif
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentRenderExtensionInit: Use of the composite extension not enabled.\n");
+ }
+ #endif
+}
+
+void nxagentRedirectDefaultWindows()
+{
+ int i;
+
+ if (nxagentOption(Rootless) == 1 ||
+ nxagentCompositeEnable == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRedirectDefaultWindows: Not redirecting default "
+ "windows with rootless mode [%d] and composite [%d].\n",
+ nxagentOption(Rootless), nxagentCompositeEnable);
+ #endif
+
+ return;
+ }
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ WindowPtr pWin = screenInfo.screens[i]->root;
+
+ ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRedirectDefaultWindows: WARNING! Redirecting default window id [%ld] "
+ "to off-screen memory.\n", (long int)nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+
+ /*
+ * When trying to redirect only the top level window,
+ * and not the subwindows, we incur in a strange be-
+ * haviour. The top level is unmapped, mapped, unmap-
+ * ped and then reparented. This at first makes the
+ * agent think that the window manager is gone, then
+ * the agent window disappears. To make thinks even
+ * more weird, this happens only at reconnection.
+ */
+
+ XCompositeRedirectSubwindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ CompositeRedirectAutomatic);
+ }
+}
+
+void nxagentRedirectWindow(WindowPtr pWin)
+{
+ if (nxagentOption(Rootless) == 0 ||
+ nxagentCompositeEnable == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRedirectWindow: Not redirecting window id [%ld] "
+ "to off-screen memory with rootless mode [%d] and composite [%d].\n",
+ nxagentWindow(pWin), nxagentOption(Rootless),
+ nxagentCompositeEnable);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRedirectWindow: WARNING! Redirecting window id [%ld] "
+ "to off-screen memory.\n", (long int)nxagentWindow(pWin));
+ #endif
+
+ XCompositeRedirectWindow(nxagentDisplay, nxagentWindow(pWin),
+ CompositeRedirectAutomatic);
+
+ nxagentWindowPriv(pWin) -> isRedirected = 1;
+}
+
+void nxagentUnredirectWindow(WindowPtr pWin)
+{
+ if (nxagentWindowPriv(pWin) -> isRedirected == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRedirectWindow: Disabling redirection of window id [%ld] "
+ "to off-screen memory.\n", nxagentWindow(pWin));
+ #endif
+
+ XCompositeUnredirectWindow(nxagentDisplay, nxagentWindow(pWin),
+ CompositeRedirectAutomatic);
+
+ nxagentWindowPriv(pWin) -> isRedirected = 0;
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "nxagentUnredirectWindow: WARNING! The window id [%ld] "
+ "was not redirected.\n", (long int)nxagentWindow(pWin));
+ }
+ #endif
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
new file mode 100644
index 000000000..abe2551bf
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -0,0 +1,59 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Composite_H__
+#define __Composite_H__
+
+/*
+ * Set if the extension is present and
+ * its use is enabled.
+ */
+
+extern int nxagentCompositeEnable;
+
+/*
+ * Query the composite extension on the
+ * remote display and set the flag if
+ * it is supported.
+ */
+
+void nxagentCompositeExtensionInit(void);
+
+/*
+ * Let the X server redirect the window
+ * on the off-screen memory.
+ */
+
+void nxagentRedirectDefaultWindows(void);
+
+/*
+ * Enable or disabel the redirection of
+ * the given window.
+ */
+
+void nxagentRedirectWindow(WindowPtr pWin);
+void nxagentUnredirectWindow(WindowPtr pWin);
+
+#endif /* __Composite_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
new file mode 100644
index 000000000..1db26b7ec
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -0,0 +1,600 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "inputstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+#include "Image.h"
+#include "Visual.h"
+#include "Keyboard.h"
+#include "Args.h"
+#include "Windows.h"
+#include "Events.h"
+#include "Render.h"
+#include "Client.h"
+
+#include "windowstr.h"
+#include "resource.h"
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Defined in Display.c. There are huge
+ * problems mixing the GC definition in
+ * Xlib with the server code. This must
+ * be reworked.
+ */
+
+extern XlibGC nxagentBitmapGC;
+
+/*
+ * From NXevents.c.
+ */
+
+extern CursorPtr GetSpriteCursor(void);
+
+void nxagentConstrainCursor(ScreenPtr pScreen, BoxPtr pBox)
+{
+ #ifdef TEST
+
+ int width, height;
+
+ width = nxagentOption(RootWidth);
+ height = nxagentOption(RootHeight);
+
+ if (pBox->x1 <= 0 && pBox->y1 <= 0 &&
+ pBox->x2 >= width && pBox->y2 >= height)
+ {
+ fprintf(stderr, "nxagentConstrainCursor: Called with box [%d,%d,%d,%d]. "
+ "Skipping the operation.\n", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentConstrainCursor: WARNING! Called with box [%d,%d,%d,%d].\n",
+ pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ }
+
+ #endif
+}
+
+void nxagentCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
+ BoxPtr pHotBox, BoxPtr pTopLeftBox)
+{
+ *pTopLeftBox = *pHotBox;
+}
+
+Bool nxagentDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+
+ /*
+ * Don't define the root cursor
+ * so that nxagent root window
+ * inherits the parent's cursor.
+ */
+
+ Cursor cursor;
+
+ cursor = (pCursor != rootCursor) ? nxagentCursor(pCursor, pScreen): None;
+
+ if (nxagentOption(Rootless) == False)
+ {
+ XDefineCursor(nxagentDisplay,
+ nxagentInputWindows[pScreen -> myNum],
+ cursor);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisplayCursor: Called for cursor at [%p] with private [%p].\n",
+ (void *) pCursor, pCursor->devPriv[pScreen->myNum]);
+ #endif
+ }
+
+ return True;
+}
+
+Bool nxagentRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ XImage *image;
+ Pixmap source, mask;
+ XColor fg_color, bg_color;
+ unsigned long valuemask;
+ XGCValues values;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRealizeCursor: Called for cursor at [%p].\n", (void *) pCursor);
+ #endif
+
+ valuemask = GCFunction |
+ GCPlaneMask |
+ GCForeground |
+ GCBackground |
+ GCClipMask;
+
+ values.function = GXcopy;
+ values.plane_mask = AllPlanes;
+ values.foreground = 1L;
+ values.background = 0L;
+ values.clip_mask = None;
+
+ XChangeGC(nxagentDisplay, nxagentBitmapGC, valuemask, &values);
+
+ source = XCreatePixmap(nxagentDisplay,
+ nxagentDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ mask = XCreatePixmap(nxagentDisplay,
+ nxagentDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ image = XCreateImage(nxagentDisplay,
+ nxagentDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->source,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(nxagentDisplay), 0);
+
+ /*
+ * If we used nxagentImageNormalize() here,
+ * we'd swap our own cursor data in place.
+ * Change byte_order and bitmap_bit_order
+ * in the image struct to let Xlib do the
+ * swap for us.
+ */
+
+ image -> byte_order = IMAGE_BYTE_ORDER;
+ image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+ NXCleanImage(image);
+
+ XPutImage(nxagentDisplay, source, nxagentBitmapGC, image,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(image);
+
+ image = XCreateImage(nxagentDisplay,
+ nxagentDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->mask,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(nxagentDisplay), 0);
+
+ image -> byte_order = IMAGE_BYTE_ORDER;
+ image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+ NXCleanImage(image);
+
+ XPutImage(nxagentDisplay, mask, nxagentBitmapGC, image,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(image);
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ pCursor->devPriv[pScreen->myNum] = (void *) malloc(sizeof(nxagentPrivCursor));
+
+ nxagentCursorPriv(pCursor, pScreen)->cursor =
+ XCreatePixmapCursor(nxagentDisplay, source, mask, &fg_color,
+ &bg_color, pCursor->bits->xhot, pCursor->bits->yhot);
+
+ nxagentCursorUsesRender(pCursor, pScreen) = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRealizeCursor: Set cursor private at [%p] cursor is [%ld].\n",
+ (void *) nxagentCursorPriv(pCursor, pScreen),
+ nxagentCursorPriv(pCursor, pScreen) -> cursor);
+ #endif
+
+ XFreePixmap(nxagentDisplay, source);
+ XFreePixmap(nxagentDisplay, mask);
+
+ return True;
+}
+
+Bool nxagentUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ if (nxagentCursorUsesRender(pCursor, pScreen))
+ {
+ PicturePtr pPicture = nxagentCursorPicture(pCursor, pScreen);
+
+ FreePicture(pPicture, pPicture -> id);
+ }
+
+ if (nxagentCursor(pCursor, pScreen) != None)
+ {
+ XFreeCursor(nxagentDisplay, nxagentCursor(pCursor, pScreen));
+
+ nxagentCursor(pCursor, pScreen) = None;
+ }
+
+ free(nxagentCursorPriv(pCursor, pScreen));
+
+ return True;
+}
+
+void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
+ Bool displayed)
+{
+ XColor fg_color, bg_color;
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ XRecolorCursor(nxagentDisplay,
+ nxagentCursor(pCursor, pScreen),
+ &fg_color, &bg_color);
+}
+
+Bool (*nxagentSetCursorPositionW)(ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+
+Bool nxagentSetCursorPosition(ScreenPtr pScreen, int x, int y,
+ Bool generateEvent)
+{
+ if (generateEvent != 0)
+ {
+ return (*nxagentSetCursorPositionW)(pScreen, x, y, generateEvent);
+ }
+ else
+ {
+ /*
+ * Calling miSetCursorPosition with generateEvent == 0
+ * causes a crash in miPoiterUpdate().
+ */
+
+ return 1;
+ }
+}
+
+void nxagentReconnectCursor(void * p0, XID x1, void * p2)
+{
+ Bool* pBool = (Bool*)p2;
+ CursorPtr pCursor = (CursorPtr) p0;
+
+ AnimCurPtr ac;
+ int j;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectCursor: pCursor at [%p]\n", pCursor);
+ #endif
+
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+ fprintf(stderr, "nxagentReconnectCursor: pCursor at [%p]\n", pCursor);
+ #endif
+
+ if (!*pBool || !pCursor)
+ {
+ return;
+ }
+
+ if (nxagentCursorPriv(pCursor, nxagentDefaultScreen) == 0)
+ {
+ if (nxagentIsAnimCursor(pCursor))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectCursor: nxagentIsAnimCursor pCursor at [%p]\n", pCursor);
+ #endif
+
+ ac = nxagentGetAnimCursor(pCursor);
+
+ for (j = 0; j < ac->nelt; j++)
+ {
+ nxagentReconnectCursor (ac->elts[j].pCursor, x1, p2);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectCursor: Iteration [%d] pCursor at [%p]\n", j, ac->elts[j].pCursor);
+ #endif
+ }
+ }
+ }
+
+ else
+ {
+ if (nxagentCursorUsesRender(pCursor, nxagentDefaultScreen))
+ {
+ PicturePtr pPicture = nxagentCursorPicture(pCursor, nxagentDefaultScreen);
+ int ret = 1;
+
+ nxagentReconnectPicture(pPicture, 0, &ret);
+
+ nxagentRenderRealizeCursor(nxagentDefaultScreen, pCursor);
+ }
+ else
+ {
+ free(nxagentCursorPriv(pCursor, nxagentDefaultScreen));
+ if (!nxagentRealizeCursor(nxagentDefaultScreen, pCursor))
+ {
+ fprintf(stderr, "nxagentReconnectCursor: nxagentRealizeCursor failed\n");
+ *pBool = False;
+ }
+ }
+ }
+
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+ fprintf(stderr, "nxagentReconnectCursor: %p - ID %lx\n", pCursor, nxagentCursor(pCursor, nxagentDefaultScreen));
+ #endif
+}
+
+/*
+ * The parameter is ignored at the moment.
+ */
+
+void nxagentReDisplayCurrentCursor()
+{
+ CursorPtr pCursor = GetSpriteCursor();
+
+ if (pCursor &&
+ nxagentCursorPriv(pCursor, nxagentDefaultScreen) &&
+ nxagentCursor(pCursor, nxagentDefaultScreen))
+ {
+ nxagentDisplayCursor(nxagentDefaultScreen, pCursor);
+ }
+}
+
+Bool nxagentReconnectAllCursor(void *p0)
+{
+ int i;
+ Bool r = True;
+
+ GrabPtr grab = inputInfo.pointer -> grab;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_CURSOR_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllCursor\n");
+ #endif
+
+ for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], RT_CURSOR, nxagentReconnectCursor, &r);
+
+ #ifdef WARNING
+
+ if (r == False)
+ {
+ fprintf(stderr, "nxagentReconnectAllCursor: WARNING! Failed to recreate "
+ "cursor for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ if (grab)
+ {
+ nxagentReconnectCursor(grab -> cursor, 0, &r);
+ }
+
+ return r;
+}
+
+void nxagentDisconnectCursor(void * p0, XID x1, void * p2)
+{
+ Bool* pBool = (Bool *) p2;
+ CursorPtr pCursor = (CursorPtr) p0;
+
+ AnimCurPtr ac;
+ int j;
+
+ if (!*pBool || !pCursor)
+ {
+ return;
+ }
+
+ if (nxagentCursorPriv(pCursor, nxagentDefaultScreen) == 0)
+ {
+ if (nxagentIsAnimCursor(pCursor))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectCursor: nxagentIsAnimCursor pCursor at [%p]\n", pCursor);
+ #endif
+
+ ac = nxagentGetAnimCursor(pCursor);
+
+ for (j = 0; j < ac->nelt; j++)
+ {
+ nxagentDisconnectCursor (ac->elts[j].pCursor, x1, p2);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectCursor: Iteration [%d] pCursor at [%p]\n", j, ac->elts[j].pCursor);
+ #endif
+ }
+ }
+ return;
+ }
+
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+ fprintf(stderr, "nxagentDisconnectCursor: %p - ID %lx\n",
+ pCursor,
+ nxagentCursor(pCursor, nxagentDefaultScreen));
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectCursor: Called with bool [%d].\n", *pBool);
+
+ fprintf(stderr, "nxagentDisconnectCursor: Pointer to cursor is [%p] with counter [%d].\n",
+ (void *) pCursor, pCursor -> refcnt);
+
+ fprintf(stderr, "nxagentDisconnectCursor: Dummy screen is at [%p].\n",
+ (void *) nxagentDefaultScreen);
+
+ fprintf(stderr, "nxagentDisconnectCursor: Cursor private is at [%p].\n",
+ (void *) nxagentCursorPriv(pCursor, nxagentDefaultScreen));
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectCursor: Dummy screen number is [%d].\n",
+ nxagentDefaultScreen -> myNum);
+
+ fprintf(stderr, "nxagentDisconnectCursor: Cursor is [%ld].\n",
+ nxagentCursor(pCursor, nxagentDefaultScreen));
+ #endif
+
+ nxagentCursor(pCursor, nxagentDefaultScreen) = None;
+
+ if (nxagentCursorUsesRender(pCursor, nxagentDefaultScreen))
+ {
+ PicturePtr pPicture = nxagentCursorPicture(pCursor, nxagentDefaultScreen);
+ int ret = 1;
+
+ #if defined(NXAGENT_RECONNECT_CURSOR_DEBUG) || defined(NXAGENT_RECONNECT_PICTURE_DEBUG)
+ fprintf(stderr, "nxagentDisconnectCursor: disconnecting attached picture %p\n", pPicture);
+ #endif
+
+ nxagentDisconnectPicture(pPicture, 0, &ret);
+ }
+}
+
+Bool nxagentDisconnectAllCursor()
+{
+ int i;
+ Bool r = True;
+
+ GrabPtr grab = inputInfo.pointer -> grab;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllCursor: Going to iterate through cursor resources.\n");
+ #endif
+
+ for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], RT_CURSOR, nxagentDisconnectCursor, &r);
+
+ #ifdef WARNING
+
+ if (r == False)
+ {
+ fprintf(stderr, "nxagentDisconnectAllCursor: WARNING! Failed to disconnect "
+ "cursor for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ if (grab)
+ {
+ nxagentDisconnectCursor(grab -> cursor, 0, &r);
+ }
+
+ return r;
+}
+
+
+#ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+
+void nxagentPrintCursorInfo(CursorPtr pCursor, char msg[])
+{
+ fprintf(stderr, "%s: %p - ID %lx - ref count %d\n",
+ msg, pCursor, nxagentCursor(pCursor, nxagentDefaultScreen), pCursor->refcnt);
+}
+
+void nxagentListCursor(void *p0, void *p1, void *p2)
+{
+ CursorPtr pCursor = (CursorPtr)p0;
+
+ nxagentPrintCursorInfo(pCursor, "CursorDebug:");
+}
+
+void nxagentListCursors(void)
+{
+ int i;
+ Bool r;
+
+ for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], RT_CURSOR, nxagentListCursor, &r);
+
+ #ifdef WARNING
+
+ if (r == False)
+ {
+ fprintf(stderr, "nxagentListCursors: WARNING! Failed to list "
+ "cursor for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ return True;
+}
+
+#endif /* NXAGENT_RECONNECT_CURSOR_DEBUG */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
new file mode 100644
index 000000000..b115dfa38
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -0,0 +1,117 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Cursor_H__
+#define __Cursor_H__
+
+#include "cursorstr.h"
+#include "picturestr.h"
+
+typedef struct {
+ Cursor cursor;
+ PicturePtr picture;
+ int uses_render;
+ int x;
+ int y;
+} nxagentPrivCursor;
+
+/*
+ * _AnimCurElt and _AnimCur already defined in animcur.c.
+ */
+
+typedef struct _AnimCurElt {
+ CursorPtr pCursor;
+ CARD32 delay;
+} AnimCurElt;
+
+typedef struct _AnimCur {
+ int nelt;
+ AnimCurElt *elts;
+} AnimCurRec, *AnimCurPtr;
+
+CursorBitsPtr nxagentAnimCursorBits;
+
+#define nxagentIsAnimCursor(c) ((c)->bits == nxagentAnimCursorBits)
+#define nxagentGetAnimCursor(c) ((AnimCurPtr) ((c) + 1))
+
+#define nxagentCursorPriv(pCursor, pScreen) \
+ ((nxagentPrivCursor *)((pCursor)->devPriv[pScreen->myNum]))
+
+#define nxagentCursor(pCursor, pScreen) \
+ (nxagentCursorPriv(pCursor, pScreen)->cursor)
+
+#define nxagentCursorPicture(pCursor, pScreen) \
+ (nxagentCursorPriv(pCursor, pScreen)->picture)
+
+#define nxagentCursorUsesRender(pCursor, pScreen) \
+ (nxagentCursorPriv(pCursor, pScreen)->uses_render)
+
+#define nxagentCursorXOffset(pCursor, pScreen) \
+ (nxagentCursorPriv(pCursor, pScreen)->x)
+
+#define nxagentCursorYOffset(pCursor, pScreen) \
+ (nxagentCursorPriv(pCursor, pScreen)->y)
+
+void nxagentConstrainCursor(ScreenPtr pScreen, BoxPtr pBox);
+
+void nxagentCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
+ BoxPtr pHotBox, BoxPtr pTopLeftBox);
+
+Bool nxagentDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+Bool nxagentRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+Bool nxagentUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
+ Bool displayed);
+
+Bool nxagentSetCursorPosition(ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+
+extern Bool (*nxagentSetCursorPositionW)(ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+
+void nxagentDisconnectCursor(void * p0, XID x1, void * p2);
+void nxagentReconnectCursor(void * p0, XID x1, void * p2);
+void nxagentReDisplayCurrentCursor(void);
+Bool nxagentReconnectAllCursor(void *p0);
+Bool nxagentDisconnectAllCursor(void);
+
+#endif /* __Cursor_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
new file mode 100644
index 000000000..b7852a0ac
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -0,0 +1,546 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include <nx-X11/Xlib.h>
+
+#include "opaque.h"
+
+#include "Args.h"
+#include "Display.h"
+#include "Dialog.h"
+
+#include <nx/NX.h>
+#include "compext/Compext.h"
+#include <nx/NXalert.h>
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int nxagentKillDialogPid = 0;
+int nxagentSuspendDialogPid = 0;
+int nxagentRootlessDialogPid = 0;
+int nxagentPulldownDialogPid = 0;
+int nxagentFontsReplacementDialogPid = 0;
+int nxagentEnableRandRModeDialogPid = 0;
+int nxagentDisableRandRModeDialogPid = 0;
+int nxagentEnableDeferModePid = 0;
+int nxagentDisableDeferModePid = 0;
+
+static int nxagentFailedReconnectionDialogPid = 0;
+
+char nxagentPulldownWindow[16];
+
+char nxagentFailedReconnectionMessage[256];
+
+void nxagentResetDialog(int pid)
+{
+ if (pid == nxagentRootlessDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting rootless dialog pid [%d].\n", nxagentRootlessDialogPid);
+ #endif
+
+ nxagentRootlessDialogPid = 0;
+ }
+ else if (pid == nxagentPulldownDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting pulldown dialog pid [%d].\n", nxagentPulldownDialogPid);
+ #endif
+
+ nxagentPulldownDialogPid = 0;
+ }
+ else if (pid == nxagentFontsReplacementDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFontsReplacementDialog: Resetting fonts replacement dialog pid [%d].\n",
+ nxagentFontsReplacementDialogPid);
+ #endif
+
+ nxagentFontsReplacementDialogPid = 0;
+ }
+ else if (pid == nxagentKillDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting kill dialog pid [%d].\n", nxagentKillDialogPid);
+ #endif
+
+ nxagentKillDialogPid = 0;
+ }
+ else if (pid == nxagentSuspendDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting suspend dialog pid [%d].\n", nxagentSuspendDialogPid);
+ #endif
+
+ nxagentSuspendDialogPid = 0;
+ }
+ else if (pid == nxagentFailedReconnectionDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting Failed Reconnection dialog pid [%d].\n",
+ nxagentFailedReconnectionDialogPid);
+ #endif
+
+ nxagentFailedReconnectionDialogPid = 0;
+ }
+ else if (pid == nxagentEnableRandRModeDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting RandR mode dialog pid [%d].\n",
+ nxagentEnableRandRModeDialogPid);
+ #endif
+
+ nxagentEnableRandRModeDialogPid = 0;
+ }
+ else if (pid == nxagentDisableRandRModeDialogPid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting NoRandR mode dialog pid [%d].\n",
+ nxagentDisableRandRModeDialogPid);
+ #endif
+
+ nxagentDisableRandRModeDialogPid = 0;
+ }
+ else if (pid == nxagentEnableDeferModePid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting enable defer mode dialog pid [%d].\n",
+ nxagentEnableDeferModePid);
+ #endif
+
+ nxagentEnableDeferModePid = 0;
+ }
+ else if (pid == nxagentDisableDeferModePid)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetDialog: Resetting disable defer mode dialog pid [%d].\n",
+ nxagentDisableDeferModePid);
+ #endif
+
+ nxagentDisableDeferModePid = 0;
+ }
+}
+
+void nxagentLaunchDialog(DialogType dialogType)
+{
+ char dialogDisplay[256];
+ sigset_t set, oldSet;
+ int *pid;
+ char *type;
+ char *message;
+ int local;
+ const char *window = NULL;
+
+ switch (dialogType)
+ {
+ case DIALOG_KILL_SESSION:
+ {
+ message = DIALOG_KILL_SESSION_MESSAGE;
+ type = DIALOG_KILL_SESSION_TYPE;
+ local = DIALOG_KILL_SESSION_LOCAL;
+ pid = &nxagentKillDialogPid;
+
+ break;
+ }
+ case DIALOG_SUSPEND_SESSION:
+ {
+ message = DIALOG_SUSPEND_SESSION_MESSAGE;
+ type = DIALOG_SUSPEND_SESSION_TYPE;
+ local = DIALOG_SUSPEND_SESSION_LOCAL;
+ pid = &nxagentSuspendDialogPid;
+
+ break;
+ }
+ case DIALOG_ROOTLESS:
+ {
+ message = DIALOG_ROOTLESS_MESSAGE;
+ type = DIALOG_ROOTLESS_TYPE;
+ local = DIALOG_ROOTLESS_LOCAL;
+ pid = &nxagentRootlessDialogPid;
+
+ break;
+ }
+ case DIALOG_PULLDOWN:
+ {
+ message = DIALOG_PULLDOWN_MESSAGE;
+ type = DIALOG_PULLDOWN_TYPE;
+ local = DIALOG_PULLDOWN_LOCAL;
+ pid = &nxagentPulldownDialogPid;
+ window = nxagentPulldownWindow;
+
+ break;
+ }
+ case DIALOG_FONT_REPLACEMENT:
+ {
+ message = DIALOG_FONT_REPLACEMENT_MESSAGE;
+ type = DIALOG_FONT_REPLACEMENT_TYPE;
+ local = DIALOG_FONT_REPLACEMENT_LOCAL;
+ pid = &nxagentFontsReplacementDialogPid;
+
+ break;
+ }
+ case DIALOG_FAILED_RECONNECTION:
+ {
+ message = DIALOG_FAILED_RECONNECTION_MESSAGE;
+ type = DIALOG_FAILED_RECONNECTION_TYPE;
+ local = DIALOG_FAILED_RECONNECTION_LOCAL;
+ pid = &nxagentFailedReconnectionDialogPid;
+
+ break;
+ }
+ case DIALOG_ENABLE_DESKTOP_RESIZE_MODE:
+ {
+ message = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_MESSAGE;
+ type = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_TYPE;
+ local = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_LOCAL;
+ pid = &nxagentEnableRandRModeDialogPid;
+
+ break;
+ }
+ case DIALOG_DISABLE_DESKTOP_RESIZE_MODE:
+ {
+ message = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_MESSAGE;
+ type = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE;
+ local = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_LOCAL;
+ pid = &nxagentDisableRandRModeDialogPid;
+
+ break;
+ }
+ case DIALOG_ENABLE_DEFER_MODE:
+ {
+ message = DIALOG_ENABLE_DEFER_MODE_MESSAGE;
+ type = DIALOG_ENABLE_DEFER_MODE_TYPE;
+ local = DIALOG_ENABLE_DEFER_MODE_LOCAL;
+ pid = &nxagentEnableDeferModePid;
+
+ break;
+ }
+ case DIALOG_DISABLE_DEFER_MODE:
+ {
+ message = DIALOG_DISABLE_DEFER_MODE_MESSAGE;
+ type = DIALOG_DISABLE_DEFER_MODE_TYPE;
+ local = DIALOG_DISABLE_DEFER_MODE_LOCAL;
+ pid = &nxagentDisableDeferModePid;
+
+ break;
+ }
+ default:
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentLaunchDialog: Unknown Dialog type [%d].\n", dialogType);
+ #endif
+
+ return;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentLaunchDialog: Launching dialog type [%d] message [%s].\n", type, message);
+ #endif
+
+ if (dialogType == DIALOG_FAILED_RECONNECTION)
+ {
+ strncpy(dialogDisplay, nxagentDisplayName, 255);
+ }
+ else
+ {
+ strcpy(dialogDisplay, ":");
+ strncat(dialogDisplay, display, 254);
+ }
+
+ *(dialogDisplay + 255) = '\0';
+
+ /*
+ * We don't want to receive SIGCHLD
+ * before we store the child pid.
+ */
+
+ sigemptyset(&set);
+
+ sigaddset(&set, SIGCHLD);
+
+ sigprocmask(SIG_BLOCK, &set, &oldSet);
+
+ *pid = NXTransDialog(nxagentDialogName, message, window,
+ type, local, dialogDisplay);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentLaunchDialog: Launched dialog %s with pid [%d] on display %s.\n",
+ DECODE_DIALOG_TYPE(dialogType), *pid, dialogDisplay);
+ #endif
+
+ *dialogDisplay = '\0';
+
+ /*
+ * Restore the previous set of
+ * blocked signal.
+ */
+
+ sigprocmask(SIG_SETMASK, &oldSet, NULL);
+}
+
+void nxagentPulldownDialog(Window wid)
+{
+ snprintf(nxagentPulldownWindow, 15, "%ld", (long int) wid);
+ nxagentPulldownWindow[15] = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPulldownDialog: Going to launch pulldown "
+ "dialog on window [%s].\n", nxagentPulldownWindow);
+ #endif
+
+ nxagentLaunchDialog(DIALOG_PULLDOWN);
+
+ nxagentPulldownWindow[0] = 0;
+}
+
+void nxagentFailedReconnectionDialog(int alert, char *error)
+{
+ if (alert == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFailedReconnectionDialog: WARNING! No valid alert provided. "
+ "Using the default.\n");
+ #endif
+
+ alert = FAILED_RESUME_DISPLAY_ALERT;
+ }
+
+ if (NXDisplayError(nxagentDisplay) == 0 &&
+ NXTransRunning(NX_FD_ANY) == 1)
+ {
+ NXTransAlert(alert, NX_ALERT_REMOTE);
+
+ /*
+ * Make it possible to interrupt the
+ * loop with a signal.
+ */
+
+ while (NXDisplayError(nxagentDisplay) == 0 &&
+ NXTransRunning(NX_FD_ANY) == 1)
+ {
+ struct timeval timeout;
+
+ timeout.tv_sec = 30;
+ timeout.tv_usec = 0;
+
+ NXTransContinue(&timeout);
+ }
+ }
+ else
+ {
+ int pid;
+ int status;
+ int options = 0;
+
+ snprintf(nxagentFailedReconnectionMessage, 255, "Reconnection failed: %s", error);
+
+ *(nxagentFailedReconnectionMessage + 255) = '\0';
+
+ nxagentLaunchDialog(DIALOG_FAILED_RECONNECTION);
+
+ while ((pid = waitpid(nxagentFailedReconnectionDialogPid, &status, options)) == -1 &&
+ errno == EINTR);
+
+ if (pid == -1)
+ {
+ if (errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFailedReconnectionDialog: Got ECHILD waiting for child [%d].\n",
+ nxagentFailedReconnectionDialogPid);
+ #endif
+
+ nxagentFailedReconnectionDialogPid = 0;
+ }
+ else
+ {
+ fprintf(stderr, "nxagentFailedReconnectionDialog: PANIC! Got unexpected error [%s] waiting "
+ "for child [%d].\n", strerror(errno), nxagentFailedReconnectionDialogPid);
+ }
+ }
+ else if (pid > 0)
+ {
+ if (WIFSTOPPED(status))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] was stopped "
+ "with signal [%d].\n", pid, (WSTOPSIG(status)));
+ #endif
+ }
+ else
+ {
+ #ifdef WARNING
+
+ if (WIFEXITED(status))
+ {
+ fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] exited "
+ "with status [%d].\n", pid, (WEXITSTATUS(status)));
+ }
+ else if (WIFSIGNALED(status))
+ {
+ fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] died "
+ "because of signal [%d].\n", pid, (WTERMSIG(status)));
+ }
+
+ #endif
+
+ nxagentResetDialog(pid);
+ }
+ }
+ #ifdef WARNING
+ else if (pid == 0)
+ {
+ fprintf(stderr, "nxagentFailedReconnectionDialog: No own child process exited.\n");
+ }
+ #endif
+ }
+}
+
+void nxagentTerminateDialog(DialogType type)
+{
+ int pid;
+
+ switch (type)
+ {
+ case DIALOG_KILL_SESSION:
+ {
+ pid = nxagentKillDialogPid;
+
+ break;
+ }
+ case DIALOG_SUSPEND_SESSION:
+ {
+ pid = nxagentSuspendDialogPid;
+
+ break;
+ }
+ case DIALOG_ROOTLESS:
+ {
+ pid = nxagentRootlessDialogPid;
+
+ break;
+ }
+ case DIALOG_PULLDOWN:
+ {
+ pid = nxagentPulldownDialogPid;
+
+ break;
+ }
+ case DIALOG_FONT_REPLACEMENT:
+ {
+ pid = nxagentFontsReplacementDialogPid;
+
+ break;
+ }
+ case DIALOG_FAILED_RECONNECTION:
+ {
+ pid = nxagentFailedReconnectionDialogPid;
+
+ break;
+ }
+ case DIALOG_ENABLE_DESKTOP_RESIZE_MODE:
+ {
+ pid = nxagentEnableRandRModeDialogPid;
+
+ break;
+ }
+ case DIALOG_DISABLE_DESKTOP_RESIZE_MODE:
+ {
+ pid = nxagentDisableRandRModeDialogPid;
+
+ break;
+ }
+ case DIALOG_ENABLE_DEFER_MODE:
+ {
+ pid = nxagentEnableDeferModePid;
+
+ break;
+ }
+ case DIALOG_DISABLE_DEFER_MODE:
+ {
+ pid = nxagentDisableDeferModePid;
+
+ break;
+ }
+ default:
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentTerminateDialog: Unknown dialog type [%d].\n", type);
+ #endif
+
+ return;
+ }
+ }
+
+ if (pid > 0)
+ {
+ if (kill(pid, SIGTERM) == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentTerminateDialog: Failed to terminate dialog pid [%d]: %s.\n",
+ pid, strerror(errno));
+ #endif
+ }
+ }
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "nxagentTerminateDialog: Dialog type [%d] is not running.\n",
+ type);
+ }
+ #endif
+}
+
+void nxagentTerminateDialogs()
+{
+ DialogType type;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentTerminateDialogs: Terminating all the running dialogs.\n");
+ #endif
+
+ for (type = DIALOG_FIRST_TAG; type < DIALOG_LAST_TAG; type++)
+ {
+ nxagentTerminateDialog(type);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
new file mode 100644
index 000000000..133dee242
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -0,0 +1,216 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Dialog_H__
+#define __Dialog_H__
+
+#include "X11/X.h"
+
+typedef enum
+{
+ DIALOG_FIRST_TAG,
+ DIALOG_KILL_SESSION = DIALOG_FIRST_TAG,
+ DIALOG_SUSPEND_SESSION,
+ DIALOG_ROOTLESS,
+ DIALOG_PULLDOWN,
+ DIALOG_FONT_REPLACEMENT,
+ DIALOG_ENABLE_DESKTOP_RESIZE_MODE,
+ DIALOG_DISABLE_DESKTOP_RESIZE_MODE,
+ DIALOG_FAILED_RECONNECTION,
+ DIALOG_ENABLE_DEFER_MODE,
+ DIALOG_DISABLE_DEFER_MODE,
+ DIALOG_LAST_TAG
+
+} DialogType;
+
+extern int nxagentKillDialogPid;
+extern int nxagentSuspendDialogPid;
+extern int nxagentRootlessDialogPid;
+extern int nxagentPulldownDialogPid;
+extern int nxagentFontsReplacementDialogPid;
+extern int nxagentEnableRandRModeDialogPid;
+extern int nxagentDisableRandRModeDialogPid;
+extern int nxagentEnableDeferModePid;
+extern int nxagentDisableDeferModePid;
+
+extern char nxagentFailedReconnectionMessage[];
+
+extern char nxagentPulldownWindow[];
+
+extern void nxagentLaunchDialog(DialogType type);
+extern void nxagentResetDialog(int pid);
+extern void nxagentTerminateDialog(DialogType type);
+extern void nxagentFailedReconnectionDialog(int alert, char *error);
+extern void nxagentPulldownDialog(Window);
+extern void nxagentTerminateDialogs(void);
+
+#define nxagentNoDialogIsRunning \
+ (nxagentSuspendDialogPid == 0 && \
+ nxagentKillDialogPid == 0 && \
+ nxagentEnableRandRModeDialogPid == 0 && \
+ nxagentDisableRandRModeDialogPid == 0 && \
+ nxagentEnableDeferModePid == 0 && \
+ nxagentDisableDeferModePid == 0)
+
+#define DECODE_DIALOG_TYPE(type) \
+ ((type) == DIALOG_KILL_SESSION ? "DIALOG_KILL_SESSION" : \
+ (type) == DIALOG_SUSPEND_SESSION ? "DIALOG_SUSPEND_SESSION" : \
+ (type) == DIALOG_ROOTLESS ? "DIALOG_ROOTLESS" : \
+ (type) == DIALOG_PULLDOWN ? "DIALOG_PULLDOWN" : \
+ (type) == DIALOG_FONT_REPLACEMENT ? "DIALOG_FONT_REPLACEMENT" : \
+ (type) == DIALOG_ENABLE_DESKTOP_RESIZE_MODE ? "DIALOG_ENABLE_DESKTOP_RESIZE_MODE" :\
+ (type) == DIALOG_DISABLE_DESKTOP_RESIZE_MODE ? "DIALOG_DISABLE_DESKTOP_RESIZE_MODE" :\
+ (type) == DIALOG_FAILED_RECONNECTION ? "DIALOG_FAILED_RECONNECTION" : \
+ (type) == DIALOG_ENABLE_DEFER_MODE ? "DIALOG_ENABLE_DEFER_MODE" : \
+ (type) == DIALOG_DISABLE_DEFER_MODE ? "DIALOG_DISABLE_DEFER_MODE" : \
+ "UNKNOWN_DIALOG")
+
+/*
+ * Message to be showed to users when the close
+ * button is pressed. The right message is chosen
+ * according if session does or does not run in
+ * persistent mode.
+ */
+
+#define DIALOG_KILL_SESSION_MESSAGE \
+\
+"\
+Do you really want to close the session?\
+"
+
+#define DIALOG_KILL_SESSION_TYPE "yesno"
+
+#define DIALOG_KILL_SESSION_LOCAL 0
+
+
+#define DIALOG_SUSPEND_SESSION_MESSAGE \
+\
+"\
+Press the disconnect button to disconnect the running session.\n\
+You will be able to resume the session at later time. Press the\n\
+terminate button to exit the session and close all the running\n\
+programs.\
+"
+
+#define DIALOG_SUSPEND_SESSION_TYPE "yesnosuspend"
+
+#define DIALOG_SUSPEND_SESSION_LOCAL 0
+
+
+#define DIALOG_ROOTLESS_MESSAGE \
+\
+"\
+All remote applications have been terminated.\n\
+Do you want to close the session?\
+"
+
+#define DIALOG_ROOTLESS_TYPE "yesno"
+
+#define DIALOG_ROOTLESS_LOCAL 0
+
+
+#define DIALOG_PULLDOWN_MESSAGE \
+\
+nxagentPulldownWindow
+
+#define DIALOG_PULLDOWN_TYPE "pulldown"
+
+#define DIALOG_PULLDOWN_LOCAL 0
+
+
+#define DIALOG_FONT_REPLACEMENT_MESSAGE \
+\
+"\
+Unable to retrieve all the fonts currently in use. \n\
+Missing fonts have been replaced.\
+"
+
+#define DIALOG_FONT_REPLACEMENT_TYPE "ok"
+
+#define DIALOG_FONT_REPLACEMENT_LOCAL 0
+
+
+#define DIALOG_FAILED_RECONNECTION_MESSAGE \
+\
+nxagentFailedReconnectionMessage
+
+#define DIALOG_FAILED_RECONNECTION_TYPE "ok"
+
+#define DIALOG_FAILED_RECONNECTION_LOCAL 0
+
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_MESSAGE \
+\
+"\
+The session is now running in desktop resize mode.\n\
+You can resize the desktop by simply dragging the\n\
+desktop window's border. You can press Ctrl+Alt+R\n\
+again to disable this option.\
+"
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_TYPE "ok"
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_LOCAL 0
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_MESSAGE \
+\
+"\
+The session is now running in viewport mode. You can\n\
+navigate across different areas of the desktop window\n\
+by dragging the desktop with the mouse or by using the\n\
+arrows keys while pressing Ctrl+Alt. Press Ctrl+Alt+R\n\
+again to return to the desktop resize mode.\
+"
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE "ok"
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_LOCAL 0
+
+
+#define DIALOG_ENABLE_DEFER_MODE_MESSAGE \
+\
+"\
+Deferred screen updates are now enabled. You can press\n\
+Ctrl+Alt+E again to disable this option.\
+"
+
+#define DIALOG_ENABLE_DEFER_MODE_TYPE "ok"
+
+#define DIALOG_ENABLE_DEFER_MODE_LOCAL 0
+
+
+#define DIALOG_DISABLE_DEFER_MODE_MESSAGE \
+\
+"\
+Deferred screen updates are now disabled. You can press\n\
+Ctrl+Alt+E to enable it again.\
+"
+
+#define DIALOG_DISABLE_DEFER_MODE_TYPE "ok"
+
+#define DIALOG_DISABLE_DEFER_MODE_LOCAL 0
+
+#endif /* __Dialog_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
new file mode 100644
index 000000000..c764f50ae
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -0,0 +1,2963 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#include <nx/NXalert.h>
+
+#include "Agent.h"
+#include "Display.h"
+#include "Visual.h"
+#include "Options.h"
+#include "Error.h"
+#include "Init.h"
+#include "Args.h"
+#include "Image.h"
+
+#define Pixmap XlibPixmap
+#include "Icons.h"
+#undef Pixmap
+
+#include "Render.h"
+#include "Font.h"
+#include "Reconnect.h"
+#include "Events.h"
+#include "Dialog.h"
+#include "Client.h"
+#include "Splash.h"
+#include "Screen.h"
+#include "Handlers.h"
+
+#include <nx/NX.h>
+#include "compext/Compext.h"
+
+#include NXAGENT_ICON_NAME
+#include X2GOAGENT_ICON_NAME
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef WATCH
+
+Display *nxagentDisplay = NULL;
+XVisualInfo *nxagentVisuals = NULL;
+Bool nxagentTrue24 = False;
+
+int nxagentNumVisuals;
+int nxagentXConnectionNumber;
+
+int nxagentIOErrorHandler(Display *display);
+
+static Bool nxagentDisplayInfoSaved = False;
+static Display *nxagentDisplayBackup = NULL;
+static XlibGC nxagentBitmapGCBackup = NULL;
+static XVisualInfo *nxagentVisualsRecBackup;
+static int nxagentNumVisualsRecBackup;
+static int nxagentNumDefaultColormapsRecBackup;
+static int *nxagentDepthsRecBackup;
+static int nxagentNumDepthsRecBackup;
+static int nxagentDefaultDepthRecBackup;
+static int nxagentDisplayWidthRecBackup;
+static int nxagentDisplayHeightRecBackup;
+static Bool nxagentRenderEnableRecBackup;
+static Bool *nxagentVisualHasBeenIgnored;
+
+static enum
+{
+ NOTHING = 0,
+ OPENED,
+ GOT_VISUAL_INFO,
+ ALLOC_DEF_COLORMAP,
+ GOT_DEPTH_LIST,
+ GOT_PIXMAP_FORMAT_LIST,
+ EVERYTHING_DONE
+} reconnectDisplayState;
+
+int nxagentDefaultVisualIndex;
+Colormap *nxagentDefaultColormaps = NULL;
+int nxagentNumDefaultColormaps;
+int *nxagentDepths = NULL;
+int nxagentNumDepths;
+XPixmapFormatValues *nxagentPixmapFormats = NULL;
+XPixmapFormatValues *nxagentRemotePixmapFormats = NULL;
+int nxagentNumPixmapFormats;
+int nxagentRemoteNumPixmapFormats;
+Pixel nxagentBlackPixel;
+Pixel nxagentWhitePixel;
+Drawable nxagentDefaultDrawables[MAXDEPTH + 1];
+Pixmap nxagentScreenSaverPixmap;
+
+/*
+ * Also used in Cursor.c. There are huge problems
+ * using GC definition. This is to be reworked.
+ */
+
+XlibGC nxagentBitmapGC;
+
+/*
+ * The "confine" window is used in the nxagentConstrainCursor
+ * procedure. We are currently overriding the original Xnest
+ * behaviour. It is unclear what this window is used for.
+ */
+
+Window nxagentConfineWindow;
+
+Pixmap nxagentIconPixmap;
+Pixmap nxagentIconShape;
+Bool useXpmIcon = False;
+
+Bool nxagentMakeIcon(Display *display, Pixmap *nxIcon, Pixmap *nxMask);
+
+
+static void nxagentInitVisuals(void);
+static void nxagentSetDefaultVisual(void);
+static void nxagentInitDepths(void);
+static void nxagentInitPixmapFormats(void);
+
+static int nxagentCheckForDefaultDepthCompatibility(void);
+static int nxagentCheckForDepthsCompatibility(void);
+static int nxagentCheckForPixmapFormatsCompatibility(void);
+static int nxagentInitAndCheckVisuals(int flexibility);
+static int nxagentCheckForColormapsCompatibility(int flexibility);
+
+/*
+ * Save Internal implementation Also called in Reconnect.c.
+ */
+
+Display *nxagentInternalOpenDisplay(char *display);
+
+#ifdef NXAGENT_TIMESTAMP
+unsigned long startTime;
+#endif
+
+/*
+ * This is located in connection.c.
+ */
+
+extern void RejectWellKnownSockets(void);
+
+int nxagentServerOrder()
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+
+ return MSBFirst;
+}
+
+/*
+ * FIXME: This error handler is not printing anything
+ * in the session log. This is OK once the session is
+ * started, because the error is handled by the other
+ * layers, but not before that point, as the agent
+ * would die without giving any feedback to the user
+ * (or, worse, to the NX server). We should check how
+ * many requests have been handled for this display
+ * and print a message if the display dies before the
+ * session is up and running.
+ */
+
+/*
+ * FIXME: This should be moved to Error.c, The other
+ * handlers should be probably moved to Handlers.c.
+ */
+
+int nxagentIOErrorHandler(Display *display)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentIOErrorHandler: Got I/O error with nxagentException.ioError [%d].\n",
+ nxagentException.ioError);
+ #endif
+
+ nxagentException.ioError++;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentIOErrorHandler: Set nxagentException.ioError to [%d].\n",
+ nxagentException.ioError);
+ #endif
+
+ return 1;
+}
+
+/*
+ * Force a shutdown of any connection attempt
+ * while connecting to the remote display.
+ * This is needed to avoid a hang up in case
+ * of loopback connections to our own listen-
+ * ing sockets.
+ */
+
+static void nxagentRejectConnection(int signal)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentRejectConnection: Going to reject client connections.\n");
+ #endif
+
+ RejectWellKnownSockets();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRejectConnection: Setting new alarm to 5 seconds from now.\n");
+ #endif
+
+ /*
+ * A further timeout is unlikely to happen
+ * in the case of loopback connections.
+ */
+
+ alarm(5);
+}
+
+/*
+ * Ignore the signal if the NX transport is
+ * not running.
+ */
+
+static void nxagentSigusrHandler(int signal)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentSigusrHandler: Nothing to do with signal [%d].\n",
+ signal);
+ #endif
+}
+
+static void nxagentSighupHandler(int signal)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Handling signal with state [%s] transport [%d] server "
+ "generation [%ld].\n", DECODE_SESSION_STATE(nxagentSessionState),
+ NXTransRunning(NX_FD_ANY), serverGeneration);
+ #endif
+
+ if (signal != SIGHUP)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentSighupHandler: PANIC! Invalid signal [%d] received in state [%s].\n",
+ signal, DECODE_SESSION_STATE(nxagentSessionState));
+ #endif
+
+ return;
+ }
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Ignoring the signal while terminating the session.\n");
+ #endif
+
+ return;
+ }
+ else if (nxagentSessionState == SESSION_UP)
+ {
+ if (nxagentOption(Persistent) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Handling the signal by disconnecting the agent.\n");
+ #endif
+
+ nxagentException.sigHup++;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Ignoring the signal with persistency disabled.\n");
+ #endif
+ }
+
+ return;
+ }
+ else if (nxagentSessionState == SESSION_STARTING)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Handling the signal by aborting the session.\n");
+ #endif
+
+ nxagentException.sigHup++;
+
+ return;
+ }
+ else if (nxagentSessionState == SESSION_DOWN)
+ {
+ if (NXTransRunning(NX_FD_ANY) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Handling the signal by aborting the reconnection.\n");
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSighupHandler: Handling the signal by resuming the session.\n");
+ #endif
+ }
+
+ nxagentException.sigHup++;
+
+ return;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSighupHandler: WARNING! Ignoring the signal in state [%s].\n",
+ DECODE_SESSION_STATE(nxagentSessionState));
+ #endif
+}
+
+static void nxagentSigchldHandler(int signal)
+{
+ int pid = 0;
+ int status;
+ int options;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSigchldHandler: Going to check the children processes.\n");
+ #endif
+
+ options = WNOHANG | WUNTRACED;
+
+ /*
+ * Try with the pid of the dialog process.
+ * Leave the other children unaffected.
+ */
+
+ if (nxagentRootlessDialogPid)
+ {
+ pid = waitpid(nxagentRootlessDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Rootless dialog).\n",
+ nxagentRootlessDialogPid);
+ #endif
+
+ pid = nxagentRootlessDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentPulldownDialogPid)
+ {
+ pid = waitpid(nxagentPulldownDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Pulldown dialog).\n",
+ nxagentPulldownDialogPid);
+ #endif
+
+ pid = nxagentPulldownDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentKillDialogPid)
+ {
+ pid = waitpid(nxagentKillDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Kill dialog).\n",
+ nxagentKillDialogPid);
+ #endif
+
+ pid = nxagentKillDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentSuspendDialogPid)
+ {
+ pid = waitpid(nxagentSuspendDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Suspend dialog).\n",
+ nxagentSuspendDialogPid);
+ #endif
+
+ pid = nxagentSuspendDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentFontsReplacementDialogPid)
+ {
+ pid = waitpid(nxagentFontsReplacementDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (Fonts replacement).\n",
+ nxagentFontsReplacementDialogPid);
+ #endif
+
+ pid = nxagentFontsReplacementDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentEnableRandRModeDialogPid)
+ {
+ pid = waitpid(nxagentEnableRandRModeDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (EnableRandRMode dialog).\n",
+ nxagentEnableRandRModeDialogPid);
+ #endif
+
+ pid = nxagentEnableRandRModeDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentDisableRandRModeDialogPid)
+ {
+ pid = waitpid(nxagentDisableRandRModeDialogPid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (DisableRandRMode dialog).\n",
+ nxagentDisableRandRModeDialogPid);
+ #endif
+
+ pid = nxagentDisableRandRModeDialogPid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentEnableDeferModePid)
+ {
+ pid = waitpid(nxagentEnableDeferModePid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (EnableDeferMode dialog).\n",
+ nxagentEnableDeferModePid);
+ #endif
+
+ pid = nxagentEnableDeferModePid = 0;
+ }
+ }
+
+ if (pid == 0 && nxagentDisableDeferModePid)
+ {
+ pid = waitpid(nxagentDisableDeferModePid, &status, options);
+
+ if (pid == -1 && errno == ECHILD)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Got ECHILD waiting for child %d (DisableDeferMode dialog).\n",
+ nxagentDisableDeferModePid);
+ #endif
+
+ pid = nxagentDisableDeferModePid = 0;
+ }
+ }
+
+ if (pid == -1)
+ {
+ FatalError("Got error '%s' waiting for the child.\n", strerror(errno));
+ }
+
+ if (pid > 0)
+ {
+ if (WIFSTOPPED(status))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSigchldHandler: Child process [%d] was stopped "
+ "with signal [%d].\n", pid, (WSTOPSIG(status)));
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+
+ if (WIFEXITED(status))
+ {
+ fprintf(stderr, "nxagentSigchldHandler: Child process [%d] exited "
+ "with status [%d].\n", pid, (WEXITSTATUS(status)));
+ }
+ else if (WIFSIGNALED(status))
+ {
+ fprintf(stderr, "nxagentSigchldHandler: Child process [%d] died "
+ "because of signal [%d].\n", pid, (WTERMSIG(status)));
+ }
+
+ #endif
+
+ nxagentResetDialog(pid);
+ }
+ }
+ else if (pid == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSigchldHandler: Forwarding the signal to the NX transport.\n");
+ #endif
+
+ NXTransSignal(SIGCHLD, NX_SIGNAL_RAISE);
+ }
+
+ return;
+}
+
+Display *nxagentInternalOpenDisplay(char *display)
+{
+ Display *newDisplay;
+
+ struct sigaction oldAction;
+ struct sigaction newAction;
+
+ int result;
+
+ /*
+ * Stop the smart schedule timer since
+ * it uses SIGALRM as we do.
+ */
+
+ nxagentStopTimer();
+
+ /*
+ * Install the handler rejecting a possible
+ * loopback connection.
+ */
+/*
+FIXME: Should print a warning if the user tries to let
+ the agent impersonate the same display as the
+ display where the agent is supposed to connect.
+ We actually handle this by means of RejectWell-
+ KnownSockets() but without giving to the user
+ a friendly explaination for the error.
+*/
+
+ newAction.sa_handler = nxagentRejectConnection;
+
+ sigfillset(&newAction.sa_mask);
+
+ newAction.sa_flags = 0;
+
+ while (((result = sigaction(SIGALRM, &newAction,
+ &oldAction)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set alarm for rejecting connections.");
+ }
+
+ alarm(10);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInternalOpenDisplay: Going to open the display [%s].\n",
+ display);
+ #endif
+
+ newDisplay = XOpenDisplay(display);
+
+ alarm(0);
+
+ while (((result = sigaction(SIGALRM, &oldAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't restore alarm for rejecting connections.");
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInternalOpenDisplay: Setting the NX flush policy to immediate.\n");
+ #endif
+
+ NXSetDisplayPolicy(nxagentDisplay, NXPolicyImmediate);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInternalOpenDisplay: Function returned display at [%p].\n",
+ (void *) newDisplay);
+ #endif
+
+ return newDisplay;
+}
+
+static void nxagentDisplayBlockHandler(Display *display, int reason)
+{
+ if (nxagentDisplay != NULL)
+ {
+ /*
+ * Don't allow the smart schedule to
+ * interrupt the agent while waiting
+ * for the remote display.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Stopping the smart schedule timer.\n");
+ #endif
+
+ nxagentStopTimer();
+
+ if (reason == NXBlockRead)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Display is blocking for [read].\n");
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Display is blocking for [write].\n");
+ #endif
+
+ nxagentBlocking = 1;
+
+ if (!SmartScheduleSignalEnable)
+ {
+
+ /*
+ * Let the dispatch attend the next
+ * client.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisplayBlockHandler: BLOCK! Yielding with agent blocked.\n");
+ #endif
+
+ nxagentDispatch.start = GetTimeInMillis();
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+
+ }
+
+ /*
+ * Give a chance to the next client.
+ */
+
+ isItTimeToYield = 1;
+ }
+ }
+}
+
+static void nxagentDisplayWriteHandler(Display *display, int length)
+{
+ if (nxagentDisplay != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisplayWriteHandler: WRITE! Called with [%d] bytes written.\n",
+ length);
+ #endif
+
+ /*
+ * Notify the dispatch handler.
+ */
+
+ nxagentDispatchHandler(NULL, 0, length);
+
+ if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+ {
+ nxagentFlush = GetTimeInMillis();
+ }
+ }
+}
+
+static CARD32 nxagentRateTime = 5000;
+static CARD32 nxagentLastTime;
+static unsigned int nxagentRate = 0;
+
+int nxagentGetDataRate(void)
+{
+ return nxagentRate;
+}
+
+static void nxagentDisplayFlushHandler(Display *display, int length)
+{
+ CARD32 time;
+
+ if (nxagentDisplay != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisplayFlushHandler: FLUSH! Called with [%d] bytes flushed.\n",
+ length);
+ #endif
+
+ nxagentCongestion = NXDisplayCongestion(nxagentDisplay);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisplayFlushHandler: FLUSH! Current congestion level is [%d].\n",
+ nxagentCongestion);
+ #endif
+
+ if (nxagentOption(LinkType) != LINK_TYPE_NONE)
+ {
+ nxagentFlush = GetTimeInMillis();
+
+ time = nxagentFlush;
+
+ time = time - nxagentLastTime;
+
+ if (time < nxagentRateTime)
+ {
+ nxagentRate = ((nxagentRate * (nxagentRateTime - time) +
+ length) * 1000) / nxagentRateTime;
+ }
+ else
+ {
+ nxagentRate = (length * 1000) / nxagentRateTime;
+ }
+
+ nxagentLastTime = nxagentFlush;
+ }
+ }
+}
+
+static int nxagentDisplayErrorPredicate(Display *display, int error)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisplayErrorPredicate: CHECK! Error is [%d] with [%d][%d][%d][%d][%d].\n",
+ ((error == 1) || (dispatchException & DE_RESET) != 0 ||
+ (dispatchException & DE_TERMINATE) != 0 || nxagentException.sigHup > 0 ||
+ nxagentException.ioError > 0), error, (dispatchException & DE_RESET) != 0,
+ (dispatchException & DE_TERMINATE), nxagentException.sigHup > 0,
+ nxagentException.ioError > 0);
+ #endif
+
+ if (error == 0)
+ {
+ if ((dispatchException & DE_RESET) != 0 ||
+ (dispatchException & DE_TERMINATE))
+ {
+ return 1;
+ }
+ else if (nxagentException.sigHup > 0 ||
+ nxagentException.ioError > 0)
+ {
+ NXForceDisplayError(display);
+
+ return 1;
+ }
+ }
+
+ return error;
+}
+
+void nxagentInstallDisplayHandlers()
+{
+ /*
+ * If the display was already opened, be sure
+ * all structures are freed.
+ */
+
+ nxagentResetDisplayHandlers();
+
+ /*
+ * We want the Xlib I/O error handler to return,
+ * instead of quitting the application. Using
+ * setjmp()/longjmp() leaves the door open to
+ * unexpected bugs when dealing with interaction
+ * with the other X server layers.
+ */
+
+ NXHandleDisplayError(1);
+
+ NXSetDisplayBlockHandler(nxagentDisplayBlockHandler);
+
+ NXSetDisplayWriteHandler(nxagentDisplayWriteHandler);
+
+ NXSetDisplayFlushHandler(nxagentDisplayFlushHandler, NULL);
+
+ /*
+ * Override the default Xlib error handler.
+ */
+
+ XSetIOErrorHandler(nxagentIOErrorHandler);
+
+ /*
+ * Let Xlib become aware of our interrupts. In theory
+ * we don't need to have the error handler installed
+ * during the normal operations and could simply let
+ * the dispatcher handle the interrupts. In practice
+ * it's better to have Xlib invalidating the display
+ * as soon as possible rather than incurring in the
+ * risk of entering a loop that doesn't care checking
+ * the display errors explicitly.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInstallDisplayHandlers: Installing the error function predicate.\n");
+ #endif
+
+ NXSetDisplayErrorPredicate(nxagentDisplayErrorPredicate);
+}
+
+void nxagentPostInstallDisplayHandlers()
+{
+ /*
+ * This is executed after having opened the
+ * display, once we know the display address.
+ */
+
+ if (nxagentDisplay != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPostInstallDisplayHandlers: Initializing the NX display internals.\n");
+ #endif
+
+ NXInitDisplay(nxagentDisplay);
+/*
+FIXME: What is the most appropriate number of elements?
+
+ NXInitCache(nxagentDisplay, 128);
+*/
+ NXInitCache(nxagentDisplay, 256);
+
+ NXSetDisplayFlushHandler(nxagentDisplayFlushHandler, nxagentDisplay);
+ }
+
+ /*
+ * Handler for the Xlib protocol errors.
+ */
+
+ XSetErrorHandler(nxagentErrorHandler);
+}
+
+void nxagentResetDisplayHandlers()
+{
+ if (nxagentDisplay != NULL)
+ {
+ /*
+ * Free the internal nxcompext
+ * structures.
+ */
+
+ NXResetDisplay(nxagentDisplay);
+
+ /*
+ * Remove the display descriptor
+ * from the listened sockets.
+ */
+
+ nxagentRemoveXConnection();
+
+ /*
+ * Restart the suspended clients.
+ */
+
+ nxagentWakeupByReconnect();
+
+ nxagentReleaseAllSplits();
+ }
+
+ /*
+ * Reset the display to a healty state.
+ */
+
+ nxagentBuffer = 0;
+ nxagentBlocking = 0;
+ nxagentCongestion = 0;
+
+ /*
+ * Reset the counter of synchronization
+ * requests pending.
+ */
+
+ nxagentTokens.soft = 0;
+ nxagentTokens.hard = 0;
+ nxagentTokens.pending = 0;
+
+ /*
+ * Reset the current dispatch information.
+ */
+
+ nxagentDispatch.client = UNDEFINED;
+ nxagentDispatch.in = 0;
+ nxagentDispatch.out = 0;
+ nxagentDispatch.start = 0;
+}
+
+void nxagentInstallSignalHandlers()
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentInstallSignalHandlers: Installing the agent signal handlers.\n");
+ #endif
+
+ /*
+ * Keep the default X server's handlers for
+ * SIGINT and SIGTERM and restore the other
+ * signals of interest to our defaults.
+ */
+
+ struct sigaction newAction;
+
+ int result;
+
+ /*
+ * By default nxcomp installs its signal handlers.
+ * We need to ensure that SIGUSR1 and SIGUSR2 are
+ * ignored if the NX transport is not running.
+ */
+
+ newAction.sa_handler = nxagentSigusrHandler;
+
+ sigfillset(&newAction.sa_mask);
+
+ newAction.sa_flags = 0;
+
+ while (((result = sigaction(SIGUSR1, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for user signal 1.");
+ }
+
+ while (((result = sigaction(SIGUSR2, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for user signal 2.");
+ }
+
+ /*
+ * Reset the SIGALRM to the default.
+ */
+
+ nxagentStopTimer();
+
+ newAction.sa_handler = SIG_DFL;
+
+ sigfillset(&newAction.sa_mask);
+
+ while (((result = sigaction(SIGALRM, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for alarm signal.");
+ }
+
+ /*
+ * Let the smart schedule set the SIGALRM
+ * handler again.
+ */
+
+ nxagentInitTimer();
+
+ /*
+ * Install our own handler for the SIGHUP.
+ */
+
+ newAction.sa_handler = nxagentSighupHandler;
+
+ sigfillset(&newAction.sa_mask);
+
+ newAction.sa_flags = 0;
+
+ while (((result = sigaction(SIGHUP, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for session suspend.");
+ }
+
+ /*
+ * We need to be notified about our children.
+ */
+
+ newAction.sa_handler = nxagentSigchldHandler;
+
+ sigfillset(&newAction.sa_mask);
+
+ newAction.sa_flags = 0;
+
+ while (((result = sigaction(SIGCHLD, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for children.");
+ }
+}
+
+void nxagentPostInstallSignalHandlers()
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentPostInstallSignalHandlers: Dealing with the proxy signal handlers.\n");
+ #endif
+
+ /*
+ * Reconfigure our signal handlers to work well
+ * with the NX transport.
+ *
+ * Let our handlers manage the SIGINT and SIGTERM.
+ * The following calls will tell the NX transport
+ * to restore the old handlers (those originally
+ * installed by us or the X server).
+ */
+
+ NXTransSignal(SIGINT, NX_SIGNAL_DISABLE);
+ NXTransSignal(SIGTERM, NX_SIGNAL_DISABLE);
+
+ /*
+ * Also tell the proxy to ignore the SIGHUP.
+ */
+
+ NXTransSignal(SIGHUP, NX_SIGNAL_DISABLE);
+
+ /*
+ * Both the proxy and the agent need to catch
+ * their children, so we'll have to send the
+ * signal to transport.
+ */
+
+ NXTransSignal(SIGCHLD, NX_SIGNAL_DISABLE);
+
+ /*
+ * Let the NX transport take care of SIGUSR1
+ * and SIGUSR2.
+ */
+}
+
+void nxagentResetSignalHandlers()
+{
+ struct sigaction newAction;
+
+ int result;
+
+ memset(&newAction, 0, sizeof(newAction));
+
+ /*
+ * Reset the signal handlers
+ * to a well known state.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetSignalHandlers: Resetting the agent the signal handlers.\n");
+ #endif
+
+ /*
+ * Reset the SIGALRM to the default.
+ */
+
+ nxagentStopTimer();
+
+ newAction.sa_handler = SIG_DFL;
+
+ sigfillset(&newAction.sa_mask);
+
+ while (((result = sigaction(SIGALRM, &newAction,
+ NULL)) == -1) && (errno == EINTR));
+
+ if (result == -1)
+ {
+ FatalError("Can't set the handler for alarm signal.");
+ }
+
+ /*
+ * Let the smart schedule set the SIGALRM
+ * handler again.
+ */
+
+ nxagentInitTimer();
+
+}
+
+void nxagentOpenDisplay(int argc, char *argv[])
+{
+ int i;
+
+ if (!nxagentDoFullGeneration) return;
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ startTime = GetTimeInMillis();
+
+ fprintf(stderr, "Display: Opening the display on real X server with time [%d] ms.\n",
+ GetTimeInMillis() - startTime);
+
+ #endif
+
+ /*
+ * Initialize the reconnector only in the case
+ * of persistent sessions.
+ */
+
+ if (nxagentOption(Persistent))
+ {
+ nxagentInitReconnector();
+ }
+
+ if (*nxagentDisplayName == '\0')
+ {
+ strncpy(nxagentDisplayName, XDisplayName(NULL), 1023);
+
+ nxagentDisplayName[1023] = '\0';
+ }
+
+ nxagentCloseDisplay();
+
+ nxagentInstallSignalHandlers();
+
+ nxagentInstallDisplayHandlers();
+
+ nxagentDisplay = nxagentInternalOpenDisplay(nxagentDisplayName);
+
+ nxagentPostInstallSignalHandlers();
+
+ nxagentPostInstallDisplayHandlers();
+
+ if (nxagentDisplay == NULL)
+ {
+/*
+FIXME: The agent should never exit the program with a FatalError()
+ but rather use a specific function that may eventually call
+ FatalError() on its turn.
+*/
+ FatalError("Unable to open display '%s'.\n", nxagentDisplayName);
+ }
+
+ if (nxagentSynchronize)
+ XSynchronize(nxagentDisplay, True);
+
+ nxagentXConnectionNumber = XConnectionNumber(nxagentDisplay);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenDisplay: Display image order is [%d] bitmap order is [%d].\n",
+ ImageByteOrder(nxagentDisplay), BitmapBitOrder(nxagentDisplay));
+
+ fprintf(stderr, "nxagentOpenDisplay: Display scanline unit is [%d] scanline pad is [%d].\n",
+ BitmapUnit(nxagentDisplay), BitmapPad(nxagentDisplay));
+ #endif
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 1.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#1 U 1 1 256 bits (0 KB) -> 150 bits (0 KB) -> 256/1 -> 150/1 = 1.707:1
+#20 1 1 119104 bits (15 KB) -> 28 bits (0 KB) -> 119104/1 -> 28/1 = 4253.714:1
+#98 2 512 bits (0 KB) -> 84 bits (0 KB) -> 256/1 -> 42/1 = 6.095:1
+*/
+
+ sleep(60);
+
+ #endif
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ fprintf(stderr, "Display: Display on real X server opened with time [%d] ms.\n",
+ GetTimeInMillis() - startTime);
+
+ #endif
+
+ nxagentUseNXTrans =
+ nxagentPostProcessArgs(nxagentDisplayName, nxagentDisplay,
+ DefaultScreenOfDisplay(nxagentDisplay));
+
+ /*
+ * Processing the arguments all the timeouts
+ * have been set. Now we have to change the
+ * screen-saver timeout.
+ */
+
+ nxagentSetScreenSaverTime();
+
+ nxagentInitVisuals();
+
+ nxagentNumDefaultColormaps = nxagentNumVisuals;
+ nxagentDefaultColormaps = (Colormap *)malloc(nxagentNumDefaultColormaps *
+ sizeof(Colormap));
+
+ for (i = 0; i < nxagentNumDefaultColormaps; i++)
+ {
+ nxagentDefaultColormaps[i] = XCreateColormap(nxagentDisplay,
+ DefaultRootWindow(nxagentDisplay),
+ nxagentVisuals[i].visual,
+ AllocNone);
+ }
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 4.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ nxagentBlackPixel = BlackPixel(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ nxagentWhitePixel = WhitePixel(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ /*
+ * Initialize the agent's event mask that will be requested
+ * for the root and all the top level windows. If the nested
+ * window is a child of an existing window, we will need to
+ * receive StructureNotify events. If we are going to manage
+ * the changes in root window's visibility we'll also need
+ * VisibilityChange events.
+ */
+
+/*
+FIXME: Use of nxagentParentWindow is strongly deprecated.
+ We need also to clarify which events are selected
+ in the diferent operating modes.
+*/
+
+ nxagentInitDefaultEventMask();
+
+ /*
+ * Initialize the pixmap depths and formats.
+ */
+
+ nxagentInitDepths();
+
+ nxagentInitPixmapFormats();
+ (void) nxagentCheckForPixmapFormatsCompatibility();
+
+ /*
+ * Create a pixmap for each depth matching the
+ * local supported formats with format available
+ * on the remote display.
+ */
+
+ nxagentSetDefaultDrawables();
+
+ #ifdef RENDER
+ if (nxagentRenderEnable)
+ {
+ nxagentRenderExtensionInit();
+ }
+ #endif
+
+ /*
+ * This GC is referenced in Cursor.c. It can be
+ * probably removed.
+ */
+
+ nxagentBitmapGC = XCreateGC(nxagentDisplay, nxagentDefaultDrawables[1], 0L, NULL);
+
+ /*
+ * Note that this "confine window" is useless at the
+ * moment as we reimplement nxagentConstrainCursor()
+ * to skip the "constrain" stuff.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenDisplay: Going to create agent's confine window.\n");
+ #endif
+
+ nxagentConfineWindow = XCreateWindow(nxagentDisplay,
+ DefaultRootWindow(nxagentDisplay),
+ 0, 0, 1, 1, 0, 0,
+ InputOnly,
+ CopyFromParent,
+ 0L, NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenDisplay: Created agent's confine window with id [%ld].\n",
+ nxagentConfineWindow);
+ #endif
+
+ if (!(nxagentUserGeometry.flag & XValue))
+ {
+ nxagentChangeOption(RootX, 0);
+ }
+
+ if (!(nxagentUserGeometry.flag & YValue))
+ {
+ nxagentChangeOption(RootY, 0);
+ }
+
+ if (nxagentParentWindow == 0)
+ {
+ if (!(nxagentUserGeometry.flag & WidthValue))
+ {
+ if (nxagentOption(Fullscreen))
+ {
+ nxagentChangeOption(RootWidth, DisplayWidth(nxagentDisplay, DefaultScreen(nxagentDisplay)));
+ }
+ else
+ {
+ nxagentChangeOption(RootWidth, 3 * DisplayWidth(nxagentDisplay,
+ DefaultScreen(nxagentDisplay)) / 4);
+ }
+ }
+
+ if (!(nxagentUserGeometry.flag & HeightValue))
+ {
+ if (nxagentOption(Fullscreen))
+ {
+ nxagentChangeOption(RootHeight, DisplayHeight(nxagentDisplay, DefaultScreen(nxagentDisplay)));
+ }
+ else
+ {
+ nxagentChangeOption(RootHeight, 3 * DisplayHeight(nxagentDisplay,
+ DefaultScreen(nxagentDisplay)) / 4);
+ }
+ }
+ }
+
+ if (!nxagentUserBorderWidth)
+ {
+ nxagentChangeOption(BorderWidth, 1);
+ }
+
+ nxagentLogoDepth = DefaultDepth(nxagentDisplay,
+ DefaultScreen(nxagentDisplay)
+ );
+
+ nxagentLogoBlack = 0x000000;
+ nxagentLogoRed = 0xff0000;
+ nxagentLogoWhite = 0xffffff;
+ nxagentLogoGray = 0x222222;
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.1.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ useXpmIcon = nxagentMakeIcon(nxagentDisplay, &nxagentIconPixmap, &nxagentIconShape);
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 5.2.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#84 2 512 bits (0 KB) -> 76 bits (0 KB) -> 256/1 -> 38/1 = 6.737:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenDisplay: Watchpoint 6.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ fprintf(stderr, "Display: Open of the display finished with time [%d] ms.\n",
+ GetTimeInMillis() - startTime);
+
+ #endif
+
+ if (nxagentOption(Persistent))
+ {
+ reconnectDisplayState = EVERYTHING_DONE;
+ }
+}
+
+void nxagentSetDefaultVisual(void)
+{
+ XVisualInfo vi;
+
+ int i;
+
+ if (nxagentUserDefaultClass || nxagentUserDefaultDepth)
+ {
+ nxagentDefaultVisualIndex = UNDEFINED;
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ if ((!nxagentUserDefaultClass ||
+ nxagentVisuals[i].class == nxagentDefaultClass)
+ &&
+ (!nxagentUserDefaultDepth ||
+ nxagentVisuals[i].depth == nxagentDefaultDepth))
+ {
+ nxagentDefaultVisualIndex = i;
+
+ break;
+ }
+ }
+
+ if (nxagentDefaultVisualIndex == UNDEFINED)
+ {
+ FatalError("Unable to find desired default visual.\n");
+ }
+ }
+ else
+ {
+ vi.visualid = XVisualIDFromVisual(DefaultVisual(nxagentDisplay,
+ DefaultScreen(nxagentDisplay)));
+ nxagentDefaultVisualIndex = 0;
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ if (vi.visualid == nxagentVisuals[i].visualid)
+ {
+ nxagentDefaultVisualIndex = i;
+ }
+ }
+ }
+}
+
+void nxagentInitVisuals(void)
+{
+ XVisualInfo vi;
+ XVisualInfo *viList = NULL;
+
+ long mask;
+ int i, viNumList;
+
+ mask = VisualScreenMask;
+ vi.screen = DefaultScreen(nxagentDisplay);
+ vi.depth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ viList = XGetVisualInfo(nxagentDisplay, mask, &vi, &viNumList);
+ nxagentVisuals = (XVisualInfo *) malloc(viNumList * sizeof(XVisualInfo));
+ nxagentNumVisuals = 0;
+
+ for (i = 0; i < viNumList; i++)
+ {
+ if (viList[i].depth == vi.depth)
+ {
+ if (nxagentVisuals != NULL)
+ {
+ memcpy(nxagentVisuals + nxagentNumVisuals, viList + i, sizeof(XVisualInfo));
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentInitVisuals: Visual:\n");
+ fprintf(stderr, "\tdepth = %d\n", nxagentVisuals[nxagentNumVisuals].depth);
+ fprintf(stderr, "\tclass = %d\n", nxagentVisuals[nxagentNumVisuals].class);
+ fprintf(stderr, "\tmask = (%lu,%lu,%lu)\n",
+ nxagentVisuals[nxagentNumVisuals].red_mask,
+ nxagentVisuals[nxagentNumVisuals].green_mask,
+ nxagentVisuals[nxagentNumVisuals].blue_mask);
+ fprintf(stderr, "\tcolormap size = %d\n", nxagentVisuals[nxagentNumVisuals].colormap_size);
+ fprintf(stderr, "\tbits_per_rgb = %d\n", nxagentVisuals[nxagentNumVisuals].bits_per_rgb);
+ #endif
+
+ nxagentNumVisuals++;
+ }
+ }
+
+ if (nxagentVisuals != NULL)
+ {
+ nxagentVisuals = (XVisualInfo *) realloc(nxagentVisuals,
+ nxagentNumVisuals * sizeof(XVisualInfo));
+ }
+
+ XFree(viList);
+
+ if (nxagentNumVisuals == 0 || nxagentVisuals == NULL)
+ {
+ FatalError("Unable to find any visuals.\n");
+ }
+
+ nxagentSetDefaultVisual();
+}
+
+void nxagentInitDepths()
+{
+ #ifdef TEST
+ int i;
+ #endif
+
+ nxagentDepths = XListDepths(nxagentDisplay, DefaultScreen(nxagentDisplay),
+ &nxagentNumDepths);
+
+ if (nxagentDepths == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentInitDepths: PANIC! Failed to get available depths.\n");
+ #endif
+
+ FatalError("Failed to get available depths and pixmap formats.");
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentInitDepths: Got [%d] available depths:\n",
+ nxagentNumDepths);
+
+ for (i = 0; i < nxagentNumDepths; i++)
+ {
+ fprintf(stderr, " [%d]", nxagentDepths[i]);
+ }
+
+ fprintf(stderr, ".\n");
+ }
+ #endif
+}
+
+void nxagentInitPixmapFormats()
+{
+ int i, j;
+ int depth;
+
+ /*
+ * Formats are created with no care of which are supported
+ * on the real display. Creating only formats supported
+ * by the remote end makes troublesome handling migration
+ * of session from a display to another.
+ */
+
+ nxagentNumPixmapFormats = 0;
+
+/*
+XXX: Some X server doesn't list 1 among available depths...
+*/
+
+ nxagentPixmapFormats = malloc((nxagentNumDepths + 1) * sizeof(XPixmapFormatValues));
+
+ for (i = 1; i <= MAXDEPTH; i++)
+ {
+ depth = 0;
+
+ if (i == 1)
+ {
+ depth = 1;
+ }
+ else
+ {
+ for (j = 0; j < nxagentNumDepths; j++)
+ {
+ if (nxagentDepths[j] == i)
+ {
+ depth = i;
+
+ break;
+ }
+ }
+ }
+
+ if (depth != 0)
+ {
+ if (nxagentNumPixmapFormats >= MAXFORMATS)
+ {
+ FatalError("nxagentInitPixmapFormats: MAXFORMATS is too small for this server.\n");
+ }
+
+ nxagentPixmapFormats[nxagentNumPixmapFormats].depth = depth;
+ nxagentPixmapFormats[nxagentNumPixmapFormats].bits_per_pixel = nxagentBitsPerPixel(depth);
+ nxagentPixmapFormats[nxagentNumPixmapFormats].scanline_pad = BITMAP_SCANLINE_PAD;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitPixmapFormats: Set format [%d] to depth [%d] "
+ "bits per pixel [%d] scanline pad [%d].\n", nxagentNumPixmapFormats,
+ depth, nxagentPixmapFormats[nxagentNumPixmapFormats].bits_per_pixel,
+ BITMAP_SCANLINE_PAD);
+ #endif
+
+ nxagentNumPixmapFormats++;
+ }
+ }
+
+ nxagentRemotePixmapFormats = XListPixmapFormats(nxagentDisplay, &nxagentRemoteNumPixmapFormats);
+
+ if (nxagentRemotePixmapFormats == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitPixmapFormats: WARNING! Failed to get available remote pixmap formats.\n");
+ #endif
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentInitPixmapFormats: Got [%d] available remote pixmap formats:\n",
+ nxagentRemoteNumPixmapFormats);
+
+ for (i = 0; i < nxagentRemoteNumPixmapFormats; i++)
+ {
+ fprintf(stderr, "nxagentInitPixmapFormats: Remote pixmap format [%d]: depth [%d] "
+ "bits_per_pixel [%d] scanline_pad [%d].\n", i, nxagentRemotePixmapFormats[i].depth,
+ nxagentRemotePixmapFormats[i].bits_per_pixel, nxagentRemotePixmapFormats[i].scanline_pad);
+ }
+ }
+ #endif
+}
+
+void nxagentSetDefaultDrawables()
+{
+ int i, j;
+
+ for (i = 0; i <= MAXDEPTH; i++)
+ {
+ nxagentDefaultDrawables[i] = None;
+ }
+
+ for (i = 0; i < nxagentNumPixmapFormats; i++)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: Checking remote pixmap format [%d] with depth [%d] "
+ "bits per pixel [%d] scanline pad [%d].\n", i, nxagentPixmapFormats[i].depth,
+ nxagentPixmapFormats[i].bits_per_pixel, nxagentPixmapFormats[i].scanline_pad);
+ #endif
+
+ if (nxagentPixmapFormats[i].depth == 24)
+ {
+ if (nxagentPixmapFormats[i].bits_per_pixel == 24)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: WARNING! Assuming remote pixmap "
+ "format [%d] as true 24 bits.\n", i);
+ #endif
+
+ nxagentTrue24 = True;
+ }
+ }
+
+ for (j = 0; j < nxagentNumDepths; j++)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: Checking depth at index [%d] with pixmap depth [%d] "
+ "and display depth [%d].\n", j, nxagentPixmapFormats[i].depth, nxagentDepths[j]);
+ #endif
+
+ if ((nxagentPixmapFormats[i].depth == 1 ||
+ nxagentPixmapFormats[i].depth == nxagentDepths[j]) &&
+ nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] == None)
+ {
+ nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] =
+ XCreatePixmap(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ 1, 1, nxagentPixmapFormats[i].depth);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: Created default drawable [%lu] for depth [%d].\n",
+ nxagentDefaultDrawables[nxagentPixmapFormats[i].depth], nxagentPixmapFormats[i].depth);
+ #endif
+ }
+ }
+
+ if (nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] == None)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: WARNING! Forcing default drawable for depth [%d].\n",
+ nxagentPixmapFormats[i].depth);
+ #endif
+
+ nxagentDefaultDrawables[nxagentPixmapFormats[i].depth] =
+ XCreatePixmap(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ 1, 1, nxagentPixmapFormats[i].depth);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetDefaultDrawables: Created default drawable [%lu] for depth [%d].\n",
+ nxagentDefaultDrawables[nxagentPixmapFormats[i].depth], nxagentPixmapFormats[i].depth);
+ #endif
+ }
+ }
+}
+
+void nxagentCloseDisplay()
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentCloseDisplay: Called with full generation [%d] and display [%p].\n",
+ nxagentDoFullGeneration, (void *) nxagentDisplay);
+ #endif
+
+ if (nxagentDoFullGeneration == 0 ||
+ nxagentDisplay == NULL)
+ {
+ return;
+ }
+
+ /*
+ * If nxagentDoFullGeneration is true, all
+ * the X resources will be destroyed upon
+ * closing the display connection, so there
+ * is no real need to generate additional
+ * traffic
+ */
+
+ free(nxagentDefaultColormaps);
+ nxagentDefaultColormaps = NULL;
+
+ XFree(nxagentVisuals);
+ nxagentVisuals = NULL;
+
+ free(nxagentDepths);
+ nxagentDepths = NULL;
+
+ XFree(nxagentPixmapFormats);
+ nxagentPixmapFormats = NULL;
+
+ XFree(nxagentRemotePixmapFormats);
+ nxagentRemotePixmapFormats = NULL;
+
+ nxagentFreeFontCache();
+/*
+FIXME: Is this needed?
+
+ nxagentFreeFontMatchStuff();
+*/
+
+ /*
+ * Free the image cache. This is useful
+ * for detecting memory leaks.
+ */
+
+ if (nxagentDisplay != NULL)
+ {
+ NXFreeCache(nxagentDisplay);
+
+ NXResetDisplay(nxagentDisplay);
+ }
+
+ /*
+ * Kill all the running dialogs.
+ */
+
+ nxagentTerminateDialogs();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCloseDisplay: Setting the display to NULL.\n");
+ #endif
+
+ XCloseDisplay(nxagentDisplay);
+
+ nxagentDisplay = NULL;
+}
+
+static FILE *nxagentLookForIconFile(char *iconName, const char *permission,
+ char *return_path)
+{
+ char *path;
+ char *end;
+ char singlePath[PATH_MAX];
+ int breakLoop;
+ FILE *fptr = NULL;
+
+ #ifdef WIN32
+ const char separator = ';';
+ const char *slash = "\\";
+ #else
+ const char separator = ':';
+ const char *slash = "/";
+ #endif
+
+ if ((path = getenv("PATH")) == NULL)
+ {
+ return NULL;
+ }
+
+ for(breakLoop = 0; breakLoop == 0 && fptr == NULL; )
+ {
+ end = strchr(path, separator);
+
+ if (end != NULL)
+ {
+ strncpy(singlePath, path, (unsigned long)(end - path));
+
+ singlePath[(unsigned long)(end - path)] = 0;
+
+ path = end + 1;
+ }
+ else
+ {
+ strcpy(singlePath, path);
+
+ breakLoop = 1;
+ }
+
+ if (singlePath[strlen(singlePath)- 1] == slash[0])
+ {
+ singlePath[strlen(singlePath)- 1] = 0;
+ }
+
+ if (strlen(singlePath) + strlen(iconName) + 1 < PATH_MAX)
+ {
+ strncat(singlePath, slash, 1);
+ strcat(singlePath, iconName);
+
+ if ((fptr = fopen(singlePath, permission)) != NULL)
+ {
+ strcpy(return_path, singlePath);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Error: Path too long.\n");
+ }
+ }
+
+ return fptr;
+}
+
+Bool nxagentMakeIcon(Display *display, Pixmap *nxIcon, Pixmap *nxMask)
+{
+ char default_path [PATH_MAX];
+ char icon_path [PATH_MAX];
+ FILE *icon_fp;
+ int status;
+ Bool success = False;
+ XlibPixmap IconPixmap;
+ XlibPixmap IconShape;
+ char* agent_icon_name;
+ char** agentIconData;
+
+ /*
+ * selecting x2go icon when running as X2Go agent
+ */
+ if(nxagentX2go)
+ {
+ agent_icon_name=X2GOAGENT_ICON_NAME;
+ agentIconData=x2goagentIconData;
+ }
+ else
+ {
+ agent_icon_name=NXAGENT_ICON_NAME;
+ agentIconData=nxagentIconData;
+ }
+
+
+ snprintf(default_path, PATH_MAX-1, "/usr/NX/share/images/%s", agent_icon_name);
+
+ if ((icon_fp = fopen(default_path, "r")) == NULL)
+ {
+ icon_fp = nxagentLookForIconFile(agent_icon_name, "r", icon_path);
+
+ if (icon_fp != NULL)
+ {
+ fclose (icon_fp);
+ success = True;
+ }
+ }
+ else
+ {
+ fclose (icon_fp);
+ success = True;
+ strcpy(icon_path, default_path);
+ }
+
+ if (success)
+ {
+ status = XpmReadFileToPixmap(display,
+ DefaultRootWindow(display),
+ icon_path,
+ &IconPixmap,
+ &IconShape,
+ NULL);
+
+ if (status != XpmSuccess)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMakeIcon: Xpm operation failed with error '%s'.\n",
+ XpmGetErrorString(status));
+ #endif
+
+ success = False;
+ }
+ }
+
+ if (!success)
+ {
+ status = XpmCreatePixmapFromData(display,
+ DefaultRootWindow(display),
+ agentIconData,
+ &IconPixmap,
+ &IconShape,
+ NULL);
+
+ if (status != XpmSuccess)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMakeIcon: Xpm operation failed with error '%s'.\n",
+ XpmGetErrorString(status));
+ #endif
+
+ success = False;
+ }
+ else
+ {
+ success = True;
+ }
+ }
+
+
+ *nxIcon = IconPixmap;
+ *nxMask = IconShape;
+
+ return success;
+}
+
+Bool nxagentXServerGeometryChanged()
+{
+ return (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) !=
+ WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplayBackup))) ||
+ (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) !=
+ HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplayBackup)));
+}
+
+void nxagentBackupDisplayInfo(void)
+{
+ if (nxagentDisplayInfoSaved)
+ {
+ return;
+ }
+
+ /*
+ * Since we need the display structure
+ * in order to behave correctly when no X
+ * connection is available, we must always
+ * have a good display record.
+ * It can be discarded only when a new X
+ * connection is available, so we store it
+ * in order to destroy whenever the recon-
+ * nection succed.
+ */
+
+ nxagentDisplayBackup = nxagentDisplay;
+ nxagentBitmapGCBackup = nxagentBitmapGC;
+ nxagentDepthsRecBackup = nxagentDepths;
+ nxagentNumDepthsRecBackup = nxagentNumDepths;
+ nxagentNumDefaultColormapsRecBackup = nxagentNumDefaultColormaps;
+ nxagentVisualsRecBackup = nxagentVisuals;
+ nxagentNumVisualsRecBackup = nxagentNumVisuals;
+ if (nxagentVisualHasBeenIgnored)
+ {
+ free(nxagentVisualHasBeenIgnored);
+ nxagentVisualHasBeenIgnored = NULL;
+ }
+ nxagentVisualHasBeenIgnored = malloc(nxagentNumVisuals * sizeof(Bool));
+ nxagentDefaultDepthRecBackup = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ nxagentDisplayWidthRecBackup = DisplayWidth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ nxagentDisplayHeightRecBackup = DisplayHeight(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ nxagentRenderEnableRecBackup = nxagentRenderEnable;
+
+ nxagentDisplayInfoSaved = True;
+}
+
+void nxagentCleanupBackupDisplayInfo(void)
+{
+ free(nxagentDepthsRecBackup);
+ nxagentNumDepthsRecBackup = 0;
+
+ nxagentNumDefaultColormapsRecBackup = 0;
+
+ free(nxagentVisualsRecBackup);
+ nxagentNumVisualsRecBackup = 0;
+
+ if (nxagentVisualHasBeenIgnored)
+ {
+ free(nxagentVisualHasBeenIgnored);
+ nxagentVisualHasBeenIgnored = NULL;
+ }
+
+ nxagentDefaultDepthRecBackup = 0;
+ nxagentDisplayWidthRecBackup = 0;
+ nxagentDisplayHeightRecBackup = 0;
+
+ if (nxagentDisplayBackup)
+ {
+ XCloseDisplay(nxagentDisplayBackup);
+
+ nxagentDisplayBackup = NULL;
+ }
+
+ if (nxagentBitmapGCBackup)
+ {
+ if (nxagentDisplayBackup)
+ {
+ XFreeGC(nxagentDisplayBackup, nxagentBitmapGCBackup);
+ }
+ else
+ {
+ free(nxagentBitmapGCBackup);
+ }
+
+ nxagentBitmapGCBackup = NULL;
+ }
+
+ nxagentDisplayInfoSaved = False;
+}
+
+void nxagentDisconnectDisplay(void)
+{
+ switch (reconnectDisplayState)
+ {
+ case EVERYTHING_DONE:
+ if (nxagentBitmapGC &&
+ nxagentBitmapGCBackup &&
+ (nxagentBitmapGC != nxagentBitmapGCBackup))
+ {
+ XFreeGC(nxagentDisplay, nxagentBitmapGC);
+ }
+
+ nxagentBitmapGC = nxagentBitmapGCBackup;
+ case GOT_PIXMAP_FORMAT_LIST:
+ case GOT_DEPTH_LIST:
+ case ALLOC_DEF_COLORMAP:
+ if (nxagentDefaultColormaps)
+ {
+ int i;
+
+ for (i = 0; i < nxagentNumDefaultColormaps; i++)
+ {
+ nxagentDefaultColormaps[i] = None;
+ }
+ }
+ case GOT_VISUAL_INFO:
+ case OPENED:
+ /*
+ * Actually we need the nxagentDisplay
+ * structure in order to let the agent
+ * go when no X connection is available.
+ */
+
+ if (nxagentDisplay &&
+ nxagentDisplayBackup &&
+ (nxagentDisplay != nxagentDisplayBackup))
+ {
+ XCloseDisplay(nxagentDisplay);
+ }
+ case NOTHING:
+ nxagentDisplay = nxagentDisplayBackup;
+ break;
+ default:
+ FatalError("Display is in unknown state. Can't continue.");
+ }
+
+ reconnectDisplayState = NOTHING;
+}
+
+static int nxagentCheckForDefaultDepthCompatibility()
+{
+ /*
+ * Depending on the (reconnect) tolerance checks value, this
+ * function checks stricter or looser:
+ * - Strict means that the old and new default depth values
+ * must match exactly.
+ * - Safe or Risky means that the default depth values might differ,
+ * but the new default depth value must be at least as
+ * high as the former default depth value. This is
+ * recommended, because it allows clients with a
+ * higher default depth value to still connect, but
+ * not lose functionality.
+ * - Bypass means that all of these checks are essentially
+ * deactivated. This is probably a very bad idea.
+ */
+
+ int dDepth;
+
+ dDepth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+ const unsigned int tolerance = nxagentOption(ReconnectTolerance);
+
+ if (ToleranceChecksBypass <= tolerance)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: WARNING! Not proceeding with any checks, "
+ "because tolerance [%u] higher than or equal [%u]. New default depth value "
+ "is [%d], former default depth value is [%d].\n", tolerance,
+ ToleranceChecksBypass, dDepth, nxagentDefaultDepthRecBackup);
+ #endif
+
+ return 1;
+ }
+
+ if (nxagentDefaultDepthRecBackup == dDepth)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: New default depth [%d] "
+ "matches with old default depth.\n", dDepth);
+ #endif
+
+ return 1;
+ }
+ else if ((ToleranceChecksSafe <= tolerance) && (nxagentDefaultDepthRecBackup < dDepth))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: WARNING! New default depth [%d] "
+ "higher than the old default depth [%d] at tolerance [%u].\n", dDepth,
+ nxagentDefaultDepthRecBackup, tolerance);
+ #endif
+
+ return 1;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDefaultDepthCompatibility: WARNING! New default depth [%d] "
+ "doesn't match with old default depth [%d] at tolerance [%u].\n", dDepth,
+ nxagentDefaultDepthRecBackup, tolerance);
+ #endif
+
+ return 0;
+ }
+}
+
+static int nxagentCheckForDepthsCompatibility()
+{
+ /*
+ * Depending on the (reconnect) tolerance checks value, this
+ * function checks stricter or looser:
+ * - Strict means that the number of old and new depths must
+ * match exactly and every old depth value must be
+ * available in the new depth array.
+ * - Safe means that the number of depths might diverge,
+ * but all former depth must also be included in the
+ * new depth array. This is recommended, because
+ * it allows clients with more depths to still
+ * connect, but not lose functionality.
+ * - Risky means that the new depths array is allowed to be
+ * smaller than the old depths array, but at least
+ * one depth value must be included in both.
+ * This is potentially unsafe.
+ * - Bypass or higher means that all of these checks are
+ * essentially deactivated. This is a very bad idea.
+ */
+
+ const unsigned int tolerance = nxagentOption(ReconnectTolerance);
+
+ if (ToleranceChecksBypass <= tolerance)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! Not proceeding with any checks, "
+ "because tolerance [%u] higher than or equal [%u]. Number of newly available depths "
+ "is [%d], number of old depths is [%d].\n", tolerance, ToleranceChecksBypass,
+ nxagentNumDepths, nxagentNumDepthsRecBackup);
+ #endif
+
+ return 1;
+ }
+
+ if ((ToleranceChecksStrict == tolerance) && (nxagentNumDepths != nxagentNumDepthsRecBackup))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! No tolerance allowed and "
+ "number of new available depths [%d] doesn't match with number of old "
+ "depths [%d].\n", nxagentNumDepths,
+ nxagentNumDepthsRecBackup);
+ #endif
+
+ return 0;
+ }
+
+ if ((ToleranceChecksSafe == tolerance) && (nxagentNumDepths < nxagentNumDepthsRecBackup))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! Tolerance [%u] not "
+ "high enough and number of new available depths [%d] "
+ "lower than number of old depths [%d].\n", tolerance,
+ nxagentNumDepths, nxagentNumDepthsRecBackup);
+ #endif
+
+ return 0;
+ }
+
+ /*
+ * By now the tolerance is either:
+ * - Strict and both depth numbers match
+ * - Safe and:
+ * o the number of old and new depths matches exactly, or
+ * o the number of old depths is lower than the number
+ * of new depths
+ * - Risky
+ */
+
+ bool compatible = true;
+ bool one_match = false;
+ bool matched = false;
+ int total_matches = 0;
+
+ /*
+ * FIXME: within this loop, we try to match all "new" depths
+ * against the "old" depths. Depending upon the flexibility
+ * value, either all "new" depths must have a corresponding
+ * counterpart in the "old" array, or at least one value
+ * must be included in both.
+ * Is this safe enough though?
+ * Shouldn't we better try to match entries in the "old"
+ * depths array against the "new" depths array, such that
+ * we know that all "old" values are covered by "new"
+ * values? Or is it more important that "new" values are
+ * covered by "old" ones, with potentially more "old"
+ * values lingering around that cannot be displayed by the
+ * connected client?
+ *
+ * This section probably needs a revisit at some point in time.
+ */
+ for (int i = 0; i < nxagentNumDepths; ++i)
+ {
+ matched = false;
+
+ for (int j = 0; j < nxagentNumDepthsRecBackup; ++j)
+ {
+ if (nxagentDepths[i] == nxagentDepthsRecBackup[j])
+ {
+ matched = true;
+ one_match = true;
+ ++total_matches;
+
+ break;
+ }
+ }
+
+ if ((ToleranceChecksRisky > tolerance) && (!matched))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! Tolerance [%u] too low and "
+ "failed to match available depth [%d].\n", tolerance, nxagentDepths[i]);
+ #endif
+
+ compatible = false;
+
+ break;
+ }
+ }
+
+ /*
+ * At Risky tolerance, only one match is necessary to be "compatible".
+ */
+ if (ToleranceChecksRisky == tolerance)
+ {
+ compatible = one_match;
+ }
+
+ int ret = (!(!compatible));
+
+ if (compatible)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: Internal depths match with "
+ "remote depths at tolerance [%u].\n", tolerance);
+ #endif
+
+ if (total_matches != nxagentNumDepths)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: only some [%d] of the new depths [%d] "
+ "match with old depths [%d] at tolerance [%u].\n", total_matches, nxagentNumDepths,
+ nxagentNumDepthsRecBackup, tolerance);
+ #endif
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForDepthsCompatibility: WARNING! New available depths [%d] don't match "
+ "with old depths [%d] at tolerance [%u]. Only [%d] depth values matched.\n",
+ nxagentNumDepths, nxagentNumDepthsRecBackup, tolerance, total_matches);
+ #endif
+ }
+
+ return (ret);
+}
+
+static int nxagentCheckForPixmapFormatsCompatibility()
+{
+ /*
+ * Depending on the (reconnect) tolerance checks value, this
+ * function checks stricter or looser:
+ * - Strict means that the number of internal and external
+ * pixmap formats must match exactly and every
+ * internal pixmap format must be available in the
+ * external pixmap format array.
+ * - Safe means that the number of pixmap formats might
+ * diverge, but all internal pixmap formats must
+ * also be included in the external pixmap formats
+ * array. This is recommended, because it allows
+ * clients with more pixmap formats to still connect,
+ * but not lose functionality.
+ * - Risky means that the internal pixmap formats array is
+ * allowed to be smaller than the external pixmap
+ * formats array, but at least one pixmap format must
+ * be included in both. This is potentially unsafe.
+ * - Bypass or higher means that all of these checks are
+ * essentially deactivated. This is a very bad idea.
+ */
+
+ const unsigned int tolerance = nxagentOption(ReconnectTolerance);
+
+ if (ToleranceChecksBypass <= tolerance)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Not proceeding with any checks, "
+ "because tolerance [%u] higher than or equal [%u]. Number of internally available "
+ "pixmap formats is [%d], number of externally available pixmap formats is [%d].\n",
+ tolerance, ToleranceChecksBypass, nxagentNumPixmapFormats, nxagentRemoteNumPixmapFormats);
+ #endif
+
+ return 1;
+ }
+
+ if ((ToleranceChecksStrict == tolerance) && (nxagentNumPixmapFormats != nxagentRemoteNumPixmapFormats))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! No tolerance allowed and number "
+ "of internal pixmap formats [%d] doesn't match with number of remote formats [%d].\n",
+ nxagentNumPixmapFormats, nxagentRemoteNumPixmapFormats);
+ #endif
+
+ return 0;
+ }
+
+ if ((ToleranceChecksSafe == tolerance) && (nxagentNumPixmapFormats > nxagentRemoteNumPixmapFormats))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Tolerance [%u] too low "
+ "and number of internal pixmap formats [%d] higher than number of external formats [%d].\n",
+ tolerance, nxagentNumPixmapFormats, nxagentRemoteNumPixmapFormats);
+ #endif
+
+ return 0;
+ }
+
+ /*
+ * By now the tolerance is either:
+ * - Strict
+ * - Safe and:
+ * o the number of internal and external pixmap formats
+ * matches exactly, or
+ * o the number of external pixmap formats is higher than
+ * the number of internal pixmap formats,
+ * - Risky
+ */
+
+ bool compatible = true;
+ bool matched = false;
+ int total_matches = 0;
+
+ for (int i = 0; i < nxagentNumPixmapFormats; ++i)
+ {
+ matched = false;
+
+ for (int j = 0; j < nxagentRemoteNumPixmapFormats; ++j)
+ {
+ if (nxagentPixmapFormats[i].depth == nxagentRemotePixmapFormats[j].depth &&
+ nxagentPixmapFormats[i].bits_per_pixel == nxagentRemotePixmapFormats[j].bits_per_pixel &&
+ nxagentPixmapFormats[i].scanline_pad == nxagentRemotePixmapFormats[j].scanline_pad)
+ {
+ matched = true;
+ ++total_matches;
+
+ break;
+ }
+ }
+
+ if ((ToleranceChecksRisky > tolerance) && (!matched))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Tolerance [%u] too low "
+ "and failed to match internal pixmap format (depth [%d] bpp [%d] pad [%d]).\n",
+ tolerance, nxagentPixmapFormats[i].depth, nxagentPixmapFormats[i].bits_per_pixel,
+ nxagentPixmapFormats[i].scanline_pad);
+ #endif
+
+ compatible = false;
+ }
+ }
+
+ int ret = !(!(compatible));
+
+ if (compatible)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: Internal pixmap formats match with "
+ "remote pixmap formats at tolerance [%u].\n", tolerance);
+ #endif
+
+ if (total_matches != nxagentNumPixmapFormats)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: Only some [%d] of the internal "
+ "pixmap formats [%d] match with external pixmap formats [%d] at tolerance [%u].\n",
+ total_matches, nxagentNumPixmapFormats, nxagentRemoteNumPixmapFormats, tolerance);
+ #endif
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForPixmapFormatsCompatibility: WARNING! Internally available "
+ "pixmap formats [%d] don't match with external pixmap formats [%d] "
+ "at tolerance [%u]. Only [%d] depth values matched.\n",
+ nxagentNumPixmapFormats, nxagentRemoteNumPixmapFormats, tolerance, total_matches);
+ #endif
+ }
+
+ return (ret);
+}
+
+static int nxagentInitAndCheckVisuals(int flexibility)
+{
+ /* FIXME: does this also need work? */
+ XVisualInfo viTemplate;
+ XVisualInfo *viList;
+ XVisualInfo *newVisuals;
+
+ long viMask;
+ int i, n;
+ int matched;
+ int compatible;
+ int viNumList;
+
+ compatible = 1;
+
+ viMask = VisualScreenMask;
+ viTemplate.screen = DefaultScreen(nxagentDisplay);
+ viTemplate.depth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ viList = XGetVisualInfo(nxagentDisplay, viMask, &viTemplate, &viNumList);
+
+ newVisuals = malloc(sizeof(XVisualInfo) * nxagentNumVisuals);
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ matched = 0;
+
+ for (n = 0; n < viNumList; n++)
+ {
+ if (nxagentCompareVisuals(nxagentVisuals[i], viList[n]) == 1)
+ {
+/*
+FIXME: Should the visual be ignored in this case?
+ We can flag the visuals with inverted masks,
+ and use this information to switch the masks
+ when contacting the remote X server.
+*/
+ if (nxagentVisuals[i].red_mask == viList[n].blue_mask &&
+ nxagentVisuals[i].blue_mask == viList[n].red_mask)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Red and blue mask inverted. "
+ "Forcing matching.\n");
+ #endif
+ }
+
+ matched = 1;
+
+ nxagentVisualHasBeenIgnored[i] = FALSE;
+
+ memcpy(newVisuals + i, viList + n, sizeof(XVisualInfo));
+
+ break;
+ }
+ }
+
+ if (matched == 0)
+ {
+ if (nxagentVisuals[i].class == DirectColor)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Ignoring not matched DirectColor visual.\n");
+ #endif
+
+ nxagentVisualHasBeenIgnored[i] = TRUE;
+
+ memcpy(newVisuals + i, nxagentVisuals + i, sizeof(XVisualInfo));
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentInitAndCheckVisuals: WARNING! Failed to match this visual:\n");
+ fprintf(stderr, "\tdepth = %d\n", nxagentVisuals[i].depth);
+ fprintf(stderr, "\tclass = %d\n", nxagentVisuals[i].class);
+ fprintf(stderr, "\tmask = (%ld,%ld,%ld)\n",
+ nxagentVisuals[i].red_mask,
+ nxagentVisuals[i].green_mask,
+ nxagentVisuals[i].blue_mask);
+ fprintf(stderr, "\tcolormap size = %d\n", nxagentVisuals[i].colormap_size);
+ fprintf(stderr, "\tbits_per_rgb = %d\n", nxagentVisuals[i].bits_per_rgb);
+ #endif
+
+ compatible = 0;
+
+ break;
+ }
+ }
+ }
+
+ XFree(viList);
+
+ if (compatible == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitAndCheckVisuals: New visuals match with old visuals.\n");
+ #endif
+
+ nxagentVisuals = newVisuals;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitAndCheckVisuals: New visuals don't match with old visuals.\n");
+ #endif
+
+ free(newVisuals);
+ }
+
+ return compatible;
+}
+
+static int nxagentCheckForColormapsCompatibility(int flexibility)
+{
+ /* FIXME: does this also need work? */
+ if (nxagentNumDefaultColormaps == nxagentNumDefaultColormapsRecBackup)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckForColormapsCompatibility: Number of new colormaps [%d] "
+ "matches with old colormaps.\n", nxagentNumDefaultColormaps);
+ #endif
+
+ return 1;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckForColormapsCompatibility: WARNING! Number of new colormaps [%d] "
+ "doesn't match with old colormaps [%d].\n", nxagentNumDefaultColormaps,
+ nxagentNumDefaultColormapsRecBackup);
+ #endif
+
+ return 0;
+ }
+}
+
+Bool nxagentReconnectDisplay(void *p0)
+{
+ int i;
+ int flexibility = *(int*)p0;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_DISPLAY_DEBUG)
+ fprintf(stderr, "nxagentReconnectDisplay\n");
+ #endif
+
+ if (reconnectDisplayState)
+ {
+ fprintf(stderr, "nxagentReconnectDisplay: Trying to reconnect a session "
+ "uncleanly disconnected\n");
+
+ return False;
+ }
+
+ /*
+ * Reset the values to their defaults.
+ */
+
+ nxagentPackMethod = -1;
+ nxagentPackQuality = -1;
+ nxagentSplitThreshold = -1;
+
+ nxagentRemoteMajor = -1;
+
+ nxagentInstallSignalHandlers();
+
+ nxagentInstallDisplayHandlers();
+
+ nxagentDisplay = nxagentInternalOpenDisplay(nxagentDisplayName);
+
+ nxagentPostInstallSignalHandlers();
+
+ nxagentPostInstallDisplayHandlers();
+
+ if (nxagentDisplay == NULL)
+ {
+ nxagentSetReconnectError(FAILED_RESUME_DISPLAY_ALERT,
+ "Couldn't open the display.");
+
+ return FALSE;
+ }
+
+ nxagentAddXConnection();
+
+ /*
+ * Display is now open.
+ */
+
+ reconnectDisplayState = OPENED;
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ fprintf(stderr, "Display: Open of the display finished with time [%d] ms.\n",
+ GetTimeInMillis() - startTime);
+
+ #endif
+
+ if (nxagentCheckForDefaultDepthCompatibility() == 0)
+ {
+ nxagentSetReconnectError(FAILED_RESUME_DISPLAY_ALERT,
+ "Default display depth doesn't match.");
+
+ return FALSE;
+ }
+
+ nxagentUseNXTrans = nxagentPostProcessArgs(nxagentDisplayName, nxagentDisplay,
+ DefaultScreenOfDisplay(nxagentDisplay));
+
+ /*
+ * After processing the arguments all the
+ * timeout values have been set. Now we
+ * have to change the screen-saver timeout.
+ */
+
+ nxagentSetScreenSaverTime();
+
+ /*
+ * Init and compare the visuals.
+ */
+
+ if (nxagentInitAndCheckVisuals(flexibility) == FALSE)
+ {
+ nxagentSetReconnectError(FAILED_RESUME_VISUALS_ALERT,
+ "Couldn't restore the required visuals.");
+
+ return FALSE;
+ }
+
+ reconnectDisplayState = GOT_VISUAL_INFO;
+
+ nxagentSetDefaultVisual();
+
+ nxagentInitAlphaVisual();
+
+ /*
+ * Re-allocate the colormaps.
+ */
+
+ nxagentNumDefaultColormaps = nxagentNumVisuals;
+
+ nxagentDefaultColormaps = (Colormap *) realloc(nxagentDefaultColormaps,
+ nxagentNumDefaultColormaps * sizeof(Colormap));
+
+ if (nxagentDefaultColormaps == NULL)
+ {
+ FatalError("Can't allocate memory for the default colormaps\n");
+ }
+
+ reconnectDisplayState = ALLOC_DEF_COLORMAP;
+
+ for (i = 0; i < nxagentNumDefaultColormaps; i++)
+ {
+ if (nxagentVisualHasBeenIgnored[i])
+ {
+ nxagentDefaultColormaps[i] = (XID)0;
+ }
+ else
+ {
+ nxagentDefaultColormaps[i] = XCreateColormap(nxagentDisplay,
+ DefaultRootWindow(nxagentDisplay),
+ nxagentVisuals[i].visual,
+ AllocNone);
+ }
+ }
+
+ nxagentCheckForColormapsCompatibility(flexibility);
+
+ /*
+ * Check the display depth.
+ */
+
+ nxagentInitDepths();
+
+ reconnectDisplayState = GOT_DEPTH_LIST;
+
+ if (nxagentCheckForDepthsCompatibility() == 0)
+ {
+ nxagentSetReconnectError(FAILED_RESUME_DEPTHS_ALERT,
+ "Couldn't restore all the required depths.");
+
+ return False;
+ }
+
+ /*
+ * nxagentPixmapFormats and nxagentRemotePixmapFormats
+ * will be reallocated in nxagentInitPixmapFormats().
+ */
+
+ if (nxagentPixmapFormats != NULL)
+ {
+ XFree(nxagentPixmapFormats);
+
+ nxagentPixmapFormats = NULL;
+ }
+
+ if (nxagentRemotePixmapFormats != NULL)
+ {
+ XFree(nxagentRemotePixmapFormats);
+
+ nxagentRemotePixmapFormats = NULL;
+ }
+
+ /*
+ * Check if all the required pixmap
+ * formats are supported.
+ */
+
+ nxagentInitPixmapFormats();
+
+ if (nxagentCheckForPixmapFormatsCompatibility() == 0)
+ {
+ nxagentSetReconnectError(FAILED_RESUME_PIXMAPS_ALERT,
+ "Couldn't restore all the required pixmap formats.");
+
+ return False;
+ }
+
+ reconnectDisplayState = GOT_PIXMAP_FORMAT_LIST;
+
+ /*
+ * Create a pixmap for each depth matching the
+ * local supported formats with format available
+ * on the remote display.
+ */
+
+ nxagentSetDefaultDrawables();
+
+ #ifdef RENDER
+
+ if (nxagentRenderEnable)
+ {
+ nxagentRenderExtensionInit();
+ }
+
+ if (nxagentRenderEnableRecBackup != nxagentRenderEnable)
+ {
+ nxagentRenderEnable = nxagentRenderEnableRecBackup;
+
+ nxagentSetReconnectError(FAILED_RESUME_RENDER_ALERT,
+ "Render extension not available or incompatible version.");
+
+ return False;
+ }
+
+ #endif
+
+ nxagentBlackPixel = BlackPixel(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ nxagentWhitePixel = WhitePixel(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+ /*
+ * Initialize the agent's event mask that will be requested
+ * for the root or all the top level windows. If the nested
+ * window is a child of an existing window we will need to
+ * receive StructureNotify events. If we are going to manage
+ * the changes in root window's visibility we'll also need
+ * VisibilityChange events.
+ */
+
+ nxagentInitDefaultEventMask();
+
+ nxagentBitmapGC = XCreateGC(nxagentDisplay, nxagentDefaultDrawables[1], 0L, NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectDisplay: Going to create agent's confine window.\n");
+ #endif
+
+ nxagentConfineWindow = XCreateWindow(nxagentDisplay,
+ DefaultRootWindow(nxagentDisplay),
+ 0, 0, 1, 1, 0, 0,
+ InputOnly,
+ CopyFromParent,
+ 0L, NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectDisplay: Created agent's confine window with id [%ld].\n",
+ nxagentConfineWindow);
+ #endif
+
+ nxagentLogoDepth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+ nxagentLogoBlack = 0x000000;
+ nxagentLogoRed = 0xff0000;
+ nxagentLogoWhite = 0xffffff;
+ nxagentLogoGray = 0x222222;
+
+ useXpmIcon = nxagentMakeIcon(nxagentDisplay, &nxagentIconPixmap, &nxagentIconShape);
+
+ /*
+ * All went fine. We can continue
+ * handling our clients.
+ */
+
+ reconnectDisplayState = EVERYTHING_DONE;
+
+ return True;
+}
+
+void nxagentAddXConnection()
+{
+ int fd = XConnectionNumber(nxagentDisplay);
+
+ nxagentXConnectionNumber = fd;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddXConnection: Adding the X connection [%d] "
+ "to the device set.\n", nxagentXConnectionNumber);
+ #endif
+
+ SetNotifyFd(XConnectionNumber(nxagentDisplay), nxagentNotifyConnection, X_NOTIFY_READ, NULL);
+}
+
+void nxagentRemoveXConnection()
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemoveXConnection: Removing the X connection [%d] "
+ "from the device set.\n", nxagentXConnectionNumber);
+ #endif
+
+ RemoveNotifyFd(nxagentXConnectionNumber);
+}
+
+/*
+ * Force an I/O error and wait until the NX trans-
+ * port is gone. It must be called before suspend-
+ * ing or terminating a session to ensure that the
+ * NX transport is terminated first.
+ */
+
+void nxagentWaitDisplay()
+{
+ /*
+ * Disable the smart scheduler's interrupts.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWaitDisplay: Stopping the smart schedule timer.\n");
+ #endif
+
+ nxagentStopTimer();
+
+ if (nxagentDisplay != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitDisplay: Going to shutdown the X connection [%d].\n",
+ nxagentXConnectionNumber);
+ #endif
+
+ NXForceDisplayError(nxagentDisplay);
+
+ XSync(nxagentDisplay, 0);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitDisplay: Going to wait for the NX transport.\n");
+ #endif
+
+ NXTransDestroy(NX_FD_ANY);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitDisplay: The NX transport is not running.\n");
+ #endif
+
+ /*
+ * Be sure the signal handlers are
+ * in a known state.
+ */
+
+ nxagentResetSignalHandlers();
+}
+
+/*
+ * This has not to do with the remote display but
+ * with the X server that the agent is impersonating.
+ * We have it here to be consistent with the other
+ * cleanup procedures which have mainly to do with
+ * the Xlib display connection.
+ */
+
+void nxagentAbortDisplay()
+{
+ /*
+ * Be sure the X server socket in .X11-unix is
+ * deleted otherwise other users may to become
+ * unable to run a session on the same display.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAbortDisplay: Cleaning up the X server sockets.\n");
+ #endif
+
+ CloseWellKnownConnections();
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
new file mode 100644
index 000000000..759b0de35
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -0,0 +1,178 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Display_H__
+#define __Display_H__
+
+#define MAXDEPTH 32
+#define MAXVISUALSPERDEPTH 256
+
+extern Display *nxagentDisplay;
+extern Display *nxagentShadowDisplay;
+extern XVisualInfo *nxagentVisuals;
+extern int nxagentNumVisuals;
+extern int nxagentDefaultVisualIndex;
+extern Colormap *nxagentDefaultColormaps;
+extern int nxagentNumDefaultColormaps;
+extern int *nxagentDepths;
+extern int nxagentNumDepths;
+extern XPixmapFormatValues *nxagentPixmapFormats;
+extern int nxagentNumPixmapFormats;
+extern Pixel nxagentBlackPixel;
+extern Pixel nxagentWhitePixel;
+extern Drawable nxagentDefaultDrawables[MAXDEPTH + 1];
+extern Pixmap nxagentScreenSaverPixmap;
+
+/*
+ * The "confine" window is used in nxagentConstrainCursor().
+ * We are currently overriding the original Xnest behaviour
+ * and just skip the "constrain" stuff.
+ */
+
+extern Window nxagentConfineWindow;
+
+/*
+ * Keyboard and pointer are handled as they were hardware
+ * devices, that is we translate the key codes according to
+ * our own transcripts. We inherit this behaviour from Xnest.
+ * The following mask will contain the event mask selected
+ * for the root window. All the keyboard and pointer events
+ * are enqueued to the mi that translates and posts them to
+ * managed clients.
+ */
+
+extern unsigned long nxagentEventMask;
+
+void nxagentOpenDisplay(int argc, char *argv[]);
+void nxagentWaitDisplay(void);
+void nxagentCloseDisplay(void);
+void nxagentAbortDisplay(void);
+
+void nxagentAddXConnection(void);
+void nxagentRemoveXConnection(void);
+
+Bool nxagentXServerGeometryChanged(void);
+
+/*
+ * Create the default drawables.
+ */
+
+void nxagentGetDepthsAndPixmapFormats(void);
+void nxagentSetDefaultDrawables(void);
+
+extern Bool nxagentTrue24;
+
+void nxagentBackupDisplayInfo(void);
+void nxagentCleanupBackupDisplayInfo(void);
+
+void nxagentInstallDisplayHandlers(void);
+void nxagentPostInstallDisplayHandlers(void);
+void nxagentResetDisplayHandlers(void);
+
+void nxagentInstallSignalHandlers(void);
+void nxagentPostInstallSignalHandlers(void);
+void nxagentResetSignalHandlers(void);
+
+void nxagentDisconnectDisplay(void);
+Bool nxagentReconnectDisplay(void *p0);
+
+/*
+ * Deal with the smart scheduler.
+ */
+
+#if HAVE_SETITIMER
+#define nxagentInitTimer() \
+\
+ SmartScheduleInit();
+
+#define nxagentStopTimer() \
+\
+ SmartScheduleStopTimer(); \
+
+#define nxagentStartTimer() \
+\
+ SmartScheduleStartTimer();
+
+#define nxagentDisableTimer() \
+\
+ SmartScheduleStopTimer(); \
+ SmartScheduleSignalEnable = FALSE;
+#else
+#define nxagentInitTimer()
+#define nxagentStopTimer()
+#define nxagentStartTimer()
+#define nxagentDisableTimer()
+#endif /* HAVE_SETITIMER */
+
+/*
+ * File descriptor currently used by
+ * Xlib for the agent display.
+ */
+
+extern int nxagentXConnectionNumber;
+
+/*
+ * File descriptor currently used by
+ * Xlib for the agent shadow display.
+ */
+
+extern int nxagentShadowXConnectionNumber;
+
+int nxagentServerOrder(void);
+
+int nxagentGetDataRate(void);
+
+#define nxagentClientOrder(client) \
+ ((client)->swapped ? !nxagentServerOrder() : nxagentServerOrder())
+
+/*
+ * Terminate the agent after the next
+ * dispatch loop.
+ */
+
+#define nxagentTerminateSession() \
+ do \
+ { \
+ dispatchException |= DE_TERMINATE; \
+ \
+ isItTimeToYield = TRUE; \
+ } \
+ while (0)
+
+#endif /* __Display_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
new file mode 100644
index 000000000..917f460ba
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -0,0 +1,3308 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Trap.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Client.h"
+#include "Visual.h"
+#include "Events.h"
+#include "GCs.h"
+#include "Utils.h"
+#include "Handlers.h"
+#include "Pixels.h"
+#include "Reconnect.h"
+#include "GCOps.h"
+
+#include "compext/Compext.h"
+
+#include "mibstorest.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/*
+ * The list of rectangles composing a region
+ * s returned by nxagentGetOptimizedRegion-
+ * Boxes() instead of RegionRects().
+ */
+
+#define USE_OPTIMIZED_BOXES
+
+/*
+ * The rectangles composing a region are de-
+ * fragmented to reduce the number of synch-
+ * ronizing PutImage's.
+ */
+
+#define ADVANCED_BOXES_DEFRAG
+
+/*
+ * If defined, send the XClearArea at the end
+ * of the loop synchronizing the shadow pixmap.
+ * In this way, large images can be splitted but
+ * the user will see more updates togheter.
+ */
+
+#undef COLLECTED_UPDATES
+
+#ifdef ADVANCED_BOXES_DEFRAG
+#define INCLUDE_MARGIN 10
+#endif
+
+struct nxagentExposeBackground
+{
+ PixmapPtr pBackground;
+ RegionPtr pExpose;
+};
+
+RESTYPE RT_NX_CORR_BACKGROUND;
+RESTYPE RT_NX_CORR_WINDOW;
+RESTYPE RT_NX_CORR_PIXMAP;
+
+int nxagentCorruptedPixmaps = 0;
+int nxagentCorruptedWindows = 0;
+int nxagentCorruptedBackgrounds = 0;
+
+int nxagentForceSynchronization = 0;
+
+_nxagentSynchronizationRec nxagentSynchronization = { (DrawablePtr) NULL, 0, 0, 0, 0, 0 };
+
+RegionPtr nxagentDeferredBackgroundExposures = NullRegion;
+
+/*
+ * Predicate functions used to synchronize the
+ * content of the remote drawable with the data
+ * stored in the virtual frame-buffer.
+ */
+
+void nxagentSynchronizeDrawablePredicate(void *p0, XID x1, void *p2);
+void nxagentExposeBackgroundPredicate(void *p0, XID x1, void *p2);
+
+/*
+ * Imported from NXresource.c
+ */
+
+extern int nxagentFindClientResource(int, RESTYPE, void *);
+
+unsigned long nxagentGetColor(DrawablePtr pDrawable, int xPixel, int yPixel);
+unsigned long nxagentGetDrawableColor(DrawablePtr pDrawable);
+unsigned long nxagentGetRegionColor(DrawablePtr pDrawable, RegionPtr pRegion);
+
+int nxagentSkipImage = 0;
+
+static int nxagentTooManyImageData(void)
+{
+ unsigned int r;
+ unsigned int limit;
+
+ limit = nxagentOption(ImageRateLimit);
+
+ r = nxagentGetDataRate() / 1000;
+
+ #ifdef TEST
+ if (r > limit)
+ {
+ fprintf(stderr, "Warning: Current bit rate is: %u kB/s.\n", r);
+ }
+ #endif
+
+ return (r > limit);
+}
+
+int nxagentSynchronizeDrawable(DrawablePtr pDrawable, int wait, unsigned int breakMask, WindowPtr owner)
+{
+ int result;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ if (nxagentLosslessTrap == 0)
+ {
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawable: Drawable [%s][%p] with id [%ld] already "
+ "synchronized.\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, pDrawable -> id);
+ #endif
+
+ return 0;
+ }
+ }
+
+ /*
+ * What we want here is to avoid drawing on the
+ * framebuffer and just perform the operation
+ * on the real X server. This is the purpose of
+ * the FB trap. At the same time we also want
+ * to avoid a split, so that the image will be
+ * transferred in a single operation.
+ */
+
+ nxagentFBTrap = 1;
+
+ nxagentSplitTrap = 1;
+
+ result = nxagentSynchronizeDrawableData(pDrawable, breakMask, owner);
+
+ nxagentSplitTrap = 0;
+
+ nxagentFBTrap = 0;
+
+ if (wait == DO_WAIT && nxagentSplitResource(pDrawable) != NULL)
+ {
+ nxagentWaitDrawable(pDrawable);
+ }
+
+ #ifdef TEST
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ fprintf(stderr, "nxagentSynchronizeDrawable: Drawable %s [%p] with id [%ld] now synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable, pDrawable -> id);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentSynchronizeDrawable: Drawable %s [%p] with id [%ld] not fully synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable, pDrawable -> id);
+ }
+
+ #endif
+
+ return result;
+}
+
+int nxagentSynchronizeDrawableData(DrawablePtr pDrawable, unsigned int breakMask, WindowPtr owner)
+{
+ int width, height, depth, length;
+ unsigned int leftPad, format;
+
+ char *data = NULL;
+ DrawablePtr pSrcDrawable;
+ GCPtr pGC;
+
+ int success;
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ leftPad = 0;
+
+ width = pDrawable -> width;
+ height = pDrawable -> height;
+ depth = pDrawable -> depth;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawableData: Synchronizing drawable (%s) with geometry [%d][%d][%d].\n",
+ nxagentDrawableType(pDrawable), width, height, depth);
+ #endif
+
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ length = nxagentImageLength(width, height, format, leftPad, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ success = 0;
+
+ goto nxagentSynchronizeDrawableDataEnd;
+ }
+
+ pSrcDrawable = (pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((DrawablePtr) nxagentVirtualPixmap((PixmapPtr) pDrawable)) :
+ pDrawable);
+
+ /*
+ * Synchronize the whole pixmap if we need
+ * to download a fresh copy with lossless
+ * compression turned off.
+ */
+
+ if (nxagentLosslessTrap == 1)
+ {
+ pGC = nxagentGetGraphicContext(pDrawable);
+
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to get the temporary GC.\n");
+ #endif
+
+ success = 0;
+
+ goto nxagentSynchronizeDrawableDataFree;
+ }
+
+ ValidateGC(pDrawable, pGC);
+
+ fbGetImage(pSrcDrawable, 0, 0,
+ width, height, format, AllPlanes, data);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawableData: Forcing synchronization of "
+ "pixmap at [%p] with lossless compression.\n", (void *) pDrawable);
+ #endif
+
+ nxagentPutImage(pDrawable, pGC, depth, 0, 0,
+ width, height, leftPad, format, data);
+
+ success = 1;
+
+ goto nxagentSynchronizeDrawableDataFree;
+ }
+ else if (nxagentReconnectTrap == 1)
+ {
+ /*
+ * The pixmap data is not synchronized unless
+ * we need it. We noticed we have to reconnect
+ * the pixmaps used by the GC's clip mask.
+ * The other data will be synchronized on demand.
+ */
+
+ if (pDrawable -> depth == 1)
+ {
+ #ifdef TEST
+
+ if (nxagentReconnectTrap == 1)
+ {
+ static int totalLength;
+ static int totalReconnectedPixmaps;
+
+ totalLength += length;
+ totalReconnectedPixmaps++;
+
+ fprintf(stderr, "nxagentSynchronizeDrawableData: Reconnecting pixmap at [%p] [%dx%d] "
+ "Depth [%d] Size [%d]. Total size [%d]. Total reconnected pixmaps [%d].\n",
+ (void *) pDrawable, width, height, depth, length,
+ totalLength, totalReconnectedPixmaps);
+ }
+
+ #endif
+
+ pGC = nxagentGetGraphicContext(pDrawable);
+
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to create the temporary GC.\n");
+ #endif
+
+ success = 0;
+
+ goto nxagentSynchronizeDrawableDataFree;
+ }
+
+ ValidateGC(pDrawable, pGC);
+
+ fbGetImage(pSrcDrawable, 0, 0,
+ width, height, format, AllPlanes, data);
+
+ nxagentPutImage(pDrawable, pGC, depth, 0, 0,
+ width, height, leftPad, format, data);
+
+ success = 1;
+
+ goto nxagentSynchronizeDrawableDataFree;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawableData: Skipping synchronization of "
+ "pixmap at [%p][%p] during reconnection.\n", (void *) pDrawable, (void*) nxagentVirtualPixmap((PixmapPtr)pDrawable));
+ #endif
+
+ nxagentMarkCorruptedRegion(pDrawable, NullRegion);
+
+ success = 1;
+
+ goto nxagentSynchronizeDrawableDataFree;
+ }
+ }
+ }
+
+ /*
+ * By calling this function with the NullRegion
+ * as parameter we are requesting to synchro-
+ * nize the full visible corrupted region of
+ * the drawable.
+ */
+
+ success = nxagentSynchronizeRegion(pDrawable, NullRegion, breakMask, owner);
+
+nxagentSynchronizeDrawableDataFree:
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+
+nxagentSynchronizeDrawableDataEnd:
+
+ return success;
+}
+
+/*
+ * If pRegion is NullRegion, all the viewable
+ * corrupted region will be synchronized.
+ */
+
+int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned int breakMask, WindowPtr owner)
+{
+ GCPtr pGC;
+ DrawablePtr pSrcDrawable;
+ BoxPtr pBox;
+ RegionPtr clipRegion;
+
+ RegionRec tileRegion;
+ RegionRec exposeRegion;
+ BoxRec box;
+ BoxRec tileBox;
+
+ #ifdef COLLECTED_UPDATES
+ RegionRec collectedUpdates;
+ #endif
+
+ char *data;
+
+ int nBox;
+ int x, y;
+ int w, h;
+ int extentWidth, extentHeight;
+ int tileWidth, tileHeight;
+ int length, format, leftPad;
+ int i;
+ int saveTrap;
+ int success;
+ int useStoredBitmap;
+
+ unsigned long now;
+ unsigned long elapsedTime;
+
+
+ leftPad = 0;
+ success = 0;
+ data = NULL;
+ pGC = NULL;
+ clipRegion = NullRegion;
+
+ #ifdef COLLECTED_UPDATES
+ RegionInit(&collectedUpdates, NullBox, 1);
+ #endif
+
+ RegionInit(&exposeRegion, NullBox, 1);
+
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap &&
+ nxagentDrawableStatus((DrawablePtr) nxagentDrawableBitmap(pDrawable)) == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Drawable [%s] at [%p] has an already synchronized "
+ "bitmap at [%p].\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable));
+ #endif
+
+ nxagentDestroyDrawableBitmap(pDrawable);
+ }
+
+ /*
+ * The stored bitmap may be used if we
+ * are going to synchronize the full
+ * drawable.
+ */
+
+ useStoredBitmap = (nxagentDrawableBitmap(pDrawable) != NullPixmap && pRegion == NullRegion);
+
+ if (useStoredBitmap != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap at [%p] "
+ "[%d,%d,%d,%d] with [%ld] rects.\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
+ RegionNumRects(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
+ #endif
+
+ clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+ /*
+ * Intersecting the viewable region of the
+ * drawable with the region remaining from
+ * a previous loop.
+ */
+
+ RegionIntersect(clipRegion, clipRegion,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)));
+
+ /*
+ * The bitmap regions used in the synchro-
+ * nizations are only those corrupted also
+ * on the drawable. In this way, if we put
+ * a tile in a bad position (e.g. if the
+ * corrupted region moves), the next synch-
+ * ronization will fix the error.
+ */
+
+ RegionIntersect(clipRegion, clipRegion,
+ nxagentCorruptedRegion(pDrawable));
+
+ /*
+ * The bitmap to synchronize is clipped.
+ */
+
+ if (RegionNil(clipRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: The bitmap region [%d,%d,%d,%d] is not viewable. "
+ "Destroying it.\n", clipRegion -> extents.x1, clipRegion -> extents.y1,
+ clipRegion -> extents.x2, clipRegion -> extents.y2);
+ #endif
+
+ nxagentDestroyDrawableBitmap(pDrawable);
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ /*
+ * Using the saved bitmap as source, instead
+ * of the drawable itself.
+ */
+
+ pSrcDrawable = ((DrawablePtr) nxagentVirtualPixmap(nxagentDrawableBitmap(pDrawable)));
+ }
+ else
+ {
+ if (pRegion != NullRegion && RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Region [%d,%d,%d,%d] is nil. Skipping synchronization.\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: The [%s] at [%p] is already synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ /*
+ * Creating a region containing the viewable
+ * area of drawable.
+ */
+
+ clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+ /*
+ * If the corrupted region is not viewable, we
+ * can skip the synchronization.
+ */
+
+ RegionIntersect(clipRegion, clipRegion, nxagentCorruptedRegion(pDrawable));
+
+ if (RegionNil(clipRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: The corrupted region [%d,%d,%d,%d] is not viewable "
+ "on [%s] at [%p]. Skipping the synchronization.\n", clipRegion -> extents.x1,
+ clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2,
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ /*
+ * We can skip the synchronization if the re-
+ * quested region is not corrupted. Specifying
+ * a NullRegion as parameter, all the viewable
+ * corrupted region will be synchronized.
+ */
+
+ if (pRegion != NullRegion)
+ {
+ RegionIntersect(clipRegion, clipRegion, pRegion);
+
+ if (RegionNil(clipRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Region requested [%d,%d,%d,%d] already "
+ "synchronized on [%s] at [%p].\n", pRegion -> extents.x1,
+ pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+ }
+
+ pSrcDrawable = (pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((DrawablePtr) nxagentVirtualPixmap((PixmapPtr) pDrawable)) :
+ pDrawable);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronizing region with coordinates [%d,%d,%d,%d] "
+ "on [%s] at [%p].\n", clipRegion -> extents.x1, clipRegion -> extents.y1,
+ clipRegion -> extents.x2, clipRegion -> extents.y2,
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ saveTrap = nxagentGCTrap;
+
+ nxagentGCTrap = 0;
+
+ nxagentFBTrap = 1;
+
+ nxagentSplitTrap = 1;
+
+ pGC = nxagentGetGraphicContext(pDrawable);
+
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to create the temporary GC.\n");
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ ValidateGC(pDrawable, pGC);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize [%ld] rects of [%s] at [%p].\n",
+ RegionNumRects(clipRegion), nxagentDrawableType(pDrawable), (void *) pDrawable);
+
+ fprintf(stderr, "nxagentSynchronizeRegion: Extents geometry [%d,%d,%d,%d].\n",
+ clipRegion -> extents.x1, clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2);
+
+ fprintf(stderr, "nxagentSynchronizeRegion: Drawable geometry [%d,%d,%d,%d].\n",
+ pDrawable -> x, pDrawable -> y, pDrawable -> width, pDrawable -> height);
+ #endif
+
+ /*
+ * We are going to synchronize the corrupted
+ * area, so we use the corrupted extents as
+ * maximum size of the image data. It's im-
+ * portant to avoid using the drawable size,
+ * because in case of a huge window it had to
+ * result in a failed data memory allocation.
+ */
+
+ extentWidth = clipRegion -> extents.x2 - clipRegion -> extents.x1;
+ extentHeight = clipRegion -> extents.y2 - clipRegion -> extents.y1;
+
+ w = tileWidth = (nxagentOption(TileWidth) > extentWidth ? extentWidth : nxagentOption(TileWidth));
+ h = tileHeight = (nxagentOption(TileHeight) > extentHeight ? extentHeight : nxagentOption(TileHeight));
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSynchronizeRegion: Using tiles of size [%dx%d].\n", tileWidth, tileHeight);
+ #endif
+
+ data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
+
+ if (data == NULL)
+ {
+ #ifdef WARNING
+
+ fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory for synchronization.\n");
+
+ /*
+ * Print detailed informations if the
+ * image length is zero.
+ */
+
+ if (length == 0)
+ {
+ fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] with region geometry [%d][%d,%d,%d,%d].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable, RegionNumRects(clipRegion),
+ clipRegion -> extents.x1, clipRegion -> extents.y1,
+ clipRegion -> extents.x2, clipRegion -> extents.y2);
+ }
+
+ #endif
+
+ goto nxagentSynchronizeRegionFree;
+ }
+
+ #ifndef USE_OPTIMIZED_BOXES
+
+ pBox = RegionRects(clipRegion);
+
+ #else
+
+ pBox = nxagentGetOptimizedRegionBoxes(clipRegion);
+
+ #endif /* USE_OPTIMIZED_BOXES */
+
+ nBox = RegionNumRects(clipRegion);
+
+ now = GetTimeInMillis();
+
+ nxagentSynchronization.abort = 0;
+
+ /*
+ * Going to split the updated region into small blocks.
+ */
+
+ for (i = 0; i < nBox; i++)
+ {
+ #ifdef USE_OPTIMIZED_BOXES
+
+ if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+ pBox[i].x2 == 0 && pBox[i].y2 == 0)
+ {
+ continue;
+ }
+
+ #endif
+
+ box = pBox[i];
+
+ for (y = box.y1; y < box.y2; y += h)
+ {
+ h = MIN(box.y2 - y, tileHeight);
+
+ for (x = box.x1; x < box.x2; x += w)
+ {
+ w = MIN(box.x2 - x, tileWidth);
+
+ /*
+ * FIXME: This should not occur.
+ */
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ #ifdef WARNING
+
+ if (pDrawable -> type == DRAWABLE_WINDOW && pSrcDrawable != pDrawable)
+ {
+ fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Trying to synchronize "
+ "the clean drawable type [%d] at [%p] with source at [%p].\n",
+ pDrawable -> type, (void *) pDrawable, (void *) pSrcDrawable);
+ }
+
+ #endif
+
+ goto nxagentSynchronizeRegionStop;
+ }
+
+ if (canBreakOnTimeout(breakMask))
+ {
+ /*
+ * Abort the synchronization loop if it
+ * lasts for more than DeferTimeout
+ * milliseconds.
+ */
+
+ elapsedTime = GetTimeInMillis() - now;
+
+ if (elapsedTime > nxagentOption(DeferTimeout))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+ "[%lu] ms elapsed.\n", elapsedTime);
+ #endif
+
+ nxagentSynchronization.abort = 1;
+
+ goto nxagentSynchronizeRegionStop;
+ }
+ }
+
+ /*
+ * Abort the loop if we go out of bandwidth.
+ */
+
+ if (breakOnCongestionDrawable(breakMask, pDrawable) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+ "congestion [%d] blocking [%d].\n", nxagentCongestion,
+ nxagentBlocking);
+ #endif
+
+ nxagentSynchronization.abort = 1;
+
+ goto nxagentSynchronizeRegionStop;
+ }
+
+ /*
+ * Abort the loop if the display blocks.
+ */
+
+ if (breakOnBlocking(breakMask) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+ "blocking [%d] congestion [%d].\n", nxagentBlocking,
+ nxagentCongestion);
+ #endif
+
+ nxagentSynchronization.abort = 1;
+
+ goto nxagentSynchronizeRegionStop;
+ }
+
+ tileBox.x1 = x;
+ tileBox.y1 = y;
+ tileBox.x2 = x + w;
+ tileBox.y2 = y + h;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize tile [%d,%d,%d,%d].\n",
+ tileBox.x1, tileBox.y1, tileBox.x2, tileBox.y2);
+ #endif
+
+ nxagentGetImage(pSrcDrawable, x, y, w, h, format, AllPlanes, data);
+
+ /*
+ * Going to unmark the synchronized
+ * region.
+ */
+
+ RegionInit(&tileRegion, &tileBox, 1);
+
+ RegionUnion(&exposeRegion, &exposeRegion, &tileRegion);
+
+ #ifdef COLLECTED_UPDATES
+ RegionAppend(&collectedUpdates, &tileRegion);
+ #endif
+
+ if (useStoredBitmap != 0)
+ {
+ /*
+ * When a bitmap's tile is synchronized,
+ * we can clear the corresponding region.
+ * We can't use the nxagentUnmarkCorrupted-
+ * Region because we have not a resource
+ * associated to this pixmap.
+ */
+
+ RegionSubtract(nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)),
+ nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)), &tileRegion);
+
+ /*
+ * The drawable's corrupted region can
+ * be cleared if the bitmap's tile data
+ * matches the drawable's content at the
+ * same position.
+ */
+
+ if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+ {
+ char *cmpData;
+
+ int cmpLength, cmpFormat;
+
+ cmpData = nxagentAllocateImageData(w, h, pDrawable -> depth, &cmpLength, &cmpFormat);
+
+ if (cmpData != NULL)
+ {
+ nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, cmpData);
+
+ if (memcmp(data, cmpData, cmpLength) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] matches drawable's data at same position.\n",
+ x, y, x + w, y + h);
+ #endif
+
+ nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] on drawable [%p] doesn't match.\n",
+ x, y, x + w, y + h, (void *) pDrawable);
+ }
+ #endif
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory to compare tiles.\n");
+ #endif
+ }
+
+ if (cmpData != NULL)
+ {
+ free(cmpData);
+ }
+ }
+ }
+ else
+ {
+ nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
+
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Going to clean bitmap at [%p] with newer data.\n",
+ (void *) nxagentDrawableBitmap(pDrawable));
+ #endif
+
+ RegionSubtract(nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)),
+ nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)), &tileRegion);
+ }
+ }
+
+ /*
+ * Realize the image after comparing the
+ * source data with the bitmap data.
+ */
+
+ nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
+ x, y, w, h, leftPad, format, data);
+
+ RegionUninit(&tileRegion);
+
+ #if !defined(COLLECTED_UPDATES)
+
+ if (owner != NULL)
+ {
+ if (nxagentOption(Shadow) == 1 &&
+ (nxagentOption(XRatio) != DONT_SCALE ||
+ nxagentOption(YRatio) != DONT_SCALE))
+ {
+ int scaledx;
+ int scaledy;
+ int scaledw;
+ int scaledh;
+
+ scaledx = nxagentScale(x, nxagentOption(XRatio));
+ scaledy = nxagentScale(y, nxagentOption(YRatio));
+
+ scaledw = nxagentScale(x + w, nxagentOption(XRatio)) - scaledx;
+ scaledh = nxagentScale(y + h, nxagentOption(YRatio)) - scaledy;
+
+ XClearArea(nxagentDisplay, nxagentWindow(owner), scaledx, scaledy, scaledw, scaledh, 0);
+ }
+ else
+ {
+ XClearArea(nxagentDisplay, nxagentWindow(owner), x, y, w, h, 0);
+ }
+ }
+
+ #endif /* #if !defined(COLLECTED_UPDATES) */
+
+ /*
+ * Abort the loop on the user's input.
+ * This is done here to check for events
+ * read after the flush caused by the
+ * PutImage.
+ */
+
+ nxagentDispatchHandler((ClientPtr) 0, 0, 0);
+
+ if (breakOnEvent(breakMask) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+ "new input events.\n");
+ #endif
+
+ nxagentSynchronization.abort = 1;
+
+ goto nxagentSynchronizeRegionStop;
+ }
+ }
+ }
+ }
+
+nxagentSynchronizeRegionStop:
+
+ nxagentSplitTrap = 0;
+
+ nxagentFBTrap = 0;
+
+ nxagentGCTrap = saveTrap;
+
+ success = 1;
+
+ if (nxagentOption(Shadow) == 0)
+ {
+ if (nxagentSynchronization.abort == 1)
+ {
+ /*
+ * Storing the pointer to the drawable we
+ * were synchronizing when the loop aborted.
+ * It is used in nxagentSynchronizeDrawable-
+ * Predicate.
+ */
+
+ nxagentSynchronization.pDrawable = pDrawable;
+ nxagentSynchronization.drawableType = pDrawable -> type;
+
+ if (nxagentDrawableBitmap(pDrawable) == NullPixmap)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Going to create the synchronization bitmap.\n");
+ #endif
+
+ nxagentCreateDrawableBitmap(pDrawable);
+ }
+ }
+ else
+ {
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeRegion: Synchronization loop finished. Going to destroy synchronization bitmap.\n");
+ #endif
+
+ nxagentDestroyDrawableBitmap(pDrawable);
+ }
+ }
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1 &&
+ RegionNil(&exposeRegion) == 0)
+ {
+ struct nxagentExposeBackground eb;
+
+ int i;
+
+ eb.pBackground = (PixmapPtr) pDrawable;
+ eb.pExpose = &exposeRegion;
+
+ for (i = 0; i < MAXCLIENTS; i++)
+ {
+ if (clients[i] != NULL)
+ {
+ FindClientResourcesByType(clients[i], RT_WINDOW,
+ nxagentExposeBackgroundPredicate, &eb);
+ }
+ }
+ }
+ }
+ #ifdef COLLECTED_UPDATES
+ else
+ {
+ if (owner != NULL)
+ {
+ int overlap = 0;
+
+ RegionValidate(&collectedUpdates, &overlap);
+
+ for (i = 0; i < RegionNumRects(&collectedUpdates); i++)
+ {
+ x = RegionRects(&collectedUpdates)[i].x1;
+ y = RegionRects(&collectedUpdates)[i].y1;
+ w = RegionRects(&collectedUpdates)[i].x2 - RegionRects(&collectedUpdates)[i].x1;
+ h = RegionRects(&collectedUpdates)[i].y2 - RegionRects(&collectedUpdates)[i].y1;
+
+ if (nxagentOption(Shadow) == 1 &&
+ (nxagentOption(XRatio) != DONT_SCALE ||
+ nxagentOption(YRatio) != DONT_SCALE))
+ {
+ int scaledx;
+ int scaledy;
+ int scaledw;
+ int scaledh;
+
+ scaledx = nxagentScale(x, nxagentOption(XRatio));
+ scaledy = nxagentScale(y, nxagentOption(YRatio));
+
+ scaledw = nxagentScale(x + w, nxagentOption(XRatio)) - scaledx;
+ scaledh = nxagentScale(y + h, nxagentOption(YRatio)) - scaledy;
+
+ XClearArea(nxagentDisplay, nxagentWindow(owner), scaledx, scaledy, scaledw, scaledh, 0);
+ }
+ else
+ {
+ XClearArea(nxagentDisplay, nxagentWindow(owner), x, y, w, h, 0);
+ }
+ }
+ }
+ }
+ #endif /* #ifdef COLLECTED_UPDATES */
+
+nxagentSynchronizeRegionFree:
+
+ if (clipRegion != NullRegion)
+ {
+ nxagentFreeRegion(pDrawable, clipRegion);
+ }
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+
+ RegionUninit(&exposeRegion);
+
+ #ifdef COLLECTED_UPDATES
+
+ RegionUninit(&collectedUpdates);
+
+ #endif /* #ifdef COLLECTED_UPDATES */
+
+ return success;
+}
+
+void nxagentSynchronizeBox(DrawablePtr pDrawable, BoxPtr pBox, unsigned int breakMask)
+{
+ RegionPtr pRegion;
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeBox: The [%s] at [%p] is already synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ if (pBox == NullBox)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeBox: Going to synchronize the whole [%s] at [%p].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ nxagentSynchronizeRegion(pDrawable, NullRegion, breakMask, NULL);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeBox: Going to create a region from box [%d,%d,%d,%d].\n",
+ pBox -> x1, pBox -> y1, pBox -> x2, pBox -> y2);
+ #endif
+
+ pRegion = nxagentCreateRegion(pDrawable, NULL, pBox -> x1, pBox -> y1,
+ pBox -> x2 - pBox -> x1, pBox -> y2 - pBox -> y1);
+
+
+ if (RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeBox: Resulting region [%d,%d,%d,%d] is nil. Skipping synchronization.\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+ #endif
+
+ nxagentFreeRegion(pDrawable, pRegion);
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeBox: Going to synchronize the region [%d,%d,%d,%d] of "
+ "[%s] at [%p].\n", pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+ pRegion -> extents.y2, nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ nxagentSynchronizeRegion(pDrawable, pRegion, breakMask, NULL);
+
+ nxagentFreeRegion(pDrawable, pRegion);
+ }
+}
+
+void nxagentSynchronizeDrawablePredicate(void *p0, XID x1, void *p2)
+{
+ DrawablePtr pDrawable = (DrawablePtr) p0;
+ unsigned int *breakMask = (unsigned int *) p2;
+
+ int shouldClearHiddenRegion = 1;
+
+ /*
+ * The nxagentSynchronization.abort propa-
+ * gates a break condition across the resour-
+ * ces loop, in order to block also the sub-
+ * sequent synchronizations.
+ */
+
+ if (nxagentSynchronization.abort == 1 ||
+ nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ return;
+ }
+
+ /*
+ * In order to implement a kind of round-robin
+ * synchronization, the previous incomplete
+ * drawable synchronization is saved to jump
+ * to the next resource available of same type.
+ */
+
+ if (nxagentSynchronization.pDrawable != NULL &&
+ pDrawable -> type == nxagentSynchronization.drawableType)
+ {
+ if (nxagentSynchronization.pDrawable != pDrawable)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping drawable [%s][%p] while looking "
+ "for last synchronized drawable [%p].\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, (void *) nxagentSynchronization.pDrawable);
+ #endif
+
+ return;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Last synchronized drawable [%p] found. "
+ "Skipping to the next resource.\n", (void *) nxagentSynchronization.pDrawable);
+ #endif
+
+ nxagentSynchronization.pDrawable = NULL;
+
+ return;
+ }
+ }
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ /*
+ * The pixmaps to be synchronized are those
+ * used as background or used as source of
+ * any deferred operations for at least 2
+ * times.
+ */
+
+ if (NXAGENT_SHOULD_SYNCHRONIZE_PIXMAP(pDrawable) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping pixmap at [%p] "
+ "with usage [%d] background [%d].\n", (void *) pDrawable,
+ nxagentPixmapUsageCounter((PixmapPtr) pDrawable),
+ nxagentIsCorruptedBackground((PixmapPtr) pDrawable));
+ #endif
+
+ return;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Synchronizing pixmap at [%p] "
+ "with usage [%d] background [%d].\n", (void *) pDrawable,
+ nxagentPixmapUsageCounter((PixmapPtr) pDrawable),
+ nxagentIsCorruptedBackground((PixmapPtr) pDrawable));
+ }
+ #endif
+ }
+ else if (NXAGENT_SHOULD_SYNCHRONIZE_WINDOW(pDrawable) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping not visible window at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ if (shouldClearHiddenRegion == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Clearing out the not visible window "
+ "at [%p].\n", (void *) pDrawable);
+ #endif
+
+ nxagentCleanCorruptedDrawable(pDrawable);
+ }
+
+ return;
+ }
+
+ /*
+ * Postpone the synchronization if we went
+ * out of bandwidth or if the display blocks.
+ * The pixmap synchronization is more careful
+ * with bandwidth usage.
+ */
+
+/*
+FIXME: This condition sounds only as a
+ complication, as the break parameters
+ are already checked while synchroni-
+ zing the drawable.
+
+ if (breakOnCongestion(*breakMask) == 1 ||
+ (pDrawable -> type == DRAWABLE_PIXMAP &&
+ *breakMask != NEVER_BREAK && nxagentCongestion > 0))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: WARNING! Breaking the "
+ "synchronization with congestion [%d] blocking [%d].\n",
+ nxagentCongestion, nxagentBlocking);
+ #endif
+
+ nxagentSynchronization.abort = 1;
+
+ return;
+ }
+*/
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Synchronizing drawable [%s][%p] "
+ "with geometry (%dx%d).\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, pDrawable -> width, pDrawable -> height);
+
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Corrupted extents [%d,%d,%d,%d] "
+ "with [%ld] rects.\n", nxagentCorruptedRegion(pDrawable) -> extents.x1,
+ nxagentCorruptedRegion(pDrawable) -> extents.y1, nxagentCorruptedRegion(pDrawable) ->
+ extents.x2, nxagentCorruptedRegion(pDrawable) -> extents.y2,
+ RegionNumRects(nxagentCorruptedRegion(pDrawable)));
+ #endif
+
+ /*
+ * The stored bitmap is destroyed inside
+ * the synchronization loop, so we have
+ * to check here its presence to know if
+ * we can clear the dirty windows.
+ */
+
+ shouldClearHiddenRegion = (nxagentDrawableBitmap(pDrawable) == NullPixmap);
+
+ nxagentSynchronizeDrawable(pDrawable, DONT_WAIT, *breakMask, NULL);
+
+ if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Drawable [%s][%p] not fully synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ /*
+ * If the remaining corrupted region is on
+ * an hidden section (not viewable or outside
+ * of the pixmap's area) of a drawable,
+ * we can clear it.
+ */
+
+ if (nxagentSynchronization.abort == 0 &&
+ shouldClearHiddenRegion == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Clearing out the remaining corrupted "
+ "[%s] at [%p].\n", nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ nxagentCleanCorruptedDrawable(pDrawable);
+ }
+ }
+}
+
+void nxagentSynchronizationLoop(unsigned int mask)
+{
+ unsigned int breakMask;
+
+ int doRoundRobin;
+
+/*
+FIXME: All drawables should be set as synchronized and
+ never marked as corrupted while the display is
+ down.
+*/
+
+ nxagentSkipImage = nxagentTooManyImageData();
+
+ if (nxagentOption(ImageRateLimit) && nxagentSkipImage)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeDrawable: Skipping due to bit rate limit reached.\n");
+ #endif
+
+ return;
+ }
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: WARNING! Not synchronizing the drawables "
+ "with the display down.\n");
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Synchronizing [%d] windows [%d] pixmaps "
+ "and [%d] backgrounds with mask [%u].\n", nxagentCorruptedWindows, nxagentCorruptedPixmaps,
+ nxagentCorruptedBackgrounds, mask);
+
+ fprintf(stderr, "nxagentSynchronizationLoop: Stored bitmaps [%d] windows [%d] pixmaps "
+ "and [%d] backgrounds.\n", nxagentSynchronization.windowBitmaps,
+ nxagentSynchronization.pixmapBitmaps, nxagentSynchronization.backgroundBitmaps);
+
+ fprintf(stderr, "nxagentSynchronizationLoop: Starting loops with congestion [%d] "
+ "blocking [%d].\n", nxagentCongestion, nxagentBlocking);
+ #endif
+
+ breakMask = mask;
+
+ /*
+ * The resource counter can be reset if we
+ * have not aborted the synchronization loop,
+ * if we are not skipping resources to do
+ * round-robin and if the bitmaps are all
+ * synchronized.
+ */
+
+ doRoundRobin = (nxagentSynchronization.pDrawable != NULL);
+
+ nxagentSynchronization.abort = 0;
+
+ /*
+ * Synchronize the windows.
+ */
+
+ if (NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_WINDOWS(mask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted window resources.\n");
+ #endif
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_WINDOW,
+ nxagentSynchronizeDrawablePredicate, &breakMask);
+
+ #ifdef TEST
+
+ if (nxagentSynchronization.abort == 0 &&
+ nxagentSynchronization.windowBitmaps == 0 &&
+ doRoundRobin == 0)
+ {
+ if (nxagentCorruptedWindows > 0)
+ {
+ fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+ "corrupted windows.\n", nxagentCorruptedWindows);
+ }
+
+ nxagentCorruptedWindows = 0;
+ }
+
+ #endif
+ }
+
+ /*
+ * Synchronize the backgrounds.
+ */
+
+ if (nxagentSynchronization.abort == 0 &&
+ NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_BACKGROUNDS(mask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted background resources.\n");
+ #endif
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_BACKGROUND,
+ nxagentSynchronizeDrawablePredicate, &breakMask);
+
+ #ifdef TEST
+
+ if (nxagentSynchronization.abort == 0 &&
+ nxagentSynchronization.backgroundBitmaps == 0 &&
+ doRoundRobin == 0)
+ {
+ if (nxagentCorruptedBackgrounds > 0)
+ {
+ fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+ "corrupted backgrounds.\n", nxagentCorruptedBackgrounds);
+ }
+
+ nxagentCorruptedBackgrounds = 0;
+ }
+
+ #endif
+ }
+
+ /*
+ * If there is bandwidth remaining, synchronize
+ * the pixmaps. Synchronizing a pixmap doesn't
+ * produce any visible results. Better is to
+ * synchronize them on demand, before using the
+ * pixmap in a copy or in a composite operation.
+ */
+
+ if (nxagentSynchronization.abort == 0 &&
+ NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_PIXMAPS(mask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted pixmap resources.\n");
+ #endif
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_PIXMAP,
+ nxagentSynchronizeDrawablePredicate, &breakMask);
+
+
+ if (nxagentSynchronization.abort == 0 &&
+ nxagentSynchronization.pixmapBitmaps == 0 &&
+ doRoundRobin == 0)
+ {
+ #ifdef TEST
+
+ if (nxagentCorruptedPixmaps > 0)
+ {
+ fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+ "corrupted pixmaps.\n", nxagentCorruptedPixmaps);
+ }
+
+ #endif
+
+ nxagentCorruptedPixmaps = 0;
+ }
+
+ }
+
+ /*
+ * If the last synchronized drawable has been
+ * removed, we have to reset the variable sto-
+ * ring its pointer.
+ */
+
+ if (nxagentSynchronization.pDrawable != NULL &&
+ nxagentFindClientResource(serverClient -> index, RT_NX_CORR_WINDOW,
+ nxagentSynchronization.pDrawable) == 0 &&
+ nxagentFindClientResource(serverClient -> index, RT_NX_CORR_BACKGROUND,
+ nxagentSynchronization.pDrawable) == 0 &&
+ nxagentFindClientResource(serverClient -> index, RT_NX_CORR_PIXMAP,
+ nxagentSynchronization.pDrawable) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Synchronization drawable [%p] removed from resources.\n",
+ (void *) nxagentSynchronization.pDrawable);
+ #endif
+
+ nxagentSynchronization.pDrawable = NULL;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizationLoop: Closing loops with congestion [%d] "
+ "blocking [%d].\n", nxagentCongestion, nxagentBlocking);
+
+ fprintf(stderr, "nxagentSynchronizationLoop: There are now [%d] windows [%d] pixmaps "
+ "and [%d] backgrounds to synchronize.\n", nxagentCorruptedWindows,
+ nxagentCorruptedPixmaps, nxagentCorruptedBackgrounds);
+ #endif
+}
+
+RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int width, int height)
+{
+ RegionPtr pRegion;
+ BoxRec box;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + width;
+ box.y2 = y + height;
+
+ pRegion = RegionCreate(&box, 1);
+
+ /*
+ * Clipping the region.
+ */
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ BoxRec tmpBox;
+ RegionRec tmpRegion;
+
+ /*
+ * The region created doesn't need to be clipped
+ * if it has the pixmap dimensions.
+ */
+
+ if (x != 0 || y != 0 ||
+ width != pDrawable -> width ||
+ height != pDrawable -> height)
+ {
+ tmpBox.x1 = 0;
+ tmpBox.y1 = 0;
+ tmpBox.x2 = pDrawable -> width;
+ tmpBox.y2 = pDrawable -> height;
+
+ RegionInit(&tmpRegion, &tmpBox, 1);
+
+ RegionIntersect(pRegion, &tmpRegion, pRegion);
+
+ RegionUninit(&tmpRegion);
+ }
+ }
+ else
+ {
+ /*
+ * We use the clipList because the borderClip
+ * contains also parts of the window covered
+ * by its children.
+ */
+
+ RegionTranslate(pRegion,
+ pDrawable -> x, pDrawable -> y);
+
+ if (nxagentWindowPriv((WindowPtr) pDrawable) -> hasTransparentChildren == 1)
+ {
+ RegionIntersect(pRegion, pRegion, &((WindowPtr) pDrawable) -> borderClip);
+ }
+ else
+ {
+ RegionIntersect(pRegion, pRegion, &((WindowPtr) pDrawable) -> clipList);
+ }
+
+ RegionTranslate(pRegion,
+ -pDrawable -> x, -pDrawable -> y);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateRegion: New region created with coordinates [%d,%d,%d,%d].\n",
+ pRegion -> extents.x1, pRegion -> extents.y1,
+ pRegion -> extents.x2, pRegion -> extents.y2);
+ #endif
+
+ /*
+ * If the pRegion is NIL we don't need
+ * to intersect it with the GC's clipmask.
+ */
+
+ if (RegionNil(pRegion) == 0 &&
+ pGC != NULL && pGC -> clientClip != NULL &&
+ pGC -> clientClipType == CT_REGION)
+ {
+ RegionRec clipRegion;
+
+ RegionInit(&clipRegion, NullBox, 1);
+
+ RegionCopy(&clipRegion, (RegionPtr) pGC -> clientClip);
+
+ /*
+ * The clip origin is relative to the origin of
+ * the destination drawable. The clip mask coor-
+ * dinates are relative to the clip origin.
+ */
+
+ if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+ {
+ RegionTranslate(&clipRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateRegion: Clipping region to the clip mask with coordinates [%d,%d,%d,%d].\n",
+ clipRegion.extents.x1, clipRegion.extents.y1,
+ clipRegion.extents.x2, clipRegion.extents.y2);
+ #endif
+
+ RegionIntersect(pRegion, pRegion, &clipRegion);
+
+ RegionUninit(&clipRegion);
+ }
+
+ return pRegion;
+}
+
+void nxagentMarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ int x;
+ int y;
+ int width;
+ int height;
+
+ if (pRegion != NullRegion && RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMarkCorruptedRegion: Region [%d,%d,%d,%d] is nil. Skipping operation.\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+ #endif
+
+ return;
+ }
+
+ /*
+ * If the drawable was synchronized, the counter
+ * reporting the number of corrupted drawables
+ * must be increased. Moreover the corrupted ti-
+ * mestamp must be set.
+ */
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ if (pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ nxagentAllocateCorruptedResource(pDrawable, RT_NX_CORR_WINDOW);
+ }
+
+ nxagentSetCorruptedTimestamp(pDrawable);
+ }
+
+ if (pRegion == NullRegion)
+ {
+ x = 0;
+ y = 0;
+
+ width = pDrawable -> width;
+ height = pDrawable -> height;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentMarkCorruptedRegion: Fully invalidating %s [%p] with "
+ "coordinates [%d,%d][%d,%d].\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, x, y, width, height);
+ #endif
+
+ pRegion = nxagentCreateRegion(pDrawable, NULL, x, y, width, height);
+
+ nxagentValidateSplit(pDrawable, pRegion);
+
+ RegionUnion(nxagentCorruptedRegion(pDrawable),
+ nxagentCorruptedRegion(pDrawable), pRegion);
+
+ nxagentFreeRegion(pDrawable, pRegion);
+ }
+ else
+ {
+ #ifdef TEST
+
+ x = pRegion -> extents.x1;
+ y = pRegion -> extents.y1;
+
+ width = pRegion -> extents.x2 - pRegion -> extents.x1;
+ height = pRegion -> extents.y2 - pRegion -> extents.y1;
+
+ fprintf(stderr, "nxagentMarkCorruptedRegion: Partly invalidating %s [%p] with "
+ "coordinates [%d,%d][%d,%d].\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable, x, y, width, height);
+
+ #endif
+
+ nxagentValidateSplit(pDrawable, pRegion);
+
+ RegionUnion(nxagentCorruptedRegion(pDrawable),
+ nxagentCorruptedRegion(pDrawable), pRegion);
+ }
+}
+
+void nxagentUnmarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ int oldStatus;
+
+ if (pRegion != NullRegion && RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentUnmarkCorruptedRegion: Region [%d,%d,%d,%d] is nil. Skipping operation.\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+ #endif
+
+ return;
+ }
+
+ oldStatus = nxagentDrawableStatus(pDrawable);
+
+ if (oldStatus == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentUnmarkCorruptedRegion: Drawable %s [%p] already synchronized.\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ if (pRegion == NullRegion)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentUnmarkCorruptedRegion: Fully validating %s [%p].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ nxagentValidateSplit(pDrawable, NULL);
+
+ RegionEmpty(nxagentCorruptedRegion(pDrawable));
+ }
+ else
+ {
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentUnmarkCorruptedRegion: Validating %s [%p] with region [%d,%d,%d,%d].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable,
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+
+ #endif
+
+ nxagentValidateSplit(pDrawable, pRegion);
+
+ RegionSubtract(nxagentCorruptedRegion(pDrawable),
+ nxagentCorruptedRegion(pDrawable), pRegion);
+ }
+
+ /*
+ * If the drawable becomes synchronized, the
+ * counter reporting the number of corrupted
+ * drawables must be decreased. Moreover the
+ * corrupted timestamp must be reset.
+ */
+
+ if (oldStatus == NotSynchronized &&
+ nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_BACKGROUND);
+
+ nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_PIXMAP);
+
+ nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> containTrapezoids = 0;
+ }
+ else
+ {
+ nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_WINDOW);
+ }
+
+ nxagentResetCorruptedTimestamp(pDrawable);
+
+ /*
+ * If the resource is no longer dirty,
+ * the associated bitmap is destroyed.
+ */
+
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ nxagentDestroyDrawableBitmap(pDrawable);
+ }
+ }
+}
+
+void nxagentMoveCorruptedRegion(WindowPtr pWin, unsigned int mask)
+{
+ /*
+ * If a window is resized, its corrupted
+ * region is moved according to the bit
+ * gravity.
+ */
+
+ if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+ {
+ if (((mask & CWHeight) && nxagentWindowPriv(pWin) -> height != pWin -> drawable.height) ||
+ ((mask & CWWidth) && nxagentWindowPriv(pWin) -> width != pWin -> drawable.width))
+ {
+ int nx, ny;
+
+ GravityTranslate(0, 0,
+ nxagentWindowPriv(pWin) -> x - pWin -> origin.x + wBorderWidth(pWin),
+ nxagentWindowPriv(pWin) -> y - pWin -> origin.y + wBorderWidth(pWin),
+ pWin -> drawable.width - nxagentWindowPriv(pWin) -> width,
+ pWin -> drawable.height - nxagentWindowPriv(pWin) -> height,
+ pWin -> bitGravity, &nx, &ny);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentMoveCorruptedRegion: Moving the corrupted region to [%d,%d] for window [%p].\n",
+ nx, ny, (void *) pWin);
+ #endif
+
+ RegionTranslate(nxagentCorruptedRegion((DrawablePtr) pWin),
+ nx, ny);
+
+ /*
+ * Having moved the corrupted region, we
+ * need to invalidate the pending commits
+ * or otherwise the image will fall in
+ * the wrong area.
+ */
+
+ nxagentValidateSplit((DrawablePtr) pWin, NULL);
+
+
+ /*
+ * The window reconfiguration invalidates
+ * the synchronization bitmap.
+ */
+
+ nxagentDestroyDrawableBitmap((DrawablePtr) pWin);
+ }
+ }
+}
+
+/*
+ * The DDX layer uses an 'Y-X banding' representation of
+ * regions: it sorts all rectangles composing a region
+ * using first the y-dimension, than the x-dimension; mo-
+ * reover it organizes the rectangles in 'bands' sharing
+ * the same y-dimension. This representation does not mi-
+ * nimize the number of rectangles. For example, the fol-
+ * lowing region has 4 rectangles:
+ *
+ * +-----------+
+ * | | +---+
+ * | A | | B |
+ * | | +---+
+ * +-----------+
+ *
+ * The rectangle 'B' creates a band which splits the rec-
+ * tangle A in 3 parts, for a total of 3 bands. The num-
+ * ber of rectangles composing the region is 4.
+ *
+ * This kind of representation is not advisable for the
+ * lazy synchronization because, in the example above,
+ * the nxagent had to send 4 put images instead of 2.
+ *
+ * To minimize the problem we use the following function:
+ * by traversing the list of rectangles we merge all bo-
+ * xes with same x coordinates and coincident y, in order
+ * to create an X-Y banding.
+ *
+ * Be careful: all the coordinates of boxes merged are
+ * set to 0, so take care of this when looping through
+ * the box list returned by this function.
+ */
+
+BoxPtr nxagentGetOptimizedRegionBoxes(RegionPtr pRegion)
+{
+ BoxPtr pBox;
+
+ BoxRec boxExtents;
+
+ int nBox;
+ int i, j;
+
+ #ifdef DEBUG
+ int nBoxOptim;
+ #endif
+
+ pBox = RegionRects(pRegion);
+
+ nBox = RegionNumRects(pRegion);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to optimize region at [%p] with [%d] rects.\n",
+ (void *) pRegion, nBox);
+ #endif
+
+ if (nBox <= 1)
+ {
+ return pBox;
+ }
+
+ #ifdef DEBUG
+ nBoxOptim = nBox;
+ #endif
+
+ /*
+ * The boxes are now grouped to grown as much
+ * as possible, using their overlapping vertex
+ * as rule.
+ */
+
+ for (i = 0; i < nBox; i++)
+ {
+ /*
+ * If the coordinates are (0,0) the box
+ * has been already merged, so we can skip
+ * it.
+ */
+
+ if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+ pBox[i].x2 == 0 && pBox[i].y2 == 0)
+ {
+ continue;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Referential box [%d] has coordinates [%d,%d,%d,%d].\n",
+ i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2);
+ #endif
+
+ #ifdef ADVANCED_BOXES_DEFRAG
+
+ boxExtents.x1 = pBox[i].x1;
+ boxExtents.y1 = pBox[i].y1;
+ boxExtents.x2 = pBox[i].x2;
+
+ #endif
+
+ boxExtents.y2 = pBox[i].y2;
+
+ for (j = i+1; j < nBox; j++)
+ {
+ if (pBox[j].x1 == 0 && pBox[j].y1 == 0 &&
+ pBox[j].x2 == 0 && pBox[j].y2 == 0)
+ {
+ continue;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Mergeable box [%d] has coordinates [%d,%d,%d,%d].\n",
+ j, pBox[j].x1, pBox[j].y1, pBox[j].x2, pBox[j].y2);
+ #endif
+
+ /*
+ * Each consequent box is merged if its
+ * higher side overlaps the lower side
+ * of current box.
+ * In case of ADVANCED_BOXES_DEFRAG the higher
+ * side must be included within a range
+ * defined by INCLUDE_MARGIN.
+ */
+
+ #ifndef ADVANCED_BOXES_DEFRAG
+
+ if (pBox[j].y1 == boxExtents.y2 &&
+ pBox[j].x1 == pBox[i].x1 &&
+ pBox[j].x2 == pBox[i].x2)
+
+ #else
+
+ if (pBox[j].x1 > boxExtents.x1 - INCLUDE_MARGIN &&
+ pBox[j].x1 < boxExtents.x1 + INCLUDE_MARGIN &&
+ pBox[j].y1 > boxExtents.y2 - INCLUDE_MARGIN &&
+ pBox[j].y1 < boxExtents.y2 + INCLUDE_MARGIN &&
+ pBox[j].x2 > boxExtents.x2 - INCLUDE_MARGIN &&
+ pBox[j].x2 < boxExtents.x2 + INCLUDE_MARGIN)
+
+ #endif
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to merge box at [%d] with box at [%d].\n",
+ j, i);
+ #endif
+
+ #ifdef ADVANCED_BOXES_DEFRAG
+
+ if (pBox[j].x1 < boxExtents.x1)
+ {
+ boxExtents.x1 = pBox[j].x1;
+ }
+
+ if (pBox[j].x2 > boxExtents.x2)
+ {
+ boxExtents.x2 = pBox[j].x2;
+ }
+
+ if (pBox[j].y1 < boxExtents.y1)
+ {
+ boxExtents.y1 = pBox[j].y1;
+ }
+
+ #endif
+
+ if (pBox[j].y2 > boxExtents.y2)
+ {
+ boxExtents.y2 = pBox[j].y2;
+ }
+
+ /*
+ * By appending a box to another, we have
+ * to remove it from the box list. We do
+ * this by setting its coordinates to (0,0)
+ * and by checking their value in the main
+ * loop.
+ */
+
+ pBox[j].x1 = pBox[j].y1 = pBox[j].x2 = pBox[j].y2 = 0;
+
+ #ifdef DEBUG
+ nBoxOptim--;
+ #endif
+ }
+ }
+
+ /*
+ * Extend the box height.
+ */
+
+ #ifdef ADVANCED_BOXES_DEFRAG
+
+ pBox[i].x1 = boxExtents.x1;
+ pBox[i].y1 = boxExtents.y1;
+ pBox[i].x2 = boxExtents.x2;
+
+ #endif
+
+ pBox[i].y2 = boxExtents.y2;
+ }
+
+ #ifdef ADVANCED_BOXES_DEFRAG
+
+ /*
+ * The new list need to be validated to
+ * avoid boxes overlapping. This code may
+ * be improved to remove also the partial-
+ * ly overlapping boxes.
+ */
+
+ for (i = 0; i < nBox; i++)
+ {
+ if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+ pBox[i].x2 == 0 && pBox[i].y2 == 0)
+ {
+ continue;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Referential box [%d] has coordinates [%d,%d,%d,%d].\n",
+ i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2);
+ #endif
+
+ boxExtents.x1 = pBox[i].x1;
+ boxExtents.y1 = pBox[i].y1;
+ boxExtents.x2 = pBox[i].x2;
+ boxExtents.y2 = pBox[i].y2;
+
+ for (j = i+1; j < nBox; j++)
+ {
+ if (pBox[j].x1 == 0 && pBox[j].y1 == 0 &&
+ pBox[j].x2 == 0 && pBox[j].y2 == 0)
+ {
+ continue;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Mergeable box [%d] has coordinates [%d,%d,%d,%d].\n",
+ j, pBox[j].x1, pBox[j].y1, pBox[j].x2, pBox[j].y2);
+ #endif
+
+ if ((boxExtents.x1 <= pBox[j].x1 &&
+ boxExtents.x2 >= pBox[j].x2 &&
+ boxExtents.y1 <= pBox[j].y1 &&
+ boxExtents.y2 >= pBox[j].y2))
+ {
+ /*
+ * If a box is completely inside
+ * another, we set its coordinates
+ * to 0 to consider it as merged.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to merge box [%d,%d,%d,%d] "
+ "with its box container [%d,%d,%d,%d].\n", pBox[j].x1, pBox[j].y1,
+ pBox[j].x2, pBox[j].y2, boxExtents.x1, boxExtents.y1, boxExtents.y1,
+ boxExtents.y2);
+ #endif
+
+ pBox[j].x1 = pBox[j].y1 = pBox[j].x2 = pBox[j].y2 = 0;
+
+ #ifdef DEBUG
+ nBoxOptim--;
+ #endif
+ }
+ }
+ }
+
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Original boxes number [%d] Optimized boxes number [%d].\n",
+ nBox, nBoxOptim);
+ #endif
+
+ return pBox;
+}
+
+unsigned long nxagentGetColor(DrawablePtr pDrawable, int xPixel, int yPixel)
+{
+ XImage *ximage;
+ Visual *pVisual;
+ char *data;
+
+ int depth, format, length;
+ int leftPad = 0;
+ unsigned long pixel;
+
+ depth = pDrawable -> depth;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+ length = nxagentImageLength(1, 1, format, leftPad, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGetColor: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ return -1;
+ }
+
+ pVisual = nxagentImageVisual(pDrawable, depth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGetColor: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ fbGetImage(pDrawable, xPixel, yPixel, 1, 1, format, AllPlanes, data);
+
+ ximage = XCreateImage(nxagentDisplay, pVisual, depth, format, leftPad, (char *) data,
+ 1, 1, BitmapPad(nxagentDisplay),
+ nxagentImagePad(1, format, leftPad, 1));
+
+ if (ximage == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGetColor: WARNING! Failed to create the XImage.\n");
+ #endif
+
+ free(data);
+
+ return -1;
+ }
+
+ pixel = XGetPixel(ximage, 0, 0);
+
+ XDestroyImage(ximage);
+
+ return pixel;
+}
+
+/*
+ * This function could be used to determine
+ * the ClearArea color of corrupted regions
+ * on screen.
+ */
+
+unsigned long nxagentGetRegionColor(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ int xPicker, yPicker;
+
+ if (RegionNil(pRegion) == 1)
+ {
+ return nxagentGetDrawableColor(pDrawable);
+ }
+
+ /*
+ * The pixel used as reference is the first
+ * outer pixel at the bottom right corner
+ * of corrupted region extents.
+ */
+
+ xPicker = pRegion -> extents.x2 + 1;
+
+ if (xPicker > pDrawable -> width)
+ {
+ xPicker = pDrawable -> width;
+ }
+
+ yPicker = pRegion -> extents.y2 + 1;
+
+ if (yPicker > pDrawable -> height)
+ {
+ yPicker = pDrawable -> height;
+ }
+
+ return nxagentGetColor(pDrawable, xPicker, yPicker);
+}
+
+unsigned long nxagentGetDrawableColor(DrawablePtr pDrawable)
+{
+ int xPicker, yPicker;
+
+ /*
+ * The pixel used to determine the co-
+ * lor of a drawable is at coordinates
+ * (x + width - 4, y + 4).
+ */
+
+ xPicker = pDrawable -> width - 4;
+
+ yPicker = 4;
+
+ return nxagentGetColor(pDrawable, xPicker, yPicker);
+}
+
+void nxagentClearRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ WindowPtr pWin;
+ BoxPtr pBox;
+
+ unsigned long color;
+ unsigned long backupPixel = 0;
+ int nBox, i;
+ int restore;
+
+ #ifdef DEBUG
+ static int nBoxCleared;
+ #endif
+
+ if (pDrawable -> type != DRAWABLE_WINDOW)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentClearRegion: Cannot clear a pixmap. Exiting.\n");
+ #endif
+
+ return;
+ }
+
+ if (pRegion == NullRegion || RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentClearRegion: The region is empty. Exiting.\n");
+ #endif
+
+ return;
+ }
+
+ pWin = (WindowPtr) pDrawable;
+
+ restore = 0;
+
+ /*
+ * If the window has already a background, we
+ * can hope it will be nice.
+ */
+
+ if (pWin -> backgroundState != None)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearRegion: Window at [%p] has background state [%u].\n",
+ (void *) pWin, pWin -> backgroundState);
+ #endif
+ }
+ else
+ {
+ /*
+ * Save the original state.
+ */
+
+ backupPixel = pWin -> background.pixel;
+
+ color = nxagentGetDrawableColor((DrawablePtr) pWin);
+
+ if (color == -1)
+ {
+ color = 0xffffff;
+ }
+
+ pWin -> backgroundState = BackgroundPixel;
+ pWin -> background.pixel = color;
+
+ nxagentChangeWindowAttributes(pWin, CWBackPixel);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearRegion: Window at [%p] now has pixel background [%ld].\n",
+ (void *) pWin, color);
+ #endif
+
+ restore = 1;
+ }
+
+ pBox = nxagentGetOptimizedRegionBoxes(pRegion);
+
+ nBox = RegionNumRects(pRegion);
+
+ for (i = 0; i < nBox; i++)
+ {
+ if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+ pBox[i].x2 == 0 && pBox[i].y2 == 0)
+ {
+ continue;
+ }
+
+ XClearArea(nxagentDisplay, nxagentWindow(pWin), pBox[i].x1, pBox[i].y1,
+ pBox[i].x2 - pBox[i].x1, pBox[i].y2 - pBox[i].y1, False);
+
+ #ifdef DEBUG
+ nBoxCleared++;
+ #endif
+ }
+
+ /*
+ * Restore the old state.
+ */
+
+ if (restore == 1)
+ {
+ pWin -> backgroundState = None;
+ pWin -> background.pixel = backupPixel;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClearRegion: Number of cleared boxes is [%d].\n", nBoxCleared);
+ #endif
+}
+
+void nxagentFillRemoteRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ GCPtr pGC;
+ BoxPtr pBox;
+ XRectangle *pRects;
+
+ int nrects;
+ int i;
+
+ if (RegionNil(pRegion) == 1)
+ {
+ return;
+ }
+
+ pGC = nxagentGetGraphicContext(pDrawable);
+
+ nrects = RegionNumRects(pRegion);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFillRemoteRegion: Going to fill remote region [%d,%d,%d,%d] rects [%d] with color [%lu].\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+ nrects, pGC -> fgPixel);
+ #endif
+
+ if (nrects == 1)
+ {
+ XFillRectangle(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ pRegion -> extents.x1, pRegion -> extents.y1,
+ pRegion -> extents.x2 - pRegion -> extents.x1,
+ pRegion -> extents.y2 - pRegion -> extents.y1);
+ }
+ else
+ {
+ pBox = RegionRects(pRegion);
+
+ pRects = malloc(nrects * sizeof(XRectangle));
+
+ for (i = 0; i < nrects; i++)
+ {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ pRects, nrects);
+
+ free(pRects);
+ }
+}
+
+int nxagentDestroyCorruptedWindowResource(void * p, XID id)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedWindowResource: Removing corrupted window [%p] from resources.\n",
+ (void *) p);
+ #endif
+
+ nxagentWindowPriv((WindowPtr) p) -> corruptedId = None;
+
+ return 1;
+}
+
+int nxagentDestroyCorruptedPixmapResource(void * p, XID id)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedPixmapResource: Removing corrupted pixmap [%p] from resources.\n",
+ (void *) p);
+ #endif
+
+ nxagentPixmapPriv((PixmapPtr) p) -> corruptedId = None;
+
+ return 1;
+}
+
+int nxagentDestroyCorruptedBackgroundResource(void * p, XID id)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedBackgroundResource: Removing corrupted pixmap background [%p] from resources.\n",
+ (void *) p);
+ #endif
+
+ nxagentPixmapPriv((PixmapPtr) p) -> corruptedBackgroundId = None;
+
+ return 1;
+}
+
+void nxagentPointsToDirtyRegion(DrawablePtr pDrawable, int mode,
+ int nPoints, xPoint *pPoints)
+{
+ RegionPtr pRegion;
+ RegionRec tmpRegion;
+ BoxRec box, extents;
+
+ xPoint *xp;
+ int np;
+
+ np = nPoints;
+ xp = pPoints;
+
+ pRegion = RegionCreate(NullBox, 1);
+
+ while (np--)
+ {
+ if (CoordModePrevious)
+ {
+ box.x1 = box.x2 = (xp-1) -> x + xp -> x;
+ box.y1 = box.y2 = (xp-1) -> y + xp -> y;
+ }
+ else
+ {
+ box.x1 = box.x2 = xp -> x;
+ box.y1 = box.y2 = xp -> y;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointsToDirtyRegion: Adding the point (%d,%d) to the dirty region.\n",
+ box.x1, box.y1);
+ #endif
+
+ /*
+ * By using REGION_APPEND() and REGION_VALIDATE()
+ * this loop could become less expensive.
+ */
+
+ RegionInit(&tmpRegion, &box, 1);
+
+ RegionUnion(pRegion, pRegion, &tmpRegion);
+
+ RegionUninit(&tmpRegion);
+
+ xp++;
+ }
+
+ extents = *RegionExtents(pRegion);
+
+ RegionReset(pRegion, &extents);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointsToDirtyRegion: The resulting dirty region has [%ld] rects and"
+ " extents (%d,%d,%d,%d).\n", RegionNumRects(pRegion), extents.x1,
+ extents.y1, extents.x2, extents.y2);
+ #endif
+
+ nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+ RegionDestroy(pRegion);
+}
+
+#ifdef DUMP
+
+#define USE_MULTIPLE_COLORS
+
+void nxagentCorruptedRegionOnWindow(void *p0, XID x, void *p2)
+{
+ WindowPtr pWin = (WindowPtr) p0;
+ RegionPtr clipRegion;
+ RegionRec visRegion;
+ BoxPtr pBox;
+
+ XlibGC gc;
+ XGCValues value;
+
+ static unsigned long color = 0xff000000;
+ int nrectangles;
+ int i;
+
+ /*
+ * There are no regions to draw.
+ */
+
+ if (nxagentDrawableStatus((DrawablePtr) pWin) == Synchronized)
+ {
+ return;
+ }
+
+ /*
+ * The window is not visible.
+ */
+
+ if (nxagentWindowIsVisible(pWin) == 0)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorruptedRegionOnWindow: Going to draw on window at [%p].\n",
+ (void *) pWin);
+ #endif
+
+ clipRegion = nxagentCreateRegion((DrawablePtr) pWin, NULL, 0, 0,
+ pWin -> drawable.width, pWin -> drawable.height);
+
+ RegionInit(&visRegion, NullBox, 1);
+
+ RegionIntersect(&visRegion, clipRegion, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+ nxagentFreeRegion(pWin -> drawable.pScreen, clipRegion);
+
+ if (RegionNil(&visRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorruptedRegionOnWindow: The corrupted region of window at [%p] is hidden.\n",
+ (void *) pWin);
+ #endif
+
+ RegionUninit(&visRegion);
+
+ return;
+ }
+
+ nxagentClearRegion((DrawablePtr) pWin, &visRegion);
+
+ #ifdef USE_MULTIPLE_COLORS
+
+ color += nxagentWindow(pWin) * 5;
+
+ if (color == 0 || color == 0xffffffff)
+ {
+ color = 0xff000000;
+ }
+
+ #endif
+
+ value.foreground = color;
+ value.subwindow_mode = IncludeInferiors;
+
+ gc = XCreateGC(nxagentDisplay, nxagentWindow(pWin), GCForeground | GCSubwindowMode, &value);
+
+ nrectangles = RegionNumRects(&visRegion);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorruptedRegionOnWindow: Going to draw the region with extents [%d,%d,%d,%d] and [%d] rects.\n",
+ visRegion.extents.x1, visRegion.extents.y1, visRegion.extents.x2, visRegion.extents.y2,
+ nrectangles);
+ #endif
+
+ pBox = nxagentGetOptimizedRegionBoxes(&visRegion);
+
+ for (i = 0; i < nrectangles; i++)
+ {
+ if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+ pBox[i].x2 == 0 && pBox[i].y2 == 0)
+ {
+ continue;
+ }
+
+ XDrawRectangle(nxagentDisplay, nxagentWindow(pWin), gc,
+ pBox[i].x1, pBox[i].y1, pBox[i].x2 - pBox[i].x1 - 1,
+ pBox[i].y2 - pBox[i].y1 - 1);
+ }
+
+ XFreeGC(nxagentDisplay, gc);
+
+ RegionUninit(&visRegion);
+}
+
+void nxagentRegionsOnScreen()
+{
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_WINDOW,
+ nxagentCorruptedRegionOnWindow, NULL);
+}
+
+#endif
+
+/*
+ * If the synchronization loop breaks and the
+ * drawable synchronization cannot be completed,
+ * the remaining data is stored in a bitmap.
+ * The synchronization loop is then restarted
+ * using the bitmap as source instead of the
+ * drawable.
+ */
+
+void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
+{
+ PixmapPtr pBitmap;
+ GCPtr pGC = NULL;
+ RegionPtr pClipRegion = NullRegion;
+
+ int x, y;
+ int w, h;
+ int saveTrap;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for [%s] at [%p].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ /*
+ * The bitmap is created only in the
+ * nxagent.
+ */
+
+ saveTrap = nxagentGCTrap;
+
+ nxagentGCTrap = 1;
+
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateDrawableBitmap: The drawable is already synchronized. Skipping bitmap creation.\n");
+ #endif
+
+ goto nxagentCreateDrawableBitmapEnd;
+ }
+
+ /*
+ * Should create a function to append
+ * a bitmap to another, instead of de-
+ * stroy the old one.
+ */
+
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreateDrawableBitmap: WARNING! Going to replace the bitmap at [%p] with corrupted [%d,%d,%d,%d].\n",
+ (void *) nxagentDrawableBitmap(pDrawable),
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2);
+ #endif
+
+ nxagentDestroyDrawableBitmap(pDrawable);
+ }
+
+ /*
+ * Clipping to the visible area.
+ */
+
+ pClipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+ RegionIntersect(pClipRegion, pClipRegion, nxagentCorruptedRegion(pDrawable));
+
+ if (RegionNil(pClipRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateDrawableBitmap: The corrupted region is not visible. Skipping bitmap creation.\n");
+ #endif
+
+ goto nxagentCreateDrawableBitmapEnd;
+ }
+
+ /*
+ * FIXME: A better way it would be create the bitmap
+ * with the same extents of the clipRegion. This
+ * requires to save the offset with respect to the
+ * drawable origin like in the backing store. This
+ * becomes particularly important when the drawable
+ * is a huge window, because the pixmap creation
+ * would fail.
+ */
+
+ pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth, 0);
+
+ if (pBitmap == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot create pixmap for the bitmap data.\n");
+ #endif
+
+ goto nxagentCreateDrawableBitmapEnd;
+ }
+
+ pGC = GetScratchGC(pBitmap -> drawable.depth, pBitmap -> drawable.pScreen);
+
+ ValidateGC((DrawablePtr) pBitmap, pGC);
+
+ x = pClipRegion -> extents.x1;
+ y = pClipRegion -> extents.y1;
+ w = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
+ h = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
+
+ nxagentCopyArea(pDrawable, (DrawablePtr) pBitmap, pGC, x, y, w, h, x, y);
+
+ RegionUnion(nxagentCorruptedRegion((DrawablePtr) pBitmap),
+ nxagentCorruptedRegion((DrawablePtr) pBitmap), pClipRegion);
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> synchronizationBitmap = pBitmap;
+
+ if (nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+ {
+ nxagentSynchronization.backgroundBitmaps++;
+ }
+ else
+ {
+ nxagentSynchronization.pixmapBitmaps++;
+ }
+ }
+ else
+ {
+ nxagentWindowPriv((WindowPtr) pDrawable) -> synchronizationBitmap = pBitmap;
+
+ nxagentSynchronization.windowBitmaps++;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateDrawableBitmap: Drawable [%p] has bitmap at [%p] with corrupted [%d,%d,%d,%d].\n",
+ (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+ nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2);
+ #endif
+
+nxagentCreateDrawableBitmapEnd:
+
+ nxagentGCTrap = saveTrap;
+
+ if (pClipRegion != NullRegion)
+ {
+ nxagentFreeRegion(pDrawable, pClipRegion);
+ }
+
+ if (pGC != NULL)
+ {
+ FreeScratchGC(pGC);
+ }
+}
+
+void nxagentDestroyDrawableBitmap(DrawablePtr pDrawable)
+{
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyDrawableBitmap: Destroying bitmap for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ nxagentDestroyPixmap(nxagentDrawableBitmap(pDrawable));
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> synchronizationBitmap = NullPixmap;
+
+ if (nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+ {
+ nxagentSynchronization.backgroundBitmaps--;
+ }
+ else
+ {
+ nxagentSynchronization.pixmapBitmaps--;
+ }
+ }
+ else
+ {
+ nxagentWindowPriv((WindowPtr) pDrawable) -> synchronizationBitmap = NullPixmap;
+
+ nxagentSynchronization.windowBitmaps--;
+ }
+ }
+}
+
+void nxagentIncreasePixmapUsageCounter(PixmapPtr pPixmap)
+{
+ if (nxagentDrawableStatus((DrawablePtr) pPixmap) == Synchronized)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentIncreasePixmapUsageCounter: Pixmap usage counter was [%d].\n",
+ nxagentPixmapUsageCounter(pPixmap));
+ #endif
+
+ nxagentPixmapUsageCounter(pPixmap) += 1;
+
+ nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+}
+
+void nxagentAllocateCorruptedResource(DrawablePtr pDrawable, RESTYPE type)
+{
+ PixmapPtr pRealPixmap;
+
+ if (nxagentSessionState == SESSION_DOWN)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentAllocateCorruptedResource: WARNING! Not allocated corrupted resource "
+ "[%s][%p] with the display down.\n", nxagentDrawableType(pDrawable),
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ if (type == RT_NX_CORR_WINDOW)
+ {
+ if (nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+ "windows counter was [%d].\n", (void *) pDrawable, nxagentCorruptedWindows);
+ #endif
+
+ nxagentCorruptedWindows++;
+
+ nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId, RT_NX_CORR_WINDOW,
+ (void *) pDrawable);
+ }
+ }
+ else if (type == RT_NX_CORR_BACKGROUND)
+ {
+ pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+ if (nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId == 0)
+ {
+ /*
+ * When a pixmap is added to the background
+ * corrupted resources, it must be removed
+ * from the pixmap corrupted resources.
+ */
+
+ nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_PIXMAP);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+ "backgrounds counter was [%d].\n", (void *) pDrawable, nxagentCorruptedBackgrounds);
+ #endif
+
+ nxagentCorruptedBackgrounds++;
+
+ nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId, RT_NX_CORR_BACKGROUND,
+ (void *) pRealPixmap);
+ }
+ }
+ else if (type == RT_NX_CORR_PIXMAP)
+ {
+ /*
+ * The shared memory pixmaps are always dirty
+ * and shouldn't be synchronized.
+ */
+
+ if (nxagentPixmapUsageCounter((PixmapPtr) pDrawable) >= MINIMUM_PIXMAP_USAGE_COUNTER &&
+ nxagentIsShmPixmap((PixmapPtr) pDrawable) == 0)
+ {
+ pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+ if (nxagentPixmapPriv(pRealPixmap) -> corruptedId == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+ "pixmaps counter was [%d].\n", (void *) pDrawable, nxagentCorruptedPixmaps);
+ #endif
+
+ nxagentCorruptedPixmaps++;
+
+ nxagentPixmapPriv(pRealPixmap) -> corruptedId = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentPixmapPriv(pRealPixmap) -> corruptedId, RT_NX_CORR_PIXMAP,
+ (void *) pRealPixmap);
+ }
+ }
+ }
+}
+
+void nxagentDestroyCorruptedResource(DrawablePtr pDrawable, RESTYPE type)
+{
+ PixmapPtr pRealPixmap;
+
+ if (type == RT_NX_CORR_WINDOW)
+ {
+ if (nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedResource: Removing resource at [%p]. Corrupted "
+ "windows counter was [%d].\n", (void *) pDrawable, nxagentCorruptedWindows);
+ #endif
+
+ if (nxagentCorruptedWindows > 0)
+ {
+ nxagentCorruptedWindows--;
+ }
+
+ FreeResource(nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId, RT_NONE);
+
+ if (nxagentSynchronization.pDrawable == pDrawable)
+ {
+ nxagentSynchronization.pDrawable = NULL;
+ }
+ }
+ }
+ else if (type == RT_NX_CORR_BACKGROUND)
+ {
+ pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+ if (nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedResource: Removing resource at [%p]. Corrupted "
+ "backgrounds counter was [%d].\n", (void *) pDrawable, nxagentCorruptedBackgrounds);
+ #endif
+
+ if (nxagentCorruptedBackgrounds > 0)
+ {
+ nxagentCorruptedBackgrounds--;
+ }
+
+ FreeResource(nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId, RT_NONE);
+
+ if (nxagentSynchronization.pDrawable == pDrawable)
+ {
+ nxagentSynchronization.pDrawable = NULL;
+ }
+ }
+ }
+ else if (type == RT_NX_CORR_PIXMAP)
+ {
+ pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+ if (nxagentPixmapPriv(pRealPixmap) -> corruptedId != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyCorruptedResource: Removing resource at [%p]. Corrupted "
+ "pixmaps counter was [%d].\n", (void *) pDrawable, nxagentCorruptedPixmaps);
+ #endif
+
+ if (nxagentCorruptedPixmaps > 0)
+ {
+ nxagentCorruptedPixmaps--;
+ }
+
+ FreeResource(nxagentPixmapPriv(pRealPixmap) -> corruptedId, RT_NONE);
+
+ if (nxagentSynchronization.pDrawable == pDrawable)
+ {
+ nxagentSynchronization.pDrawable = NULL;
+ }
+ }
+ }
+}
+
+void nxagentCleanCorruptedDrawable(DrawablePtr pDrawable)
+{
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCleanCorruptedDrawable: Clearing out the corrupted drawable [%s][%p].\n",
+ nxagentDrawableType(pDrawable), (void *) pDrawable);
+ #endif
+
+ nxagentUnmarkCorruptedRegion(pDrawable, NullRegion);
+
+ if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+ {
+ nxagentDestroyDrawableBitmap(pDrawable);
+ }
+}
+
+void nxagentUnmarkExposedRegion(WindowPtr pWin, RegionPtr pRegion, RegionPtr pOther)
+{
+ RegionRec clipRegion;
+
+ if (pRegion != NullRegion && RegionNil(pRegion) == 0 &&
+ nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+ {
+ RegionInit(&clipRegion, NullBox, 1);
+
+ RegionCopy(&clipRegion, pRegion);
+
+ if (pOther != NullRegion && RegionNil(pOther) == 0)
+ {
+ RegionUnion(&clipRegion, &clipRegion, pOther);
+ }
+
+ RegionTranslate(&clipRegion, -pWin -> drawable.x, -pWin -> drawable.y);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUnmarkExposedRegion: Validating expose region [%d,%d,%d,%d] "
+ "on window [%p].\n", clipRegion.extents.x1, clipRegion.extents.y1,
+ clipRegion.extents.x2, clipRegion.extents.y2, (void *) pWin);
+ #endif
+
+ nxagentUnmarkCorruptedRegion((DrawablePtr) pWin, &clipRegion);
+
+ RegionUninit(&clipRegion);
+ }
+}
+
+int nxagentSynchronizationPredicate()
+{
+ if (nxagentCorruptedWindows == 0 &&
+ nxagentCorruptedBackgrounds == 0 &&
+ nxagentCorruptedPixmaps == 0)
+ {
+ return NotNeeded;
+ }
+
+ if (nxagentBlocking == 0 &&
+ nxagentCongestion <= 4 &&
+ nxagentReady == 0 &&
+ nxagentUserInput(NULL) == 0)
+ {
+ return Needed;
+ }
+
+ /*
+ * If there are resources to synchronize
+ * but the conditions to start the loop
+ * are not satisfied, a little delay is
+ * requested to check for a new loop as
+ * soon as possible.
+ */
+
+ return Delayed;
+}
+
+void nxagentSendBackgroundExpose(WindowPtr pWin, PixmapPtr pBackground, RegionPtr pExpose)
+{
+ RegionRec expose;
+ miBSWindowPtr pBackingStore;
+
+ RegionInit(&expose, NullBox, 1);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSendBackgroundExpose: Original expose region is [%d,%d,%d,%d].\n",
+ pExpose -> extents.x1, pExpose -> extents.y1,
+ pExpose -> extents.x2, pExpose -> extents.y2);
+
+ fprintf(stderr, "nxagentSendBackgroundExpose: Window clipList is [%d,%d,%d,%d].\n",
+ pWin -> clipList.extents.x1, pWin -> clipList.extents.y1,
+ pWin -> clipList.extents.x2, pWin -> clipList.extents.y2);
+ #endif
+
+ if (nxagentDrawableStatus((DrawablePtr) pBackground) == Synchronized &&
+ (pBackground -> drawable.width < pWin -> drawable.width ||
+ pBackground -> drawable.height < pWin -> drawable.height))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSendBackgroundExpose: Pixmap background [%dx%d] is "
+ "smaller than window [%dx%d]. Going to expose the winSize.\n",
+ pBackground -> drawable.width, pBackground -> drawable.height,
+ pWin -> drawable.width, pWin -> drawable.height);
+ #endif
+
+ RegionCopy(&expose, &pWin -> winSize);
+ }
+ else
+ {
+ RegionCopy(&expose, pExpose);
+
+ RegionTranslate(&expose, pWin -> drawable.x, pWin -> drawable.y);
+ }
+
+ RegionSubtract(&expose, &expose, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+ if (RegionNil(&pWin -> clipList) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSendBackgroundExpose: Exposures deferred because the window "
+ "is hidden.\n");
+ #endif
+
+ RegionUnion(nxagentDeferredBackgroundExposures,
+ nxagentDeferredBackgroundExposures, &expose);
+
+ nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 1;
+
+ goto nxagentSendBackgroundExposeEnd;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSendBackgroundExpose: Sending expose [%d,%d,%d,%d].\n",
+ expose.extents.x1, expose.extents.y1, expose.extents.x2, expose.extents.y2);
+ #endif
+
+ /*
+ * This prevents hidden region to be exposed.
+ */
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+
+ if ((pBackingStore != NULL) && (RegionNil(&pBackingStore->SavedRegion) == 0))
+ {
+ RegionTranslate(&expose, -pWin -> drawable.x, -pWin -> drawable.y);
+
+ RegionSubtract(&expose, &expose, &pBackingStore -> SavedRegion);
+
+ RegionTranslate(&expose, pWin -> drawable.x, pWin -> drawable.y);
+ }
+
+ RegionIntersect(&expose, &expose, &pWin -> clipList);
+
+ /*
+ * Reduce the overall region to expose.
+ */
+
+ RegionTranslate(&expose, -pWin -> drawable.x, -pWin -> drawable.y);
+
+ RegionSubtract(pExpose, pExpose, &expose);
+
+ RegionTranslate(&expose, pWin -> drawable.x, pWin -> drawable.y);
+
+ miWindowExposures(pWin, &expose, &expose);
+
+nxagentSendBackgroundExposeEnd:
+
+ RegionUninit(&expose);
+}
+
+void nxagentExposeBackgroundPredicate(void *p0, XID x1, void *p2)
+{
+ WindowPtr pWin = (WindowPtr) p0;
+ WindowPtr pParent;
+
+ struct nxagentExposeBackground *pPair = p2;
+
+ if (RegionNil(pPair -> pExpose) != 0)
+ {
+ return;
+ }
+
+ if (pWin -> backgroundState == BackgroundPixmap &&
+ pWin -> background.pixmap == pPair -> pBackground)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExposeBackgroundPredicate: Window at [%p] uses pixmap [%p] "
+ "as background.\n", (void *) pWin, (void *) pPair -> pBackground);
+ #endif
+
+ nxagentSendBackgroundExpose(pWin, pPair -> pBackground, pPair -> pExpose);
+ }
+ else if (pWin -> backgroundState == ParentRelative)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExposeBackgroundPredicate: Window [%p] uses parent's background.\n",
+ (void *) pWin);
+ #endif
+
+ pParent = pWin -> parent;
+
+ while (pParent != NULL)
+ {
+ if (pParent -> backgroundState == BackgroundPixmap &&
+ pParent -> background.pixmap == pPair -> pBackground)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExposeBackgroundPredicate: Parent window at [%p] uses pixmap [%p] "
+ "as background.\n", (void *) pParent, (void *) pPair -> pBackground);
+ #endif
+
+ nxagentSendBackgroundExpose(pWin, pPair -> pBackground, pPair -> pExpose);
+
+ break;
+ }
+
+ pParent = pParent -> parent;
+ }
+ }
+}
+
+/*
+ * This function is similar to nxagentClipAndSendExpose().
+ */
+
+int nxagentClipAndSendClearExpose(WindowPtr pWin, void * ptr)
+{
+ RegionPtr exposeRgn;
+ RegionPtr remoteExposeRgn;
+
+ #ifdef DEBUG
+ BoxRec box;
+ #endif
+
+ remoteExposeRgn = (RegionRec *) ptr;
+
+ if (nxagentWindowPriv(pWin) -> deferredBackgroundExpose == 1)
+ {
+ exposeRgn = RegionCreate(NULL, 1);
+
+ #ifdef DEBUG
+ box = *RegionExtents(remoteExposeRgn);
+
+ fprintf(stderr, "nxagentClipAndSendClearExpose: Background expose extents: [%d,%d,%d,%d].\n",
+ box.x1, box.y1, box.x2, box.y2);
+
+ box = *RegionExtents(&pWin -> clipList);
+
+ fprintf(stderr, "nxagentClipAndSendClearExpose: Clip list extents for window at [%p]: [%d,%d,%d,%d].\n",
+ (void *) pWin, box.x1, box.y1, box.x2, box.y2);
+ #endif
+
+ RegionIntersect(exposeRgn, remoteExposeRgn, &pWin -> clipList);
+
+ /*
+ * If the region will be synchronized,
+ * the expose on corrupted regions can
+ * be ignored.
+ */
+
+ RegionSubtract(exposeRgn, exposeRgn, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+ if (RegionNotEmpty(exposeRgn))
+ {
+ #ifdef DEBUG
+ box = *RegionExtents(exposeRgn);
+
+ fprintf(stderr, "nxagentClipAndSendClearExpose: Forwarding expose [%d,%d,%d,%d] to window at [%p] pWin.\n",
+ box.x1, box.y1, box.x2, box.y2, (void *) pWin);
+ #endif
+
+ RegionSubtract(remoteExposeRgn, remoteExposeRgn, exposeRgn);
+
+ miWindowExposures(pWin, exposeRgn, exposeRgn);
+ }
+
+ RegionDestroy(exposeRgn);
+
+ nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 0;
+ }
+
+ if (RegionNotEmpty(remoteExposeRgn))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClipAndSendClearExpose: Region not empty. Walk children.\n");
+ #endif
+
+
+ return WT_WALKCHILDREN;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClipAndSendClearExpose: Region empty. Stop walking.\n");
+ #endif
+
+ return WT_STOPWALKING;
+ }
+}
+
+void nxagentSendDeferredBackgroundExposures(void)
+{
+ if (nxagentDeferredBackgroundExposures == NullRegion)
+ {
+ nxagentDeferredBackgroundExposures = RegionCreate(NullBox, 1);
+ }
+
+ if (RegionNotEmpty(nxagentDeferredBackgroundExposures) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSendDeferredBackgroundExposures: Going to send deferred exposures to the root window.\n");
+ #endif
+
+ TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures);
+
+ RegionEmpty(nxagentDeferredBackgroundExposures);
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
new file mode 100644
index 000000000..6388d5c12
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -0,0 +1,229 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Drawable_H__
+#define __Drawable_H__
+
+#include "resource.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+
+/*
+ * Structures and macros used to manage the Lazy encoding.
+ */
+
+typedef struct
+{
+ DrawablePtr pDrawable;
+ int drawableType;
+ int abort;
+ int windowBitmaps;
+ int pixmapBitmaps;
+ int backgroundBitmaps;
+
+} _nxagentSynchronizationRec;
+
+extern _nxagentSynchronizationRec nxagentSynchronization;
+
+enum DrawableStatus
+{
+ Synchronized,
+ NotSynchronized
+};
+
+enum SynchronizationPredicate
+{
+ Needed,
+ NotNeeded,
+ Delayed
+};
+
+/*
+ * Shall the synchronization wait for the
+ * drawable wakening?
+ */
+
+#define DONT_WAIT 0
+#define DO_WAIT 1
+
+/*
+ * How the synchronization loop can be
+ * interrupted? A 0 mask means that the
+ * loop can't be stopped.
+ */
+
+#define EVENT_BREAK (1 << 0)
+#define CONGESTION_BREAK (1 << 1)
+#define BLOCKING_BREAK (1 << 2)
+
+#define NEVER_BREAK 0
+#define ALWAYS_BREAK (EVENT_BREAK | \
+ CONGESTION_BREAK | \
+ BLOCKING_BREAK)
+
+/*
+ * Minimum value of usage counter which
+ * a pixmap should have to be synchronized.
+ */
+
+#define MINIMUM_PIXMAP_USAGE_COUNTER 2
+
+/*
+ * This is the macro used to get the external XID
+ * from a generic pointer to a drawable.
+ */
+
+#define nxagentDrawable(pDrawable) \
+ ((pDrawable)->type == DRAWABLE_WINDOW ? \
+ nxagentWindow((WindowPtr)pDrawable) : \
+ nxagentPixmap((PixmapPtr)pDrawable))
+
+#define nxagentVirtualDrawable(pDrawable) \
+ (DrawablePtr)((pDrawable)->type == DRAWABLE_WINDOW ? \
+ NULL : nxagentVirtualPixmap((PixmapPtr)pDrawable))
+
+#define nxagentDrawablePicture(pDrawable) \
+ ((DrawablePtr)((pDrawable)->type == DRAWABLE_WINDOW ? \
+ nxagentWindowPriv((WindowPtr)pDrawable) -> pPicture : \
+ nxagentPixmapPriv((PixmapPtr)pDrawable) -> pPicture))
+
+#define nxagentCorruptedRegion(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+ nxagentPixmapCorruptedRegion((PixmapPtr) pDrawable) : \
+ nxagentWindowCorruptedRegion((WindowPtr) pDrawable))
+
+#define nxagentDrawableStatus(pDrawable) \
+ (RegionNil(nxagentCorruptedRegion(pDrawable)) ? \
+ Synchronized : NotSynchronized)
+
+#define nxagentDrawableContainGlyphs(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+ nxagentPixmapContainGlyphs((PixmapPtr) (pDrawable)) : \
+ nxagentWindowContainGlyphs((WindowPtr) (pDrawable)))
+
+#define nxagentSetDrawableContainGlyphs(pDrawable, value) \
+do \
+{ \
+ if ((pDrawable) -> type == DRAWABLE_PIXMAP) \
+ { \
+ nxagentPixmapContainGlyphs(nxagentRealPixmap((PixmapPtr) (pDrawable))) = (value); \
+ } \
+ else \
+ { \
+ nxagentWindowContainGlyphs((WindowPtr) (pDrawable)) = (value); \
+ } \
+} while (0)
+
+#define nxagentDrawableBitmap(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+ nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) (pDrawable))) -> synchronizationBitmap : \
+ nxagentWindowPriv((WindowPtr) (pDrawable)) -> synchronizationBitmap)
+
+#define nxagentDrawableTimestamp(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+ nxagentPixmapTimestamp((PixmapPtr) pDrawable) : \
+ nxagentWindowTimestamp((WindowPtr) pDrawable))
+
+#define nxagentDrawableType(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? "pixmap" : "window")
+
+extern RESTYPE RT_NX_CORR_BACKGROUND;
+extern RESTYPE RT_NX_CORR_WINDOW;
+extern RESTYPE RT_NX_CORR_PIXMAP;
+
+extern int nxagentCorruptedPixmaps;
+extern int nxagentCorruptedWindows;
+extern int nxagentCorruptedBackgrounds;
+
+extern int nxagentForceSynchronization;
+
+extern RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int width, int height);
+
+#define nxagentFreeRegion(pDrawable, pRegion) \
+ RegionDestroy(pRegion);
+
+extern void nxagentMarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentUnmarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentMoveCorruptedRegion(WindowPtr pWin, unsigned int mask);
+extern void nxagentIncreasePixmapUsageCounter(PixmapPtr pPixmap);
+
+extern int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned int breakMask, WindowPtr owner);
+extern void nxagentSynchronizeBox(DrawablePtr pDrawable, BoxPtr pBox, unsigned int breakMask);
+extern int nxagentSynchronizeDrawable(DrawablePtr pDrawable, int wait, unsigned int breakMask, WindowPtr owner);
+extern int nxagentSynchronizeDrawableData(DrawablePtr pDrawable, unsigned int breakMask, WindowPtr owner);
+extern void nxagentSynchronizationLoop(unsigned int mask);
+
+extern int nxagentSynchronizationPredicate(void);
+
+extern BoxPtr nxagentGetOptimizedRegionBoxes(RegionPtr pRegion);
+
+extern void nxagentCleanCorruptedDrawable(DrawablePtr pDrawable);
+
+extern void nxagentUnmarkExposedRegion(WindowPtr pWin, RegionPtr pRegion, RegionPtr pOther);
+extern void nxagentSendDeferredBackgroundExposures(void);
+
+extern void nxagentClearRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentFillRemoteRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+
+extern void nxagentAllocateCorruptedResource(DrawablePtr pDrawable, RESTYPE type);
+extern void nxagentDestroyCorruptedResource(DrawablePtr pDrawable, RESTYPE type);
+extern int nxagentDestroyCorruptedBackgroundResource(void * p, XID id);
+extern int nxagentDestroyCorruptedWindowResource(void * p, XID id);
+extern int nxagentDestroyCorruptedPixmapResource(void * p, XID id);
+
+extern void nxagentCreateDrawableBitmap(DrawablePtr pDrawable);
+extern void nxagentDestroyDrawableBitmap(DrawablePtr pDrawable);
+
+extern void nxagentRegionsOnScreen(void);
+
+#define PRINT_REGION_BOXES(pRegion, strRegion) \
+do \
+{ \
+ int i; \
+ int numRects; \
+ BoxPtr pBox; \
+\
+ if (pRegion == NullRegion) \
+ { \
+ fprintf(stderr, "printRegionBoxes:: Region " strRegion " is null.\n"); \
+ break; \
+ } \
+\
+ numRects = RegionNumRects(pRegion); \
+ pBox = RegionRects(pRegion); \
+\
+ fprintf(stderr, "printRegionBoxes:: Region " strRegion " at [%p] has [%d] boxes:\n", \
+ (void *) (pRegion), numRects); \
+\
+ for (i = 0; i < numRects; i++) \
+ { \
+ fprintf(stderr, "[%d] [%d,%d,%d,%d]\n", \
+ i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2); \
+ } \
+\
+} while (0)
+
+#endif /* __Drawable_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
new file mode 100644
index 000000000..05d0f3081
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -0,0 +1,644 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "os.h"
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include "Xlib.h"
+#include "Xproto.h"
+
+#include "Error.h"
+#include "Args.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+
+/*
+ * Duplicated stderr file descriptor.
+ */
+
+static int nxagentStderrDup = -1;
+
+/*
+ * Saved stderr file descriptor.
+ */
+
+static int nxagentStderrBackup = -1;
+
+/*
+ * Clients log file descriptor.
+ */
+
+static int nxagentClientsLog = -1;
+
+#define DEFAULT_STRING_LENGTH 256
+
+
+/*
+ * Clients log file name.
+ */
+
+char nxagentClientsLogName[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * User's home.
+ */
+
+static char nxagentHomeDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * NX root directory.
+ */
+
+static char nxagentRootDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * Session log Directory.
+ */
+
+static char nxagentSessionDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+char *nxagentGetClientsPath(void);
+
+static int nxagentPrintError(Display *dpy, XErrorEvent *event, FILE *fp);
+
+/* declare an error handler that does not exit when an error
+ * event is catched.
+ */
+
+int nxagentErrorHandler(Display *dpy, XErrorEvent *event)
+{
+ if (nxagentVerbose == 1)
+ {
+ nxagentPrintError(dpy, event, stderr);
+ }
+
+ return 0;
+}
+
+/* copied from XlibInt.c */
+/* extension stuff roughly commented out */
+static int nxagentPrintError(dpy, event, fp)
+ Display *dpy;
+ XErrorEvent *event;
+ FILE *fp;
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ char *mtype = "XlibMessage";
+ /*
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ */
+ XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(fp, mesg, event->request_code);
+ if (event->request_code < 128) {
+ sprintf(number, "%d", event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ /* for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ */
+ buffer[0] = '\0';
+ }
+ (void) fprintf(fp, " (%s)\n", buffer);
+ if (event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->minor_code);
+ /*
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(fp, " (%s)", buffer);
+ }
+ */
+ fputs("\n", fp);
+ }
+ if (event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ /*
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ event->error_code - bext->codes.first_error);
+ else
+ */
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ /* let extensions try to print the values */
+ /*
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, event, fp);
+ }
+ */
+ } else if ((event->error_code == BadWindow) ||
+ (event->error_code == BadPixmap) ||
+ (event->error_code == BadCursor) ||
+ (event->error_code == BadFont) ||
+ (event->error_code == BadDrawable) ||
+ (event->error_code == BadColor) ||
+ (event->error_code == BadGC) ||
+ (event->error_code == BadIDChoice) ||
+ (event->error_code == BadValue) ||
+ (event->error_code == BadAtom)) {
+ if (event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->resourceid);
+ fputs("\n", fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", fp);
+ (void) fprintf(fp, mesg, event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", fp);
+ /* (void) fprintf(fp, mesg, dpy->request); */
+ fputs("\n", fp);
+ if (event->error_code == BadImplementation) return 0;
+ return 1;
+}
+
+int nxagentExitHandler(const char *message)
+{
+ FatalError("%s", message);
+
+ return 0;
+}
+
+void nxagentOpenClientsLogFile()
+{
+ char * clientsLogName;
+
+ if (*nxagentClientsLogName == '\0')
+ {
+ clientsLogName = nxagentGetClientsPath();
+
+ if (clientsLogName != NULL)
+ {
+ free(clientsLogName);
+ }
+ }
+
+ if (nxagentClientsLogName != NULL && *nxagentClientsLogName !='\0')
+ {
+ nxagentClientsLog = open(nxagentClientsLogName, O_RDWR | O_CREAT | O_APPEND, 0600);
+
+ if (nxagentClientsLog == -1)
+ {
+ fprintf(stderr, "Warning: Failed to open clients log. Error is %d '%s'.\n",
+ errno, strerror(errno));
+ }
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenClientsLogFile: Cannot open clients log file. The path does not exist.\n");
+ #endif
+ }
+}
+
+void nxagentCloseClientsLogFile(void)
+{
+ close(nxagentClientsLog);
+}
+
+void nxagentStartRedirectToClientsLog(void)
+{
+ nxagentOpenClientsLogFile();
+
+ if (nxagentClientsLog != -1)
+ {
+ if (nxagentStderrBackup == -1)
+ {
+ nxagentStderrBackup = dup(2);
+ }
+
+ if (nxagentStderrBackup != -1)
+ {
+ nxagentStderrDup = dup2(nxagentClientsLog, 2);
+
+ if (nxagentStderrDup == -1)
+ {
+ fprintf(stderr, "Warning: Failed to redirect stderr. Error is %d '%s'.\n",
+ errno, strerror(errno));
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Failed to backup stderr. Error is %d '%s'.\n",
+ errno, strerror(errno));
+ }
+ }
+}
+
+void nxagentEndRedirectToClientsLog(void)
+{
+ if (nxagentStderrBackup != -1)
+ {
+ nxagentStderrDup = dup2(nxagentStderrBackup, 2);
+
+ if (nxagentStderrDup == -1)
+ {
+ fprintf(stderr, "Warning: Failed to restore stderr. Error is %d '%s'.\n",
+ errno, strerror(errno));
+ }
+ }
+
+ nxagentCloseClientsLogFile();
+}
+
+char *nxagentGetHomePath(void)
+{
+ char *homeEnv;
+ char *homePath;
+
+ if (*nxagentHomeDir == '\0')
+ {
+ /*
+ * Check the NX_HOME environment.
+ */
+
+ homeEnv = getenv("NX_HOME");
+
+ if (homeEnv == NULL || *homeEnv == '\0')
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetHomePath: No environment for NX_HOME.\n");
+ #endif
+
+ homeEnv = getenv("HOME");
+
+ if (homeEnv == NULL || *homeEnv == '\0')
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetHomePath: PANIC! No environment for HOME.\n");
+ #endif
+
+ return NULL;
+ }
+ }
+
+ if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - 1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetHomePath: PANIC! Invalid value for the NX "
+ "home directory '%s'.\n", homeEnv);
+ #endif
+ }
+
+ strncpy(nxagentHomeDir, homeEnv, DEFAULT_STRING_LENGTH - 1);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetHomePath: Assuming NX user's home directory '%s'.\n", nxagentHomeDir);
+ #endif
+ }
+
+ homePath = (char*) malloc(strlen(nxagentHomeDir) + 1);
+
+ if (homePath == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetHomePath: PANIC! Can't allocate memory for the home path.\n");
+ #endif
+
+ return NULL;
+ }
+
+ strcpy(homePath, nxagentHomeDir);
+
+ return homePath;
+}
+
+char *nxagentGetRootPath(void)
+{
+ char *rootEnv;
+ char *homeEnv;
+ char *rootPath;
+
+ struct stat dirStat;
+
+ if (*nxagentRootDir == '\0')
+ {
+ /*
+ * Check the NX_ROOT environment.
+ */
+
+ rootEnv = getenv("NX_ROOT");
+
+ if (rootEnv == NULL || *rootEnv == '\0')
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetRootPath: WARNING! No environment for NX_ROOT.\n");
+ #endif
+
+ /*
+ * We will determine the root NX directory
+ * based on the NX_HOME or HOME directory
+ * settings.
+ */
+
+ homeEnv = nxagentGetHomePath();
+
+ if (homeEnv == NULL)
+ {
+
+ #ifdef PANIC
+ #endif
+
+ return NULL;
+ }
+
+ if (strlen(homeEnv) > DEFAULT_STRING_LENGTH -
+ strlen("/.nx") - 1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetRootPath: PANIC! Invalid value for the NX "
+ "home directory '%s'.\n", homeEnv);
+ #endif
+
+ free(homeEnv);
+
+ return NULL;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetRootPath: Assuming NX root directory in '%s'.\n", homeEnv);
+ #endif
+
+ strcpy(nxagentRootDir, homeEnv);
+ strcat(nxagentRootDir, "/.nx");
+
+ free(homeEnv);
+
+ /*
+ * Create the NX root directory.
+ */
+
+ if ((stat(nxagentRootDir, &dirStat) == -1) && (errno == ENOENT))
+ {
+ if (mkdir(nxagentRootDir, 0777) < 0 && (errno != EEXIST))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetRootPath: PANIC! Can't create directory '%s'. Error is %d '%s'.\n",
+ nxagentRootDir, errno, strerror(errno));
+ #endif
+
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ if (strlen(rootEnv) > DEFAULT_STRING_LENGTH - 1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetRootPath: PANIC! Invalid value for the NX root directory '%s'.\n",
+ rootEnv);
+ #endif
+
+ return NULL;
+ }
+
+ strcpy(nxagentRootDir, rootEnv);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetRootPath: Assuming NX root directory '%s'.\n",
+ nxagentRootDir);
+ #endif
+
+ }
+
+ rootPath = malloc(strlen(nxagentRootDir) + 1);
+
+ if (rootPath == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetRootPath: Can't allocate memory for the root path.\n");
+ #endif
+
+ return NULL;
+ }
+
+ strcpy(rootPath, nxagentRootDir);
+
+ return rootPath;
+}
+
+char *nxagentGetSessionPath(void)
+{
+
+ char *rootPath;
+ char *sessionPath;
+
+ struct stat dirStat;
+
+ if (*nxagentSessionDir == '\0')
+ {
+ /*
+ * If nxagentSessionId does not exist we
+ * assume that the sessionPath cannot be
+ * realized and do not use the clients
+ * log file.
+ */
+
+ if (*nxagentSessionId == '\0')
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetSessionPath: Session id does not exist. Assuming session path NULL.\n");
+ #endif
+
+ return NULL;
+ }
+
+ rootPath = nxagentGetRootPath();
+
+ if (rootPath == NULL)
+ {
+ return NULL;
+ }
+
+ strcpy(nxagentSessionDir, rootPath);
+
+ free(rootPath);
+
+ if (strlen(nxagentSessionDir) + strlen("/C-") + strlen(nxagentSessionId) > DEFAULT_STRING_LENGTH - 1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetSessionPath: PANIC!: Invalid value for the NX session directory '%s'.\n",
+ nxagentSessionDir);
+ #endif
+
+ return NULL;
+ }
+
+ strcat(nxagentSessionDir, "/C-");
+
+ strcat(nxagentSessionDir, nxagentSessionId);
+
+ if ((stat(nxagentSessionDir, &dirStat) == -1) && (errno == ENOENT))
+ {
+ if (mkdir(nxagentSessionDir, 0777) < 0 && (errno != EEXIST))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetSessionPath: PANIC! Can't create directory '%s'. Error is %d '%s'.\n",
+ nxagentSessionDir, errno, strerror(errno));
+ #endif
+
+ return NULL;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetSessionPath: NX session is '%s'.\n",
+ nxagentSessionDir);
+ #endif
+
+ }
+
+ sessionPath = malloc(strlen(nxagentSessionDir) + 1);
+
+ if (sessionPath == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetSessionPath:: PANIC! Can't allocate memory for the session path.\n");
+ #endif
+
+ return NULL;
+ }
+
+
+ strcpy(sessionPath, nxagentSessionDir);
+
+ return sessionPath;
+}
+
+char *nxagentGetClientsPath()
+{
+ char *sessionPath;
+ char *clientsPath;
+
+ if (*nxagentClientsLogName == '\0')
+ {
+ sessionPath = nxagentGetSessionPath();
+
+ if (sessionPath == NULL)
+ {
+ return NULL;
+ }
+
+ if (strlen(sessionPath) + strlen("/clients") > DEFAULT_STRING_LENGTH - 1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetClientsPath: PANIC! Invalid value for the NX clients Log File Path '%s'.\n",
+ nxagentClientsLogName);
+ #endif
+
+ free(sessionPath);
+
+ return NULL;
+ }
+
+ strcpy(nxagentClientsLogName, sessionPath);
+
+ strcat(nxagentClientsLogName, "/clients");
+
+ free(sessionPath);
+ }
+
+ clientsPath = malloc(strlen(nxagentClientsLogName) + 1);
+
+ if (clientsPath == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentGetClientsPath: PANIC! Can't allocate memory for the clients Log File Path path.\n");
+ #endif
+
+ return NULL;
+ }
+
+ strcpy(clientsPath, nxagentClientsLogName);
+
+ return clientsPath;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
new file mode 100644
index 000000000..1d0d9a827
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -0,0 +1,47 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Error_H__
+#define __Error_H__
+
+/*
+ * Clients log file name.
+ */
+
+extern char nxagentClientsLogName[];
+
+extern char nxagentVerbose;
+
+int nxagentErrorHandler(Display *dpy, XErrorEvent *event);
+
+int nxagentExitHandler(const char *message);
+
+void nxagentStartRedirectToClientsLog(void);
+
+void nxagentEndRedirectToClientsLog(void);
+
+char *nxagentGetSessionPath(void);
+
+#endif /* __Error_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
new file mode 100644
index 000000000..e360d21f6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -0,0 +1,4767 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "X.h"
+#include "signal.h"
+#include "unistd.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "dix.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "selection.h"
+#include "keysym.h"
+#include "fb.h"
+#include "mibstorest.h"
+#include "osdep.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Atoms.h"
+#include "Colormap.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+#include "Keyboard.h"
+#include "Keystroke.h"
+#include "Events.h"
+#include "Pointer.h"
+#include "Rootless.h"
+#include "Splash.h"
+#include "Trap.h"
+#include "Dialog.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Split.h"
+#include "Drawable.h"
+#include "Handlers.h"
+#include "Utils.h"
+#include "Error.h"
+
+#include <nx/NX.h>
+#include <nx/NXvars.h>
+#include <nx/NXproto.h>
+
+#include "xfixesproto.h"
+#define Window XlibWindow
+#define Atom XlibAtom
+#define Time XlibXID
+#include "X11/include/Xfixes_nxagent.h"
+#undef Window
+#undef Atom
+#undef Time
+
+#ifdef NXAGENT_FIXKEYS
+#include "inputstr.h"
+#include "input.h"
+#endif
+
+#define Time XlibXID
+#include "XKBlib.h"
+#undef Time
+
+#define GC XlibGC
+#define Font XlibFont
+#define KeySym XlibKeySym
+#define XID XlibXID
+#include "Xlibint.h"
+#undef GC
+#undef Font
+#undef KeySym
+#undef XID
+
+#include <nx-X11/cursorfont.h>
+
+#include <nx/Shadow.h>
+#include "X11/include/Xrandr_nxagent.h"
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level. Please note
+ * that if you want to enable DEBUG here, then
+ * you need to enable DEBUG even in Rootless.c
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef BLOCKS
+
+extern Bool nxagentOnce;
+
+extern WindowPtr nxagentRootTileWindow;
+extern int nxagentSplashCount;
+
+extern int nxagentLastClipboardClient;
+
+#ifdef NX_DEBUG_INPUT
+int nxagentDebugInput = 0;
+#endif
+
+#ifdef DEBUG
+extern Bool nxagentRootlessTreesMatch(void);
+#endif
+
+extern Selection *CurrentSelections;
+extern int NumCurrentSelections;
+
+typedef union _XFixesSelectionEvent {
+ int type;
+ XFixesSelectionNotifyEvent xfixesselection;
+ XEvent core;
+} XFixesSelectionEvent;
+
+Bool xkbdRunning = False;
+pid_t pidkbd;
+
+WindowPtr nxagentLastEnteredWindow = NULL;
+
+PropertyRequestRec nxagentPropertyRequests[NXNumberOfResources];
+
+void nxagentHandleCollectPropertyEvent(XEvent*);
+
+/*
+ * Finalize the asynchronous handling
+ * of the X_GrabPointer requests.
+ */
+
+void nxagentHandleCollectGrabPointerEvent(int resource);
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr);
+
+/*
+ * Used in Handlers.c to synchronize
+ * the agent with the remote X server.
+ */
+
+void nxagentHandleCollectInputFocusEvent(int resource);
+
+/*
+ * Viewport navigation.
+ */
+
+static int viewportInc = 1;
+static enum HandleEventResult viewportLastKeyPressResult;
+static int viewportLastX;
+static int viewportLastY;
+static Cursor viewportCursor;
+
+#define MAX_INC 200
+#define INC_STEP 5
+#define nextinc(x) ((x) < MAX_INC ? (x) += INC_STEP : (x))
+
+/*
+ * Keyboard and pointer are handled as they were real devices by
+ * Xnest and we inherit this behaviour. The following mask will
+ * contain the event mask selected for the root window of the
+ * agent. All the keyboard and pointer events will be translated
+ * by the agent and sent to the internal clients according to
+ * events selected by the inferior windows.
+ */
+
+static Mask defaultEventMask;
+
+static int lastEventSerial = 0;
+
+/*
+ * Used to mask the appropriate bits in
+ * the state reported by XkbStateNotify
+ * and XkbGetIndicatorState.
+ */
+
+#define CAPSFLAG_IN_REPLY 1
+#define CAPSFLAG_IN_EVENT 2
+#define NUMFLAG_IN_EVENT 16
+#define NUMFLAG_IN_REPLY 2
+
+CARD32 nxagentLastEventTime = 0;
+CARD32 nxagentLastKeyPressTime = 0;
+Time nxagentLastServerTime = 0;
+
+/*
+ * Used for storing windows that need to
+ * receive expose events from the agent.
+ */
+
+#define nxagentExposeQueueHead nxagentExposeQueue.exposures[nxagentExposeQueue.start]
+
+ExposeQueue nxagentExposeQueue;
+
+RegionPtr nxagentRemoteExposeRegion = NULL;
+
+static void nxagentForwardRemoteExpose(void);
+
+static int nxagentClipAndSendExpose(WindowPtr pWin, void * ptr);
+
+/*
+ * This is from NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset,
+ long longLength, Bool delete, Atom type,
+ Atom *actualType, int *format, unsigned
+ long *nItems, unsigned long *bytesAfter,
+ unsigned char **propData);
+
+/*
+ * Associate a resource to a drawable and
+ * store the region affected by the split
+ * operation.
+ */
+
+SplitResourceRec nxagentSplitResources[NXNumberOfResources];
+
+/*
+ * Associate a resource to an unpack
+ * operation.
+ */
+
+UnpackResourceRec nxagentUnpackResources[NXNumberOfResources];
+
+/*
+ * We have to check these before launching
+ * the terminate dialog in rootless mode.
+ */
+
+Bool nxagentLastWindowDestroyed = False;
+Time nxagentLastWindowDestroyedTime = 0;
+
+/*
+ * Set this flag when an user input event
+ * is received.
+ */
+
+int nxagentInputEvent = 0;
+
+int nxagentKeyDown = 0;
+
+void nxagentSwitchResizeMode(ScreenPtr pScreen);
+
+int nxagentCheckWindowConfiguration(XConfigureEvent* X);
+
+#define nxagentMonitoredDuplicate(keysym) \
+ ((keysym) == XK_Left || (keysym) == XK_Up || \
+ (keysym) == XK_Right || (keysym) == XK_Down || \
+ (keysym) == XK_Page_Up || (keysym) == XK_Page_Down || \
+ (keysym) == XK_Delete || (keysym) == XK_BackSpace)
+
+void nxagentRemoveDuplicatedKeys(XEvent *X);
+
+void ProcessInputEvents()
+{
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "ProcessInputEvents: Processing input.\n");
+ }
+ #endif
+
+ mieqProcessInputEvents();
+}
+
+#ifdef DEBUG_TREE
+
+/*
+ * Print ID and name of window.
+ */
+
+void nxagentRemoteWindowID(Window window, Bool newline)
+{
+#ifdef NO_I18N
+ char *winName;
+#else
+ XTextProperty tp;
+#endif
+
+ fprintf(stderr, "0x%lx", window);
+
+ if (!window)
+ {
+ fprintf(stderr, " (none) ");
+ }
+ else
+ {
+ if (window == DefaultRootWindow(nxagentDisplay))
+ {
+ fprintf(stderr, " (the root window) ");
+ }
+
+#ifdef NO_I18N
+
+ if (!XFetchName(nxagentDisplay, window, &winName))
+ {
+ fprintf(stderr, " (has no name) ");
+ }
+ else if (winName)
+ {
+ fprintf(stderr, " \"%s\" ", winName);
+ XFree(winName);
+ }
+
+#else
+
+ if (XGetWMName(nxagentDisplay, window, &tp) != 0)
+ {
+ fprintf(stderr, " (has no name) ");
+ }
+ else if (tp.nitems > 0)
+ {
+ int count = 0;
+ int i, ret;
+ char **list = NULL;
+
+ fprintf(stderr, " \"");
+
+ ret = XmbTextPropertyToTextList(nxagentDisplay, &tp, &list, &count);
+
+ if ((ret == Success || ret > 0) && list != NULL)
+ {
+ for (i = 0; i < count; i++)
+ {
+ fprintf(stderr, "%s", list[i]);
+ }
+
+ XFreeStringList(list);
+ }
+ else
+ {
+ fprintf(stderr, "%s", tp.value);
+ }
+
+ fprintf(stderr, "\" ");
+ }
+
+#endif
+
+ else
+ {
+ fprintf(stderr, " (has no name) ");
+ }
+ }
+
+ if (newline == TRUE)
+ {
+ fprintf(stderr, "\n");
+ }
+
+ return;
+}
+
+/*
+ * Print info about remote window.
+ */
+
+void nxagentRemoteWindowInfo(Window win, int indent, Bool newLine)
+{
+ XWindowAttributes attributes;
+ int i;
+
+ if (XGetWindowAttributes(nxagentDisplay, win, &attributes) == 0)
+ {
+ return;
+ }
+
+ for (i = 0; i < indent; i++)
+ {
+ fprintf(stderr, " ");
+ }
+
+ fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+ "override_redirect=%s\n", attributes.x, attributes.y,
+ attributes.width, attributes.height,
+ (attributes.class == 0) ? "CopyFromParent" :
+ ((attributes.class == 1) ? "InputOutput" : "InputOnly"),
+ (attributes.map_state == 0) ?
+ "IsUnmapped" : (attributes.map_state == 1 ?
+ "IsUnviewable" : "IsViewable"),
+ (attributes.override_redirect == 0) ?
+ "No" : "Yes" );
+
+ if (newLine == TRUE)
+ {
+ fprintf(stderr, "\n");
+ }
+}
+
+/*
+ * Walk remote windows tree.
+ */
+
+void nxagentRemoteWindowsTree(Window window, int level)
+{
+ int i, j;
+ unsigned long rootWin, parentWin;
+ unsigned int numChildren;
+ unsigned long *childList;
+
+ if (!XQueryTree(nxagentDisplay, window, &rootWin, &parentWin, &childList,
+ &numChildren))
+ {
+ fprintf(stderr, "nxagentRemoteWindowsTree - XQueryTree failed.\n");
+
+ return;
+ }
+
+ if (level == 0)
+ {
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Root Window ID: ");
+ nxagentRemoteWindowID(rootWin, TRUE);
+
+ fprintf(stderr, " Parent window ID: ");
+ nxagentRemoteWindowID(parentWin, TRUE);
+ }
+
+ if (level == 0 || numChildren > 0)
+ {
+ fprintf(stderr, " ");
+
+ for (j = 0; j < level; j++)
+ {
+ fprintf(stderr, " ");
+ }
+
+ fprintf(stderr, "%d child%s%s\n", numChildren, (numChildren == 1) ? "" :
+ "ren", (numChildren == 1) ? ":" : ".");
+ }
+
+ for (i = (int) numChildren - 1; i >= 0; i--)
+ {
+ fprintf(stderr, " ");
+
+ for (j = 0; j < level; j++)
+ {
+ fprintf(stderr, " ");
+ }
+
+ nxagentRemoteWindowID(childList[i], TRUE);
+
+ nxagentRemoteWindowInfo(childList[i], (level * 5) + 6, TRUE);
+
+ nxagentRemoteWindowsTree(childList[i], level + 1);
+ }
+
+ if (childList)
+ {
+ XFree((char *) childList);
+ }
+}
+
+/*
+ * Print info about internal window.
+ */
+
+void nxagentInternalWindowInfo(WindowPtr pWin, int indent, Bool newLine)
+{
+ int i;
+ int result;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ Atom atomReturnType;
+ int iReturnFormat;
+ unsigned char *pszReturnData = NULL;
+
+ fprintf(stderr, "Window ID=[0x%lx] Remote ID=[0x%lx] ", pWin -> drawable.id,
+ nxagentWindow(pWin));
+
+ result = GetWindowProperty(pWin, MakeAtom("WM_NAME", 7, False) , 0,
+ sizeof(CARD32), False, AnyPropertyType,
+ &atomReturnType, &iReturnFormat,
+ &ulReturnItems, &ulReturnBytesLeft,
+ &pszReturnData);
+
+ fprintf(stderr, "Name: ");
+
+ if (result == Success && pszReturnData != NULL)
+ {
+ pszReturnData[ulReturnItems] = '\0';
+
+ fprintf(stderr, "\"%s\"\n", (char *) pszReturnData);
+ }
+ else
+ {
+ fprintf(stderr, "%s\n", "( has no name )");
+ }
+
+ for (i = 0; i < indent; i++)
+ {
+ fprintf(stderr, " ");
+ }
+
+ fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+ "override_redirect=%s", pWin -> drawable.x, pWin -> drawable.y,
+ pWin -> drawable.width, pWin -> drawable.height,
+ (pWin -> drawable.class == 0) ? "CopyFromParent" :
+ ((pWin -> drawable.class == 1) ? "InputOutput" :
+ "InputOnly"),
+ (pWin -> mapped == 0) ?
+ "IsUnmapped" : (pWin -> realized == 0 ?
+ "IsUnviewable" : "IsViewable"),
+ (pWin -> overrideRedirect == 0) ?
+ "No" : "Yes");
+
+ if (newLine == TRUE)
+ {
+ fprintf(stderr, "\n");
+ }
+}
+
+/*
+ * Walk internal windows tree.
+ */
+
+void nxagentInternalWindowsTree(WindowPtr pWin, int indent)
+{
+ WindowPtr pChild;
+ int i;
+
+ while (pWin)
+ {
+ pChild = pWin -> firstChild;
+
+ for (i = 0; i < indent; i++)
+ {
+ fprintf(stderr, " ");
+ }
+
+ nxagentInternalWindowInfo(pWin, indent, TRUE);
+
+ fprintf(stderr, "\n");
+
+ nxagentInternalWindowsTree(pChild, indent + 4);
+
+ pWin = pWin -> nextSib;
+ }
+}
+
+#endif /* DEBUG_TREE */
+
+void nxagentSwitchResizeMode(ScreenPtr pScreen)
+{
+ XSizeHints sizeHints;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSwitchResizeMode called.\n");
+ #endif
+
+ int desktopResize = nxagentOption(DesktopResize);
+
+ nxagentChangeOption(DesktopResize, !desktopResize);
+
+ sizeHints.flags = PMaxSize;
+
+ if (nxagentOption(DesktopResize) == 0)
+ {
+ fprintf(stderr,"Info: Disabled desktop resize mode in agent.\n");
+
+ nxagentLaunchDialog(DIALOG_DISABLE_DESKTOP_RESIZE_MODE);
+
+ if (nxagentOption(Fullscreen) == 0)
+ {
+ sizeHints.max_width = nxagentOption(RootWidth);
+ sizeHints.max_height = nxagentOption(RootHeight);
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ &sizeHints);
+ }
+ }
+ else
+ {
+ fprintf(stderr,"Info: Enabled desktop resize mode in agent.\n");
+
+ nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
+
+ nxagentChangeScreenConfig(0, nxagentOption(Width), nxagentOption(Height),
+ 0, 0);
+
+ if (nxagentOption(ClientOs) == ClientOsWinnt)
+ {
+ NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
+ }
+
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ &sizeHints);
+ }
+}
+
+void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
+{
+ XSizeHints sizeHints;
+
+ int desktopResize = nxagentOption(DesktopResize);
+
+ nxagentChangeOption(DesktopResize, !desktopResize);
+
+ sizeHints.flags = PMaxSize;
+
+ if (nxagentOption(DesktopResize) == 0)
+ {
+ nxagentShadowSetRatio(1.0, 1.0);
+
+ nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root,
+ screenInfo.screens[0]->root -> drawable.width, screenInfo.screens[0]->root -> drawable.height);
+
+ sizeHints.max_width = nxagentOption(RootWidth);
+ sizeHints.max_height = nxagentOption(RootHeight);
+
+ fprintf(stderr,"Info: Disabled resize mode in shadow agent.\n");
+ }
+ else
+ {
+ nxagentShadowSetRatio(nxagentOption(Width) * 1.0 /
+ screenInfo.screens[0]->root -> drawable.width,
+ nxagentOption(Height) * 1.0 /
+ screenInfo.screens[0]->root -> drawable.height);
+
+ nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+ screenInfo.screens[0]->root, screenInfo.screens[0]->root -> drawable.width,
+ screenInfo.screens[0]->root -> drawable.height);
+
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+ fprintf(stderr,"Info: Enabled resize mode in shadow agent.\n");
+ }
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+ &sizeHints);
+}
+
+static void nxagentSwitchDeferMode(void)
+{
+ if (nxagentOption(DeferLevel) == 0)
+ {
+ nxagentChangeOption(DeferLevel, UNDEFINED);
+
+ nxagentSetDeferLevel();
+ }
+ else
+ {
+ nxagentChangeOption(DeferLevel, 0);
+ }
+
+ if (nxagentOption(DeferLevel) != 0)
+ {
+ nxagentLaunchDialog(DIALOG_ENABLE_DEFER_MODE);
+ }
+ else
+ {
+ nxagentLaunchDialog(DIALOG_DISABLE_DEFER_MODE);
+
+ nxagentForceSynchronization = 1;
+ }
+}
+
+static Bool nxagentExposurePredicate(Display *display, XEvent *event, XPointer window)
+{
+ /*
+ * Handle both Expose and ProcessedExpose events.
+ * The latters are those not filtered by function
+ * nxagentWindowExposures().
+ */
+
+ if (window)
+ {
+ return ((event -> type == Expose || event -> type == ProcessedExpose) &&
+ event -> xexpose.window == *((Window *) window));
+ }
+ else
+ {
+ return (event -> type == Expose || event -> type == ProcessedExpose);
+ }
+}
+
+static int nxagentAnyEventPredicate(Display *display, XEvent *event, XPointer parameter)
+{
+ return 1;
+}
+
+int nxagentInputEventPredicate(Display *display, XEvent *event, XPointer parameter)
+{
+ switch (event -> type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ return 1;
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+}
+
+void nxagentInitDefaultEventMask()
+{
+ Mask mask = NoEventMask;
+
+ mask |= (StructureNotifyMask | VisibilityChangeMask);
+
+ mask |= ExposureMask;
+
+ mask |= NXAGENT_KEYBOARD_EVENT_MASK;
+ mask |= NXAGENT_POINTER_EVENT_MASK;
+
+ defaultEventMask = mask;
+}
+
+void nxagentGetDefaultEventMask(Mask *mask_return)
+{
+ *mask_return = defaultEventMask;
+}
+
+void nxagentSetDefaultEventMask(Mask mask)
+{
+ defaultEventMask = mask;
+}
+
+void nxagentGetEventMask(WindowPtr pWin, Mask *mask_return)
+{
+ Mask mask = NoEventMask;
+
+ if (nxagentOption(Rootless))
+ {
+ /*
+ * mask = pWin -> eventMask &
+ * ~(NXAGENT_KEYBOARD_EVENT_MASK | NXAGENT_POINTER_EVENT_MASK);
+ */
+
+ if (pWin -> drawable.class == InputOutput)
+ {
+ if (nxagentWindowTopLevel(pWin))
+ {
+ mask = defaultEventMask;
+ }
+ else
+ {
+ mask = ExposureMask | VisibilityChangeMask | PointerMotionMask;
+ }
+ }
+
+ mask |= PropertyChangeMask;
+ }
+ else if (pWin -> drawable.class != InputOnly)
+ {
+ mask = ExposureMask | VisibilityChangeMask;
+ }
+
+ *mask_return = mask;
+}
+
+static int nxagentChangeMapPrivate(WindowPtr pWin, void * ptr)
+{
+ if (pWin && nxagentWindowPriv(pWin))
+ {
+ nxagentWindowPriv(pWin) -> isMapped = *((Bool *) ptr);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int nxagentChangeVisibilityPrivate(WindowPtr pWin, void * ptr)
+{
+ if (pWin && nxagentWindowPriv(pWin))
+ {
+ nxagentWindowPriv(pWin) -> visibilityState = *((int *) ptr);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+void nxagentDispatchEvents(PredicateFuncPtr predicate)
+{
+ XEvent X;
+ xEvent x;
+ ScreenPtr pScreen = NULL;
+
+ Bool minimize = False;
+ Bool startKbd = False;
+ Bool closeSession = False;
+ Bool switchFullscreen = False;
+ Bool switchAllScreens = False;
+
+ /*
+ * Last entered top level window.
+ */
+
+ static WindowPtr nxagentLastEnteredTopLevelWindow = NULL;
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin read]\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new events with "
+ "predicate [%p].\n", predicate);
+ #endif
+
+ if (nxagentRemoteExposeRegion == NULL)
+ {
+ nxagentInitRemoteExposeRegion();
+ }
+
+ /*
+ * We must read here, even if apparently there is
+ * nothing to read. The ioctl() based readable
+ * function, in fact, is often unable to detect a
+ * failure of the socket, in particular if the
+ * agent was connected to the proxy and the proxy
+ * is gone. Thus we must trust the wakeup handler
+ * that called us after the select().
+ */
+
+ #ifdef TEST
+
+ if (nxagentPendingEvents(nxagentDisplay) == 0)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: PANIC! No event needs to be dispatched.\n");
+ }
+
+ #endif
+
+ /*
+ * We want to process all the events already in
+ * the queue, plus any additional event that may
+ * be read from the network. If no event can be
+ * read, we want to continue handling our clients
+ * without flushing the output buffer.
+ */
+
+ while (nxagentCheckEvents(nxagentDisplay, &X, predicate != NULL ? predicate :
+ nxagentAnyEventPredicate, NULL) == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new event type [%d].\n",
+ X.type);
+ #endif
+
+ /*
+ * Handle the incoming event.
+ */
+
+ switch (X.type)
+ {
+ #ifdef NXAGENT_CLIPBOARD
+
+ case SelectionClear:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionClear event.\n");
+ #endif
+
+ nxagentClearSelection(&X);
+
+ break;
+ }
+ case SelectionRequest:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionRequest event.\n");
+ #endif
+
+ nxagentRequestSelection(&X);
+
+ break;
+ }
+ case SelectionNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionNotify event.\n");
+ #endif
+
+ nxagentNotifySelection(&X);
+
+ break;
+ }
+
+ #endif /* NXAGENT_CLIPBOARD */
+
+ case PropertyNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: PropertyNotify on "
+ "prop %d[%s] window %lx state %d\n",
+ (int)X.xproperty.atom, validateString(XGetAtomName(nxagentDisplay, X.xproperty.atom)),
+ X.xproperty.window, X.xproperty.state);
+ #endif
+
+ nxagentHandlePropertyNotify(&X);
+
+ break;
+ }
+ case KeyPress:
+ {
+ enum HandleEventResult result;
+
+ KeySym keysym;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyPress event.\n");
+ #endif
+
+ nxagentInputEvent = 1;
+
+ nxagentKeyDown++;
+
+ nxagentHandleKeyPress(&X, &result);
+
+ if (viewportLastKeyPressResult != result)
+ {
+ viewportInc = 1;
+
+ viewportLastKeyPressResult = result;
+ }
+
+ if (result != doNothing && result != doStartKbd)
+ {
+ pScreen = nxagentScreen(X.xkey.window);
+ }
+
+ switch (result)
+ {
+ case doNothing:
+ {
+ break;
+ }
+
+ #ifdef DEBUG_TREE
+
+ case doDebugTree:
+ {
+ fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n");
+ nxagentRemoteWindowsTree(nxagentWindow(screenInfo.screens[0]->root), 0);
+
+ fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n");
+ nxagentInternalWindowsTree(screenInfo.screens[0]->root, 0);
+
+ break;
+ }
+
+ #endif /* DEBUG_TREE */
+
+ case doCloseSession:
+ {
+ closeSession = TRUE;
+
+ break;
+ }
+ case doMinimize:
+ {
+ minimize = TRUE;
+
+ break;
+ }
+ case doStartKbd:
+ {
+ startKbd = TRUE;
+
+ break;
+ }
+ case doSwitchFullscreen:
+ {
+ switchFullscreen = TRUE;
+
+ break;
+ }
+ case doSwitchAllScreens:
+ {
+ switchAllScreens = TRUE;
+
+ break;
+ }
+ case doViewportMoveUp:
+ {
+ nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
+
+ break;
+ }
+ case doViewportMoveDown:
+ {
+ nxagentMoveViewport(pScreen, 0, nxagentOption(Height));
+
+ break;
+ }
+ case doViewportMoveLeft:
+ {
+ nxagentMoveViewport(pScreen, -nxagentOption(Width), 0);
+
+ break;
+ }
+ case doViewportMoveRight:
+ {
+ nxagentMoveViewport(pScreen, nxagentOption(Width), 0);
+
+ break;
+ }
+ case doViewportUp:
+ {
+ nxagentMoveViewport(pScreen, 0, -nextinc(viewportInc));
+
+ break;
+ }
+ case doViewportDown:
+ {
+ nxagentMoveViewport(pScreen, 0, +nextinc(viewportInc));
+
+ break;
+ }
+ case doViewportLeft:
+ {
+ nxagentMoveViewport(pScreen, -nextinc(viewportInc), 0);
+
+ break;
+ }
+ case doViewportRight:
+ {
+ nxagentMoveViewport(pScreen, +nextinc(viewportInc), 0);
+
+ break;
+ }
+ case doSwitchResizeMode:
+ {
+ if (nxagentOption(Shadow) == 0)
+ {
+ if (nxagentNoDialogIsRunning)
+ {
+ nxagentSwitchResizeMode(pScreen);
+ }
+ }
+ else
+ {
+ nxagentShadowSwitchResizeMode(pScreen);
+ }
+
+ break;
+ }
+ case doSwitchDeferMode:
+ {
+ if (nxagentNoDialogIsRunning)
+ {
+ nxagentSwitchDeferMode();
+ }
+
+ break;
+ }
+ default:
+ {
+ FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
+
+ break;
+ }
+ }
+
+ /*
+ * Elide multiple KeyPress/KeyRelease events of
+ * the same key and generate a single pair. This
+ * is intended to reduce the impact of the laten-
+ * cy on the key auto-repeat, handled by the re-
+ * mote X server. We may optionally do that only
+ * if the timestamps in the events show an exces-
+ * sive delay.
+ */
+
+ keysym = XKeycodeToKeysym(nxagentDisplay, X.xkey.keycode, 0);
+
+ if (nxagentMonitoredDuplicate(keysym) == 1)
+ {
+ nxagentRemoveDuplicatedKeys(&X);
+ }
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) == 1 && result == doNothing)
+ {
+ X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
+ NXShadowEvent(nxagentDisplay, X);
+ }
+
+ break;
+ }
+ case KeyRelease:
+ {
+ enum HandleEventResult result;
+ int sendKey = 0;
+
+/*
+FIXME: If we don't flush the queue here, it could happen
+ that the inputInfo structure will not be up to date
+ when we perform the following check on down keys.
+*/
+ ProcessInputEvents();
+
+/*
+FIXME: Don't enqueue the KeyRelease event if the key was
+ not already pressed. This workaround avoids a fake
+ KeyPress is enqueued by the XKEYBOARD extension.
+ Another solution would be to let the events are
+ enqueued and to remove the KeyPress afterwards.
+*/
+ if (BitIsOn(inputInfo.keyboard -> key -> down,
+ nxagentConvertKeycode(X.xkey.keycode)))
+ {
+ sendKey = 1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyRelease event.\n");
+ #endif
+
+ nxagentInputEvent = 1;
+
+ nxagentKeyDown--;
+
+ if (nxagentKeyDown <= 0)
+ {
+ nxagentKeyDown = 0;
+ }
+
+ if (nxagentXkbState.Initialized == 0)
+ {
+ if (X.xkey.keycode == nxagentCapsLockKeycode)
+ {
+ nxagentXkbCapsTrap = 1;
+ }
+ else if (X.xkey.keycode == nxagentNumLockKeycode)
+ {
+ nxagentXkbNumTrap = 1;
+ }
+
+ nxagentInitKeyboardState();
+
+ nxagentXkbCapsTrap = 0;
+ nxagentXkbNumTrap = 0;
+ }
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = KeyRelease;
+ x.u.u.detail = nxagentConvertKeycode(X.xkey.keycode);
+ x.u.keyButtonPointer.time = nxagentLastKeyPressTime +
+ (X.xkey.time - nxagentLastServerTime);
+
+ nxagentLastServerTime = X.xkey.time;
+
+ nxagentLastEventTime = GetTimeInMillis();
+
+ if (x.u.keyButtonPointer.time > nxagentLastEventTime)
+ {
+ x.u.keyButtonPointer.time = nxagentLastEventTime;
+ }
+
+ if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)) && sendKey == 1)
+ {
+ mieqEnqueue(&x);
+
+ CriticalOutputPending = 1;
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+ {
+ X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
+ NXShadowEvent(nxagentDisplay, X);
+ }
+ }
+
+ break;
+ }
+ case ButtonPress:
+ {
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
+ }
+ #endif
+
+ nxagentInputEvent = 1;
+
+ if (nxagentOption(Fullscreen))
+ {
+ if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
+ {
+ pScreen = nxagentScreen(X.xbutton.window);
+
+ minimize = True;
+
+ break;
+ }
+ }
+
+ if (nxagentIpaq && nxagentClients <= 0)
+ {
+ closeSession = TRUE;
+ }
+
+ if (nxagentOption(DesktopResize) == False &&
+ (X.xbutton.state & (ControlMask | Mod1Mask)) == (ControlMask | Mod1Mask))
+ {
+ /*
+ * Start viewport navigation mode.
+ */
+
+ int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+ nxagentCollectGrabPointerPredicate);
+
+ ScreenPtr pScreen = nxagentScreen(X.xbutton.window);
+ viewportCursor = XCreateFontCursor(nxagentDisplay, XC_fleur);
+
+ NXCollectGrabPointer(nxagentDisplay, resource,
+ nxagentDefaultWindows[pScreen -> myNum], True,
+ NXAGENT_POINTER_EVENT_MASK, GrabModeAsync,
+ GrabModeAsync, None, viewportCursor,
+ CurrentTime);
+ viewportLastX = X.xbutton.x;
+ viewportLastY = X.xbutton.y;
+
+ break;
+ }
+
+ if (!(nxagentOption(Fullscreen) &&
+ X.xbutton.window == nxagentFullscreenWindow &&
+ X.xbutton.subwindow == None))
+ {
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = ButtonPress;
+ x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button]];
+ x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+ if (nxagentOption(Rootless))
+ {
+ x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+ x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+ }
+ else
+ {
+ x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+ x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+ }
+
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Adding ButtonPress event.\n");
+ }
+ #endif
+
+ mieqEnqueue(&x);
+
+ CriticalOutputPending = 1;
+ }
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+ {
+ X.xbutton.x -= nxagentOption(RootX);
+ X.xbutton.y -= nxagentOption(RootY);
+
+ if (nxagentOption(YRatio) != DONT_SCALE)
+ {
+ X.xbutton.x = (X.xbutton.x << PRECISION) / nxagentOption(YRatio);
+ }
+
+ if (nxagentOption(XRatio) != DONT_SCALE)
+ {
+ X.xbutton.y = (X.xbutton.y << PRECISION) / nxagentOption(YRatio);
+ }
+
+ NXShadowEvent(nxagentDisplay, X);
+ }
+
+ break;
+ }
+ case ButtonRelease:
+ {
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
+ }
+ #endif
+
+ nxagentInputEvent = 1;
+
+ if (viewportCursor)
+ {
+ /*
+ * Leave viewport navigation mode.
+ */
+
+ XUngrabPointer(nxagentDisplay, CurrentTime);
+
+ XFreeCursor(nxagentDisplay, viewportCursor);
+
+ viewportCursor = None;
+ }
+
+ if (minimize != True)
+ {
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = ButtonRelease;
+ x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button]];
+ x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+ if (nxagentOption(Rootless))
+ {
+ x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+ x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+ }
+ else
+ {
+ x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+ x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+ }
+
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Adding ButtonRelease event.\n");
+ }
+ #endif
+
+ mieqEnqueue(&x);
+
+ CriticalOutputPending = 1;
+ }
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+ {
+ X.xbutton.x -= nxagentOption(RootX);
+ X.xbutton.y -= nxagentOption(RootY);
+
+ if (nxagentOption(XRatio) != DONT_SCALE)
+ {
+ X.xbutton.x = (X.xbutton.x << PRECISION) / nxagentOption(XRatio);
+ }
+
+ if (nxagentOption(YRatio) != DONT_SCALE)
+ {
+ X.xbutton.y = (X.xbutton.y << PRECISION) / nxagentOption(YRatio);
+ }
+
+ NXShadowEvent(nxagentDisplay, X);
+ }
+
+ break;
+ }
+ case MotionNotify:
+ {
+ ScreenPtr pScreen = nxagentScreen(X.xmotion.window);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new MotionNotify event.\n");
+ #endif
+
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Handling motion notify window [%ld] root [%ld] child [%ld].\n",
+ X.xmotion.window, X.xmotion.root, X.xmotion.subwindow);
+
+ fprintf(stderr, "nxagentDispatchEvents: Pointer at [%d][%d] relative root [%d][%d].\n",
+ X.xmotion.x, X.xmotion.y, X.xmotion.x_root, X.xmotion.y_root);
+ }
+ #endif
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = MotionNotify;
+
+ if (nxagentOption(Rootless))
+ {
+ WindowPtr pWin = nxagentWindowPtr(X.xmotion.window);
+
+ if (pWin)
+ {
+ nxagentLastEnteredWindow = pWin;
+ }
+
+ if (nxagentPulldownDialogPid == 0 && nxagentLastEnteredTopLevelWindow &&
+ (X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
+ {
+ if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 &&
+ nxagentLastEnteredTopLevelWindow -> parent == screenInfo.screens[0]->root &&
+ nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
+ X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
+ (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
+ X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
+ (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
+ nxagentOption(Menu) == 1)
+ {
+ nxagentPulldownDialog(nxagentLastEnteredTopLevelWindow -> drawable.id);
+ }
+ }
+
+ x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+ x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+ }
+ else
+ {
+ x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+ x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+ }
+
+ x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+ if (viewportCursor == None &&
+ !(nxagentOption(Fullscreen) &&
+ X.xmotion.window == nxagentDefaultWindows[pScreen -> myNum]
+ && X.xmotion.subwindow == None))
+ {
+ #ifdef NX_DEBUG_INPUT
+ if (nxagentDebugInput == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n",
+ x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
+ }
+ #endif
+
+ mieqEnqueue(&x);
+ }
+
+ /*
+ * This test is more complicated and probably not necessary, compared
+ * to a simple check on viewportCursor.
+ *
+ * if (!nxagentOption(Fullscreen) &&
+ * (X.xmotion.state & (ControlMask | Mod1Mask | Button1Mask)) ==
+ * (ControlMask | Mod1Mask | Button1Mask))
+ */
+
+ if (viewportCursor)
+ {
+ /*
+ * Pointer is in viewport navigation mode.
+ */
+
+ nxagentMoveViewport(pScreen, viewportLastX - X.xmotion.x, viewportLastY - X.xmotion.y);
+
+ viewportLastX = X.xmotion.x;
+ viewportLastY = X.xmotion.y;
+ }
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) && !viewportCursor)
+ {
+ X.xmotion.x -= nxagentOption(RootX);
+ X.xmotion.y -= nxagentOption(RootY);
+
+ if (nxagentOption(XRatio) != DONT_SCALE)
+ {
+ X.xmotion.x = (X.xmotion.x << PRECISION) / nxagentOption(XRatio);
+ }
+
+ if (nxagentOption(YRatio) != DONT_SCALE)
+ {
+ X.xmotion.y = (X.xmotion.y << PRECISION) / nxagentOption(YRatio);
+ }
+
+ NXShadowEvent(nxagentDisplay, X);
+ }
+
+ if (nxagentOption(Shadow) == 0)
+ {
+ nxagentInputEvent = 1;
+ }
+
+ break;
+ }
+ case FocusIn:
+ {
+ WindowPtr pWin;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new FocusIn event.\n");
+ #endif
+
+ /*
+ * Here we change the focus state in the agent.
+ * It looks like this is needed only for root-
+ * less mode at the present moment.
+ */
+
+ if (nxagentOption(Rootless) &&
+ (pWin = nxagentWindowPtr(X.xfocus.window)))
+ {
+ SetInputFocus(serverClient, inputInfo.keyboard, pWin -> drawable.id,
+ RevertToPointerRoot, GetTimeInMillis(), False);
+ }
+
+ if (X.xfocus.detail != NotifyInferior)
+ {
+ pScreen = nxagentScreen(X.xfocus.window);
+
+ if (pScreen)
+ {
+ nxagentDirectInstallColormaps(pScreen);
+ }
+ }
+
+ break;
+ }
+ case FocusOut:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new FocusOut event.\n");
+ #endif
+
+ if (X.xfocus.detail != NotifyInferior)
+ {
+ pScreen = nxagentScreen(X.xfocus.window);
+
+ if (pScreen)
+ {
+ nxagentDirectUninstallColormaps(pScreen);
+ }
+ }
+
+ #ifdef NXAGENT_FIXKEYS
+
+ {
+ /*
+ * Force the keys all up when focus is lost.
+ */
+
+ int i, k;
+ int mask = 1;
+ CARD8 val;
+
+ XEvent xM;
+ memset(&xM, 0, sizeof(XEvent));
+
+ for (i = 0; i < DOWN_LENGTH; i++) /* input.h */
+ {
+ val = inputInfo.keyboard->key->down[i];
+
+ if (val != 0)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ if (val & (mask << k))
+ {
+ #ifdef NXAGENT_FIXKEYS_DEBUG
+ fprintf(stderr, "sending KeyRelease event for keycode: %x\n",
+ i * 8 + k);
+ #endif
+
+ if (!nxagentOption(Rootless) ||
+ inputInfo.keyboard->key->modifierMap[i * 8 + k])
+ {
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = KeyRelease;
+ x.u.u.detail = i * 8 + k;
+ x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+ if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+ {
+ xM.type = KeyRelease;
+ xM.xkey.display = nxagentDisplay;
+ xM.xkey.type = KeyRelease;
+ xM.xkey.keycode = i * 8 + k;
+ xM.xkey.state = inputInfo.keyboard->key->state;
+ xM.xkey.time = GetTimeInMillis();
+ NXShadowEvent(nxagentDisplay, xM);
+ }
+
+ mieqEnqueue(&x);
+ }
+ }
+ }
+ }
+ }
+
+ nxagentKeyDown = 0;
+ }
+
+ #endif /* NXAGENT_FIXKEYS */
+
+ break;
+ }
+ case KeymapNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeymapNotify event.\n");
+ #endif
+
+ break;
+ }
+ case EnterNotify:
+ {
+ WindowPtr pWin;
+
+ WindowPtr pTLWin = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new EnterNotify event.\n");
+ #endif
+
+ if (nxagentOption(Rootless))
+ {
+ pWin = nxagentWindowPtr(X.xcrossing.window);
+
+ if (pWin != NULL)
+ {
+ for (pTLWin = pWin;
+ pTLWin -> parent != pTLWin -> drawable.pScreen -> root;
+ pTLWin = pTLWin -> parent);
+ }
+
+ if (pTLWin)
+ {
+ nxagentLastEnteredTopLevelWindow = pTLWin;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: nxagentLastEnteredTopLevelWindow [%p].\n",
+ nxagentLastEnteredTopLevelWindow);
+ #endif
+ }
+
+ if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+ (pWin = nxagentWindowPtr(X.xcrossing.window)) &&
+ nxagentWindowTopLevel(pWin) && !pWin -> overrideRedirect &&
+ (pWin -> drawable.x != X.xcrossing.x_root - X.xcrossing.x - pWin -> borderWidth ||
+ pWin -> drawable.y != X.xcrossing.y_root - X.xcrossing.y - pWin -> borderWidth))
+ {
+ /*
+ * This code is useful for finding the window
+ * position. It should be re-implemented by
+ * following the ICCCM 4.1.5 recommendations.
+ */
+
+ XID values[4];
+ register XID *value = values;
+ Mask mask = 0;
+ ClientPtr pClient = wClient(pWin);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: pWin -> drawable.x [%d] pWin -> drawable.y [%d].\n",
+ pWin -> drawable.x, pWin -> drawable.y);
+ #endif
+
+ *value++ = (XID) (X.xcrossing.x_root - X.xcrossing.x - pWin -> borderWidth);
+ *value++ = (XID) (X.xcrossing.y_root - X.xcrossing.y - pWin -> borderWidth);
+
+ /*
+ * nxagentWindowPriv(pWin)->x = (X.xcrossing.x_root - X.xcrossing.x);
+ * nxagentWindowPriv(pWin)->y = (X.xcrossing.y_root - X.xcrossing.y);
+ */
+
+ mask = CWX | CWY;
+
+ nxagentScreenTrap = 1;
+
+ ConfigureWindow(pWin, mask, (XID *) values, pClient);
+
+ nxagentScreenTrap = 0;
+ }
+
+ if (nxagentOption(Fullscreen) == 1 &&
+ X.xcrossing.window == nxagentFullscreenWindow &&
+ X.xcrossing.detail != NotifyInferior)
+ {
+ nxagentGrabPointerAndKeyboard(&X);
+ }
+
+ if (X.xcrossing.detail != NotifyInferior)
+ {
+ pScreen = nxagentScreen(X.xcrossing.window);
+
+ if (pScreen)
+ {
+ NewCurrentScreen(pScreen, X.xcrossing.x, X.xcrossing.y);
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = MotionNotify;
+
+ if (nxagentOption(Rootless))
+ {
+ nxagentLastEnteredWindow = nxagentWindowPtr(X.xcrossing.window);
+ x.u.keyButtonPointer.rootX = X.xcrossing.x_root;
+ x.u.keyButtonPointer.rootY = X.xcrossing.y_root;
+ }
+ else
+ {
+ x.u.keyButtonPointer.rootX = X.xcrossing.x - nxagentOption(RootX);
+ x.u.keyButtonPointer.rootY = X.xcrossing.y - nxagentOption(RootY);
+ }
+
+ x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+ mieqEnqueue(&x);
+
+ nxagentDirectInstallColormaps(pScreen);
+ }
+ }
+
+ nxagentInputEvent = 1;
+
+ break;
+ }
+ case LeaveNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new LeaveNotify event.\n");
+ #endif
+
+ if (nxagentOption(Rootless) && X.xcrossing.mode == NotifyNormal &&
+ X.xcrossing.detail != NotifyInferior)
+ {
+ nxagentLastEnteredWindow = NULL;
+ }
+
+ if (X.xcrossing.window == nxagentDefaultWindows[0] &&
+ X.xcrossing.detail != NotifyInferior &&
+ X.xcrossing.mode == NotifyNormal)
+ {
+ nxagentUngrabPointerAndKeyboard(&X);
+ }
+
+ if (X.xcrossing.detail != NotifyInferior)
+ {
+ pScreen = nxagentScreen(X.xcrossing.window);
+
+ if (pScreen)
+ {
+ nxagentDirectUninstallColormaps(pScreen);
+ }
+ }
+
+ nxagentInputEvent = 1;
+
+ break;
+ }
+ case DestroyNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new DestroyNotify event.\n");
+ #endif
+
+ if (nxagentParentWindow != (Window) 0 &&
+ X.xdestroywindow.window == nxagentParentWindow)
+ {
+ fprintf(stderr, "Warning: Unhandled destroy notify event received in agent.\n");
+ }
+
+ break;
+ }
+ case ClientMessage:
+ {
+ enum HandleEventResult result;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new ClientMessage event.\n");
+ #endif
+
+ nxagentHandleClientMessageEvent(&X, &result);
+
+ if (result == doCloseSession)
+ {
+ closeSession = TRUE;
+ }
+
+ break;
+ }
+ case VisibilityNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new VisibilityNotify event.\n");
+ #endif
+
+ if (X.xvisibility.window != nxagentDefaultWindows[0])
+ {
+ Window window = X.xvisibility.window;
+
+ WindowPtr pWin = nxagentWindowPtr(window);
+
+ if (pWin && nxagentWindowPriv(pWin))
+ {
+ if (nxagentWindowPriv(pWin) -> visibilityState != X.xvisibility.state)
+ {
+ int value = X.xvisibility.state;
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ TraverseTree(pWin, nxagentChangeVisibilityPrivate, &value);
+ }
+ else
+ {
+ nxagentChangeVisibilityPrivate(pWin, &value);
+ }
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Suppressing visibility notify on window [%lx].\n",
+ X.xvisibility.window);
+ #endif
+
+ break;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Visibility notify state is [%d] with previous [%d].\n",
+ X.xvisibility.state, nxagentVisibility);
+ #endif
+
+ nxagentVisibility = X.xvisibility.state;
+
+ break;
+ }
+ case Expose:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new Expose event.\n");
+
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! Received Expose event "
+ "for drawable [%lx] geometry [%d, %d, %d, %d] count [%d].\n",
+ X.xexpose.window, X.xexpose.x, X.xexpose.y, X.xexpose.width,
+ X.xexpose.height, X.xexpose.count);
+ #endif
+
+ nxagentHandleExposeEvent(&X);
+
+ break;
+ }
+ case GraphicsExpose:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new GraphicsExpose event.\n");
+
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! Received GraphicsExpose event "
+ "for drawable [%lx] geometry [%d, %d, %d, %d] count [%d].\n",
+ X.xgraphicsexpose.drawable, X.xgraphicsexpose.x, X.xgraphicsexpose.y,
+ X.xgraphicsexpose.width, X.xgraphicsexpose.height,
+ X.xgraphicsexpose.count);
+ #endif
+
+ nxagentHandleGraphicsExposeEvent(&X);
+
+ break;
+ }
+ case NoExpose:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new NoExpose event.\n");
+
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! Received NoExpose event for "
+ "drawable [%lx].\n", X.xnoexpose.drawable);
+ #endif
+
+ break;
+ }
+ case CirculateNotify:
+ {
+ /*
+ * WindowPtr pWin;
+ * WindowPtr pSib;
+ * ClientPtr pClient;
+
+ * XID values[2];
+ * register XID *value = values;
+ * Mask mask = 0;
+ */
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new CirculateNotify event.\n");
+ #endif
+
+ /*
+ * FIXME: Do we need this?
+ *
+ * pWin = nxagentWindowPtr(X.xcirculate.window);
+ *
+ * if (!pWin)
+ * {
+ * pWin = nxagentRootlessTopLevelWindow(X.xcirculate.window);
+ * }
+ *
+ * if (!pWin)
+ * {
+ * break;
+ * }
+ *
+ * XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ * &root_return, &parent_return, &children_return, &nchildren_return);
+ *
+ * nxagentRootlessRestack(children_return, nchildren_return);
+ */
+
+ break;
+ }
+ case ConfigureNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new ConfigureNotify event.\n");
+ #endif
+
+ if (nxagentConfiguredSynchroWindow == X.xconfigure.window)
+ {
+ if (nxagentExposeQueue.exposures[nxagentExposeQueue.start].serial != X.xconfigure.x)
+ {
+ #ifdef WARNING
+ if (nxagentVerbose == 1)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: Requested ConfigureNotify changes didn't take place.\n");
+ }
+ #endif
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Received ConfigureNotify and going to call "
+ "nxagentSynchronizeExpose.\n");
+ #endif
+
+ nxagentSynchronizeExpose();
+
+ break;
+ }
+
+ nxagentHandleConfigureNotify(&X);
+
+ break;
+ }
+ case GravityNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new GravityNotify event.\n");
+ #endif
+
+ break;
+ }
+ case ReparentNotify:
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new ReparentNotify event.\n");
+ #endif
+
+ nxagentHandleReparentNotify(&X);
+
+ break;
+ }
+ case UnmapNotify:
+ {
+ WindowPtr pWin;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new UnmapNotify event.\n");
+ #endif
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ if ((pWin = nxagentRootlessTopLevelWindow(X.xunmap.window)) != NULL ||
+ ((pWin = nxagentWindowPtr(X.xunmap.window)) != NULL &&
+ nxagentWindowTopLevel(pWin) == 1))
+ {
+ nxagentScreenTrap = 1;
+
+ UnmapWindow(pWin, False);
+
+ nxagentScreenTrap = 0;
+ }
+ }
+
+ if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
+ nxagentOption(Nested) == 0 &&
+ X.xmap.window != nxagentIconWindow)
+ {
+ nxagentVisibility = VisibilityFullyObscured;
+ }
+
+ break;
+ }
+ case MapNotify:
+ {
+ WindowPtr pWin;
+ ClientPtr pClient;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Going to handle new MapNotify event.\n");
+ #endif
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ Bool value = 1;
+
+ if ((pWin = nxagentRootlessTopLevelWindow(X.xmap.window)) != NULL ||
+ ((pWin = nxagentWindowPtr(X.xmap.window)) != NULL &&
+ nxagentWindowTopLevel(pWin) == 1))
+ {
+ pClient = wClient(pWin);
+
+ nxagentScreenTrap = 1;
+
+ MapWindow(pWin, pClient);
+
+ nxagentScreenTrap = 0;
+ }
+
+ if (pWin != NULL)
+ {
+ TraverseTree(pWin, nxagentChangeMapPrivate, &value);
+ }
+ }
+
+ if (nxagentOption(AllScreens) == 1)
+ {
+ if (X.xmap.window == nxagentIconWindow)
+ {
+ pScreen = nxagentScreen(X.xmap.window);
+ nxagentMaximizeToFullScreen(pScreen);
+ }
+ }
+
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ nxagentVisibility = VisibilityUnobscured;
+ nxagentVisibilityStop = False;
+ nxagentVisibilityTimeout = GetTimeInMillis() + 2000;
+ }
+
+ break;
+ }
+ case MappingNotify:
+ {
+ XMappingEvent *mappingEvent = (XMappingEvent *) &X;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! Going to handle new MappingNotify event.\n");
+ #endif
+
+ if (mappingEvent -> request == MappingPointer)
+ {
+ nxagentInitPointerMap();
+ }
+
+ break;
+ }
+ default:
+ {
+ /*
+ * Let's check if this is a XKB
+ * state modification event.
+ */
+
+ if (nxagentHandleKeyboardEvent(&X) == 0 && nxagentHandleXFixesSelectionNotify(&X) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! Unhandled event code [%d].\n",
+ X.type);
+ #endif
+ }
+
+ break;
+ }
+
+ } /* End of switch (X.type) */
+
+ if (X.xany.serial < lastEventSerial)
+ {
+ /*
+ * Start over.
+ */
+
+ nxagentDeleteStaticResizedWindow(0);
+ }
+ else
+ {
+ nxagentDeleteStaticResizedWindow(X.xany.serial - 1);
+ }
+
+ lastEventSerial = X.xany.serial;
+
+ } /* End of while (...) */
+
+ /*
+ * Send the exposed regions to the clients.
+ */
+
+ nxagentForwardRemoteExpose();
+
+ /*
+ * Handle the agent window's changes.
+ */
+
+ if (closeSession)
+ {
+ if (nxagentOption(Persistent))
+ {
+ if (nxagentNoDialogIsRunning)
+ {
+ nxagentLaunchDialog(DIALOG_SUSPEND_SESSION);
+ }
+ }
+ else
+ {
+ if (nxagentNoDialogIsRunning)
+ {
+ nxagentLaunchDialog(DIALOG_KILL_SESSION);
+ }
+ }
+ }
+
+ if (minimize)
+ {
+ nxagentWMDetect();
+
+ if (nxagentWMIsRunning)
+ {
+ if (nxagentOption(AllScreens))
+ {
+ nxagentMinimizeFromFullScreen(pScreen);
+ }
+ else
+ {
+ XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
+ DefaultScreen(nxagentDisplay));
+ }
+ }
+ }
+
+ if (switchFullscreen)
+ {
+ if (nxagentOption(AllScreens) == 1 && nxagentOption(Fullscreen) == 1)
+ {
+ nxagentSwitchAllScreens(pScreen, 0);
+ }
+ else
+ {
+ nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+ }
+ }
+
+ if (switchAllScreens)
+ {
+ if (nxagentOption(AllScreens) == 0 && nxagentOption(Fullscreen) == 1)
+ {
+ nxagentSwitchFullscreen(pScreen, 0);
+ }
+ else
+ {
+ nxagentSwitchAllScreens(pScreen, !nxagentOption(AllScreens));
+ }
+ }
+
+ if (startKbd)
+ {
+ if (xkbdRunning)
+ {
+ #ifdef NXAGENT_XKBD_DEBUG
+ fprintf(stderr, "Events: nxkbd now is NOT running: %d, %d\n",
+ X.xkey.keycode, escapecode);
+ #endif
+
+ xkbdRunning = False;
+
+ kill(pidkbd, 9);
+ }
+ else
+ {
+ char kbddisplay[6];
+ char *kbdargs[6];
+
+ strcpy(kbddisplay,":");
+ strncat(kbddisplay, display, 4);
+
+ kbdargs[0] = "nxkbd";
+ kbdargs[1] = "-geometry";
+ kbdargs[2] = "240x70+0+250";
+ kbdargs[3] = "-display";
+ kbdargs[4] = kbddisplay;
+ kbdargs[5] = NULL;
+
+ switch (pidkbd = fork())
+ {
+ case 0:
+ {
+ execvp(kbdargs[0], kbdargs);
+
+ #ifdef NXAGENT_XKBD_DEBUG
+ fprintf(stderr, "Events: The execvp of nxkbd process failed.\n");
+ #endif
+
+ exit(1);
+
+ break;
+ }
+ case -1:
+ {
+ #ifdef NXAGENT_XKBD_DEBUG
+ fprintf(stderr, "Events: Can't fork to run the nxkbd process.\n");
+ #endif
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ #ifdef NXAGENT_XKBD_DEBUG
+ fprintf(stderr, "Events: The nxkbd process now running with [%d][%d].\n",
+ X.xkey.keycode, escapecode);
+ #endif
+
+ xkbdRunning = True;
+ }
+ }
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End read]\n");
+ #endif
+
+ /*
+ * Let the underlying X server code
+ * process the input events.
+ */
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin events]\n");
+ #endif
+
+ ProcessInputEvents();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Output pending flag is [%d] critical [%d].\n",
+ NewOutputPending, CriticalOutputPending);
+ #endif
+
+ /*
+ * Write the events to our clients. We may
+ * flush only in the case of critical output
+ * but this doesn't seem beneficial.
+ *
+ * if (CriticalOutputPending == 1)
+ * {
+ * FlushAllOutput();
+ * }
+ */
+
+ if (NewOutputPending == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchEvents: Flushed the processed events to clients.\n");
+ #endif
+
+ FlushAllOutput();
+ }
+
+ #ifdef TEST
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ fprintf(stderr, "nxagentDispatchEvents: WARNING! More events need to be dispatched.\n");
+ }
+
+ #endif
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End events]\n");
+ #endif
+}
+
+/*
+ * Functions providing the ad-hoc handling
+ * of the remote X events.
+ */
+
+int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
+{
+ xEvent x;
+
+ if (nxagentXkbState.Initialized == 0)
+ {
+ if (X -> xkey.keycode == nxagentCapsLockKeycode)
+ {
+ nxagentXkbCapsTrap = 1;
+ }
+ else if (X -> xkey.keycode == nxagentNumLockKeycode)
+ {
+ nxagentXkbNumTrap = 1;
+ }
+
+ nxagentInitKeyboardState();
+
+ nxagentXkbCapsTrap = 0;
+ nxagentXkbNumTrap = 0;
+ }
+
+ if (nxagentCheckSpecialKeystroke(&X -> xkey, result))
+ {
+ return 1;
+ }
+
+ if (X -> xkey.keycode == nxagentCapsLockKeycode)
+ {
+ nxagentXkbState.Caps = (~nxagentXkbState.Caps & 1);
+ }
+ else if (X -> xkey.keycode == nxagentNumLockKeycode)
+ {
+ nxagentXkbState.Num = (~nxagentXkbState.Num & 1);
+ }
+
+ nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = KeyPress;
+ x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
+ x.u.keyButtonPointer.time = nxagentLastKeyPressTime;
+
+ nxagentLastServerTime = X -> xkey.time;
+
+ mieqEnqueue(&x);
+
+ CriticalOutputPending = 1;
+
+ return 1;
+}
+
+int nxagentHandlePropertyNotify(XEvent *X)
+{
+ int resource;
+
+ if (nxagentOption(Rootless) && !nxagentNotifyMatchChangeProperty((XPropertyEvent *) X))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandlePropertyNotify: Property %ld on window %lx.\n",
+ X -> xproperty.atom, X -> xproperty.window);
+ #endif
+
+ if (nxagentWindowPtr(X -> xproperty.window) != NULL)
+ {
+ resource = NXGetCollectPropertyResource(nxagentDisplay);
+
+ if (resource == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandlePropertyNotify: WARNING! Asynchronous get property queue is full.\n");
+ #endif
+
+ return 0;
+ }
+
+ NXCollectProperty(nxagentDisplay, resource,
+ X -> xproperty.window, X -> xproperty.atom, 0,
+ MAX_RETRIEVED_PROPERTY_SIZE, False, AnyPropertyType);
+
+ nxagentPropertyRequests[resource].window = X -> xproperty.window;
+ nxagentPropertyRequests[resource].property = X -> xproperty.atom;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentHandlePropertyNotify: Failed to look up remote window property.\n");
+ }
+ #endif
+ }
+
+ return 1;
+}
+
+int nxagentHandleExposeEvent(XEvent *X)
+{
+ WindowPtr pWin = NULL;
+ Window window = None;
+
+ RegionRec sum;
+ RegionRec add;
+ BoxRec box;
+ int index = 0;
+ int overlap = 0;
+
+ StaticResizedWindowStruct *resizedWinPtr = NULL;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleExposeEvent: Checking remote expose events.\n");
+
+ fprintf(stderr, "nxagentHandleExposeEvent: Looking for window id [%ld].\n",
+ X -> xexpose.window);
+ #endif
+
+ window = X -> xexpose.window;
+
+ pWin = nxagentWindowPtr(window);
+
+ if (pWin != NULL)
+ {
+ RegionInit(&sum, (BoxRec *) NULL, 1);
+/*
+FIXME: This can be maybe optimized by consuming the
+ events that do not match the predicate.
+*/
+ do
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleExposeEvent: Adding event for window id [%ld].\n",
+ X -> xexpose.window);
+ #endif
+
+ box.x1 = pWin -> drawable.x + wBorderWidth(pWin) + X -> xexpose.x;
+ box.y1 = pWin -> drawable.y + wBorderWidth(pWin) + X -> xexpose.y;
+
+ resizedWinPtr = nxagentFindStaticResizedWindow(X -> xany.serial);
+
+ while (resizedWinPtr)
+ {
+ if (resizedWinPtr -> pWin == pWin)
+ {
+ box.x1 += resizedWinPtr -> offX;
+ box.y1 += resizedWinPtr -> offY;
+ }
+
+ resizedWinPtr = resizedWinPtr -> prev;
+ }
+
+ box.x2 = box.x1 + X -> xexpose.width;
+ box.y2 = box.y1 + X -> xexpose.height;
+
+ RegionInit(&add, &box, 1);
+
+ RegionAppend(&sum, &add);
+
+ RegionUninit(&add);
+
+ if (X -> xexpose.count == 0)
+ {
+ break;
+ }
+ }
+ while (nxagentCheckEvents(nxagentDisplay, X, nxagentExposurePredicate,
+ (XPointer) &window) == 1);
+
+ RegionValidate(&sum, &overlap);
+
+ RegionIntersect(&sum, &sum,
+ &pWin->drawable.pScreen->root->winSize);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleExposeEvent: Sending events for window id [%ld].\n",
+ X -> xexpose.window);
+ #endif
+
+ /*
+ * If the agent has already sent auto-generated expose,
+ * save received exposes for later processing.
+ */
+
+ index = nxagentLookupByWindow(pWin);
+
+ if (index == -1)
+ {
+ miWindowExposures(pWin, &sum, NullRegion);
+ }
+ else
+ {
+ RegionTranslate(&sum, -pWin -> drawable.x, -pWin -> drawable.y);
+
+ if (nxagentExposeQueue.exposures[index].remoteRegion == NullRegion)
+ {
+ nxagentExposeQueue.exposures[index].remoteRegion = RegionCreate(NULL, 1);
+ }
+
+ RegionUnion(nxagentExposeQueue.exposures[index].remoteRegion,
+ nxagentExposeQueue.exposures[index].remoteRegion, &sum);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleExposeEvent: Added region for window [%ld] to position [%d].\n",
+ nxagentWindow(pWin), index);
+ #endif
+
+ if (X -> xexpose.count == 0)
+ {
+ nxagentExposeQueue.exposures[index].remoteRegionIsCompleted = True;
+ }
+ else
+ {
+ nxagentExposeQueue.exposures[index].remoteRegionIsCompleted = False;
+ }
+ }
+
+ if (nxagentRootTileWindow != NULL)
+ {
+ if (nxagentWindowPriv(nxagentRootTileWindow) -> window == nxagentWindowPriv(pWin) -> window &&
+ nxagentSplashCount == 1 && X -> xexpose.count == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleExposeEvent: Clearing root tile window id [%ld].\n",
+ nxagentWindowPriv(nxagentRootTileWindow) -> window);
+ #endif
+
+ XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow) -> window);
+ }
+ }
+
+ RegionUninit(&sum);
+ }
+
+ return 1;
+}
+
+int nxagentHandleGraphicsExposeEvent(XEvent *X)
+{
+ /*
+ * Send an expose event to client, instead of graphics
+ * expose. If target drawable is a backing pixmap, send
+ * expose event for the saved window, else do nothing.
+ */
+
+ RegionPtr exposeRegion;
+ BoxRec rect;
+ WindowPtr pWin;
+ StoringPixmapPtr pStoringPixmapRec = NULL;
+ miBSWindowPtr pBSwindow = NULL;
+ int drawableType;
+
+ pWin = nxagentWindowPtr(X -> xgraphicsexpose.drawable);
+
+ if (pWin != NULL)
+ {
+ drawableType = DRAWABLE_WINDOW;
+ }
+ else
+ {
+ drawableType = DRAWABLE_PIXMAP;
+ }
+
+ if (drawableType == DRAWABLE_PIXMAP)
+ {
+ pStoringPixmapRec = nxagentFindItemBSPixmapList(X -> xgraphicsexpose.drawable);
+
+ if (pStoringPixmapRec == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleGraphicsExposeEvent: WARNING! Storing pixmap not found.\n");
+ #endif
+
+ return 1;
+ }
+
+ pBSwindow = (miBSWindowPtr) pStoringPixmapRec -> pSavedWindow -> backStorage;
+
+ if (pBSwindow == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleGraphicsExposeEvent: WARNING! Back storage not found.\n");
+ #endif
+
+ return 1;
+ }
+
+ pWin = pStoringPixmapRec -> pSavedWindow;
+ }
+
+ /*
+ * Rectangle affected by GraphicsExpose
+ * event.
+ */
+
+ rect.x1 = X -> xgraphicsexpose.x;
+ rect.y1 = X -> xgraphicsexpose.y;
+ rect.x2 = rect.x1 + X -> xgraphicsexpose.width;
+ rect.y2 = rect.y1 + X -> xgraphicsexpose.height;
+
+ exposeRegion = RegionCreate(&rect, 0);
+
+ if (drawableType == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleGraphicsExposeEvent: Handling GraphicsExpose event on pixmap with id"
+ " [%lu].\n", X -> xgraphicsexpose.drawable);
+ #endif
+
+ /*
+ * The exposeRegion coordinates are relative
+ * to the pixmap to which GraphicsExpose
+ * event refers. But the BS coordinates of
+ * the savedRegion are relative to the
+ * window.
+ */
+
+ RegionTranslate(exposeRegion, pStoringPixmapRec -> backingStoreX,
+ pStoringPixmapRec -> backingStoreY);
+
+ /*
+ * We remove from SavedRegion the part
+ * affected by the GraphicsExpose event.
+ */
+
+ RegionSubtract(&(pBSwindow -> SavedRegion), &(pBSwindow -> SavedRegion),
+ exposeRegion);
+ }
+
+ /*
+ * Store the exposeRegion in order to send
+ * the expose event later. The coordinates
+ * must be relative to the screen.
+ */
+
+ RegionTranslate(exposeRegion, pWin -> drawable.x, pWin -> drawable.y);
+
+ RegionUnion(nxagentRemoteExposeRegion, nxagentRemoteExposeRegion, exposeRegion);
+
+ RegionDestroy(exposeRegion);
+
+ return 1;
+}
+
+int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
+{
+ WindowPtr pWin;
+
+ *result = doNothing;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleClientMessageEvent: ClientMessage event window [%ld] with "
+ "type [%ld] format [%d].\n", X -> xclient.window, X -> xclient.message_type,
+ X -> xclient.format);
+ #endif
+
+ /*
+ * If window is 0, message_type is 0 and format is
+ * 32 then we assume event is coming from proxy.
+ */
+
+ if (X -> xclient.window == 0 &&
+ X -> xclient.message_type == 0 &&
+ X -> xclient.format == 32)
+ {
+ nxagentHandleProxyEvent(X);
+
+ return 1;
+ }
+
+ if (nxagentOption(Rootless))
+ {
+ Atom message_type = nxagentRemoteToLocalAtom(X -> xclient.message_type);
+
+ if (!ValidAtom(message_type))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleClientMessageEvent: WARNING Invalid type in client message.\n");
+ #endif
+
+ return 0;
+ }
+
+ pWin = nxagentWindowPtr(X -> xclient.window);
+
+ if (pWin == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "WARNING: Invalid window in ClientMessage.\n");
+ #endif
+
+ return 0;
+ }
+
+ if (message_type == MakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), False))
+ {
+ #ifdef TEST
+ char *message_data;
+ #endif
+
+ xEvent x;
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = ClientMessage;
+ x.u.u.detail = X -> xclient.format;
+
+ x.u.clientMessage.window = pWin -> drawable.id;
+ x.u.clientMessage.u.l.type = message_type;
+ x.u.clientMessage.u.l.longs0 = nxagentRemoteToLocalAtom(X -> xclient.data.l[0]);
+ x.u.clientMessage.u.l.longs1 = GetTimeInMillis();
+
+ if (!ValidAtom(x.u.clientMessage.u.l.longs0))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleClientMessageEvent: WARNING Invalid value in client message "
+ "of type WM_PROTOCOLS.\n");
+ #endif
+
+ return 0;
+ }
+ #ifdef TEST
+ else
+ {
+ message_data = validateString(NameForAtom(x.u.clientMessage.u.l.longs0));
+ }
+
+ fprintf(stderr, "nxagentHandleClientMessageEvent: Sent client message of type WM_PROTOCOLS "
+ "and value [%s].\n", message_data);
+ #endif
+
+ TryClientEvents(wClient(pWin), &x, 1, 1, 1, 0);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleClientMessageEvent: Ignored message type %ld [%s].\n",
+ (long int) message_type, validateString(NameForAtom(message_type)));
+ #endif
+
+ return 0;
+ }
+
+ return 1;
+ }
+
+ if (X -> xclient.message_type == nxagentAtoms[1]) /* WM_PROTOCOLS */
+ {
+ Atom deleteWMatom, wmAtom;
+
+ wmAtom = (Atom) X -> xclient.data.l[0];
+
+ deleteWMatom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+ if (wmAtom == deleteWMatom)
+ {
+ if (nxagentOnce && (nxagentClients == 0))
+ {
+ GiveUp(0);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
+ #endif
+
+ if (X -> xclient.window == nxagentIconWindow)
+ {
+ XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+ DefaultScreen(nxagentDisplay));
+
+ }
+
+ if (X -> xclient.window == (nxagentOption(Fullscreen) ?
+ nxagentIconWindow : nxagentDefaultWindows[0]) ||
+ nxagentWMIsRunning == 0)
+ {
+ *result = doCloseSession;
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+int nxagentHandleKeyboardEvent(XEvent *X)
+{
+ XkbEvent *xkbev = (XkbEvent *) X;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Handling event with caps [%d] num [%d] locked [%d].\n",
+ nxagentXkbState.Caps, nxagentXkbState.Num, nxagentXkbState.Locked);
+ #endif
+
+ if (xkbev -> type == nxagentXkbInfo.EventBase + XkbEventCode &&
+ xkbev -> any.xkb_type == XkbStateNotify)
+ {
+ nxagentXkbState.Locked = xkbev -> state.locked_mods;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Updated XKB locked modifier bits to [%x].\n",
+ nxagentXkbState.Locked);
+ #endif
+
+ nxagentXkbState.Initialized = 1;
+
+ if (nxagentXkbState.Caps == 0 &&
+ (nxagentXkbState.Locked & CAPSFLAG_IN_EVENT))
+ {
+ nxagentXkbState.Caps = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to engage capslock.\n");
+ #endif
+
+ if (!nxagentXkbCapsTrap)
+ {
+ nxagentSendFakeKey(66);
+ }
+ }
+
+ if (nxagentXkbState.Caps == 1 &&
+ !(nxagentXkbState.Locked & CAPSFLAG_IN_EVENT))
+ {
+ nxagentXkbState.Caps = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to release capslock.\n");
+ #endif
+
+ nxagentSendFakeKey(66);
+ }
+
+ if (nxagentXkbState.Caps == 0 &&
+ !(nxagentXkbState.Locked & CAPSFLAG_IN_EVENT) &&
+ nxagentXkbCapsTrap)
+ {
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to release capslock.\n");
+ #endif
+
+ nxagentSendFakeKey(66);
+ }
+
+ if (nxagentXkbState.Num == 0 &&
+ (nxagentXkbState.Locked & NUMFLAG_IN_EVENT))
+ {
+ nxagentXkbState.Num = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to engage numlock.\n");
+ #endif
+
+ if (!nxagentXkbNumTrap)
+ {
+ nxagentSendFakeKey(77);
+ }
+ }
+
+ if (nxagentXkbState.Num == 1 &&
+ !(nxagentXkbState.Locked & NUMFLAG_IN_EVENT))
+ {
+ nxagentXkbState.Num = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to release numlock.\n");
+ #endif
+
+ nxagentSendFakeKey(77);
+ }
+
+ if (nxagentXkbState.Num == 0 &&
+ !(nxagentXkbState.Locked & NUMFLAG_IN_EVENT) &&
+ nxagentXkbNumTrap)
+ {
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to release numlock.\n");
+ #endif
+
+ nxagentSendFakeKey(77);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int nxagentHandleXFixesSelectionNotify(XEvent *X)
+{
+ int i;
+ Atom local;
+
+ XFixesSelectionEvent *xfixesEvent = (XFixesSelectionEvent *) X;
+
+ if (nxagentXFixesInfo.Initialized == 0 ||
+ xfixesEvent -> type != (nxagentXFixesInfo.EventBase + XFixesSelectionNotify))
+ return 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Handling event.\n");
+ #endif
+
+ local = nxagentRemoteToLocalAtom(xfixesEvent -> xfixesselection.selection);
+
+ if (SelectionCallback)
+ {
+ i = 0;
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != local)
+ i++;
+
+ if (i < NumCurrentSelections)
+ {
+ SelectionInfoRec info;
+
+ if (CurrentSelections[i].client != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Do nothing.\n");
+ #endif
+
+ return 1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Calling callbacks for %d [%s] selection.\n",
+ CurrentSelections[i].selection, NameForAtom(CurrentSelections[i].selection));
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Subtype ");
+
+ switch (xfixesEvent -> xfixesselection.subtype)
+ {
+ case SelectionSetOwner:
+ fprintf(stderr, "SelectionSetOwner.\n");
+ break;
+ case SelectionWindowDestroy:
+ fprintf(stderr, "SelectionWindowDestroy.\n");
+ break;
+ case SelectionClientClose:
+ fprintf(stderr, "SelectionClientClose.\n");
+ break;
+ default:
+ fprintf(stderr, ".\n");
+ break;
+ }
+ #endif
+
+ info.selection = &CurrentSelections[i];
+ info.kind = xfixesEvent->xfixesselection.subtype;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+ }
+ return 1;
+}
+
+int nxagentHandleProxyEvent(XEvent *X)
+{
+ switch (X -> xclient.data.l[0])
+ {
+ case NXNoSplitNotify:
+ case NXStartSplitNotify:
+ {
+ /*
+ * We should never receive such events
+ * in the event loop, as they should
+ * be caught at the time the split is
+ * initiated.
+ */
+
+ #ifdef PANIC
+
+ int client = (int) X -> xclient.data.l[1];
+
+ if (X -> xclient.data.l[0] == NXNoSplitNotify)
+ {
+ fprintf(stderr, "nxagentHandleProxyEvent: PANIC! NXNoSplitNotify received "
+ "with client [%d].\n", client);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentHandleProxyEvent: PANIC! NXStartSplitNotify received "
+ "with client [%d].\n", client);
+ }
+
+ #endif
+
+ return 1;
+ }
+ case NXCommitSplitNotify:
+ {
+ /*
+ * We need to commit an image. Image can be the
+ * result of a PutSubImage() generated by Xlib,
+ * so there can be more than a single image to
+ * commit, even if only one PutImage was perfor-
+ * med by the agent.
+ */
+
+ int client = (int) X -> xclient.data.l[1];
+ int request = (int) X -> xclient.data.l[2];
+ int position = (int) X -> xclient.data.l[3];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleProxyEvent: NXCommitSplitNotify received with "
+ "client [%d] request [%d] and position [%d].\n",
+ client, request, position);
+ #endif
+
+ nxagentHandleCommitSplitEvent(client, request, position);
+
+ return 1;
+ }
+ case NXEndSplitNotify:
+ {
+ /*
+ * All images for the split were transferred and
+ * we need to restart the client.
+ */
+
+ int client = (int) X -> xclient.data.l[1];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleProxyEvent: NXEndSplitNotify received with "
+ "client [%d].\n", client);
+ #endif
+
+ nxagentHandleEndSplitEvent(client);
+
+ return 1;
+ }
+ case NXEmptySplitNotify:
+ {
+ /*
+ * All splits have been completed and none remain.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleProxyEvent: NXEmptySplitNotify received.\n");
+ #endif
+
+ nxagentHandleEmptySplitEvent();
+
+ return 1;
+ }
+ case NXCollectPropertyNotify:
+ {
+ #ifdef TEST
+ int resource = (int) X -> xclient.data.l[1];
+
+ fprintf(stderr, "nxagentHandleProxyEvent: NXCollectPropertyNotify received with resource [%d].\n",
+ resource);
+ #endif
+
+ nxagentHandleCollectPropertyEvent(X);
+
+ return 1;
+ }
+ case NXCollectGrabPointerNotify:
+ {
+ int resource = (int) X -> xclient.data.l[1];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleProxyEvent: NXCollectGrabPointerNotify received with resource [%d].\n",
+ resource);
+ #endif
+
+ nxagentHandleCollectGrabPointerEvent(resource);
+
+ return 1;
+ }
+ case NXCollectInputFocusNotify:
+ {
+ int resource = (int) X -> xclient.data.l[1];
+
+ /*
+ * This is not used at the present moment.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleProxyEvent: NXCollectInputFocusNotify received with resource [%d].\n",
+ resource);
+ #endif
+
+ nxagentHandleCollectInputFocusEvent(resource);
+
+ return 1;
+ }
+ default:
+ {
+ /*
+ * Not a recognized ClientMessage event.
+ */
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleProxyEvent: WARNING! Not a recognized ClientMessage proxy event [%d].\n",
+ (int) X -> xclient.data.l[0]);
+ #endif
+
+ return 0;
+ }
+ }
+}
+
+/*
+ * In this function it is assumed that we never
+ * get a configure with both stacking order and
+ * geometry changed, this way we can ignore
+ * stacking changes if the geometry has changed.
+ */
+
+int nxagentCheckWindowConfiguration(XConfigureEvent* X)
+{
+ static int x = 0;
+ static int y = 0;
+ static int width = 0;
+ static int height = 0;
+ static Window win = None;
+ Bool geometryChanged = False;
+
+ XlibWindow root_return = 0;
+ XlibWindow parent_return = 0;
+ XlibWindow *children_return = NULL;
+ unsigned int nchildren_return = 0;
+ Status result;
+
+ if (win == X -> window)
+ {
+ if (x != X -> x ||
+ y != X -> y ||
+ width != X -> width ||
+ height != X -> height)
+ {
+ geometryChanged = True;
+ }
+ }
+
+ win = X -> window;
+
+ x = X -> x;
+ y = X -> y;
+ width = X -> width;
+ height = X -> height;
+
+ if (geometryChanged)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckWindowConfiguration: Configure frame. No restack.\n");
+ #endif
+
+ return 1;
+ }
+
+ #ifdef TEST
+ {
+ WindowPtr pSib;
+
+ fprintf(stderr, "nxagentCheckWindowConfiguration: Before restacking top level window [%p]\n",
+ (void *) nxagentWindowPtr(X -> window));
+
+ for (pSib = screenInfo.screens[0]->root -> firstChild; pSib; pSib = pSib -> nextSib)
+ {
+ fprintf(stderr, "nxagentCheckWindowConfiguration: Top level window: [%p].\n",
+ (void *) pSib);
+ }
+ }
+ #endif
+
+ result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ &root_return, &parent_return, &children_return, &nchildren_return);
+
+ if (result)
+ {
+ nxagentRootlessRestack(children_return, nchildren_return);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckWindowConfiguration: WARNING! Failed QueryTree request.\n");
+ #endif
+ }
+
+ if (result && nchildren_return)
+ {
+ XFree(children_return);
+ }
+
+ #if 0
+ fprintf(stderr, "nxagentCheckWindowConfiguration: Trees match: %s\n",
+ nxagentRootlessTreesMatch() ? "Yes" : "No");
+ #endif
+
+ return 1;
+}
+
+int nxagentHandleConfigureNotify(XEvent* X)
+{
+ if (nxagentOption(Rootless) == True)
+ {
+ ClientPtr pClient;
+ WindowPtr pWinWindow;
+ WindowPtr pWin;
+ int sendEventAnyway = 0;
+
+ pWinWindow = nxagentWindowPtr(X -> xconfigure.window);
+
+ #ifdef TEST
+ {
+ WindowPtr pWinEvent = nxagentWindowPtr(X -> xconfigure.event);
+
+ fprintf(stderr, "nxagentHandleConfigureNotify: Generating window is [%p][%ld] target [%p][%ld].\n",
+ (void *) pWinEvent, X -> xconfigure.event, (void *) pWinWindow, X -> xconfigure.window);
+ }
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConfigureNotify: New configuration for window [%p][%ld] is [%d][%d][%d][%d] "
+ "send_event [%i].\n", (void *) pWinWindow, X -> xconfigure.window,
+ X -> xconfigure.x, X -> xconfigure.y, X -> xconfigure.width,
+ X -> xconfigure.height, X -> xconfigure.send_event);
+ #endif
+
+ if ((pWin = nxagentRootlessTopLevelWindow(X -> xconfigure.window)) != NULL)
+ {
+ /*
+ * Cheking for new geometry or stacking order changes.
+ */
+
+ nxagentCheckWindowConfiguration((XConfigureEvent*)X);
+
+ return 1;
+ }
+
+ if (nxagentWindowTopLevel(pWinWindow) && !X -> xconfigure.override_redirect)
+ {
+ XID values[5];
+ Mask mask = 0;
+
+ register XID *value = values;
+
+ pClient = wClient(pWinWindow);
+
+ if (X -> xconfigure.send_event || !nxagentWMIsRunning ||
+ X -> xconfigure.override_redirect)
+ {
+ *value++ = (XID)X -> xconfigure.x;
+ *value++ = (XID)X -> xconfigure.y;
+
+ /*
+ * nxagentWindowPriv(pWinWindow)->x = X -> xconfigure.x;
+ * nxagentWindowPriv(pWinWindow)->y = X -> xconfigure.y;
+ */
+
+ mask |= CWX | CWY;
+ }
+
+ *value++ = (XID)X -> xconfigure.width;
+ *value++ = (XID)X -> xconfigure.height;
+ *value++ = (XID)X -> xconfigure.border_width;
+
+ /*
+ * We don't need width and height here.
+ *
+ * nxagentWindowPriv(pWinWindow)->width = X -> xconfigure.width;
+ * nxagentWindowPriv(pWinWindow)->height = X -> xconfigure.height;
+ */
+
+ mask |= CWHeight | CWWidth | CWBorderWidth;
+
+ nxagentScreenTrap = 1;
+
+ ConfigureWindow(pWinWindow, mask, (XID *) values, pClient);
+
+ nxagentScreenTrap = 0;
+
+ nxagentCheckWindowConfiguration((XConfigureEvent*)X);
+
+ /*
+ * This workaround should help with
+ * Java 1.6.0 that seems to ignore
+ * non-synthetic events.
+ */
+
+ if (nxagentOption(ClientOs) == ClientOsWinnt)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConfigureNotify: Apply workaround for NXWin.\n");
+ #endif
+
+ sendEventAnyway = 1;
+ }
+
+ if (sendEventAnyway || X -> xconfigure.send_event)
+ {
+ xEvent x;
+
+ memset(&x, 0, sizeof(xEvent));
+ x.u.u.type = X -> xconfigure.type;
+ x.u.u.type |= 0x80;
+
+ x.u.configureNotify.event = pWinWindow -> drawable.id;
+ x.u.configureNotify.window = pWinWindow -> drawable.id;
+
+ if (pWinWindow -> nextSib)
+ {
+ x.u.configureNotify.aboveSibling = pWinWindow -> nextSib -> drawable.id;
+ }
+ else
+ {
+ x.u.configureNotify.aboveSibling = None;
+ }
+
+ x.u.configureNotify.x = X -> xconfigure.x;
+ x.u.configureNotify.y = X -> xconfigure.y;
+ x.u.configureNotify.width = X -> xconfigure.width;
+ x.u.configureNotify.height = X -> xconfigure.height;
+ x.u.configureNotify.borderWidth = X -> xconfigure.border_width;
+ x.u.configureNotify.override = X -> xconfigure.override_redirect;
+
+ TryClientEvents(pClient, &x, 1, 1, 1, 0);
+ }
+
+ return 1;
+ }
+ }
+ else
+ {
+ /*
+ * Save the position of the agent default window. Don't
+ * save the values if the agent is in fullscreen mode.
+ *
+ * If we use these values to restore the position of a
+ * window after that we have dynamically changed the
+ * fullscreen attribute, depending on the behaviour of
+ * window manager, we could be not able to place the
+ * window exactly in the requested position, so let the
+ * window manager do the job for us.
+ */
+
+ ScreenPtr pScreen = nxagentScreen(X -> xconfigure.window);
+
+ Bool doRandR = False;
+ struct timeval timeout;
+
+ if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
+ {
+ if (nxagentOption(AllScreens) == 0)
+ {
+ if (nxagentOption(DesktopResize) == 1)
+ {
+ if (nxagentOption(Width) != X -> xconfigure.width ||
+ nxagentOption(Height) != X -> xconfigure.height ||
+ nxagentOption(X) != X -> xconfigure.x ||
+ nxagentOption(Y) != X -> xconfigure.y)
+ {
+ Bool newEvents = False;
+
+ doRandR = True;
+
+ NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+ do
+ {
+ newEvents = False;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500 * 1000;
+
+ nxagentWaitEvents(nxagentDisplay, &timeout);
+
+ /*
+ * This should also flush
+ * the NX link for us.
+ */
+
+ XSync(nxagentDisplay, 0);
+
+ while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+ ConfigureNotify, X))
+ {
+ newEvents = True;
+ }
+
+ } while (newEvents);
+ }
+ }
+
+ if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+ {
+ nxagentChangeOption(X, X -> xconfigure.x);
+ nxagentChangeOption(Y, X -> xconfigure.y);
+ }
+
+ if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+ (nxagentOption(Width) != X -> xconfigure.width ||
+ nxagentOption(Height) != X -> xconfigure.height))
+ {
+ nxagentShadowResize = 1;
+ }
+
+ nxagentChangeOption(Width, X -> xconfigure.width);
+ nxagentChangeOption(Height, X -> xconfigure.height);
+
+ nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+ (int) nxagentOption(RootWidth));
+ nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+ (int) nxagentOption(RootHeight));
+
+ nxagentMoveViewport(pScreen, 0, 0);
+
+ /* if in shadowing mode or if neither size nor position have
+ changed we do not need to adjust RandR */
+ /* FIXME: Comment makes no sense */
+ if (nxagentOption(Shadow) == 1 ||
+ (nxagentOption(Width) == nxagentOption(RootWidth) &&
+ nxagentOption(Height) == nxagentOption(RootHeight) &&
+ nxagentOption(X) == nxagentOption(RootX) &&
+ nxagentOption(Y) == nxagentOption(RootY)))
+ {
+ doRandR = False;
+ }
+
+ nxagentChangeOption(Width, X -> xconfigure.width);
+ nxagentChangeOption(Height, X -> xconfigure.height);
+
+ XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+ X -> xconfigure.width, X -> xconfigure.height);
+
+ if (nxagentOption(Fullscreen) == 0)
+ {
+ nxagentMoveViewport(pScreen, 0, 0);
+ }
+ else
+ {
+ nxagentChangeOption(RootX, (nxagentOption(Width) -
+ nxagentOption(RootWidth)) / 2);
+ nxagentChangeOption(RootY, (nxagentOption(Height) -
+ nxagentOption(RootHeight)) / 2);
+ nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
+ nxagentOption(RootWidth));
+ nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
+ nxagentOption(RootHeight));
+
+ nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
+ nxagentOption(RootHeight));
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
+ nxagentOption(RootX), nxagentOption(RootY));
+ }
+
+ if (doRandR)
+ {
+ #ifdef TEST
+ fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+ nxagentOption(Width), nxagentOption(Height));
+ #endif
+
+ nxagentChangeScreenConfig(0, nxagentOption(Width),
+ nxagentOption(Height), 0, 0);
+ }
+ }
+
+ return 1;
+ }
+ else
+ {
+ if ( (X -> xconfigure.window == DefaultRootWindow(nxagentDisplay)) || nxagentFullscreenWindow )
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConfigureNotify: remote root window has changed: %d,%d %dx%d\n", X -> xconfigure.x, X -> xconfigure.y, X -> xconfigure.width, X -> xconfigure.height);
+ #endif
+
+ nxagentChangeOption(RootX, X -> xconfigure.x);
+ nxagentChangeOption(RootY, X -> xconfigure.y);
+ nxagentChangeOption(RootWidth, X -> xconfigure.width);
+ nxagentChangeOption(RootHeight, X -> xconfigure.height);
+
+ nxagentChangeScreenConfig(0, nxagentOption(Width),
+ nxagentOption(Height), 0, 0);
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int nxagentHandleReparentNotify(XEvent* X)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleReparentNotify: Going to handle a new reparent event.\n");
+ #endif
+
+ if (nxagentOption(Rootless))
+ {
+ WindowPtr pWin;
+
+ XlibWindow w;
+ XlibWindow root_return = 0;
+ XlibWindow parent_return = 0;
+ XlibWindow *children_return = NULL;
+ unsigned int nchildren_return = 0;
+ Status result;
+
+ pWin = nxagentWindowPtr(X -> xreparent.window);
+
+ #ifdef TEST
+
+ {
+ WindowPtr pParent = nxagentWindowPtr(X -> xreparent.parent);
+ WindowPtr pEvent = nxagentWindowPtr(X -> xreparent.event);
+
+ fprintf(stderr, "nxagentHandleReparentNotify: event %p[%lx] window %p[%lx] parent %p[%lx] at (%d, %d)\n",
+ (void*)pEvent, X -> xreparent.event, (void*)pWin, X -> xreparent.window,
+ (void*)pParent, X -> xreparent.parent, X -> xreparent.x, X -> xreparent.y);
+ }
+
+ #endif
+
+ if (nxagentWindowTopLevel(pWin))
+ {
+ /*
+ * If the window manager reparents our top level
+ * window, we need to know the new top level
+ * ancestor.
+ */
+
+ w = None;
+ parent_return = X -> xreparent.parent;
+
+ while (parent_return != RootWindow(nxagentDisplay, 0))
+ {
+ w = parent_return;
+ result = XQueryTree(nxagentDisplay, w, &root_return,
+ &parent_return, &children_return, &nchildren_return);
+
+ if (!result)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
+ #endif
+
+ break;
+ }
+
+ if (result && children_return)
+ {
+ XFree(children_return);
+ }
+ }
+
+ if (w && !nxagentWindowPtr(w))
+ {
+ XSelectInput(nxagentDisplay, w, StructureNotifyMask);
+
+ nxagentRootlessAddTopLevelWindow(pWin, w);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleReparentNotify: new top level window [%ld].\n", w);
+ fprintf(stderr, "nxagentHandleReparentNotify: reparented window [%ld].\n",
+ X -> xreparent.window);
+ #endif
+
+ result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ &root_return, &parent_return, &children_return, &nchildren_return);
+
+ if (result)
+ {
+ nxagentRootlessRestack(children_return, nchildren_return);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
+ #endif
+ }
+
+ if (result && nchildren_return)
+ {
+ XFree(children_return);
+ }
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleReparentNotify: Window at [%p] has been reparented to [%ld]"
+ " top level parent [%ld].\n", (void *) pWin, X -> xreparent.parent, w);
+ #endif
+
+ nxagentRootlessDelTopLevelWindow(pWin);
+ }
+ }
+
+ return 1;
+ }
+ else if (nxagentWMIsRunning == 1 && nxagentOption(Fullscreen) == 0 &&
+ nxagentOption(WMBorderWidth) == -1)
+ {
+ XlibWindow w;
+ XlibWindow rootReturn = 0;
+ XlibWindow parentReturn = 0;
+ XlibWindow junk;
+ XlibWindow *childrenReturn = NULL;
+ unsigned int nchildrenReturn = 0;
+ Status result;
+ XWindowAttributes attributes;
+ int x, y;
+ int xParent, yParent;
+
+ /*
+ * Calculate the absolute upper-left X e Y
+ */
+
+ if ((XGetWindowAttributes(nxagentDisplay, X -> xreparent.window,
+ &attributes) == 0))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+ "XGetWindowAttributes failed.\n");
+ #endif
+
+ return 1;
+ }
+
+ x = attributes.x;
+ y = attributes.y;
+
+ XTranslateCoordinates(nxagentDisplay, X -> xreparent.window,
+ attributes.root, -attributes.border_width,
+ -attributes.border_width, &x, &y, &junk);
+
+ /*
+ * Calculate the parent X and parent Y.
+ */
+
+ w = X -> xreparent.parent;
+
+ if (w != DefaultRootWindow(nxagentDisplay))
+ {
+ do
+ {
+ result = XQueryTree(nxagentDisplay, w, &rootReturn, &parentReturn,
+ &childrenReturn, &nchildrenReturn);
+
+ if (parentReturn == rootReturn || parentReturn == 0 || result == 0)
+ {
+ break;
+ }
+
+ if (result == 1 && childrenReturn != NULL)
+ {
+ XFree(childrenReturn);
+ }
+
+ w = parentReturn;
+ }
+ while (True);
+
+ /*
+ * WM reparented. Find edge of the frame.
+ */
+
+ if (XGetWindowAttributes(nxagentDisplay, w, &attributes) == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+ "XGetWindowAttributes failed for parent window.\n");
+ #endif
+
+ return 1;
+ }
+
+ xParent = attributes.x;
+ yParent = attributes.y;
+
+ /*
+ * Difference between Absolute X and Parent X gives thickness of side frame.
+ * Difference between Absolute Y and Parent Y gives thickness of title bar.
+ */
+
+ nxagentChangeOption(WMBorderWidth, (x - xParent));
+ nxagentChangeOption(WMTitleHeight, (y - yParent));
+ }
+ }
+
+ return 1;
+}
+
+void nxagentEnableKeyboardEvents()
+{
+ int i;
+ Mask mask;
+
+ nxagentGetDefaultEventMask(&mask);
+
+ mask |= NXAGENT_KEYBOARD_EVENT_MASK;
+
+ nxagentSetDefaultEventMask(mask);
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+ }
+
+ XkbSelectEvents(nxagentDisplay, XkbUseCoreKbd,
+ NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK,
+ NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK);
+}
+
+void nxagentDisableKeyboardEvents()
+{
+ int i;
+ Mask mask;
+
+ nxagentGetDefaultEventMask(&mask);
+
+ mask &= ~NXAGENT_KEYBOARD_EVENT_MASK;
+
+ nxagentSetDefaultEventMask(mask);
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+ }
+
+ XkbSelectEvents(nxagentDisplay, XkbUseCoreKbd, 0x0, 0x0);
+}
+
+void nxagentEnablePointerEvents()
+{
+ int i;
+ Mask mask;
+
+ nxagentGetDefaultEventMask(&mask);
+
+ mask |= NXAGENT_POINTER_EVENT_MASK;
+
+ nxagentSetDefaultEventMask(mask);
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+ }
+}
+
+void nxagentDisablePointerEvents()
+{
+ int i;
+ Mask mask;
+
+ nxagentGetDefaultEventMask(&mask);
+
+ mask &= ~NXAGENT_POINTER_EVENT_MASK;
+
+ nxagentSetDefaultEventMask(mask);
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+ }
+}
+
+void nxagentSendFakeKey(int key)
+{
+ xEvent fake;
+ Time now;
+
+ now = GetTimeInMillis();
+
+ memset(&fake, 0, sizeof(xEvent));
+ fake.u.u.type = KeyPress;
+ fake.u.u.detail = key;
+ fake.u.keyButtonPointer.time = now;
+
+ mieqEnqueue(&fake);
+
+ fake.u.u.type = KeyRelease;
+ fake.u.u.detail = key;
+ fake.u.keyButtonPointer.time = now;
+
+ mieqEnqueue(&fake);
+}
+
+int nxagentInitKeyboardState()
+{
+ XEvent X;
+
+ unsigned int modifiers;
+
+ XkbEvent *xkbev = (XkbEvent *) &X;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitKeyboardState: Initializing XKB state.\n");
+ #endif
+
+ memset(&X, 0, sizeof(XEvent));
+
+ XkbGetIndicatorState(nxagentDisplay, XkbUseCoreKbd, &modifiers);
+
+ xkbev -> state.locked_mods = 0x0;
+
+ if (modifiers & CAPSFLAG_IN_REPLY)
+ {
+ xkbev -> state.locked_mods |= CAPSFLAG_IN_EVENT;
+ }
+
+ if (modifiers & NUMFLAG_IN_REPLY)
+ {
+ xkbev -> state.locked_mods |= NUMFLAG_IN_EVENT;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitKeyboardState: Assuming XKB locked modifier bits [%x].\n",
+ xkbev -> state.locked_mods);
+ #endif
+
+ xkbev -> type = nxagentXkbInfo.EventBase + XkbEventCode;
+ xkbev -> any.xkb_type = XkbStateNotify;
+
+ nxagentHandleKeyboardEvent(&X);
+
+ return 1;
+}
+
+int nxagentWaitForResource(GetResourceFuncPtr pGetResource, PredicateFuncPtr pPredicate)
+{
+ int resource;
+
+ while ((resource = (*pGetResource)(nxagentDisplay)) == -1)
+ {
+ if (nxagentWaitEvents(nxagentDisplay, NULL) == -1)
+ {
+ return -1;
+ }
+
+ nxagentDispatchEvents(pPredicate);
+ }
+
+ return resource;
+}
+
+void nxagentGrabPointerAndKeyboard(XEvent *X)
+{
+ unsigned long now;
+
+ int resource;
+
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
+ (void *) X);
+ #endif
+
+ if (X != NULL)
+ {
+ now = X -> xcrossing.time;
+ }
+ else
+ {
+ now = CurrentTime;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
+ #endif
+
+ result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
+ True, GrabModeAsync, GrabModeAsync, now);
+
+ if (result != GrabSuccess)
+ {
+ return;
+ }
+
+ /*
+ * The smart scheduler could be stopped while
+ * waiting for the reply. In this case we need
+ * to yield explicitly to avoid to be stuck in
+ * the dispatch loop forever.
+ */
+
+ isItTimeToYield = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the pointer in context [B2].\n");
+ #endif
+
+ resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+ nxagentCollectGrabPointerPredicate);
+
+ NXCollectGrabPointer(nxagentDisplay, resource,
+ nxagentFullscreenWindow, True, NXAGENT_POINTER_EVENT_MASK,
+ GrabModeAsync, GrabModeAsync, None, None, now);
+
+ /*
+ * This should not be needed.
+ *
+ * XGrabKey(nxagentDisplay, AnyKey, AnyModifier, nxagentFullscreenWindow,
+ * True, GrabModeAsync, GrabModeAsync);
+ */
+
+ if (X != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to force focus in context [B4].\n");
+ #endif
+
+ XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
+ RevertToParent, now);
+ }
+}
+
+void nxagentUngrabPointerAndKeyboard(XEvent *X)
+{
+ unsigned long now;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
+ (void *) X);
+ #endif
+
+ if (X != NULL)
+ {
+ now = X -> xcrossing.time;
+ }
+ else
+ {
+ now = CurrentTime;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Going to ungrab the keyboard in context [B5].\n");
+ #endif
+
+ XUngrabKeyboard(nxagentDisplay, now);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to ungrab the pointer in context [B6].\n");
+ #endif
+
+ XUngrabPointer(nxagentDisplay, now);
+}
+
+void nxagentDeactivatePointerGrab()
+{
+ GrabPtr grab = inputInfo.pointer -> grab;
+
+ XButtonEvent X;
+
+ if (grab)
+ {
+ X.type = ButtonRelease;
+ X.serial = 0;
+ X.send_event = FALSE;
+ X.time = currentTime.milliseconds;
+ X.display = nxagentDisplay;
+ X.window = nxagentWindow(grab -> window);
+ X.root = RootWindow(nxagentDisplay, 0);
+ X.subwindow = 0;
+ X.x = X.y = X.x_root = X.y_root = 0;
+ X.state = 0x100;
+ X.button = 1;
+ X.same_screen = TRUE;
+
+ XPutBackEvent(nxagentDisplay, (XEvent*)&X);
+ }
+}
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr)
+{
+ return (X -> xclient.window == 0 &&
+ X -> xclient.message_type == 0 &&
+ X -> xclient.format == 32 &&
+ X -> xclient.data.l[0] == NXCollectGrabPointerNotify);
+}
+
+void nxagentHandleCollectGrabPointerEvent(int resource)
+{
+ int status;
+
+ if (NXGetCollectedGrabPointer(nxagentDisplay, resource, &status) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleCollectGrabPointerEvent: PANIC! Failed to get GrabPointer "
+ "reply for resource [%d].\n", resource);
+ #endif
+ }
+}
+
+void nxagentHandleCollectPropertyEvent(XEvent *X)
+{
+ Window window;
+ Atom property;
+ Atom atomReturnType;
+ int resultFormat;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ int result;
+ int resource;
+
+ resource = X -> xclient.data.l[1];
+
+ if (X -> xclient.data.l[2] == False)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentHandleCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+ resource);
+ #endif
+
+ return;
+ }
+
+ if (resource == nxagentLastClipboardClient)
+ {
+ nxagentCollectPropertyEvent(resource);
+ }
+ else
+ {
+ result = NXGetCollectedProperty(nxagentDisplay,
+ resource,
+ &atomReturnType,
+ &resultFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
+
+ if (result == True)
+ {
+ window = nxagentPropertyRequests[resource].window;
+ property = nxagentPropertyRequests[resource].property;
+
+ nxagentImportProperty(window, property, atomReturnType, resultFormat,
+ ulReturnItems, ulReturnBytesLeft, pszReturnData);
+ }
+
+ if (result == 0)
+ {
+ #ifdef DEBUG
+ fprintf (stderr, "nxagentHandleCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+ resource);
+ #endif
+ }
+
+ if (pszReturnData != NULL)
+ {
+ XFree(pszReturnData);
+ }
+
+ return;
+ }
+}
+
+void nxagentSynchronizeExpose(void)
+{
+ WindowPtr pWin;
+
+ if (nxagentExposeQueue.length <= 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeExpose: PANIC! Called with nxagentExposeQueue.length [%d].\n",
+ nxagentExposeQueue.length);
+ #endif
+
+ return;
+ }
+
+ pWin = nxagentExposeQueueHead.pWindow;
+
+ if (pWin)
+ {
+ if ((nxagentExposeQueueHead.localRegion) != NullRegion)
+ {
+ RegionTranslate((nxagentExposeQueueHead.localRegion),
+ pWin -> drawable.x, pWin -> drawable.y);
+ }
+
+ if ((nxagentExposeQueueHead.remoteRegion) != NullRegion)
+ {
+ RegionTranslate((nxagentExposeQueueHead.remoteRegion),
+ pWin -> drawable.x, pWin -> drawable.y);
+ }
+
+ if ((nxagentExposeQueueHead.localRegion) != NullRegion &&
+ (nxagentExposeQueueHead.remoteRegion) != NullRegion)
+ {
+ RegionSubtract((nxagentExposeQueueHead.remoteRegion),
+ (nxagentExposeQueueHead.remoteRegion),
+ (nxagentExposeQueueHead.localRegion));
+
+ if (RegionNil(nxagentExposeQueueHead.remoteRegion) == 0 &&
+ ((pWin -> eventMask|wOtherEventMasks(pWin)) & ExposureMask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeExpose: Going to call miWindowExposures"
+ " for window [%ld] - rects [%ld].\n", nxagentWindow(pWin),
+ RegionNumRects(nxagentExposeQueueHead.remoteRegion));
+ #endif
+
+ miWindowExposures(pWin, nxagentExposeQueueHead.remoteRegion, NullRegion);
+ }
+ }
+ }
+
+ nxagentExposeQueueHead.pWindow = NULL;
+
+ if (nxagentExposeQueueHead.localRegion != NullRegion)
+ {
+ RegionDestroy(nxagentExposeQueueHead.localRegion);
+ }
+
+ nxagentExposeQueueHead.localRegion = NullRegion;
+
+ if (nxagentExposeQueueHead.remoteRegion != NullRegion)
+ {
+ RegionDestroy(nxagentExposeQueueHead.remoteRegion);
+ }
+
+ nxagentExposeQueueHead.remoteRegion = NullRegion;
+
+ nxagentExposeQueueHead.remoteRegionIsCompleted = False;
+
+ nxagentExposeQueue.start = (nxagentExposeQueue.start + 1) % EXPOSED_SIZE;
+
+ nxagentExposeQueue.length--;
+
+ return;
+}
+
+int nxagentLookupByWindow(WindowPtr pWin)
+{
+ int i;
+ int j;
+
+ for (j = 0; j < nxagentExposeQueue.length; j++)
+ {
+ i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+ if (nxagentExposeQueue.exposures[i].pWindow == pWin &&
+ !nxagentExposeQueue.exposures[i].remoteRegionIsCompleted)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void nxagentRemoveDuplicatedKeys(XEvent *X)
+{
+ _XQEvent *prev;
+ _XQEvent *qelt;
+
+ _XQEvent *qeltKeyRelease;
+ _XQEvent *prevKeyRelease;
+
+ KeyCode lastKeycode = X -> xkey.keycode;
+
+ qelt = nxagentDisplay -> head;
+
+ if (qelt == NULL)
+ {
+ #ifdef TEST
+
+ int more;
+
+ fprintf(stderr, "nxagentRemoveDuplicatedKeys: Trying to read more events "
+ "from the X server.\n");
+
+ more = nxagentReadEvents(nxagentDisplay);
+
+ if (more > 0)
+ {
+ fprintf(stderr, "nxagentRemoveDuplicatedKeys: Successfully read more events "
+ "from the X server.\n");
+ }
+
+ #else
+
+ nxagentReadEvents(nxagentDisplay);
+
+ #endif
+
+ qelt = nxagentDisplay -> head;
+ }
+
+ if (qelt != NULL)
+ {
+ prev = qeltKeyRelease = prevKeyRelease = NULL;
+
+ LockDisplay(nxagentDisplay);
+
+ while (qelt != NULL)
+ {
+ if (qelt -> event.type == KeyRelease ||
+ qelt -> event.type == KeyPress)
+ {
+ if (qelt -> event.xkey.keycode != lastKeycode ||
+ (qelt -> event.type == KeyPress && qeltKeyRelease == NULL) ||
+ (qelt -> event.type == KeyRelease && qeltKeyRelease != NULL))
+ {
+ break;
+ }
+
+ if (qelt -> event.type == KeyRelease)
+ {
+ prevKeyRelease = prev;
+
+ qeltKeyRelease = qelt;
+ }
+ else if (qelt -> event.type == KeyPress)
+ {
+ _XDeq(nxagentDisplay, prev, qelt);
+
+ qelt = prev -> next;
+
+ if (prev == qeltKeyRelease)
+ {
+ prev = prevKeyRelease;
+ }
+
+ _XDeq(nxagentDisplay, prevKeyRelease, qeltKeyRelease);
+
+ qeltKeyRelease = prevKeyRelease = NULL;
+
+ continue;
+ }
+ }
+
+ prev = qelt;
+
+ qelt = qelt -> next;
+ }
+
+ UnlockDisplay(nxagentDisplay);
+ }
+}
+
+void nxagentInitRemoteExposeRegion(void)
+{
+ if (nxagentRemoteExposeRegion == NULL)
+ {
+ nxagentRemoteExposeRegion = RegionCreate(NULL, 1);
+
+ if (nxagentRemoteExposeRegion == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentInitRemoteExposeRegion: PANIC! Failed to create expose region.\n");
+ #endif
+ }
+ }
+}
+
+void nxagentForwardRemoteExpose(void)
+{
+ if (RegionNotEmpty(nxagentRemoteExposeRegion))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentForwardRemoteExpose: Going to forward events.\n");
+ #endif
+
+ TraverseTree(screenInfo.screens[0]->root, nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion);
+
+ /*
+ * Now this region should be empty.
+ */
+
+ RegionEmpty(nxagentRemoteExposeRegion);
+ }
+}
+
+void nxagentAddRectToRemoteExposeRegion(BoxPtr rect)
+{
+ RegionRec exposeRegion;
+
+ if (nxagentRemoteExposeRegion == NULL)
+ {
+ return;
+ }
+
+ RegionInit(&exposeRegion, rect, 1);
+
+ RegionUnion(nxagentRemoteExposeRegion,
+ nxagentRemoteExposeRegion, &exposeRegion);
+
+ RegionUninit(&exposeRegion);
+}
+
+int nxagentClipAndSendExpose(WindowPtr pWin, void * ptr)
+{
+ RegionPtr exposeRgn;
+ RegionPtr remoteExposeRgn;
+
+ #ifdef DEBUG
+ BoxRec box;
+
+ fprintf(stderr, "nxagentClipAndSendExpose: Called.\n");
+ #endif
+
+ remoteExposeRgn = (RegionRec *) ptr;
+
+ if (pWin -> drawable.class != InputOnly)
+ {
+ exposeRgn = RegionCreate(NULL, 1);
+
+ #ifdef DEBUG
+ box = *RegionExtents(remoteExposeRgn);
+
+ fprintf(stderr, "nxagentClipAndSendExpose: Root expose extents: [%d] [%d] [%d] [%d].\n",
+ box.x1, box.y1, box.x2, box.y2);
+
+ box = *RegionExtents(&pWin -> clipList);
+
+ fprintf(stderr, "nxagentClipAndSendExpose: Clip list extents for window at [%p]: [%d] [%d] [%d] [%d].\n",
+ pWin, box.x1, box.y1, box.x2, box.y2);
+ #endif
+
+ RegionIntersect(exposeRgn, remoteExposeRgn, &pWin -> clipList);
+
+ if (RegionNotEmpty(exposeRgn))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClipAndSendExpose: Forwarding expose to window at [%p] pWin.\n",
+ pWin);
+ #endif
+
+ /*
+ * The miWindowExposures() clears out the
+ * region parameters, so the subtract ope-
+ * ration must be done before calling it.
+ */
+
+ RegionSubtract(remoteExposeRgn, remoteExposeRgn, exposeRgn);
+
+ miWindowExposures(pWin, exposeRgn, NullRegion);
+ }
+
+ RegionDestroy(exposeRgn);
+ }
+
+ if (RegionNotEmpty(remoteExposeRgn))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClipAndSendExpose: Region not empty. Walk children.\n");
+ #endif
+
+ return WT_WALKCHILDREN;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentClipAndSendExpose: Region empty. Stop walking.\n");
+ #endif
+
+ return WT_STOPWALKING;
+ }
+}
+
+int nxagentUserInput(void *p)
+{
+ int result = 0;
+
+ /*
+ * This function is used as callback in
+ * the polling handler of agent in shadow
+ * mode. When inside the polling loop the
+ * handlers are never called, so we have
+ * to dispatch enqueued events to eventu-
+ * ally change the nxagentInputEvent sta-
+ * tus.
+ */
+
+ if (nxagentOption(Shadow) == 1 &&
+ nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ nxagentDispatchEvents(NULL);
+ }
+
+ if (nxagentInputEvent == 1)
+ {
+ nxagentInputEvent = 0;
+
+ result = 1;
+ }
+
+ /*
+ * The agent working in shadow mode synch-
+ * ronizes the remote X server even if a
+ * button/key is not released (i.e. when
+ * scrolling a long browser's page), in
+ * order to update the screen smoothly.
+ */
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ return result;
+ }
+
+ if (result == 0)
+ {
+ /*
+ * If there is at least one button/key down,
+ * we are receiving an input. This is not a
+ * condition to break a synchronization loop
+ * if there is enough bandwidth.
+ */
+
+ if (nxagentCongestion > 0 &&
+ (inputInfo.pointer -> button -> buttonsDown > 0 ||
+ nxagentKeyDown > 0))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentUserInput: Buttons [%d] Keys [%d].\n",
+ inputInfo.pointer -> button -> buttonsDown, nxagentKeyDown);
+ #endif
+
+ result = 1;
+ }
+ }
+
+ return result;
+}
+
+int nxagentHandleRRScreenChangeNotify(XEvent *X)
+{
+ XRRScreenChangeNotifyEvent *Xr;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleRRScreenChangeNotify called.\n");
+ #endif
+
+ Xr = (XRRScreenChangeNotifyEvent *) X;
+
+ nxagentResizeScreen(screenInfo.screens[DefaultScreen(nxagentDisplay)], Xr -> width, Xr -> height,
+ Xr -> mwidth, Xr -> mheight);
+
+ nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], screenInfo.screens[0]->root,
+ Xr -> width, Xr -> height);
+
+ nxagentShadowSetWindowsSize();
+
+ return 1;
+}
+
+/*
+ * Returns true if there is any event waiting to
+ * be dispatched. This function is critical for
+ * the performance because it is called very,
+ * very often. It must also handle the case when
+ * the display is down. The display descriptor,
+ * in fact, may have been reused by some other
+ * client.
+ */
+
+int nxagentPendingEvents(Display *dpy)
+{
+ if (_XGetIOError(dpy) != 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPendingEvents: Returning error with display down.\n");
+ #endif
+
+ return -1;
+ }
+ else if (XQLength(dpy) > 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPendingEvents: Returning true with [%d] events queued.\n",
+ XQLength(dpy));
+ #endif
+
+ return 1;
+ }
+ else
+ {
+ int result;
+ int readable;
+
+ result = NXTransReadable(dpy -> fd, &readable);
+
+ if (result == 0)
+ {
+ if (readable > 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPendingEvents: Returning true with [%d] bytes readable.\n",
+ readable);
+ #endif
+
+ return 1;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPendingEvents: Returning false with [%d] bytes readable.\n",
+ readable);
+ #endif
+
+ return 0;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPendingEvents: WARNING! Error detected on the X display.\n");
+ #endif
+
+ NXForceDisplayError(dpy);
+
+ return -1;
+ }
+}
+
+/*
+ * Blocks until an event becomes
+ * available.
+ */
+
+int nxagentWaitEvents(Display *dpy, struct timeval *tm)
+{
+ XEvent ev;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWaitEvents called.\n");
+ #endif
+
+ NXFlushDisplay(dpy, NXFlushLink);
+
+ /*
+ * If the transport is not running we
+ * have to rely on Xlib to wait for an
+ * event. In this case the timeout is
+ * ignored.
+ */
+
+ if (NXTransRunning(NX_FD_ANY) == 1)
+ {
+ NXTransContinue(tm);
+ }
+ else
+ {
+ XPeekEvent(dpy, &ev);
+ }
+
+ /*
+ * Check if we encountered a display
+ * error. If we did, wait for the
+ * time requested by the caller.
+ */
+
+ if (NXDisplayError(dpy) == 1)
+ {
+ if (tm != NULL)
+ {
+ usleep(tm -> tv_sec * 1000 * 1000 +
+ tm -> tv_usec);
+ }
+
+ return -1;
+ }
+
+ return 1;
+}
+
+#ifdef NX_DEBUG_INPUT
+
+void nxagentDumpInputInfo(void)
+{
+ fprintf(stderr, "Dumping input info ON.\n");
+}
+
+void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
+{
+ if (strcmp(validateString(NameForAtom(property)), "NX_DEBUG_INPUT") == 0)
+ {
+ if (*data != 0)
+ {
+ nxagentDebugInput = 1;
+ }
+ else
+ {
+ nxagentDebugInput = 0;
+ }
+ }
+}
+
+void nxagentDeactivateInputDevicesGrabs()
+{
+ fprintf(stderr, "Info: Deactivating input devices grabs.\n");
+
+ if (inputInfo.pointer -> grab)
+ {
+ (*inputInfo.pointer -> DeactivateGrab)(inputInfo.pointer);
+ }
+
+ if (inputInfo.keyboard -> grab)
+ {
+ (*inputInfo.keyboard -> DeactivateGrab)(inputInfo.keyboard);
+ }
+}
+
+static const char *nxagentGrabStateToString(int state)
+{
+ switch (state)
+ {
+ case 0:
+ return "NOT_GRABBED";
+ case 1:
+ return "THAWED";
+ case 2:
+ return "THAWED_BOTH";
+ case 3:
+ return "FREEZE_NEXT_EVENT";
+ case 4:
+ return "FREEZE_BOTH_NEXT_EVENT";
+ case 5:
+ return "FROZEN_NO_EVENT";
+ case 6:
+ return "FROZEN_WITH_EVENT";
+ case 7:
+ return "THAW_OTHERS";
+ default:
+ return "unknown state";
+ }
+}
+
+void nxagentDumpInputDevicesState(void)
+{
+ int i, k;
+ int mask = 1;
+ CARD8 val;
+ DeviceIntPtr dev;
+ GrabPtr grab;
+ WindowPtr pWin = NULL;
+
+ fprintf(stderr, "\n*** Dump input devices state: BEGIN ***"
+ "\nKeys down:");
+
+ dev = inputInfo.keyboard;
+
+ for (i = 0; i < DOWN_LENGTH; i++)
+ {
+ val = dev -> key -> down[i];
+
+ if (val != 0)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ if (val & (mask << k))
+ {
+ fprintf(stderr, "\n\t[%d] [%s]", i * 8 + k,
+ XKeysymToString(XKeycodeToKeysym(nxagentDisplay, i * 8 + k, 0)));
+ }
+ }
+ }
+ }
+
+ fprintf(stderr, "\nKeyboard device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+ "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+ "\n\tfrom passive grab [%s]\n\tactivating key [%d]", dev,
+ dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes": "No",
+ nxagentGrabStateToString(dev -> sync.state),
+ dev -> sync.other, dev -> sync.evcount,
+ dev -> fromPassiveGrab ? "Yes" : "No",
+ dev -> activatingKey);
+
+ grab = dev -> grab;
+
+ if (grab)
+ {
+ fprintf(stderr, "\nKeyboard grab state: \n\twindow pointer [%p]"
+ "\n\towner events flag [%s]\n\tgrab mode [%s]",
+ grab -> window, grab -> ownerEvents ? "True" : "False",
+ grab -> keyboardMode ? "asynchronous" : "synchronous");
+
+ /*
+ * Passive grabs.
+ */
+
+ pWin = grab -> window;
+ grab = wPassiveGrabs(pWin);
+
+ while (grab)
+ {
+ fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+ "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+ "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+ grab -> device, grab -> ownerEvents ? "True" : "False",
+ grab -> pointerMode ? "asynchronous" : "synchronous",
+ grab -> keyboardMode ? "asynchronous" : "synchronous",
+ grab -> type, grab -> modifiersDetail.exact,
+ grab -> detail.exact, grab -> eventMask);
+
+ grab = grab -> next;
+ }
+ }
+
+ fprintf(stderr, "\nButtons down:");
+
+ dev = inputInfo.pointer;
+
+ for (i = 0; i < DOWN_LENGTH; i++)
+ {
+ val = dev -> button -> down[i];
+
+ if (val != 0)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ if (val & (mask << k))
+ {
+ fprintf(stderr, "\n\t[%d]", i * 8 + k);
+ }
+ }
+ }
+ }
+
+ fprintf(stderr, "\nPointer device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+ "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+ "\n\tfrom passive grab [%s]\n\tactivating button [%d]", dev,
+ dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes" : "No",
+ nxagentGrabStateToString(dev -> sync.state),
+ dev -> sync.other, dev -> sync.evcount,
+ dev -> fromPassiveGrab ? "Yes" : "No",
+ dev -> activatingKey);
+
+ grab = dev -> grab;
+
+ if (grab)
+ {
+ fprintf(stderr, "\nPointer grab state: \n\twindow pointer [%p]"
+ "\n\towner events flag [%s]\n\tgrab mode [%s]",
+ grab -> window, grab -> ownerEvents ? "True" : "False",
+ grab -> pointerMode ? "asynchronous" : "synchronous");
+
+ if (grab -> window != pWin)
+ {
+ /*
+ * Passive grabs.
+ */
+
+ grab = wPassiveGrabs(grab -> window);
+
+ while (grab)
+ {
+ fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+ "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+ "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+ grab -> device, grab -> ownerEvents ? "True" : "False",
+ grab -> pointerMode ? "asynchronous" : "synchronous",
+ grab -> keyboardMode ? "asynchronous" : "synchronous",
+ grab -> type, grab -> modifiersDetail.exact,
+ grab -> detail.exact, grab -> eventMask);
+
+ grab = grab -> next;
+ }
+ }
+ }
+
+ fprintf(stderr, "\n*** Dump input devices state: FINISH ***\n");
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
new file mode 100644
index 000000000..7d313c331
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -0,0 +1,238 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Events_H__
+#define __Events_H__
+
+#include <nx-X11/Xmd.h>
+
+#define ProcessedExpose (LASTEvent + 1)
+#define ProcessedNotify (LASTEvent + 2)
+
+#define EXPOSED_SIZE 256
+
+enum HandleEventResult
+{
+ doNothing = 0,
+ doMinimize,
+ doDebugTree,
+ doCloseSession,
+ doStartKbd,
+ doSwitchFullscreen,
+ doSwitchAllScreens,
+ doViewportMoveUp,
+ doViewportMoveLeft,
+ doViewportMoveRight,
+ doViewportMoveDown,
+ doViewportLeft,
+ doViewportUp,
+ doViewportRight,
+ doViewportDown,
+ doSwitchResizeMode,
+ doSwitchDeferMode
+};
+
+extern CARD32 nxagentLastEventTime;
+
+/*
+ * Manage incoming events.
+ */
+
+typedef Bool (*PredicateFuncPtr)(Display*, XEvent*, XPointer);
+
+extern void nxagentDispatchEvents(PredicateFuncPtr);
+
+typedef int (*GetResourceFuncPtr)(Display*);
+
+int nxagentWaitForResource(GetResourceFuncPtr, PredicateFuncPtr);
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr);
+
+int nxagentInputEventPredicate(Display *display, XEvent *event, XPointer parameter);
+
+/*
+ * Enable and disable notification of
+ * remote X server events.
+ */
+
+extern void nxagentEnableKeyboardEvents(void);
+extern void nxagentEnablePointerEvents(void);
+
+extern void nxagentDisableKeyboardEvents(void);
+extern void nxagentDisablePointerEvents(void);
+
+/*
+ * Manage default event mask.
+ */
+
+extern void nxagentInitDefaultEventMask(void);
+extern void nxagentGetDefaultEventMask(Mask *mask_return);
+extern void nxagentSetDefaultEventMask(Mask mask);
+extern void nxagentGetEventMask(WindowPtr pWin, Mask *mask_return);
+
+/*
+ * Bring keyboard device in known state. It needs
+ * a round-trip so it only gets called if a pre-
+ * vious XKB event did not implicitly initialized
+ * the internal state. This is unlikely to happen.
+ */
+
+extern int nxagentInitKeyboardState(void);
+
+/*
+ * Update the keyboard state according
+ * to focus and XKB events received
+ * from the remote X server.
+ */
+
+extern int nxagentHandleKeyboardEvent(XEvent *X);
+
+/*
+ * Handle sync and karma messages and
+ * other notification event coming
+ * from proxy.
+ */
+
+extern int nxagentHandleProxyEvent(XEvent *X);
+
+/*
+ * Other functions providing the ad-hoc
+ * handling of the remote X events.
+ */
+
+extern int nxagentHandleExposeEvent(XEvent *X);
+extern int nxagentHandleGraphicsExposeEvent(XEvent *X);
+extern int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult*);
+extern int nxagentHandlePropertyNotify(XEvent *X);
+extern int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult*);
+extern int nxagentHandleReparentNotify(XEvent *X);
+extern int nxagentHandleConfigureNotify(XEvent *X);
+extern int nxagentHandleXFixesSelectionNotify(XEvent *X);
+
+/*
+ * Send a fake keystroke to the remote
+ * X server.
+ */
+
+extern void nxagentSendFakeKey(int key);
+
+/*
+ * Called to manage grab of pointer and
+ * keyboard when running in fullscreen
+ * mode.
+ */
+
+extern void nxagentGrabPointerAndKeyboard(XEvent *X);
+extern void nxagentUngrabPointerAndKeyboard(XEvent *X);
+
+extern void nxagentDeactivatePointerGrab(void);
+
+/*
+ * Handle the selection property received
+ * in the event loop.
+ */
+
+void nxagentCollectPropertyEvent(int resource);
+
+/*
+ * Synchronize expose events between agent and
+ * the real X server.
+ */
+
+typedef struct _ExposuresRec
+{
+ WindowPtr pWindow;
+ RegionPtr localRegion;
+ RegionPtr remoteRegion;
+ Bool remoteRegionIsCompleted;
+ int serial;
+ int synchronize;
+
+} ExposuresRec;
+
+extern RegionPtr nxagentRemoteExposeRegion;
+
+typedef struct _ExposeQueue
+{
+ unsigned int start;
+ int length;
+ ExposuresRec exposures[EXPOSED_SIZE];
+} ExposeQueue;
+
+extern void nxagentSynchronizeExpose(void);
+extern int nxagentLookupByWindow(WindowPtr pWin);
+extern void nxagentUpdateExposeArray(void);
+
+extern ExposeQueue nxagentExposeQueue;
+
+/*
+ * Handle the split related notifications.
+ */
+
+int nxagentWaitSplitEvent(int resource);
+
+void nxagentHandleNoSplitEvent(int resource);
+void nxagentHandleStartSplitEvent(int resource);
+void nxagentHandleCommitSplitEvent(int resource, int request, int position);
+void nxagentHandleEndSplitEvent(int resource);
+void nxagentHandleEmptySplitEvent(void);
+
+void nxagentInitRemoteExposeRegion(void);
+void nxagentAddRectToRemoteExposeRegion(BoxPtr);
+
+extern int nxagentUserInput(void *p);
+
+/*
+* We have to check these before launching the terminate
+ * dialog in rootless mode.
+ */
+
+extern Bool nxagentLastWindowDestroyed;
+extern Time nxagentLastWindowDestroyedTime;
+
+/*
+ * Set this flag if an user input event is received.
+ */
+
+extern int nxagentInputEvent;
+
+/*
+ * Event-handling utilities.
+ */
+
+Bool nxagentPendingEvents(Display *dpy);
+
+#define nxagentQueuedEvents(display) \
+ XQLength((display))
+
+#define nxagentReadEvents(display) \
+ XEventsQueued((display), QueuedAfterReading)
+
+#define nxagentCheckEvents(display, event, predicate, argument) \
+ XCheckIfEventNoFlush((display), (event), (predicate), (argument))
+
+int nxagentWaitEvents(Display *, struct timeval *);
+
+#endif /* __Events_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
new file mode 100644
index 000000000..d9db1a8aa
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -0,0 +1,470 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "micmap.h"
+#include "scrnintstr.h"
+#include "../../randr/randrstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Options.h"
+#include "Extensions.h"
+#include "Windows.h"
+
+void GlxExtensionInit(void);
+void GlxWrapInitVisuals(void *procPtr);
+
+static int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width,
+ CARD16 height, CARD32 mmWidth,
+ CARD32 mmHeight);
+
+static int nxagentRandRInitSizes(ScreenPtr pScreen);
+
+#if RANDR_14_INTERFACE
+static Bool
+nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
+ PixmapPtr pPixmap,
+ Bool enable);
+#endif
+
+#if RANDR_13_INTERFACE
+static Bool
+nxagentRandROutputGetProperty(ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property);
+static Bool
+nxagentRandRGetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+static Bool
+nxagentRandRSetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border);
+#endif
+
+#if RANDR_12_INTERFACE
+static Bool nxagentRandRCrtcSet (ScreenPtr pScreen, RRCrtcPtr crtc,
+ RRModePtr mode, int x, int y,
+ Rotation rotation, int numOutputs,
+ RROutputPtr *outputs);
+#endif
+
+#ifdef __DARWIN__
+
+void DarwinHandleGUI(int argc, char *argv[])
+{
+}
+
+void DarwinGlxExtensionInit()
+{
+ GlxExtensionInit();
+}
+
+void DarwinGlxWrapInitVisuals(void *procPtr)
+{
+ GlxWrapInitVisuals(procPtr);
+}
+
+#endif
+
+void nxagentInitGlxExtension(VisualPtr *visuals, DepthPtr *depths,
+ int *numVisuals, int *numDepths, int *rootDepth,
+ VisualID *defaultVisual)
+{
+ miInitVisualsProcPtr initVisuals;
+
+ /*
+ * Initialize the visuals to use the GLX extension.
+ */
+
+ initVisuals = NULL;
+
+ GlxWrapInitVisuals(&initVisuals);
+
+ if (initVisuals(visuals, depths, numVisuals, numDepths,
+ rootDepth, defaultVisual, 0, 0, 0) == 0)
+ {
+ fprintf(stderr, "Warning: Failed to initialize the GLX extension.\n");
+ }
+}
+
+void nxagentInitRandRExtension(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pRandRScrPriv;
+
+ if (RRScreenInit(pScreen) == 0)
+ {
+ fprintf(stderr, "Warning: Failed to initialize the RandR extension.\n");
+ }
+
+
+ /* FIXME: do we need this at all with the new rand/xinerama stuff? */
+ nxagentRandRInitSizes(pScreen);
+
+ /*
+ * RRScreenInit sets these pointers to NULL,
+ * so requiring the server to set up its own
+ * replacements.
+ */
+
+ pRandRScrPriv = rrGetScrPriv(pScreen);
+
+ pRandRScrPriv -> rrGetInfo = nxagentRandRGetInfo;
+
+ #if RANDR_15_INTERFACE
+ /* nothing to be assigned here, so far */
+ #endif
+
+ #if RANDR_14_INTERFACE
+ /* no pixmap sharing in nx-X11 */
+ pScreen->ReplaceScanoutPixmap = nxagentRandRReplaceScanoutPixmap;
+ pRandRScrPriv -> rrCrtcSetScanoutPixmap = NULL;
+
+ /* only fake provider support in nx-X11, so far */
+ pRandRScrPriv -> provider = RRProviderCreate(pScreen, "default", 7);
+ pRandRScrPriv -> rrProviderSetOutputSource = NULL;
+ pRandRScrPriv -> rrProviderSetOffloadSink = NULL;
+ pRandRScrPriv -> rrProviderGetProperty = NULL;
+ pRandRScrPriv -> rrProviderSetProperty = NULL;
+ #endif
+
+ #if RANDR_13_INTERFACE
+ pRandRScrPriv -> rrOutputGetProperty = nxagentRandROutputGetProperty;
+ pRandRScrPriv -> rrGetPanning = nxagentRandRGetPanning;
+ pRandRScrPriv -> rrSetPanning = nxagentRandRSetPanning;
+ #endif
+
+ #if RANDR_12_INTERFACE
+ pRandRScrPriv -> rrScreenSetSize = nxagentRandRScreenSetSize;
+ pRandRScrPriv -> rrCrtcSet = nxagentRandRCrtcSet;
+ #endif
+
+ #if RANDR_10_INTERFACE
+ pRandRScrPriv -> rrSetConfig = nxagentRandRSetConfig;
+ #endif
+}
+
+#if RANDR_14_INTERFACE
+static Bool
+nxagentRandRReplaceScanoutPixmap(DrawablePtr pDrawable,
+ PixmapPtr pPixmap,
+ Bool enable)
+{
+ /* FALSE means: not supported */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRReplaceScanoutPixmap: NX's RANDR does not support scan-out pixmaps.\n");
+#endif
+ return FALSE;
+}
+#endif
+
+#if RANDR_13_INTERFACE
+static Bool
+nxagentRandROutputGetProperty(ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property)
+{
+ /* FALSE means: no property required to be modified on the fly here */
+ return FALSE;
+}
+
+static Bool
+nxagentRandRGetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ /* FALSE means: no, panning is not supported at the moment...
+ * Panning requires several modes to be available for
+ * the NX<n> output(s).
+ *
+ * FIXME: Add more modes per output than the current window size.
+ * At least when in fullscreen mode.
+ */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRGetPanning: RANDR Panning is currently not supported.\n");
+#endif
+ return FALSE;
+}
+
+static Bool
+nxagentRandRSetPanning(ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ /* FALSE means: no, panning is not supported at the moment...
+ * Panning requires several modes to be available for
+ * the NX<n> output(s).
+ *
+ * FIXME: Add more modes per output than the current window size.
+ * At least when in fullscreen mode.
+ */
+#ifdef DEBUG
+ fprintf(stderr, "nxagentRandRSetPanning: RANDR Panning is currently not supported.\n");
+#endif
+ return FALSE;
+}
+#endif
+
+#if RANDR_12_INTERFACE
+/*
+ * Request that the Crtc be reconfigured
+ */
+
+static Bool
+nxagentRandRCrtcSet (ScreenPtr pScreen,
+ RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int numOutputs,
+ RROutputPtr *outputs)
+{
+ return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutputs, outputs);
+}
+#endif
+
+
+int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
+{
+ /*
+ * Rotation is not supported.
+ */
+
+ *pRotations = RR_Rotate_0;
+
+ return 1;
+}
+
+static int nxagentRandRInitSizes(ScreenPtr pScreen)
+{
+ RRScreenSizePtr pSize;
+
+ int width;
+ int height;
+
+ int maxWidth;
+ int maxHeight;
+
+/*
+ int w[] = {0, 160, 320, 640, 800, 1024, 1152, 1280, 1280, 1280, 1280, 1280,
+ 1280, 1360, 1440, 1600, 1600, 1680, 1920, 1920, 0, 0};
+ int h[] = {0, 120, 240, 480, 600, 768, 864, 600, 720, 800, 854, 960,
+ 1024, 768, 900, 900, 1200, 1050, 1080, 1200, 0, 0};
+*/
+ int w[] = {0, 320, 640, 640, 800, 800, 1024, 1024, 1152, 1280, 1280, 1280, 1360,
+ 1440, 1600, 1600, 1680, 1920, 1920, 0, 0};
+ int h[] = {0, 240, 360, 480, 480, 600, 600, 768, 864, 720, 800, 1024, 768,
+ 900, 900, 1200, 1050, 1080, 1200, 0, 0};
+
+ int i;
+ int nSizes;
+
+ int mmWidth;
+ int mmHeight;
+
+ /*
+ * Register all the supported sizes. The third
+ * parameter is the refresh rate.
+ */
+
+ maxWidth = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ maxHeight = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+ nSizes = sizeof w / sizeof(int);
+
+ /*
+ * Add current and max sizes.
+ */
+
+ w[nSizes - 1] = pScreen -> width;
+ h[nSizes - 1] = pScreen -> height;
+
+ w[nSizes - 2] = maxWidth;
+ h[nSizes - 2] = maxHeight;
+
+ /*
+ * Compute default size.
+ */
+
+ w[0] = w[2];
+ h[0] = h[2];
+
+ for (i = 3; i < nSizes - 1; i++)
+ {
+ if ((w[i] <= maxWidth * 3 / 4) &&
+ (h[i] <= maxHeight * 3 / 4) &&
+ (w[i] >= w[0]) &&
+ (h[i] >= h[0]))
+ {
+ w[0] = w[i];
+ h[0] = h[i];
+ }
+ }
+
+ for (i = 0; i < nSizes; i++)
+ {
+ width = w[i];
+ height = h[i];
+
+ mmWidth = (width * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+ if (mmWidth < 1)
+ {
+ mmWidth = 1;
+ }
+
+ mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+ if (mmHeight < 1)
+ {
+ mmHeight = 1;
+ }
+
+ pSize = RRRegisterSize(pScreen, width, height, mmWidth, mmHeight);
+
+ if (pSize == NULL)
+ {
+ return 0;
+ }
+
+ RRRegisterRate (pScreen, pSize, 60);
+ }
+
+ RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+
+ return 1;
+}
+
+#if RANDR_10_INTERFACE
+
+int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize)
+{
+ int r;
+
+ UpdateCurrentTime();
+
+ /*
+ * Whatever size is OK for us.
+ */
+
+ r = nxagentResizeScreen(pScreen, pSize -> width, pSize -> height,
+ pSize -> mmWidth, pSize -> mmHeight);
+
+ nxagentMoveViewport(pScreen, 0, 0);
+
+ return r;
+}
+
+#endif
+
+#if RANDR_12_INTERFACE
+
+void nxagentRandRSetWindowsSize(int width, int height)
+{
+ if (width == 0)
+ {
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ }
+ else
+ {
+ width = nxagentOption(Width);
+ }
+ }
+
+ if (height == 0)
+ {
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ }
+ else
+ {
+ height = nxagentOption(Height);
+ }
+ }
+
+ XResizeWindow(nxagentDisplay, nxagentDefaultWindows[0], width, height);
+
+ if (nxagentOption(Rootless) == 0)
+ {
+ XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0, width,
+ height);
+ }
+}
+
+int nxagentRandRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
+ CARD32 mmWidth, CARD32 mmHeight)
+{
+ int result;
+
+ UpdateCurrentTime();
+
+ if (nxagentOption(DesktopResize) == 1 &&
+ (nxagentOption(Fullscreen) == 1 ||
+ width > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) ||
+ height > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))))
+ {
+ if (nxagentOption(ClientOs) != ClientOsWinnt
+ /*&& nxagentOption(ClientOs) != ClientNXPlayer*/)
+ {
+ nxagentChangeOption(DesktopResize, 0);
+ }
+ }
+
+ if (nxagentOption(DesktopResize) == 1 && nxagentOption(Fullscreen) == 0 &&
+ nxagentOption(AllScreens) == 0)
+ {
+ nxagentChangeOption(Width, width);
+ nxagentChangeOption(Height, height);
+ }
+
+ result = nxagentResizeScreen(pScreen, width, height, mmWidth, mmHeight);
+
+ if (result == 1 && nxagentOption(DesktopResize) == 1 &&
+ nxagentOption(Fullscreen) == 0 && nxagentOption(AllScreens) == 0)
+ {
+ nxagentRandRSetWindowsSize(width, height);
+ nxagentSetWMNormalHints(pScreen -> myNum);
+ }
+
+ nxagentMoveViewport(pScreen, 0, 0);
+
+ return result;
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
new file mode 100644
index 000000000..9b3672f5a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -0,0 +1,43 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Initialize the additional extensions.
+ */
+
+void nxagentInitGlxExtension(VisualPtr *visuals, DepthPtr *depths,
+ int *numVisuals, int *numDepths, int *rootDepth,
+ VisualID *defaultVisual);
+
+void nxagentInitRandRExtension(ScreenPtr pScreen);
+
+/*
+ * Basic interface to the RandR extension.
+ */
+
+int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations);
+
+int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+ int rate, RRScreenSizePtr pSize);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
new file mode 100644
index 000000000..f9c682765
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -0,0 +1,1864 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "opaque.h"
+
+#include "Agent.h"
+
+#include "Display.h"
+#include "Font.h"
+#include "Error.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include "resource.h"
+#include "Reconnect.h"
+
+#include "Args.h"
+#include "Utils.h"
+
+#include "compext/Compext.h"
+#include <nx/NXalert.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define NXAGENT_DEFAULT_FONT_DIR "/usr/share/nx/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR "/usr/share/X11/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR_2 "/usr/share/fonts/X11"
+#define NXAGENT_ALTERNATE_FONT_DIR_3 "/usr/X11R6/lib/X11/fonts"
+
+#define NXAGENT_DEFAULT_FONT_PATH \
+"/usr/share/nx/fonts/misc/,/usr/share/nx/fonts/Speedo/,\
+/usr/share/nx/fonts/Type1/,/usr/share/nx/fonts/75dpi/,\
+/usr/share/nx/fonts/100dpi/,/usr/share/nx/fonts/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH \
+"/usr/share/X11/fonts/misc/,/usr/share/X11/fonts/Speedo/,\
+/usr/share/X11/fonts/Type1/,/usr/share/X11/fonts/75dpi/,\
+/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_2 \
+"/usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Speedo/,\
+/usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,\
+/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_3 \
+"/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,\
+/usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/75dpi/,\
+/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/"
+
+#undef NXAGENT_FONTCACHE_DEBUG
+#undef NXAGENT_RECONNECT_FONT_DEBUG
+#undef NXAGENT_FONTMATCH_DEBUG
+
+#define FIELDS 14
+
+static int reconnectFlexibility;
+
+static void nxagentCleanCacheAfterReconnect(void);
+static void nxagentFontReconnect(FontPtr, XID, void *);
+static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont);
+static XFontStruct *nxagentLoadQueryFont(register Display *dpy , char *fontName , FontPtr pFont);
+int nxagentFreeFont(XFontStruct *fs);
+static Bool nxagentGetFontServerPath(char * fontServerPath);
+
+static char * nxagentMakeScalableFontName(const char *fontName, int scalableResolution);
+
+RESTYPE RT_NX_FONT;
+
+#ifdef NXAGENT_RECONNECT_FONT_DEBUG
+static void printFontCacheDump(char*);
+#endif
+
+typedef struct _nxagentFontRec
+{
+ char *name;
+ int status;
+} nxagentFontRec, *nxagentFontRecPtr;
+
+typedef struct _nxagentFontList
+{
+ nxagentFontRecPtr *list;
+ int length;
+ int listSize;
+} nxagentFontList, *nxagentFontListPtr;
+
+nxagentFontList nxagentRemoteFontList = {NULL, (int)0, (int)0};
+
+int nxagentFontPrivateIndex;
+
+typedef struct _nxCacheFontEntry
+{
+ Atom atom;
+ XFontStruct *font_struct;
+ char *name;
+} nxCacheFontEntryRec, *nxCacheFontEntryRecPtr;
+
+static struct _nxagentFontCache
+{
+ nxCacheFontEntryRecPtr *entry;
+ int index;
+ int size;
+} nxagentFontCache = { NULL, (int) 0, (int) 0 };
+
+#define CACHE_ENTRY_PTR (nxagentFontCache.entry)
+#define CACHE_INDEX (nxagentFontCache.index)
+#define CACHE_SIZE (nxagentFontCache.size)
+#define CACHE_ENTRY(A) (CACHE_ENTRY_PTR[A])
+#define CACHE_FSTRUCT(A) (CACHE_ENTRY(A) -> font_struct)
+#define CACHE_NAME(A) (CACHE_ENTRY(A) -> name)
+#define CACHE_ATOM(A) (CACHE_ENTRY(A) -> atom)
+
+static struct _nxagentFailedToReconnectFonts
+{
+ FontPtr *font;
+ XID *id;
+ int size;
+ int index;
+} nxagentFailedToReconnectFonts = {NULL, NULL, 0, 0};
+
+/*
+ * This is used if nxagentFullGeneration is true
+ * in CloseDisplay().
+ */
+
+void nxagentFreeFontCache(void)
+{
+ int i;
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: Freeing nxagent font cache\n");
+ #endif
+
+ if (CACHE_INDEX == 0)
+ return;
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: Freeing nxagent font cache, there are [%d] entries.\n", CACHE_INDEX);
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: Freeing nxagent font cache entry [%d] entry pointer is [%p], name [%s]\n",
+ i, CACHE_ENTRY(i), CACHE_NAME(i));
+ #endif
+
+ if (CACHE_FSTRUCT(i))
+ {
+ nxagentFreeFont(CACHE_FSTRUCT(i));
+ }
+
+ free(CACHE_NAME(i));
+ free(CACHE_ENTRY(i));
+ }
+
+ free(CACHE_ENTRY_PTR);
+ CACHE_ENTRY_PTR = NULL;
+ CACHE_INDEX = 0;
+ CACHE_SIZE = 0;
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: nxagent font cache fully freed\n");
+ #endif
+
+ return;
+}
+
+void nxagentListRemoteFonts(const char *searchPattern, const int maxNames)
+{
+ int i, q, p;
+
+ char **xList;
+ int xLen = 0;
+
+ const char *patterns[] = {"*", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"};
+ int patternsQt = 2;
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return;
+ }
+
+ /*
+ * Avoid querying again the remote
+ * fonts.
+ */
+
+ if (nxagentRemoteFontList.length > 0)
+ {
+ return;
+ }
+
+ /*
+ * We can't retrieve the full remote font
+ * list with a single query, because the
+ * number of dashes in the pattern acts as
+ * a rule to select how to search for the
+ * font names, so the pattern '*' is useful
+ * to retrive the font aliases, while the
+ * other one will select the 'real' fonts.
+ */
+
+ for (p = 0; p < patternsQt; p++)
+ {
+ xList = XListFonts(nxagentDisplay, patterns[p], maxNames, &xLen);
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxagentListRemoteFonts: NXagent remote list [%s] has %d elements.\n", patterns[p], xLen);
+ #endif
+
+ /*
+ * Add the ListFont request pattern to the list with
+ * the last requested maxnames.
+ */
+
+ nxagentListRemoteAddName(searchPattern, maxNames);
+
+ for (i = 0; i < xLen; i++)
+ {
+ q = 1;
+
+ nxagentListRemoteAddName(xList[i], q);
+ }
+
+ XFreeFontNames(xList);
+ }
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+
+ fprintf(stderr, "nxagentListRemoteFonts: Printing remote font list.\n");
+
+ for (i = 0; i < nxagentRemoteFontList.length; i++)
+ {
+ fprintf(stderr, "Font# %d, \"%s\"\n", i, nxagentRemoteFontList.list[i]->name);
+ }
+
+ fprintf(stderr, "nxagentListRemoteFonts: End of list\n");
+
+ #endif
+}
+
+void nxagentListRemoteAddName(const char *name, int status)
+{
+ int pos;
+
+ if (nxagentFontFind(name, &pos))
+ {
+ if (nxagentRemoteFontList.list[pos]->status < status)
+ {
+ nxagentRemoteFontList.list[pos]->status = status;
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Font: Font# %d, [%s] change status to %s\n",
+ pos, nxagentRemoteFontList.list[pos]->name,nxagentRemoteFontList.list[pos]->status?"OK":"deleted");
+ #endif
+ }
+ return;
+ }
+
+ if (nxagentRemoteFontList.length == nxagentRemoteFontList.listSize)
+ {
+ nxagentRemoteFontList.list = realloc(nxagentRemoteFontList.list, sizeof(nxagentFontRecPtr)
+ * (nxagentRemoteFontList.listSize + 1000));
+
+ if (nxagentRemoteFontList.list == NULL)
+ {
+ FatalError("Font: remote list memory re-allocation failed!.\n");
+ }
+
+ nxagentRemoteFontList.listSize += 1000;
+ }
+
+ if (pos < nxagentRemoteFontList.length)
+ {
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Font: Going to move list from %p to %p len = %d!.\n",
+ &nxagentRemoteFontList.list[pos], &nxagentRemoteFontList.list[pos+1],
+ (nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
+ #endif
+
+ memmove(&nxagentRemoteFontList.list[pos+1],
+ &nxagentRemoteFontList.list[pos],
+ (nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
+ }
+
+ if ((nxagentRemoteFontList.list[pos] = malloc(sizeof(nxagentFontRec))))
+ {
+ nxagentRemoteFontList.list[pos]->name = malloc(strlen(name) +1);
+ if (nxagentRemoteFontList.list[pos]->name == NULL)
+ {
+ fprintf(stderr, "Font: remote list name memory allocation failed!.\n");
+ return;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Font: remote list record memory allocation failed!.\n");
+ return;
+ }
+ strcpy(nxagentRemoteFontList.list[pos]->name,name);
+ nxagentRemoteFontList.list[pos]->status = status;
+ nxagentRemoteFontList.length++;
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Font: remote font list added [%s] in position [%d] as %s !.\n",
+ name, pos, status ? "OK" : "deleted");
+ fprintf(stderr, "Font: remote font list total len is [%d] Size is [%d] !.\n",
+ nxagentRemoteFontList.length, nxagentRemoteFontList.listSize);
+ #endif
+}
+
+static void nxagentFreeRemoteFontList(nxagentFontList *listRec)
+{
+ int l;
+
+ for (l = 0; l < listRec -> length; l++)
+ {
+ if (listRec -> list[l])
+ {
+ free(listRec -> list[l] -> name);
+ listRec -> list[l] -> name = NULL;
+
+ free(listRec -> list[l]);
+ listRec -> list[l] = NULL;
+ }
+ }
+
+ listRec -> length = listRec -> listSize = 0;
+
+ free(listRec -> list);
+ listRec -> list = NULL;
+
+ return;
+}
+
+Bool nxagentFontFind(const char *name, int *pos)
+{
+ int low,high,res,iter,lpos;
+
+ if (!nxagentRemoteFontList.length)
+ {
+ *pos=0;
+ return False;
+ }
+ low = 0;
+ high = nxagentRemoteFontList.length - 1;
+ iter = 0;
+ res = 1;
+ lpos = nxagentRemoteFontList.length;
+ while (low <= high)
+ {
+ *pos = (high + low)/2;
+ iter ++;
+ res = strcasecmp(nxagentRemoteFontList.list[*pos]->name,name);
+ if (res > 0)
+ {
+ high = *pos - 1;
+ lpos = *pos;
+ continue;
+ }
+ else if (res < 0)
+ {
+ low = *pos + 1;
+ lpos = low;
+ continue;
+ }
+ break;
+ }
+ *pos = (res == 0)?*pos:lpos;
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ if (res == 0)
+ fprintf(stderr, "Font: font found in %d iterations in pos = %d\n", iter, *pos);
+ else
+ fprintf(stderr, "Font: not font found in %d iterations insertion pos is = %d\n", iter, *pos);
+ #endif
+
+ return (res == 0);
+
+}
+
+Bool nxagentFontLookUp(const char *name)
+{
+ int i;
+ int result;
+
+ char *scalable;
+
+ if (name != NULL && strlen(name) == 0)
+ {
+ return 0;
+ }
+
+ result = nxagentFontFind(name, &i);
+
+ scalable = NULL;
+
+ /*
+ * Let's try with the scalable font description.
+ */
+
+ if (result == 0)
+ {
+ scalable = nxagentMakeScalableFontName(name, 0);
+
+ if (scalable != NULL)
+ {
+ result = nxagentFontFind(scalable, &i);
+
+ free(scalable);
+ }
+ }
+
+ /*
+ * Let's try again after replacing zero to xdpi and ydpi in the pattern.
+ */
+
+ if (result == 0)
+ {
+ scalable = nxagentMakeScalableFontName(name, 1);
+
+ if (scalable != NULL)
+ {
+ result = nxagentFontFind(scalable, &i);
+
+ free(scalable);
+ }
+ }
+
+ if (result == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return (nxagentRemoteFontList.list[i]->status > 0);
+ }
+}
+
+Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ void * priv;
+ Atom name_atom, value_atom;
+ int nprops;
+ FontPropPtr props;
+ int i;
+ const char *name;
+ char *origName = (char*) pScreen;
+
+#ifdef HAS_XFONT2
+ xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL);
+#else
+ FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
+#endif /* HAS_XFONT2 */
+
+ if (requestingClient && XpClientIsPrintClient(requestingClient, NULL))
+ return True;
+
+ name_atom = MakeAtom("FONT", 4, True);
+ value_atom = 0L;
+
+ nprops = pFont->info.nprops;
+ props = pFont->info.props;
+
+ for (i = 0; i < nprops; i++)
+ if ((Atom)props[i].name == name_atom) {
+ value_atom = props[i].value;
+ break;
+ }
+
+ if (!value_atom) return False;
+
+ name = NameForAtom(value_atom);
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: nxagentRealizeFont, realizing font: %s\n", validateString(name));
+ fprintf(stderr, " atom: %ld\n", value_atom);
+ fprintf(stderr, "Font: Cache dump:\n");
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ fprintf(stderr, "nxagentFontCache.entry[%d]->name: %s font_struct at %p\n",
+ i, CACHE_NAME(i), CACHE_FSTRUCT(i));
+ }
+ #endif
+
+ if (!name) return False;
+
+ if ((strcasecmp(origName, name) != 0) && !strchr(origName,'*'))
+ {
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Font: Changing font name to realize from [%s] to [%s]\n",
+ validateString(name), origName);
+ #endif
+
+ name = origName;
+ }
+
+ priv = (void *)malloc(sizeof(nxagentPrivFont));
+#ifdef HAS_XFONT2
+ xfont2_font_set_private(pFont, nxagentFontPrivateIndex, priv);
+#else
+ FontSetPrivate(pFont, nxagentFontPrivateIndex, priv);
+#endif /* HAS_XFONT2 */
+
+ nxagentFontPriv(pFont) -> mirrorID = 0;
+
+ for (i = 0; i < nxagentFontCache.index; i++)
+ {
+/* if (value_atom == CACHE_ATOM(i))*/
+ if (strcasecmp(CACHE_NAME(i), name) == 0)
+ {
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: nxagentFontCache hit [%s] = [%s]!\n", CACHE_NAME(i), validateString(name));
+ #endif
+
+ break;
+ }
+ }
+
+ if (i < CACHE_INDEX)
+ {
+ nxagentFontPriv(pFont)->font_struct = CACHE_FSTRUCT(i);
+ strcpy(nxagentFontPriv(pFont)->fontName, name);
+ }
+ else
+ {
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: nxagentFontCache fail.\n");
+ #endif
+
+ if (CACHE_INDEX == CACHE_SIZE)
+ {
+ CACHE_ENTRY_PTR = realloc(CACHE_ENTRY_PTR, sizeof(nxCacheFontEntryRecPtr) * (CACHE_SIZE + 100));
+
+ if (CACHE_ENTRY_PTR == NULL)
+ {
+ FatalError("Font: Cache list memory re-allocation failed.\n");
+ }
+
+ CACHE_SIZE += 100;
+ }
+
+ CACHE_ENTRY(CACHE_INDEX) = malloc(sizeof(nxCacheFontEntryRec));
+
+ if (CACHE_ENTRY(CACHE_INDEX) == NULL)
+ {
+ return False;
+ }
+
+ CACHE_NAME(CACHE_INDEX) = malloc(strlen(name) + 1);
+
+ if (CACHE_NAME(CACHE_INDEX) == NULL)
+ {
+ return False;
+ }
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Font: Going to realize font [%s],[%s] on real X server.\n", validateString(name), origName);
+ #endif
+
+ if (nxagentRemoteFontList.length == 0 && (NXDisplayError(nxagentDisplay) == 0))
+ {
+ nxagentListRemoteFonts("*", nxagentMaxFontNames);
+ }
+
+ nxagentFontPriv(pFont)->font_struct = nxagentLoadQueryFont(nxagentDisplay, (char *)name, pFont);
+ strcpy(nxagentFontPriv(pFont)->fontName, name);
+ if (nxagentFontPriv(pFont)->font_struct != NULL)
+ {
+ CACHE_ATOM(i) = value_atom;
+ strcpy(CACHE_NAME(i), name);
+ CACHE_FSTRUCT(i) = nxagentFontPriv(pFont)->font_struct;
+ CACHE_INDEX++;
+
+ nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+ AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "Font: nxagentFontCache adds font [%s] in pos. [%d].\n",
+ validateString(name), CACHE_INDEX - 1);
+ #endif
+ }
+ }
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+
+ if (nxagentFontPriv(pFont)->font_struct == NULL)
+ {
+ if (nxagentFontLookUp(name) == False)
+ {
+ fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s, not in our remote list\n",
+ validateString(name));
+ }
+ else
+ {
+ fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s but the font is in our remote list\n",
+ validateString(name));
+ }
+ }
+ else
+ fprintf(stderr, "Font: nxagentRealizeFont OK realizing font Font=%s\n",
+ validateString(name));
+
+ #endif
+
+ return (nxagentFontPriv(pFont)->font_struct != NULL);
+}
+
+Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ if (nxagentFontPriv(pFont))
+ {
+ if (NXDisplayError(nxagentDisplay) == 0)
+ {
+ if (nxagentFontStruct(pFont))
+ {
+ int i;
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (CACHE_FSTRUCT(i) == nxagentFontStruct(pFont))
+ {
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "nxagentUnrealizeFont: Not freeing the font in cache.\n");
+ #endif
+
+ break;
+ }
+ }
+
+ if (i == CACHE_INDEX)
+ {
+ /*
+ * This font is not in the cache.
+ */
+
+ #ifdef NXAGENT_FONTCACHE_DEBUG
+ fprintf(stderr, "nxagentUnrealizeFont: Freeing font not found in cache '%d'\n",
+ CACHE_ATOM(i));
+ #endif
+
+ XFreeFont(nxagentDisplay, nxagentFontStruct(pFont));
+ }
+ }
+ }
+
+ if (nxagentFontPriv(pFont) -> mirrorID)
+ FreeResource(nxagentFontPriv(pFont) -> mirrorID, RT_NONE);
+
+ free(nxagentFontPriv(pFont));
+#ifdef HAS_XFONT2
+ xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL);
+#else
+ FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
+#endif /* HAS_XFONT2 */
+ }
+
+ return True;
+}
+
+int nxagentDestroyNewFontResourceType(void * p, XID id)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyNewFontResourceType: Destroying mirror id [%ld] for font at [%p].\n",
+ nxagentFontPriv((FontPtr) p) -> mirrorID, (void *) p);
+ #endif
+
+/*
+FIXME: It happens that this resource had been already
+ destroied. We should verify if the same font is
+ assigned both to the server client and another
+ client. We had a crash when freeing server client
+ resources.
+*/
+ if (nxagentFontPriv((FontPtr) p) != NULL)
+ {
+ nxagentFontPriv((FontPtr) p) -> mirrorID = None;
+ }
+
+ return 1;
+}
+
+static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont)
+{
+ XFontStruct *fontStruct;
+
+ char *substFontBuf;
+
+ /* X Logical Font Description Conventions
+ * require 14 fields in the font names.
+ *
+ */
+ char *searchFields[FIELDS+1];
+ char *fontNameFields[FIELDS+1];
+ int i;
+ int j;
+ int numSearchFields = 0;
+ int numFontFields = 0;
+ int weight = 0;
+ int tempWeight = 1;
+ int fieldOrder[14] = { 4, /* Slant */
+ 11, /* Spacing */
+ 12, /* Width info */
+ 13, /* Charset */
+ 14, /* Language */
+ 7, /* Height */
+ 6, /* Add-style */
+ 3, /* Weight */
+ 2, /* Name */
+ 1, /* Foundry */
+ 9, /* DPI_x */
+ 5, /* Set-width */
+ 8, /* Point size */
+ 10 /* DPI_y */
+ };
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentLoadBestQueryFont: Searching font '%s' .\n", fontName);
+ #endif
+
+ substFontBuf = (char *) malloc(sizeof(char) * 512);
+
+
+ numFontFields = nxagentSplitString(fontName, fontNameFields, FIELDS + 1, "-");
+
+ memcpy(substFontBuf, "fixed\0", strlen("fixed") + 1);
+
+ if (numFontFields <= FIELDS)
+ {
+ #ifdef WARNING
+ if (nxagentVerbose == 1)
+ {
+ fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Font name in non standard format. \n");
+ }
+ #endif
+ }
+ else
+ {
+ for (i = 1 ; i < nxagentRemoteFontList.length ; i++)
+ {
+ numSearchFields = nxagentSplitString(nxagentRemoteFontList.list[i]->name, searchFields, FIELDS+1, "-");
+
+
+ /* The following code attemps to find an accurate approximation
+ * of the missing font. The current candidate and the missing font are
+ * compared on the 14 fields of the X Logical Font Description Convention.
+ * The selection is performed by the analysis of the matching fields,
+ * shifting left the value of the Weight variable on the right matches
+ * and shifting right the value of the Weight on the wrong ones;
+ * due a probability of overmuch right shifting, the starting weight is set
+ * to a high value. At the end of matching the selected font is the one
+ * with the bigger final Weight. The shift operation has been used instead
+ * of other operation for a performance issue.
+ * In some check the shift is performed by more than one position, because
+ * of the relevance of the field; for example a correct slant or a matching
+ * charset is more relevant than the size.
+ */
+
+ if (numSearchFields > FIELDS)
+ {
+
+ tempWeight = 0;
+
+ for (j = 0; j < FIELDS; j++)
+ {
+ if (strcasecmp(searchFields[fieldOrder[j]], fontNameFields[fieldOrder[j]]) == 0 ||
+ strcmp(searchFields[fieldOrder[j]], "") == 0 ||
+ strcmp(fontNameFields[fieldOrder[j]], "") != 0 ||
+ strcmp(searchFields[fieldOrder[j]], "*") == 0 ||
+ strcmp(fontNameFields[fieldOrder[j]], "*") == 0)
+ {
+ tempWeight ++;
+ }
+
+ tempWeight <<= 1;
+ }
+
+ }
+
+ if (tempWeight > weight)
+ {
+ /* Found more accurate font */
+
+ weight = tempWeight;
+ memcpy(substFontBuf, nxagentRemoteFontList.list[i]->name, strlen(nxagentRemoteFontList.list[i]->name));
+ substFontBuf[strlen(nxagentRemoteFontList.list[i]->name)] = '\0';
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentLoadBestQueryFont: Weight '%d' of more accurate font '%s' .\n", weight, substFontBuf);
+ #endif
+ }
+
+ for (j = 0; j < numSearchFields; j++)
+ {
+ if (searchFields[j] != NULL)
+ {
+ free(searchFields[j]);
+ }
+ }
+ }
+ }
+
+ #ifdef WARNING
+ if (nxagentVerbose == 1)
+ {
+ fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Failed to load font '%s'. Replacing with '%s'.\n",
+ fontName, substFontBuf);
+ }
+ #endif
+
+ fontStruct = nxagentLoadQueryFont(dpy, substFontBuf, pFont);
+
+ free (substFontBuf);
+
+ for (j = 0; j < numFontFields; j++)
+ {
+ if (fontNameFields[j] != NULL)
+ {
+ free(fontNameFields[j]);
+ }
+ }
+
+ return fontStruct;
+}
+
+static void nxagentFontDisconnect(FontPtr pFont, XID param1, void * param2)
+{
+ nxagentPrivFont *privFont;
+ Bool *pBool = (Bool*)param2;
+ int i;
+
+ if (pFont == NULL || !*pBool)
+ return;
+
+ privFont = nxagentFontPriv(pFont);
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontDisconnect: pFont %p, XID %lx\n",
+ (void *) pFont, privFont -> font_struct ? nxagentFont(pFont) : 0);
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontDisconnect: font %s found in cache at position %d\n",
+ privFont -> fontName, i);
+ #endif
+
+ privFont -> font_struct = NULL;
+ return;
+ }
+ }
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontDisconnect: WARNING font %s not found in cache freeing it now\n",
+ privFont -> fontName);
+ #endif
+
+ if (privFont -> font_struct)
+ {
+ XFreeFont(nxagentDisplay, privFont -> font_struct);
+ privFont -> font_struct = NULL;
+ }
+}
+
+static void nxagentCollectFailedFont(FontPtr fpt, XID id)
+{
+
+ if (nxagentFailedToReconnectFonts.font == NULL)
+ {
+ nxagentFailedToReconnectFonts.size = 8;
+
+ nxagentFailedToReconnectFonts.font = malloc(nxagentFailedToReconnectFonts.size *
+ sizeof(FontPtr));
+
+ nxagentFailedToReconnectFonts.id = malloc(nxagentFailedToReconnectFonts.size * sizeof(XID));
+
+ if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
+ {
+ FatalError("Font: font not reconnected memory allocation failed!.\n");
+ }
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentCollectFailedFont: allocated [%d] bytes.\n",
+ 8 * (sizeof(FontPtr)+ sizeof(XID)));
+ #endif
+ }
+ else if (nxagentFailedToReconnectFonts.index == nxagentFailedToReconnectFonts.size - 1)
+ {
+ nxagentFailedToReconnectFonts.size *= 2;
+
+ nxagentFailedToReconnectFonts.font = realloc(nxagentFailedToReconnectFonts.font,
+ nxagentFailedToReconnectFonts.size *
+ sizeof(FontPtr));
+
+ nxagentFailedToReconnectFonts.id = realloc(nxagentFailedToReconnectFonts.id,
+ nxagentFailedToReconnectFonts.size *
+ sizeof(XID));
+
+ if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
+ {
+ FatalError("Font: font not reconnected memory re-allocation failed!.\n");
+ }
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr,"nxagentCollectFailedFont: reallocated memory.\n ");
+ #endif
+ }
+
+ nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index] = fpt;
+
+ nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index] = id;
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentCollectFailedFont: font not reconnected at [%p], "
+ "put in nxagentFailedToReconnectFonts.font[%d] = [%p], with XID = [%lu].\n",
+ (void*) fpt, nxagentFailedToReconnectFonts.index,
+ (void *)nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index],
+ nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index]);
+ #endif
+
+ nxagentFailedToReconnectFonts.index++;
+}
+
+static void nxagentFontReconnect(FontPtr pFont, XID param1, void * param2)
+{
+ int i;
+ nxagentPrivFont *privFont;
+ Bool *pBool = (Bool*)param2;
+
+ if (pFont == NULL)
+ return;
+
+ privFont = nxagentFontPriv(pFont);
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontReconnect: pFont %p - XID %lx - name %s\n",
+ (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
+ privFont -> fontName);
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "\tfound in cache");
+ #endif
+
+ if (!CACHE_FSTRUCT(i))
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, " --- font struct not valid\n");
+ #endif
+
+ break;
+ }
+
+ nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
+
+ return;
+ }
+ }
+
+ if (i == CACHE_INDEX)
+ {
+ FatalError("nxagentFontReconnect: font not found in cache.");
+ }
+
+ privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+
+ if ((privFont -> font_struct == NULL) && reconnectFlexibility)
+ {
+ privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+ }
+
+ if (privFont->font_struct != NULL)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
+ #endif
+
+ CACHE_FSTRUCT(i) = privFont -> font_struct;
+ }
+ else
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontReconnect: failed\n");
+ #endif
+
+ nxagentCollectFailedFont(pFont, param1);
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFontReconnect: reconnection of font [%s] failed.\n",
+ privFont -> fontName);
+ #endif
+
+ nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
+ "Couldn't restore the font '%s'", privFont -> fontName);
+
+ *pBool = False;
+ }
+
+ return;
+}
+
+static void nxagentFreeCacheBeforeReconnect(void)
+{
+ int i;
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ printFontCacheDump("nxagentFreeCacheBeforeReconnect");
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (CACHE_FSTRUCT(i))
+ {
+ nxagentFreeFont(CACHE_FSTRUCT(i));
+ CACHE_FSTRUCT(i) = NULL;
+ }
+ }
+}
+
+static void nxagentCleanCacheAfterReconnect(void)
+{
+ int i, j;
+ int real_size = CACHE_INDEX;
+ nxCacheFontEntryRecPtr swapEntryPtr;
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ printFontCacheDump("nxagentCleanCacheAfterReconnect");
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if(CACHE_FSTRUCT(i) == NULL)
+ {
+ XFree(CACHE_NAME(i));
+ real_size--;
+ }
+ }
+
+ for (i = 0; i < real_size; i++)
+ {
+ /* Find - first bad occurrence if exist. */
+ while ((i < real_size) && CACHE_FSTRUCT(i)) i++;
+
+ /* Really nothing more to do. */
+ if (i == real_size)
+ break;
+
+ /*
+ * Find - first good occurrence (moving backward from right end) entry in
+ * order to replace the bad one.
+ */
+ for (j = CACHE_INDEX - 1; CACHE_FSTRUCT(j) == NULL; j--);
+
+ /*
+ * Now we can swap the two entry
+ * and reduce the Cache index
+ */
+ swapEntryPtr = CACHE_ENTRY(i);
+ CACHE_ENTRY(i) = CACHE_ENTRY(j);
+ CACHE_ENTRY(j) = swapEntryPtr;
+ }
+
+ CACHE_INDEX = real_size;
+}
+
+#ifdef NXAGENT_RECONNECT_FONT_DEBUG
+static void printFontCacheDump(char* msg)
+{
+ int i;
+
+ fprintf(stderr, "%s - begin -\n", msg);
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (CACHE_FSTRUCT(i))
+ {
+ fprintf(stderr, "\tXID %lx - %s\n", CACHE_FSTRUCT(i) -> fid, CACHE_NAME(i));
+ }
+ else
+ {
+ fprintf(stderr, "\tdestroyed - %s\n", CACHE_NAME(i));
+ }
+ }
+ fprintf(stderr, "%s - end -\n", msg);
+}
+#endif
+
+Bool nxagentReconnectAllFonts(void *p0)
+{
+ int cid;
+ Bool fontSuccess = True;
+
+ reconnectFlexibility = *((int *) p0);
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllFonts\n");
+ #endif
+
+ /*
+ * The resource type RT_NX_FONT is created on the
+ * server client only, so we can avoid to loop
+ * through all the clients.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
+ (FindResType) nxagentFontReconnect, &fontSuccess);
+
+ for (cid = 0; cid < MAXCLIENTS; cid++)
+ {
+ if (clients[cid])
+ {
+ FindClientResourcesByType(clients[cid], RT_FONT,
+ (FindResType) nxagentFontReconnect, &fontSuccess);
+ }
+ }
+
+ if (fontSuccess)
+ {
+ nxagentCleanCacheAfterReconnect();
+ }
+
+ return fontSuccess;
+}
+
+static void nxagentFailedFontReconnect(FontPtr pFont, XID param1, void * param2)
+{
+ int i;
+ nxagentPrivFont *privFont;
+ Bool *pBool = (Bool*)param2;
+
+ if (pFont == NULL)
+ return;
+
+ privFont = nxagentFontPriv(pFont);
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFailedFontReconnect: pFont %p - XID %lx - name %s\n",
+ (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
+ privFont -> fontName);
+ #endif
+
+ for (i = 0; i < CACHE_INDEX; i++)
+ {
+ if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "\tfound in cache");
+ #endif
+
+ if (!CACHE_FSTRUCT(i))
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, " --- font struct not valid\n");
+ #endif
+
+ break;
+ }
+
+ nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
+
+ return;
+ }
+ }
+
+ if (i == CACHE_INDEX)
+ {
+ FatalError("nxagentFailedFontReconnect: font not found in cache.");
+ }
+
+ privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+
+ if (privFont -> font_struct == NULL)
+ {
+ privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+ }
+
+ if (privFont->font_struct != NULL)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
+ #endif
+
+ CACHE_FSTRUCT(i) = privFont -> font_struct;
+ }
+ else
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFailedFontReconnect: failed\n");
+ #endif
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentFailedFontReconnect: reconnection of font [%s] failed.\n",
+ privFont -> fontName);
+ #endif
+
+ nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
+ "Couldn't restore the font '%s'", privFont -> fontName);
+
+ *pBool = False;
+ }
+
+ return;
+}
+
+static void nxagentFreeFailedToReconnectFonts()
+{
+ if (nxagentFailedToReconnectFonts.font != NULL)
+ {
+ free(nxagentFailedToReconnectFonts.font);
+ nxagentFailedToReconnectFonts.font = NULL;
+ }
+
+ if (nxagentFailedToReconnectFonts.id != NULL)
+ {
+ free(nxagentFailedToReconnectFonts.id);
+ nxagentFailedToReconnectFonts.id = NULL;
+ }
+
+ nxagentFailedToReconnectFonts.size = 0;
+ nxagentFailedToReconnectFonts.index = 0;
+}
+
+Bool nxagentReconnectFailedFonts(void *p0)
+{
+ int i;
+ int attempt = 1;
+ const int maxAttempt = 5;
+
+ char **fontPaths, **localFontPaths, **newFontPaths;
+ char fontServerPath[256] = "";
+ int nPaths = 0;
+
+ Bool repeat = True;
+ Bool fontSuccess = True;
+
+ reconnectFlexibility = *((int *) p0);
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentReconnectFailedFonts: \n");
+ #endif
+
+ if (nxagentGetFontServerPath(fontServerPath) == False)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectFailedFonts: WARNING! "
+ "Font server tunneling not retrieved.\n");
+ #endif
+ }
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentReconnectFailedFonts: font server path [%s]\n", fontServerPath);
+ #endif
+
+ fontPaths = XGetFontPath(nxagentDisplay, &nPaths);
+
+ if ((newFontPaths = malloc((nPaths + 1) * sizeof(char *))) == NULL)
+ {
+ FatalError("nxagentReconnectFailedFonts: malloc failed.");
+ }
+
+ memcpy(newFontPaths, fontPaths, nPaths * sizeof(char*));
+
+ localFontPaths = newFontPaths;
+ localFontPaths += nPaths;
+ *localFontPaths = fontServerPath;
+
+ while(repeat)
+ {
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentReconnectFailedFonts: attempt [%d].\n", attempt);
+ #endif
+
+ repeat = False;
+
+ XSetFontPath(nxagentDisplay, newFontPaths, nPaths + 1);
+ nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+ nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+ for(i = 0; i < nxagentFailedToReconnectFonts.index; i++)
+ {
+ fontSuccess = True;
+
+ if(nxagentFailedToReconnectFonts.font[i])
+ {
+ nxagentFailedFontReconnect(nxagentFailedToReconnectFonts.font[i],
+ nxagentFailedToReconnectFonts.id[i],
+ &fontSuccess);
+
+ if (fontSuccess)
+ {
+ nxagentFailedToReconnectFonts.font[i] = NULL;
+ }
+ else
+ {
+ repeat = True;
+ }
+
+ }
+ }
+
+ attempt++;
+
+ if (attempt > maxAttempt)
+ {
+ nxagentFreeFailedToReconnectFonts();
+
+ XSetFontPath(nxagentDisplay, fontPaths, nPaths);
+ nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+ nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+ XFreeFontPath(fontPaths);
+ free(newFontPaths);
+
+ return False;
+ }
+ }
+
+ nxagentFreeFailedToReconnectFonts();
+
+ XSetFontPath(nxagentDisplay, fontPaths, nPaths);
+
+ XFreeFontPath(fontPaths);
+ free(newFontPaths);
+
+ nxagentCleanCacheAfterReconnect();
+
+ return True;
+}
+
+Bool nxagentDisconnectAllFonts()
+{
+ int cid;
+ Bool fontSuccess = True;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
+ fprintf(stderr, "nxagentDisconnectAllFonts\n");
+ #endif
+
+ nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+ nxagentFreeCacheBeforeReconnect();
+
+ /*
+ * The resource type RT_NX_FONT is created on the
+ * server client only, so we can avoid to loop
+ * through all the clients.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
+ (FindResType) nxagentFontDisconnect, &fontSuccess);
+
+ for(cid = 0; cid < MAXCLIENTS; cid++)
+ {
+ if( clients[cid] && fontSuccess )
+ {
+ FindClientResourcesByType(clients[cid], RT_FONT,
+ (FindResType) nxagentFontDisconnect, &fontSuccess);
+ }
+ }
+
+ return True;
+}
+
+static Bool nxagentGetFontServerPath(char * fontServerPath)
+{
+ char path[256];
+
+ if (NXGetFontParameters(nxagentDisplay, 256, path) == True)
+ {
+ if (*path != '\0')
+ {
+ strncpy(fontServerPath, path + 1, *path);
+
+ *(fontServerPath + *path) = '\0';
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetFontServerPath: Got path [%s].\n",
+ fontServerPath);
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetFontServerPath: WARNING! Font server tunneling not enabled.\n");
+ #endif
+
+ return False;
+ }
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetFontServerPath: WARNING! Failed to get path for font server tunneling.\n");
+ #endif
+
+ return False;
+ }
+
+ return True;
+}
+
+void nxagentVerifyDefaultFontPath(void)
+{
+ struct stat dirStat;
+ static char *fontPath;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Going to search for one or more valid font paths.\n");
+ #endif
+
+ fontPath = malloc(strlen(defaultFontPath) + 1);
+
+ if (fontPath == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Unable to allocate memory for a new font path. "
+ "Using the default font path [%s].\n", validateString(defaultFontPath));
+ #endif
+
+ return;
+ }
+
+ /*
+ * Set the default font path as the first choice.
+ */
+
+ strcpy(fontPath, defaultFontPath);
+
+ if (stat(NXAGENT_DEFAULT_FONT_DIR, &dirStat) == 0 &&
+ S_ISDIR(dirStat.st_mode) != 0)
+ {
+ /*
+ * Let's use the old "/usr/share/nx/fonts" style.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+ validateString(NXAGENT_DEFAULT_FONT_DIR));
+ #endif
+
+ if (*fontPath != '\0')
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_DEFAULT_FONT_PATH) + 2);
+ strcat(fontPath, ",");
+ }
+ else
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_DEFAULT_FONT_PATH) + 1);
+ }
+
+ strcat(fontPath, NXAGENT_DEFAULT_FONT_PATH);
+ }
+
+ if (stat(NXAGENT_ALTERNATE_FONT_DIR, &dirStat) == 0 &&
+ S_ISDIR(dirStat.st_mode) != 0)
+ {
+ /*
+ * Let's use the new "/usr/share/X11/fonts" path.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+ validateString(NXAGENT_ALTERNATE_FONT_DIR));
+ #endif
+
+ if (*fontPath != '\0')
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH) + 2);
+ strcat(fontPath, ",");
+ }
+ else
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH) + 1);
+ }
+
+ strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH);
+ }
+
+ if (stat(NXAGENT_ALTERNATE_FONT_DIR_2, &dirStat) == 0 &&
+ S_ISDIR(dirStat.st_mode) != 0)
+ {
+ /*
+ * Let's use the "/usr/share/fonts/X11" path.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+ validateString(NXAGENT_ALTERNATE_FONT_DIR_2));
+ #endif
+
+ if (*fontPath != '\0')
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_2) + 2);
+ strcat(fontPath, ",");
+ }
+ else
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_2) + 1);
+ }
+
+ strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_2);
+ }
+
+ if (stat(NXAGENT_ALTERNATE_FONT_DIR_3, &dirStat) == 0 &&
+ S_ISDIR(dirStat.st_mode) != 0)
+ {
+ /*
+ * Let's use the "/usr/X11R6/lib/X11/fonts" path.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+ validateString(NXAGENT_ALTERNATE_FONT_DIR_3));
+ #endif
+
+ if (*fontPath != '\0')
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_3) + 2);
+ strcat(fontPath, ",");
+ }
+ else
+ {
+ fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_3) + 1);
+ }
+
+ strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_3);
+ }
+ if (*fontPath == '\0')
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Can't find a valid font directory.\n");
+
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Using font path [%s].\n",
+ validateString(defaultFontPath));
+ #endif
+ }
+ else
+ {
+ defaultFontPath = fontPath;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentVerifyDefaultFontPath: Using font path [%s].\n",
+ validateString(defaultFontPath));
+ #endif
+ }
+
+ return;
+}
+
+XFontStruct* nxagentLoadQueryFont(register Display *dpy, char *name, FontPtr pFont)
+{
+ XFontStruct* fs;
+ xCharInfo *xcip;
+
+ fs = (XFontStruct *) malloc (sizeof (XFontStruct));
+
+ if (fs == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontStruct.\n");
+ #endif
+
+ return (XFontStruct *)NULL;
+ }
+
+ #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+ fprintf(stderr, "nxagentLoadQueryFont: Looking for font '%s'.\n", name);
+ #endif
+
+ if (nxagentFontLookUp(name) == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentLoadQueryFont: WARNING! Font not found '%s'.\n", name);
+ #endif
+
+ free(fs);
+
+ return (XFontStruct *) NULL;
+ }
+
+ fs -> ext_data = NULL; /* Hook for extension to hang data.*/
+ fs -> fid = XLoadFont(dpy, name); /* Font id for this font. */
+ fs -> direction = pFont->info.drawDirection; /* Hint about the direction font is painted. */
+ fs -> min_char_or_byte2 = pFont->info.firstCol; /* First character. */
+ fs -> max_char_or_byte2 = pFont->info.lastCol; /* Last character. */
+ fs -> min_byte1 = pFont->info.firstRow; /* First row that exists. */
+ fs -> max_byte1 = pFont->info.lastRow; /* Last row that exists. */
+ fs -> all_chars_exist = pFont->info.allExist; /* Flag if all characters have nonzero size. */
+ fs -> default_char = pFont->info.defaultCh; /* Char to print for undefined character. */
+ fs -> n_properties = pFont->info.nprops; /* How many properties there are. */
+
+ /*
+ * If no properties defined for the font, then it is bad
+ * font, but shouldn't try to read nothing.
+ */
+
+ if (fs -> n_properties > 0)
+ {
+ register long nbytes;
+
+ nbytes = pFont -> info.nprops * sizeof(XFontProp);
+ fs -> properties = (XFontProp *) malloc((unsigned) nbytes);
+
+ if (fs -> properties == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontProp.");
+ #endif
+
+ free((char *) fs);
+ return (XFontStruct *) NULL;
+ }
+
+ memmove(fs -> properties, pFont -> info.props, nbytes);
+ }
+
+ xcip = (xCharInfo *) &pFont -> info.ink_minbounds;
+
+ fs -> min_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing);
+ fs -> min_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing);
+ fs -> min_bounds.width = cvtINT16toShort(xcip -> characterWidth);
+ fs -> min_bounds.ascent = cvtINT16toShort(xcip -> ascent);
+ fs -> min_bounds.descent = cvtINT16toShort(xcip -> descent);
+ fs -> min_bounds.attributes = xcip -> attributes;
+
+ xcip = (xCharInfo *) &pFont -> info.ink_maxbounds;
+
+ fs -> max_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing);
+ fs -> max_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing);
+ fs -> max_bounds.width = cvtINT16toShort(xcip -> characterWidth);
+ fs -> max_bounds.ascent = cvtINT16toShort(xcip -> ascent);
+ fs -> max_bounds.descent = cvtINT16toShort(xcip -> descent);
+ fs -> max_bounds.attributes = xcip -> attributes;
+
+ fs -> per_char = NULL; /* First_char to last_char information. */
+ fs -> ascent = pFont->info.fontAscent; /* Logical extent above baseline for spacing. */
+ fs -> descent = pFont->info.fontDescent; /* Logical decent below baseline for spacing. */
+
+ return fs;
+}
+
+int nxagentFreeFont(XFontStruct *fs)
+{
+
+ if (fs -> per_char)
+ {
+ #ifdef USE_XF86BIGFONT
+ _XF86BigfontFreeFontMetrics(fs);
+ #else
+ free ((char *) fs->per_char);
+ #endif
+ }
+
+ if (fs -> properties)
+ {
+ free (fs->properties);
+ }
+
+ XFree(fs);
+
+ return 1;
+}
+
+
+int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
+{
+ int seplen;
+ int fieldlen;
+ int last;
+ int len;
+ int i;
+
+ char *current;
+ char *next;
+
+ seplen = strlen(sep);
+ len = strlen(string);
+
+ current = string;
+
+ i = 0;
+ last = 0;
+
+ for (;;)
+ {
+ next = NULL;
+
+ if (current < string + len)
+ {
+ next = strstr(current, sep);
+ }
+
+ if (next == NULL)
+ {
+ next = string + len;
+ last = 1;
+ }
+
+ fieldlen = next - current;
+
+ if (i < nfields)
+ {
+ fields[i] = (char *) malloc(fieldlen + 1);
+ strncpy(fields[i], current, fieldlen);
+ *(fields[i] + fieldlen) = 0;
+ }
+ else
+ {
+ fields[i] = NULL;
+ }
+
+ current = next + seplen;
+
+ i++;
+
+ if (last == 1)
+ {
+ break;
+ }
+ }
+
+ return i;
+}
+
+char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution)
+{
+ char *scalableFontName;
+ const char *s;
+ int len;
+ int field;
+
+ len = strlen(fontName) + 1;
+
+ scalableFontName = malloc(len);
+
+ if (scalableFontName == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
+ #endif
+
+ return NULL;
+ }
+
+ scalableFontName[0] = 0;
+
+ if (*fontName != '-')
+ {
+ goto MakeScalableFontNameError;
+ }
+
+ s = fontName;
+
+ field = 0;
+
+ while (s != NULL)
+ {
+ s = strchr(s + 1, '-');
+
+ if (s != NULL)
+ {
+ if (field == 6 || field == 7 || field == 11)
+ {
+ /*
+ * PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
+ */
+
+ strcat(scalableFontName, "-0");
+ }
+ else if (scalableResolution == 1 && (field == 8 || field == 9))
+ {
+ /*
+ * RESOLUTION_X || RESOLUTION_Y
+ */
+
+ strcat(scalableFontName, "-0");
+ }
+ else
+ {
+ strncat(scalableFontName, fontName, s - fontName);
+ }
+
+ fontName = s;
+ }
+ else
+ {
+ strcat(scalableFontName, fontName);
+ }
+
+ field++;
+ }
+
+ if (field != 14)
+ {
+ goto MakeScalableFontNameError;
+ }
+
+ return scalableFontName;
+
+MakeScalableFontNameError:
+
+ free(scalableFontName);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n");
+ #endif
+
+ return NULL;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
new file mode 100644
index 000000000..c5b236562
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -0,0 +1,85 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Font_H__
+#define __Font_H__
+
+#include <X11/fonts/fontstruct.h>
+#include "resource.h"
+
+extern RESTYPE RT_NX_FONT;
+
+extern int nxagentFontPrivateIndex;
+
+typedef struct
+{
+ XFontStruct *font_struct;
+ char fontName[256];
+ XID mirrorID;
+} nxagentPrivFont;
+
+extern const int nxagentMaxFontNames;
+
+#define nxagentFontPriv(pFont) \
+ ((nxagentPrivFont *)FontGetPrivate(pFont, nxagentFontPrivateIndex))
+
+#define nxagentFontStruct(pFont) (nxagentFontPriv(pFont)->font_struct)
+
+#define nxagentFont(pFont) (nxagentFontStruct(pFont)->fid)
+
+Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont);
+Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+void nxagentFreeFontCache(void);
+
+void nxagentListRemoteFonts(const char *searchPattern, const int maxNames);
+int nxagentFontLookUp(const char *name);
+Bool nxagentFontFind(const char *name, int *pos);
+void nxagentListRemoteAddName(const char *name, int status);
+
+int nxagentDestroyNewFontResourceType(void * p, XID id);
+
+Bool nxagentDisconnectAllFonts(void);
+Bool nxagentReconnectAllFonts(void *p0);
+
+void nxagentVerifyDefaultFontPath(void);
+
+int nxagentSplitString(char *string, char *fields[], int nfields, char *sep);
+
+#endif /* __Font_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
new file mode 100644
index 000000000..abe66602a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -0,0 +1,1717 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "mistruct.h"
+#include "region.h"
+
+#include "Agent.h"
+
+#include "Display.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "Font.h"
+#include "Colormap.h"
+#include "Trap.h"
+#include "Screen.h"
+#include "Pixels.h"
+
+#include "../../fb/fb.h"
+
+RESTYPE RT_NX_GC;
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int nxagentGCPrivateIndex;
+
+nxagentGraphicContextsPtr nxagentGraphicContexts;
+int nxagentGraphicContextsSize;
+
+void nxagentDisconnectGraphicContexts(void);
+GCPtr nxagentCreateGraphicContext(int depth);
+
+static void nxagentReconnectGC(void*, XID, void*);
+static void nxagentReconnectClip(GCPtr, int, void *, int);
+static int nxagentCompareRegions(RegionPtr, RegionPtr);
+
+struct nxagentGCRec
+{
+ GCPtr pGC;
+ XlibGC gc;
+ struct nxagentGCRec *next;
+};
+
+static struct
+{
+ struct nxagentGCRec *first;
+ struct nxagentGCRec *last;
+ int size;
+} nxagentGCList = { NULL, NULL, 0 };
+
+static struct nxagentGCRec *nxagentGetFirstGC(void);
+
+static void nxagentRestoreGCList(void);
+
+static GCFuncs nxagentFuncs =
+{
+ nxagentValidateGC,
+ nxagentChangeGC,
+ nxagentCopyGC,
+ nxagentDestroyGC,
+ nxagentChangeClip,
+ nxagentDestroyClip,
+ nxagentCopyClip,
+};
+
+static GCOps nxagentOps =
+{
+ nxagentFillSpans,
+ nxagentSetSpans,
+ nxagentPutImage,
+ nxagentCopyArea,
+ nxagentCopyPlane,
+ nxagentPolyPoint,
+ nxagentPolyLines,
+ nxagentPolySegment,
+ nxagentPolyRectangle,
+ nxagentPolyArc,
+ nxagentFillPolygon,
+ nxagentPolyFillRect,
+ nxagentPolyFillArc,
+ nxagentPolyText8,
+ nxagentPolyText16,
+ nxagentImageText8,
+ nxagentImageText16,
+ nxagentImageGlyphBlt,
+ nxagentPolyGlyphBlt,
+ nxagentPushPixels
+};
+
+Bool nxagentCreateGC(GCPtr pGC)
+{
+ FbGCPrivPtr pPriv;
+
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+
+ pGC->funcs = &nxagentFuncs;
+ pGC->ops = &nxagentOps;
+
+ pGC->miTranslate = 1;
+
+ if (pGC -> stipple && !nxagentPixmapIsVirtual(pGC -> stipple))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCreateGC: GC at [%p] got real stipple at [%p] switched to virtual.\n",
+ (void*)pGC, (void*)pGC -> stipple);
+ #endif
+
+ pGC -> stipple = nxagentVirtualPixmap(pGC -> stipple);
+ }
+
+ /*
+ * We create the GC based on the default
+ * drawables. The proxy knows this and
+ * optimizes the encoding of the create
+ * GC message to include the id of the
+ * drawable in the checksum.
+ */
+
+ nxagentGCPriv(pGC)->gc = XCreateGC(nxagentDisplay,
+ nxagentDefaultDrawables[pGC->depth],
+ 0L, NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateGC: GC [%p]\n", (void *) pGC);
+ #endif
+
+ pPriv = (pGC)->devPrivates[fbGCPrivateIndex].ptr;
+
+ fbGetRotatedPixmap(pGC) = 0;
+ fbGetExpose(pGC) = 1;
+ fbGetFreeCompClip(pGC) = 0;
+ fbGetCompositeClip(pGC) = 0;
+
+ pPriv->bpp = BitsPerPixel (pGC->depth);
+
+ nxagentGCPriv(pGC)->nClipRects = 0;
+
+ memset(&(nxagentGCPriv(pGC) -> lastServerValues), 0, sizeof(XGCValues));
+
+ /*
+ * Init to default GC values.
+ */
+
+ nxagentGCPriv(pGC) -> lastServerValues.background = 1;
+
+ nxagentGCPriv(pGC) -> lastServerValues.plane_mask = ~0;
+
+ nxagentGCPriv(pGC) -> lastServerValues.graphics_exposures = 1;
+
+ nxagentGCPriv(pGC) -> lastServerValues.dashes = 4;
+
+ nxagentGCPriv(pGC) -> mid = FakeClientID(serverClient -> index);
+
+ nxagentGCPriv(pGC) -> pPixmap = NULL;
+
+ AddResource(nxagentGCPriv(pGC) -> mid, RT_NX_GC, (void *) pGC);
+
+ return True;
+}
+
+void nxagentValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ PixmapPtr lastTile, lastStipple;
+
+ DrawablePtr pVirtual = (pDrawable -> type == DRAWABLE_PIXMAP) ?
+ nxagentVirtualDrawable(pDrawable) :
+ pDrawable;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateGC: Going to validate GC at [%p] for drawable at [%p] with changes [%lx].\n",
+ (void *) pGC, (void *) pDrawable, changes);
+ #endif
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+
+ if (!pGC -> tileIsPixel && !nxagentPixmapIsVirtual(pGC -> tile.pixmap))
+ {
+ pGC -> tile.pixmap = nxagentVirtualPixmap(pGC -> tile.pixmap);
+ }
+
+ lastTile = pGC -> tile.pixmap;
+
+ lastStipple = pGC->stipple;
+
+ if (lastStipple)
+ {
+ pGC->stipple = nxagentVirtualPixmap(pGC->stipple);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateGC: Drawable at [%p] has type [%s] virtual [%p] bits per pixel [%d].\n",
+ (void *) pDrawable, (pDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+ (void *) pVirtual, pVirtual -> bitsPerPixel);
+ #endif
+
+ if (pVirtual -> bitsPerPixel == 0)
+ {
+ /*
+ * Don't enter fbValidateGC() with 0 bpp
+ * or agent will block in a endless loop.
+ */
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentValidateGC: WARNING! Virtual drawable at [%p] has invalid bits per pixel.\n",
+ (void *) pVirtual);
+
+ fprintf(stderr, "nxagentValidateGC: WARNING! While validating GC at [%p] for drawable at [%p] with changes [%lx].\n",
+ (void *) pGC, (void *) pDrawable, changes);
+
+ fprintf(stderr, "nxagentValidateGC: WARNING! Bad drawable at [%p] has type [%s] virtual [%p] bits per pixel [%d].\n",
+ (void *) pDrawable, (pDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+ (void *) pVirtual, pVirtual -> bitsPerPixel);
+ #endif
+ }
+ else
+ {
+ fbValidateGC(pGC, changes, pVirtual);
+ }
+
+ if (pGC->tile.pixmap != lastTile)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentValidateGC: WARNING! Transforming pixmap at [%p] virtual at [%p] "
+ "in virtual pixmap.\n", (void *) nxagentPixmapPriv(pGC -> tile.pixmap) -> pRealPixmap,
+ (void *) nxagentPixmapPriv(pGC -> tile.pixmap) -> pRealPixmap);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateGC: GC [%p] new tile [%p] from fb set as virtual\n",
+ (void *) pGC, (void *) pGC->tile.pixmap);
+ #endif
+
+ nxagentPixmapIsVirtual(pGC->tile.pixmap) = True;
+ nxagentRealPixmap(pGC->tile.pixmap) = nxagentRealPixmap(lastTile);
+
+ if (nxagentRealPixmap(lastTile))
+ {
+ nxagentPixmapPriv(nxagentRealPixmap(lastTile))->pVirtualPixmap = pGC->tile.pixmap;
+ }
+ }
+
+ pGC->stipple = lastStipple;
+}
+
+void nxagentChangeGC(GCPtr pGC, unsigned long mask)
+{
+ #ifdef TEST
+ static int nDiscarded;
+ #endif
+
+ XGCValues values;
+
+ int changeFlag = 0;
+
+ if (mask & GCFunction)
+ {
+ values.function = pGC->alu;
+
+ changeFlag |= nxagentTestGC(values.function, function);
+ }
+
+ if (mask & GCPlaneMask)
+ {
+ values.plane_mask = pGC->planemask;
+
+ changeFlag += nxagentTestGC(values.plane_mask, plane_mask);
+ }
+
+ if (mask & GCForeground)
+ {
+ values.foreground = nxagentPixel(pGC->fgPixel);
+
+ changeFlag += nxagentTestGC(values.foreground, foreground);
+ }
+
+ if (mask & GCBackground)
+ {
+ values.background = nxagentPixel(pGC->bgPixel);
+
+ changeFlag += nxagentTestGC(values.background, background);
+ }
+
+ if (mask & GCLineWidth)
+ {
+ values.line_width = pGC->lineWidth;
+
+ changeFlag += nxagentTestGC(values.line_width, line_width);
+ }
+
+ if (mask & GCLineStyle)
+ {
+ values.line_style = pGC->lineStyle;
+
+ changeFlag += nxagentTestGC(values.line_style, line_style);
+ }
+
+ if (mask & GCCapStyle)
+ {
+ values.cap_style = pGC->capStyle;
+
+ changeFlag += nxagentTestGC(values.cap_style, cap_style);
+ }
+
+ if (mask & GCJoinStyle)
+ {
+ values.join_style = pGC->joinStyle;
+
+ changeFlag += nxagentTestGC(values.join_style, join_style);
+ }
+
+ if (mask & GCFillStyle)
+ {
+ values.fill_style = pGC->fillStyle;
+
+ changeFlag += nxagentTestGC(values.fill_style, fill_style);
+ }
+
+ if (mask & GCFillRule)
+ {
+ values.fill_rule = pGC->fillRule;
+
+ changeFlag += nxagentTestGC(values.fill_rule, fill_rule);
+ }
+
+ if (mask & GCTile)
+ {
+ if (pGC->tileIsPixel)
+ {
+ mask &= ~GCTile;
+ }
+ else
+ {
+ if (nxagentDrawableStatus((DrawablePtr) pGC -> tile.pixmap) == NotSynchronized &&
+ nxagentGCTrap == 0)
+ {
+ /*
+ * If the tile is corrupted and is not too
+ * much large, it can be synchronized imme-
+ * diately. In the other cases, the tile is
+ * cleared with a solid color to become usa-
+ * ble. This approach should solve the high
+ * delay on slow links waiting for a back-
+ * ground tile to be synchronized.
+ */
+
+ if (nxagentOption(DeferLevel) >= 2 &&
+ (pGC -> tile.pixmap -> drawable.width > 240 ||
+ pGC -> tile.pixmap -> drawable.height > 240))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: WARNING! Going to fill with solid color the corrupted tile at [%p] "
+ "for GC at [%p] with size [%dx%d].\n", (void *) pGC -> tile.pixmap, (void *)pGC,
+ ((DrawablePtr) pGC -> tile.pixmap) -> width, ((DrawablePtr) pGC -> tile.pixmap) -> height);
+ #endif
+
+ nxagentFillRemoteRegion((DrawablePtr) pGC -> tile.pixmap, nxagentCorruptedRegion((DrawablePtr) pGC -> tile.pixmap));
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: WARNING! Synchronizing GC at [%p] due the tile at [%p] with size [%dx%d].\n",
+ (void *)pGC, (void *)pGC -> tile.pixmap, ((DrawablePtr) pGC -> tile.pixmap) -> width,
+ ((DrawablePtr) pGC -> tile.pixmap) -> height);
+ #endif
+
+ nxagentSynchronizeDrawable((DrawablePtr) pGC -> tile.pixmap, DO_WAIT, NEVER_BREAK, NULL);
+ }
+ }
+
+ values.tile = nxagentPixmap(pGC->tile.pixmap);
+
+ pGC->tile.pixmap = nxagentVirtualPixmap(pGC->tile.pixmap);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: New tile on GC [%p] tile is [%p]\n",
+ (void *) pGC, (void *) pGC->tile.pixmap);
+ #endif
+
+ changeFlag += nxagentTestGC(values.tile, tile);
+ }
+ }
+
+ if (mask & GCStipple)
+ {
+ if (nxagentDrawableStatus((DrawablePtr) pGC -> stipple) == NotSynchronized &&
+ nxagentGCTrap == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: WARNING! Synchronizing GC at [%p] due the stipple at [%p].\n",
+ (void *)pGC, (void *)pGC -> stipple);
+ #endif
+
+ nxagentSynchronizeDrawable((DrawablePtr) pGC -> stipple, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ values.stipple = nxagentPixmap(pGC->stipple);
+
+ pGC->stipple = nxagentVirtualPixmap(pGC->stipple);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: New stipple on GC [%p] stipple is [%p]\n",
+ (void *) pGC, (void *) pGC->stipple);
+ #endif
+
+ changeFlag += nxagentTestGC(values.stipple, stipple);
+ }
+
+ if (mask & GCTileStipXOrigin)
+ {
+ values.ts_x_origin = pGC->patOrg.x;
+
+ changeFlag += nxagentTestGC(values.ts_x_origin, ts_x_origin);
+ }
+
+ if (mask & GCTileStipYOrigin)
+ {
+ values.ts_y_origin = pGC->patOrg.y;
+
+ changeFlag += nxagentTestGC(values.ts_y_origin, ts_y_origin);
+ }
+
+ if (mask & GCFont)
+ {
+ if (!nxagentFontStruct(pGC -> font))
+ {
+ mask &= ~GCFont;
+ }
+ else
+ {
+ values.font = nxagentFont(pGC->font);
+
+ changeFlag += nxagentTestGC(values.font, font);
+ }
+ }
+
+ if (mask & GCSubwindowMode)
+ {
+ values.subwindow_mode = pGC->subWindowMode;
+
+ changeFlag += nxagentTestGC(values.subwindow_mode, subwindow_mode);
+ }
+
+ if (mask & GCGraphicsExposures)
+ {
+ values.graphics_exposures = pGC->graphicsExposures;
+
+ changeFlag += nxagentTestGC(values.graphics_exposures, graphics_exposures);
+ }
+
+ if (mask & GCClipXOrigin)
+ {
+ values.clip_x_origin = pGC->clipOrg.x;
+
+ changeFlag += nxagentTestGC(values.clip_x_origin, clip_x_origin);
+ }
+
+ if (mask & GCClipYOrigin)
+ {
+ values.clip_y_origin = pGC->clipOrg.y;
+
+ changeFlag += nxagentTestGC(values.clip_y_origin, clip_y_origin);
+ }
+
+ if (mask & GCClipMask)
+ {
+ /*
+ * This is handled in the change clip.
+ */
+
+ mask &= ~GCClipMask;
+ }
+
+ if (mask & GCDashOffset)
+ {
+ values.dash_offset = pGC->dashOffset;
+
+ changeFlag += nxagentTestGC(values.dash_offset, dash_offset);
+ }
+
+ if (mask & GCDashList)
+ {
+ mask &= ~GCDashList;
+
+ if (nxagentGCTrap == 0)
+ {
+ XSetDashes(nxagentDisplay, nxagentGC(pGC),
+ pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
+ }
+ }
+
+ if (mask & GCArcMode)
+ {
+ values.arc_mode = pGC->arcMode;
+
+ changeFlag += nxagentTestGC(values.arc_mode, arc_mode);
+ }
+
+ if (nxagentGCTrap == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeGC: Skipping change of GC at [%p] on the real X server.\n",
+ (void *) pGC);
+ #endif
+
+ return;
+ }
+
+ if (mask && changeFlag)
+ {
+ XChangeGC(nxagentDisplay, nxagentGC(pGC), mask, &values);
+ }
+ #ifdef TEST
+ else if (mask)
+ {
+ fprintf(stderr, "nxagentChangeGC: Discarded [%d] Mask [%lu]\n", ++nDiscarded, mask);
+ }
+ #endif
+}
+
+void nxagentCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyGC: Copying the GC with source at [%p] destination "
+ "at [%p] mask [%lu].\n", pGCSrc, pGCDst, mask);
+ #endif
+
+ /*
+ * The MI function doesn't do anything.
+ *
+ * miCopyGC(pGCSrc, mask, pGCDst);
+ */
+
+ XCopyGC(nxagentDisplay, nxagentGC(pGCSrc), mask, nxagentGC(pGCDst));
+
+ /*
+ * Copy the private foreground field
+ * of the GC if GCForeground is set.
+ */
+
+ nxagentCopyGCPriv(GCForeground,foreground,pGCSrc,mask,pGCDst);
+}
+
+void nxagentDestroyGC(GCPtr pGC)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyGC: GC at [%p].\n", (void *) pGC);
+ #endif
+
+ if (nxagentGCPriv(pGC) -> mid != 0)
+ {
+ FreeResource(nxagentGCPriv(pGC) -> mid, RT_NONE);
+ }
+
+ XFreeGC(nxagentDisplay, nxagentGC(pGC));
+
+ miDestroyGC(pGC);
+}
+
+void nxagentChangeClip(GCPtr pGC, int type, void * pValue, int nRects)
+{
+ int i, size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+ int clipsMatch = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeClip: Going to change clip on GC [%p]\n",
+ (void *) pGC);
+ #endif
+
+ switch (type)
+ {
+ case CT_NONE:
+ {
+ clipsMatch = (pGC -> clientClipType == None);
+
+ break;
+ }
+ case CT_REGION:
+ {
+ clipsMatch = nxagentCompareRegions(pGC -> clientClip, (RegionPtr) pValue);
+
+ break;
+ }
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+ {
+ RegionPtr pReg = RegionFromRects(nRects, (xRectangle *)pValue, type);
+
+ clipsMatch = nxagentCompareRegions(pGC -> clientClip, pReg);
+
+ RegionDestroy(pReg);
+
+ break;
+ }
+ default:
+ {
+ clipsMatch = 0;
+
+ break;
+ }
+ }
+
+ nxagentDestroyClipHelper(pGC);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeClip: Type [%d] regions clipsMatch [%d].\n",
+ type, clipsMatch);
+ #endif
+
+ switch (type)
+ {
+ case CT_NONE:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+ }
+
+ break;
+ }
+ case CT_REGION:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ nRects = RegionNumRects((RegionPtr)pValue);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) malloc(size);
+ pBox = RegionRects((RegionPtr)pValue);
+
+ for (i = nRects; i-- > 0;)
+ {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y,
+ pRects, nRects, Unsorted);
+ free((char *) pRects);
+ }
+
+ break;
+ }
+ case CT_PIXMAP:
+ {
+ if (nxagentGCTrap == 0)
+ {
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+ nxagentPixmap((PixmapPtr)pValue));
+ }
+
+ pGC->clientClip = (void *) (*pGC->pScreen->BitmapToRegion)((PixmapPtr) pValue);
+
+ nxagentGCPriv(pGC)->pPixmap = (PixmapPtr)pValue;
+
+ pValue = pGC->clientClip;
+
+ type = CT_REGION;
+
+ break;
+ }
+ case CT_UNSORTED:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, Unsorted);
+ }
+
+ break;
+ }
+ case CT_YSORTED:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YSorted);
+ }
+
+ break;
+ }
+ case CT_YXSORTED:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXSorted);
+ }
+
+ break;
+ }
+ case CT_YXBANDED:
+ {
+ if (clipsMatch == 0 && nxagentGCTrap == 0)
+ {
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXBanded);
+ }
+
+ break;
+ }
+ }
+
+ switch(type)
+ {
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+ {
+ /*
+ * Other parts of the server can only
+ * deal with CT_NONE, CT_PIXMAP and
+ * CT_REGION client clips.
+ */
+
+ pGC->clientClip = (void *) RegionFromRects(nRects,
+ (xRectangle *)pValue, type);
+ free(pValue);
+
+ pValue = pGC->clientClip;
+
+ type = CT_REGION;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ pGC->clientClipType = type;
+ pGC->clientClip = pValue;
+
+ nxagentGCPriv(pGC)->nClipRects = nRects;
+}
+
+void nxagentDestroyClip(GCPtr pGC)
+{
+ miDestroyClip(pGC);
+
+ if (pGC->clientClipType == CT_PIXMAP)
+ {
+ (*pGC->pScreen->DestroyPixmap)((PixmapPtr) (pGC->clientClip));
+ }
+
+ nxagentDestroyClipHelper(pGC);
+
+ if (nxagentGCTrap == 0)
+ {
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+ }
+
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+
+ nxagentGCPriv(pGC)->nClipRects = 0;
+}
+
+void nxagentDestroyClipHelper(GCPtr pGC)
+{
+ switch (pGC->clientClipType)
+ {
+ default:
+ case CT_NONE:
+ break;
+ case CT_REGION:
+ RegionDestroy(pGC->clientClip);
+ break;
+ case CT_PIXMAP:
+ nxagentDestroyPixmap((PixmapPtr)pGC->clientClip);
+ break;
+ }
+
+ if (nxagentGCPriv(pGC)->pPixmap != NULL)
+ {
+ nxagentDestroyPixmap(nxagentGCPriv(pGC)->pPixmap);
+ nxagentGCPriv(pGC)->pPixmap = NULL;
+ }
+}
+
+void nxagentCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+ RegionPtr pRgn;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyClip: Going to copy clip from GC [%p] to GC [%p]\n",
+ (void *) pGCDst, (void *) pGCSrc);
+ #endif
+
+ switch (pGCSrc->clientClipType)
+ {
+ case CT_REGION:
+ if (nxagentGCPriv(pGCSrc)->pPixmap == NULL)
+ {
+ pRgn = RegionCreate(NULL, 1);
+ RegionCopy(pRgn, pGCSrc->clientClip);
+ nxagentChangeClip(pGCDst, CT_REGION, pRgn, 0);
+ }
+ else
+ {
+ nxagentGCPriv(pGCSrc)->pPixmap->refcnt++;
+
+ nxagentChangeClip(pGCDst, CT_PIXMAP, nxagentGCPriv(pGCSrc)->pPixmap, 0);
+ }
+ break;
+ case CT_PIXMAP:
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyClip: WARNING! Not incrementing counter for virtual pixmap at [%p].\n",
+ (void *) nxagentVirtualPixmap((PixmapPtr) pGCSrc->clientClip));
+ #endif
+
+ ((PixmapPtr) pGCSrc->clientClip)->refcnt++;
+
+ nxagentChangeClip(pGCDst, CT_PIXMAP, pGCSrc->clientClip, 0);
+
+ break;
+
+ case CT_NONE:
+ nxagentDestroyClip(pGCDst);
+ break;
+
+ }
+}
+
+static struct nxagentGCRec *nxagentGetFirstGC()
+{
+ struct nxagentGCRec *tmp = nxagentGCList.first;
+
+ if (nxagentGCList.size)
+ {
+ nxagentGCList.first = nxagentGCList.first -> next;
+ nxagentGCList.size--;
+
+ if (nxagentGCList.size == 0)
+ {
+ nxagentGCList.last = NULL;
+ }
+ }
+
+ return tmp;
+}
+
+static void nxagentFreeGCRec(struct nxagentGCRec *t)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeGCRec: Freeing record at %p GC freed at %p.\n",
+ (void *) t, (void *) t -> gc);
+ #endif
+
+ free(t -> gc);
+
+ free(t);
+}
+
+static void nxagentRestoreGCRec(struct nxagentGCRec *t)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentRestoreGCRec: Freeing record at %p GC freed at %p.\n",
+ (void*)t, (void*)t -> gc);
+ #endif
+
+ if (nxagentGC(t -> pGC))
+ {
+ free(nxagentGC(t -> pGC));
+ }
+
+ nxagentGC(t -> pGC) = t -> gc;
+
+ free(t);
+}
+
+static void nxagentAddGCToList(GCPtr pGC)
+{
+ struct nxagentGCRec *tempGC = malloc(sizeof(struct nxagentGCRec));
+
+ if (tempGC == NULL)
+ {
+ FatalError("nxagentAddGCToList: malloc failed.");
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddGCToList: Adding GC %p to list at memory %p list size is %d.\n",
+ (void *) pGC, (void *) tempGC, nxagentGCList.size);
+ #endif
+
+ tempGC -> pGC = pGC;
+ tempGC -> gc = nxagentGC(pGC);
+ tempGC -> next = NULL;
+
+ if (nxagentGCList.size == 0 || nxagentGCList.first == NULL || nxagentGCList.last == NULL)
+ {
+ nxagentGCList.first = tempGC;
+ }
+ else
+ {
+ nxagentGCList.last -> next = tempGC;
+ }
+
+ nxagentGCList.last = tempGC;
+ nxagentGCList.size++;
+}
+
+void nxagentFreeGCList()
+{
+ struct nxagentGCRec *tempGC;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeGCList: List size is %d first elt at %p last elt at %p.\n",
+ nxagentGCList.size, (void*)nxagentGCList.first, (void*)nxagentGCList.last);
+ #endif
+
+ while ((tempGC = nxagentGetFirstGC()))
+ {
+ nxagentFreeGCRec(tempGC);
+ }
+}
+
+static void nxagentRestoreGCList()
+{
+ struct nxagentGCRec *tempGC;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRestoreGCList: List size is %d first elt at %p last elt at %p.\n",
+ nxagentGCList.size, (void*)nxagentGCList.first, (void*)nxagentGCList.last);
+ #endif
+
+ while ((tempGC = nxagentGetFirstGC()))
+ {
+ nxagentRestoreGCRec(tempGC);
+ }
+}
+
+int nxagentDestroyNewGCResourceType(void * p, XID id)
+{
+ /*
+ * Address of the destructor is set in Init.c.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyNewGCResourceType: Destroying mirror id [%ld] for GC at [%p].\n",
+ nxagentGCPriv((GCPtr) p) -> mid, (void *) p);
+ #endif
+
+ nxagentGCPriv((GCPtr) p) -> mid = None;
+
+ return 1;
+}
+
+static void nxagentReconnectGC(void *param0, XID param1, void * param2)
+{
+ XGCValues values;
+ unsigned long valuemask;
+ GCPtr pGC = (GCPtr) param0;
+ Bool *pBool = (Bool*)param2;
+
+ if (pGC == NULL || !*pBool)
+ {
+ return;
+ }
+
+ if (nxagentGC(pGC))
+ {
+ nxagentAddGCToList(pGC);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectGC: GCRec %p doesn't have a valid pointer to GC data.\n", (void*)pGC);
+ #endif
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconnectGC: GC at [%p].\n", (void *) pGC);
+ #endif
+
+ valuemask = 0;
+ memset(&values,0,sizeof(XGCValues));
+ values.function = pGC->alu;
+ valuemask |= GCFunction;
+ values.plane_mask = pGC->planemask;
+ valuemask |= GCPlaneMask;
+ values.foreground = nxagentPixel(pGC->fgPixel);
+ valuemask |= GCForeground;
+ values.background = nxagentPixel(pGC->bgPixel);
+ valuemask |= GCBackground;
+
+ values.line_width = pGC->lineWidth;
+ valuemask |= GCLineWidth;
+ values.line_style = pGC->lineStyle;
+ valuemask |= GCLineStyle;
+ values.cap_style = pGC->capStyle;
+ valuemask |= GCCapStyle;
+ values.join_style = pGC->joinStyle;
+ valuemask |= GCJoinStyle;
+ values.fill_style = pGC->fillStyle;
+ valuemask |= GCFillStyle;
+ values.fill_rule = pGC->fillRule;
+ valuemask |= GCFillRule;
+
+ if (!pGC -> tileIsPixel && (pGC -> tile.pixmap != NULL))
+ {
+ if (nxagentPixmapIsVirtual(pGC -> tile.pixmap))
+ {
+ values.tile = nxagentPixmap(nxagentRealPixmap(pGC -> tile.pixmap));
+ }
+ else
+ {
+ values.tile = nxagentPixmap(pGC -> tile.pixmap);
+ }
+
+ valuemask |= GCTile;
+ }
+
+ if (pGC->stipple != NULL)
+ {
+ if (nxagentPixmapIsVirtual(pGC -> stipple))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectGC: Reconnecting virtual stipple [%p] for GC [%p].\n",
+ (void *) pGC -> stipple, (void *) pGC);
+ #endif
+
+ if (nxagentPixmap(nxagentRealPixmap(pGC -> stipple)) == 0)
+ {
+ nxagentReconnectPixmap(nxagentRealPixmap(pGC -> stipple), 0, pBool);
+ }
+
+ values.stipple = nxagentPixmap(nxagentRealPixmap(pGC -> stipple));
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectGC: Reconnecting stipple [%p] for GC [%p].\n",
+ (void *) pGC -> stipple, (void *) pGC);
+ #endif
+
+ if (nxagentPixmap(pGC -> stipple) == 0)
+ {
+ nxagentReconnectPixmap(pGC -> stipple, 0, pBool);
+ }
+
+ values.stipple = nxagentPixmap(pGC->stipple);
+ }
+ valuemask |= GCStipple;
+ }
+
+ values.ts_x_origin = pGC->patOrg.x;
+ valuemask |= GCTileStipXOrigin;
+ values.ts_y_origin = pGC->patOrg.y;
+ valuemask |= GCTileStipYOrigin;
+
+ if (pGC->font != NULL)
+ {
+ values.font = nxagentFont(pGC->font);
+ valuemask |= GCFont;
+ }
+
+ values.subwindow_mode = pGC->subWindowMode;
+ valuemask |= GCSubwindowMode;
+ values.graphics_exposures = pGC->graphicsExposures;
+ valuemask |= GCGraphicsExposures;
+ values.clip_x_origin = pGC->clipOrg.x;
+ valuemask |= GCClipXOrigin;
+ values.clip_y_origin = pGC->clipOrg.y;
+ valuemask |= GCClipYOrigin;
+ valuemask |= GCClipMask;
+ values.dash_offset = pGC->dashOffset;
+ valuemask |= GCDashOffset;
+
+ if (pGC->dash != NULL)
+ {
+ values.dashes = *pGC->dash;
+ valuemask |= GCDashList;
+ }
+
+ values.arc_mode = pGC->arcMode;
+ valuemask |= GCArcMode;
+
+ if ((nxagentGC(pGC) = XCreateGC(nxagentDisplay,
+ nxagentDefaultDrawables[pGC->depth],
+ valuemask, &values)) == NULL)
+ {
+ *pBool = False;
+ }
+
+ nxagentReconnectClip(pGC,
+ pGC -> clientClipType,
+ pGC -> clientClip, nxagentGCPriv(pGC) -> nClipRects);
+
+ #ifdef DEBUG
+ XSync(nxagentDisplay, 0);
+ #endif
+}
+
+Bool nxagentReconnectAllGCs(void *p0)
+{
+ int cid;
+ Bool GCSuccess = True;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconnectAllGCs\n");
+ #endif
+
+ /*
+ * The resource type RT_NX_GC is created on the
+ * server client only, so we can avoid to loop
+ * through all the clients.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_GC, nxagentReconnectGC, &GCSuccess);
+
+ for (cid = 0; (cid < MAXCLIENTS) && GCSuccess; cid++)
+ {
+ if (clients[cid])
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllGCs: Going to reconnect GC of client [%d].\n", cid);
+ #endif
+
+ FindClientResourcesByType(clients[cid], RT_GC, nxagentReconnectGC, &GCSuccess);
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllGCs: GCs reconnection completed.\n");
+ #endif
+
+ return GCSuccess;
+}
+
+void nxagentDisconnectGC(void * p0, XID x1, void * p2)
+{
+ GCPtr pGC = (GCPtr) p0;
+ Bool* pBool = (Bool*) p2;
+
+ if (!*pBool || !pGC)
+ {
+ if (!pGC)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentDisconnectGC: WARNING! pGC is NULL.\n");
+ #endif
+ }
+
+ return;
+ }
+
+ if (pGC -> stipple)
+ {
+ PixmapPtr pMap = pGC -> stipple;
+
+ nxagentDisconnectPixmap(nxagentRealPixmap(pMap), 0, pBool);
+ }
+}
+
+Bool nxagentDisconnectAllGCs()
+{
+ int cid;
+ Bool success = True;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisconnectAllGCs\n");
+ #endif
+
+ /*
+ * The resource type RT_NX_GC is created on the
+ * server client only, so we can avoid to loop
+ * through all the clients.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_GC,
+ (FindResType) nxagentDisconnectGC, &success);
+
+ for (cid = 0; (cid < MAXCLIENTS) && success; cid++)
+ {
+ if (clients[cid])
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllGCs: Going to disconnect GC of client [%d].\n", cid);
+ #endif
+
+ FindClientResourcesByType(clients[cid], RT_GC,
+ (FindResType) nxagentDisconnectGC, &success);
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllGCs: GCs disconnection completed.\n");
+ #endif
+
+ nxagentRestoreGCList();
+
+ nxagentDisconnectGraphicContexts();
+
+ return success;
+}
+
+static void nxagentReconnectClip(GCPtr pGC, int type, void * pValue, int nRects)
+{
+ int i, size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectClip: going to change clip on GC [%p]\n",
+ (void *) pGC);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconnectClip: Type is [%s].\n", (type == CT_NONE) ?
+ "CT_NONE" : (type == CT_REGION) ? "CT_REGION" : (type == CT_PIXMAP) ?
+ "CT_REGION" : "UNKNOWN");
+ #endif
+
+ switch(type)
+ {
+ case CT_NONE:
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+ break;
+
+ case CT_REGION:
+ if (nxagentGCPriv(pGC)->pPixmap == NULL)
+ {
+ nRects = RegionNumRects((RegionPtr)pValue);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) malloc(size);
+ pBox = RegionRects((RegionPtr)pValue);
+ for (i = nRects; i-- > 0;) {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ /*
+ * Originally, the clip origin area were 0,0
+ * but it didn't work with kedit and family,
+ * because it got the clip mask of the pixmap
+ * all traslated.
+ */
+
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y,
+ pRects, nRects, Unsorted);
+ free((char *) pRects);
+ }
+ else
+ {
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+ nxagentPixmap(nxagentGCPriv(pGC)->pPixmap));
+
+ XSetClipOrigin(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y);
+ }
+
+ break;
+
+ case CT_PIXMAP:
+
+ XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+ nxagentPixmap((PixmapPtr)pValue));
+
+ XSetClipOrigin(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y);
+
+ pGC->clientClip = (void *) (*pGC->pScreen->BitmapToRegion)((PixmapPtr) pValue);
+
+ nxagentGCPriv(pGC)->pPixmap = (PixmapPtr)pValue;
+
+ pValue = pGC->clientClip;
+
+ type = CT_REGION;
+
+ break;
+
+ case CT_UNSORTED:
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, Unsorted);
+ break;
+
+ case CT_YSORTED:
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YSorted);
+ break;
+
+ case CT_YXSORTED:
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXSorted);
+ break;
+
+ case CT_YXBANDED:
+ XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXBanded);
+ break;
+ }
+
+ switch(type)
+ {
+ default:
+ break;
+
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+
+ /*
+ * other parts of server can only deal with CT_NONE,
+ * CT_PIXMAP and CT_REGION client clips.
+ */
+
+ pGC->clientClip = (void *) RegionFromRects(nRects,
+ (xRectangle *)pValue, type);
+ free(pValue);
+ pValue = pGC->clientClip;
+ type = CT_REGION;
+
+ break;
+ }
+
+ pGC->clientClipType = type;
+ pGC->clientClip = pValue;
+
+ nxagentGCPriv(pGC)->nClipRects = nRects;
+}
+
+static int nxagentCompareRegions(RegionPtr r1, RegionPtr r2)
+{
+ int i;
+
+ /*
+ * It returns 1 if regions are equal, 0 otherwise
+ */
+
+ if (r1 == NULL && r2 == NULL)
+ {
+ return 1;
+ }
+
+ if ((r1 == NULL) || (r2 == NULL))
+ {
+ return 0;
+ }
+
+ if (RegionNumRects(r1) != RegionNumRects(r2))
+ {
+ return 0;
+ }
+ else if (RegionNumRects(r1) == 0)
+ {
+ return 1;
+ }
+ else if ((*RegionExtents(r1)).x1 != (*RegionExtents(r2)).x1) return 0;
+ else if ((*RegionExtents(r1)).x2 != (*RegionExtents(r2)).x2) return 0;
+ else if ((*RegionExtents(r1)).y1 != (*RegionExtents(r2)).y1) return 0;
+ else if ((*RegionExtents(r1)).y2 != (*RegionExtents(r2)).y2) return 0;
+ else
+ {
+ for (i = 0; i < RegionNumRects(r1); i++)
+ {
+ if (RegionRects(r1)[i].x1 != RegionRects(r2)[i].x1) return 0;
+ else if (RegionRects(r1)[i].x2 != RegionRects(r2)[i].x2) return 0;
+ else if (RegionRects(r1)[i].y1 != RegionRects(r2)[i].y1) return 0;
+ else if (RegionRects(r1)[i].y2 != RegionRects(r2)[i].y2) return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * This function have to be called in the place
+ * of GetScratchGC if the GC will be used to per-
+ * form operations also on the remote X Server.
+ * This is why we call the XChangeGC at the end of
+ * the function.
+ */
+GCPtr nxagentGetScratchGC(unsigned depth, ScreenPtr pScreen)
+{
+ GCPtr pGC;
+ XGCValues values;
+ unsigned long mask;
+ int nxagentSaveGCTrap;
+
+ /*
+ * The GC trap is temporarily disabled in
+ * order to allow the remote clipmask reset
+ * requested by GetScratchGC().
+ */
+
+ nxagentSaveGCTrap = nxagentGCTrap;
+
+ nxagentGCTrap = 0;
+
+ pGC = GetScratchGC(depth, pScreen);
+
+ nxagentGCTrap = nxagentSaveGCTrap;
+
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGetScratchGC: Failed to retrieve the scratch GC.\n");
+ #endif
+
+ return NULL;
+ }
+
+ mask = 0;
+
+ values.function = pGC -> alu;
+ mask |= GCFunction;
+
+ values.plane_mask = pGC -> planemask;
+ mask |= GCPlaneMask;
+
+ values.foreground = nxagentPixel(pGC -> fgPixel);
+ mask |= GCForeground;
+
+ values.background = nxagentPixel(pGC -> bgPixel);
+ mask |= GCBackground;
+
+ values.line_width = pGC -> lineWidth;
+ mask |= GCLineWidth;
+
+ values.line_style = pGC -> lineStyle;
+ mask |= GCLineStyle;
+
+ values.cap_style = pGC -> capStyle;
+ mask |= GCCapStyle;
+
+ values.join_style = pGC -> joinStyle;
+ mask |= GCJoinStyle;
+
+ values.fill_style = pGC -> fillStyle;
+ mask |= GCFillStyle;
+
+ values.fill_rule = pGC -> fillRule;
+ mask |= GCFillRule;
+
+ values.arc_mode = pGC -> arcMode;
+ mask |= GCArcMode;
+
+ values.ts_x_origin = pGC -> patOrg.x;
+ mask |= GCTileStipXOrigin;
+
+ values.ts_y_origin = pGC -> patOrg.y;
+ mask |= GCTileStipYOrigin;
+
+ values.subwindow_mode = pGC -> subWindowMode;
+ mask |= GCSubwindowMode;
+
+ values.graphics_exposures = pGC -> graphicsExposures;
+ mask |= GCGraphicsExposures;
+
+ /*
+ * The GCClipMask is set to none inside
+ * the GetScratchGC() function.
+ */
+
+ values.clip_x_origin = pGC -> clipOrg.x;
+ mask |= GCClipXOrigin;
+
+ values.clip_y_origin = pGC -> clipOrg.y;
+ mask |= GCClipYOrigin;
+
+ XChangeGC(nxagentDisplay, nxagentGC(pGC), mask, &values);
+
+ memset(&(nxagentGCPriv(pGC) -> lastServerValues), 0, sizeof(XGCValues));
+
+ return pGC;
+}
+
+/*
+ * This function is only a wrapper for
+ * FreeScratchGC.
+ */
+void nxagentFreeScratchGC(GCPtr pGC)
+{
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFreeScratchGC: WARNING! pGC is NULL.\n");
+ #endif
+
+ return;
+ }
+
+ FreeScratchGC(pGC);
+}
+
+/*
+ * The GCs belonging to this list are used
+ * only in the synchronization put images,
+ * to be sure they preserve the default va-
+ * lues and to avoid XChangeGC() requests.
+ */
+
+GCPtr nxagentGetGraphicContext(DrawablePtr pDrawable)
+{
+ int i;
+ int result;
+
+ for (i = 0; i < nxagentGraphicContextsSize; i++)
+ {
+ if (pDrawable -> depth == nxagentGraphicContexts[i].depth)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetGraphicContext: Found a valid GC at [%p] for depth [%d].\n",
+ (void *) nxagentGraphicContexts[i].pGC, pDrawable -> depth);
+ #endif
+
+ /*
+ * Reconnect the GC if needed.
+ */
+
+ if (nxagentGraphicContexts[i].dirty == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentGetGraphicContext: Going to reconnect the GC.\n");
+ #endif
+
+ result = 1;
+
+ nxagentReconnectGC(nxagentGraphicContexts[i].pGC, (XID) 0, &result);
+
+ if (result == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGetGraphicContext: WARNING! Failed to reconnect the GC.\n");
+ #endif
+
+ return NULL;
+ }
+
+ nxagentGraphicContexts[i].dirty = 0;
+ }
+
+ return nxagentGraphicContexts[i].pGC;
+ }
+ }
+
+ return nxagentCreateGraphicContext(pDrawable -> depth);
+}
+
+GCPtr nxagentCreateGraphicContext(int depth)
+{
+ GCPtr pGC;
+
+ nxagentGraphicContextsPtr nxagentGCs;
+
+ XID attributes[2];
+
+ /*
+ * We have not found a GC, so we have
+ * to spread the list and add a new GC.
+ */
+
+ nxagentGCs = realloc(nxagentGraphicContexts, (nxagentGraphicContextsSize + 1) * sizeof(nxagentGraphicContextsRec));
+
+ if (nxagentGCs == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreateGraphicContext: Cannot allocate memory for a GC.\n");
+ #endif
+
+ return NULL;
+ }
+
+ nxagentGraphicContexts = nxagentGCs;
+
+ pGC = CreateScratchGC(nxagentDefaultScreen, depth);
+
+ if (pGC == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreateGraphicContext: Failed to create a GC for depth [%d].\n",
+ depth);
+ #endif
+
+ return NULL;
+ }
+
+ /*
+ * Color used in nxagentFillRemoteRegion().
+ */
+
+ attributes[0] = 0xc1c1c1;
+
+ if (depth == 15 || depth == 16)
+ {
+ Color32to16(attributes[0]);
+ }
+
+ /*
+ * The IncludeInferiors property is useful to
+ * solve problems when synchronizing windows
+ * covered by an invisible child.
+ */
+
+ attributes[1] = IncludeInferiors;
+
+ ChangeGC(pGC, GCForeground | GCSubwindowMode, attributes);
+
+ nxagentGraphicContexts[nxagentGraphicContextsSize].pGC = pGC;
+ nxagentGraphicContexts[nxagentGraphicContextsSize].depth = depth;
+ nxagentGraphicContexts[nxagentGraphicContextsSize].dirty = 0;
+
+ nxagentGraphicContextsSize++;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCreateGraphicContext: GC [%p] for depth [%d] added to the list of size [%d].\n",
+ (void *) pGC, depth, nxagentGraphicContextsSize);
+ #endif
+
+ return pGC;
+}
+
+/*
+ * This initialization is called in the InitOutput()
+ * function immediately after opening the screen,
+ * which is used to create the GCs.
+ */
+
+void nxagentAllocateGraphicContexts(void)
+{
+ int *depths;
+
+ int i;
+
+ depths = nxagentDepths;
+
+ for (i = 0; i < nxagentNumDepths; i++)
+ {
+ nxagentCreateGraphicContext(*depths);
+
+ depths++;
+ }
+}
+
+void nxagentDisconnectGraphicContexts(void)
+{
+ int i;
+
+ for (i = 0; i < nxagentGraphicContextsSize; i++)
+ {
+ nxagentGraphicContexts[i].dirty = 1;
+ }
+
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
new file mode 100644
index 000000000..1bca067fc
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -0,0 +1,2104 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Composite.h"
+#include "Display.h"
+#include "Visual.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Image.h"
+#include "Font.h"
+#include "Events.h"
+#include "Client.h"
+#include "Trap.h"
+#include "Holder.h"
+#include "Args.h"
+#include "Screen.h"
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/*
+ * Temporarily set/reset the trap.
+ */
+
+static int nxagentSaveGCTrap;
+
+#define SET_GC_TRAP() \
+{ \
+ nxagentSaveGCTrap = nxagentGCTrap;\
+\
+ nxagentGCTrap = 1; \
+}
+
+#define RESET_GC_TRAP() \
+{ \
+ nxagentGCTrap = nxagentSaveGCTrap; \
+}
+
+/*
+ * This is currently unused.
+ */
+
+RegionPtr nxagentBitBlitHelper(GC *pGC);
+
+/*
+ * The NX agent implementation of the
+ * X server's graphics functions.
+ */
+
+void nxagentFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans,
+ xPoint *pPoints, int *pWidths, int fSorted)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to FillSpans on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbFillSpans(nxagentVirtualDrawable(pDrawable), pGC, nSpans, pPoints, pWidths, fSorted);
+ }
+ else
+ {
+ fbFillSpans(pDrawable, pGC, nSpans, pPoints, pWidths, fSorted);
+ }
+}
+
+void nxagentSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
+ xPoint *pPoints, int *pWidths, int nSpans, int fSorted)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to SetSpans on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbSetSpans(nxagentVirtualDrawable(pDrawable), pGC, pSrc, pPoints, pWidths, nSpans, fSorted);
+ }
+ else
+ {
+ fbSetSpans(pDrawable, pGC, pSrc, pPoints, pWidths, nSpans, fSorted);
+ }
+}
+
+void nxagentGetSpans(DrawablePtr pDrawable, int maxWidth, xPoint *pPoints,
+ int *pWidths, int nSpans, char *pBuffer)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: going to GetSpans on FB pixmap [%p].\n",
+ (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbGetSpans(nxagentVirtualDrawable(pDrawable), maxWidth, pPoints, pWidths, nSpans, pBuffer);
+ }
+ else
+ {
+ fbGetSpans(pDrawable, maxWidth, pPoints, pWidths, nSpans, pBuffer);
+ }
+}
+
+void nxagentQueryBestSize(int class, unsigned short *pwidth,
+ unsigned short *pheight, ScreenPtr pScreen)
+{
+ unsigned width, test;
+
+ switch(class)
+ {
+ case CursorShape:
+ if (*pwidth > pScreen->width)
+ *pwidth = pScreen->width;
+ if (*pheight > pScreen->height)
+ *pheight = pScreen->height;
+ break;
+ case TileShape:
+ case StippleShape:
+ width = *pwidth;
+ if (!width) break;
+ /* Return the closes power of two not less than what they gave me */
+ test = 0x80000000;
+ /* Find the highest 1 bit in the width given */
+ while(!(test & width))
+ test >>= 1;
+ /* If their number is greater than that, bump up to the next
+ * power of two */
+ if((test - 1) & width)
+ test <<= 1;
+ *pwidth = test;
+ /* We don't care what height they use */
+ break;
+ }
+}
+
+RegionPtr nxagentBitBlitHelper(GC *pGC)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentBitBlitHelper: Called for GC at [%p].\n", (void *) pGC);
+ #endif
+
+ /*
+ * Force NullRegion. We consider enough the graphics
+ * expose events generated internally by the nxagent
+ * server.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBitBlitHelper: WARNING! Skipping check on exposures events.\n");
+ #endif
+
+ return NullRegion;
+}
+
+/*
+ * The deferring of X_RenderCompositeTrapezoids caused
+ * an ugly effect on pulldown menu: as the background
+ * may be not synchronized, the text floats in an invi-
+ * sible window. To avoid such effects, we use a system
+ * to guess if the destination target of a copy area
+ * is a popup, by assuming that those kind of windows
+ * use the override redirect property.
+ */
+
+int nxagentWindowIsPopup(DrawablePtr pDrawable)
+{
+ WindowPtr parent;
+
+ int windowIsPopup;
+ int level;
+
+ if (pDrawable -> type != DRAWABLE_WINDOW)
+ {
+ return 0;
+ }
+
+ windowIsPopup = 0;
+
+ if (((WindowPtr) pDrawable) -> overrideRedirect == 1)
+ {
+ windowIsPopup = 1;
+ }
+ else
+ {
+ parent = ((WindowPtr) pDrawable) -> parent;
+
+ /*
+ * Go up on the tree until a parent
+ * exists or 4 windows has been che-
+ * cked. This seems a good limit to
+ * up children's popup.
+ */
+
+ level = 0;
+
+ while (parent != NULL && ++level <= 4)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWindowIsPopup: Window [%p] has parent [%p] in tree with OverrideRedirect [%d] "
+ " Level [%d].\n", (void *) pDrawable, (void *) parent, parent -> overrideRedirect, level);
+ #endif
+
+ if (parent -> overrideRedirect == 1)
+ {
+ windowIsPopup = 1;
+
+ break;
+ }
+
+ parent = parent -> parent;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowIsPopup: Window [%p] %s to be a popup.\n", (void *) pDrawable,
+ windowIsPopup == 1 ? "seems" : "does not seem");
+ #endif
+
+ return windowIsPopup;
+}
+
+/*
+ * This function returns 1 if the
+ * XCopyArea request must be skipped.
+ */
+
+int nxagentDeferCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width,
+ int height, int dstx, int dsty)
+{
+ RegionPtr pSrcRegion;
+ RegionPtr pClipRegion, pCorruptedRegion;
+ RegionRec corruptedRegion, tmpRegion;
+
+ /*
+ * If the destination drawable is a popup
+ * window, we try to synchronize the source
+ * drawable to show a nice menu. Anyway if
+ * this synchronization breaks, the copy area
+ * is handled in the normal way.
+ */
+
+/*
+FIXME: The popup could be synchronized with one
+ single put image, clipped to the corrup-
+ ted region. As an intermediate step, the
+ pixmap to synchronize could be copied on
+ a cleared scratch pixmap, in order to
+ have a solid color in the clipped regions.
+*/
+
+ if (nxagentOption(DeferLevel) >= 2 &&
+ pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentPixmapContainTrapezoids((PixmapPtr) pSrcDrawable) == 1 &&
+ nxagentWindowIsPopup(pDstDrawable) == 1)
+ {
+ pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Copying to a popup menu. Source region [%d,%d,%d,%d].\n",
+ pSrcRegion -> extents.x1, pSrcRegion -> extents.y1,
+ pSrcRegion -> extents.x2, pSrcRegion -> extents.y2);
+ #endif
+
+ RegionInit(&corruptedRegion, NullBox, 1);
+
+ RegionIntersect(&corruptedRegion,
+ pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+ if (RegionNil(&corruptedRegion) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDeferCopyArea: Forcing the synchronization of source drawable at [%p].\n",
+ (void *) pSrcDrawable);
+ #endif
+
+ nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion, EVENT_BREAK, NULL);
+ }
+
+ RegionUninit(&corruptedRegion);
+
+ nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+
+ if (nxagentDrawableStatus(pSrcDrawable) == Synchronized)
+ {
+ return 0;
+ }
+ }
+
+ /*
+ * We are going to decide if the source drawable
+ * must be synchronized before using it, or if
+ * the copy will be clipped to the synchronized
+ * source region.
+ */
+
+ if ((pDstDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentOption(DeferLevel) > 0) || nxagentOption(DeferLevel) >= 3)
+ {
+ pClipRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy,
+ width, height);
+
+ /*
+ * We called this variable pCorruptedRegion
+ * because in the worst case the corrupted
+ * region will be equal to the destination
+ * region. The GC's clip mask is used to
+ * narrow the destination.
+ */
+
+ pCorruptedRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty,
+ width, height);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Copy area source region is [%d,%d,%d,%d].\n",
+ pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+ pClipRegion -> extents.x2, pClipRegion -> extents.y2);
+ #endif
+
+ RegionSubtract(pClipRegion, pClipRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Usable copy area source region is [%d,%d,%d,%d].\n",
+ pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+ pClipRegion -> extents.x2, pClipRegion -> extents.y2);
+ #endif
+
+ if (pGC -> clientClip == NULL || pGC -> clientClipType != CT_REGION)
+ {
+ #ifdef WARNING
+
+ if (pGC -> clientClipType != CT_NONE)
+ {
+ fprintf(stderr, "nxagentDeferCopyArea: WARNING! pGC [%p] has a clip type [%d].\n",
+ (void *) pGC, pGC -> clientClipType);
+ }
+
+ #endif
+
+ RegionTranslate(pClipRegion, dstx - srcx, dsty - srcy);
+ }
+ else
+ {
+ RegionInit(&tmpRegion, NullBox, 1);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Going to modify the original GC [%p] with clip mask "
+ "[%d,%d,%d,%d] and origin [%d,%d].\n",
+ (void *) pGC,
+ ((RegionPtr) pGC -> clientClip) -> extents.x1, ((RegionPtr) pGC -> clientClip) -> extents.y1,
+ ((RegionPtr) pGC -> clientClip) -> extents.x2, ((RegionPtr) pGC -> clientClip) -> extents.y2,
+ pGC -> clipOrg.x, pGC -> clipOrg.y);
+ #endif
+
+ RegionCopy(&tmpRegion, (RegionPtr) pGC -> clientClip);
+
+ if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+ {
+ RegionTranslate(&tmpRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+ }
+
+ RegionTranslate(pClipRegion, dstx - srcx, dsty - srcy);
+
+ RegionIntersect(pClipRegion, &tmpRegion, pClipRegion);
+
+ RegionUninit(&tmpRegion);
+ }
+
+ /*
+ * The corrupted region on the destination
+ * drawable is composed by the areas of the
+ * destination that we are not going to copy.
+ */
+
+ RegionSubtract(pCorruptedRegion, pCorruptedRegion, pClipRegion);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Recomputed clip region is [%d,%d,%d,%d][%ld].\n",
+ pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+ pClipRegion -> extents.x2, pClipRegion -> extents.y2,
+ RegionNumRects(pClipRegion));
+
+ fprintf(stderr, "nxagentDeferCopyArea: Inherited corrupted region is [%d,%d,%d,%d][%ld].\n",
+ pCorruptedRegion -> extents.x1, pCorruptedRegion -> extents.y1,
+ pCorruptedRegion -> extents.x2, pCorruptedRegion -> extents.y2,
+ RegionNumRects(pCorruptedRegion));
+ #endif
+
+ /*
+ * The destination drawable inherits both the
+ * synchronized and the corrupted region.
+ */
+
+ if (RegionNil(pClipRegion) == 0)
+ {
+ nxagentUnmarkCorruptedRegion(pDstDrawable, pClipRegion);
+ }
+
+ if (RegionNil(pCorruptedRegion) == 0)
+ {
+ nxagentMarkCorruptedRegion(pDstDrawable, pCorruptedRegion);
+ }
+
+ if (RegionNil(pClipRegion) == 0)
+ {
+ GCPtr targetGC;
+
+ CARD32 targetAttributes[2];
+
+ Bool pClipRegionFree = True;
+
+ /*
+ * As we want to copy only the synchronized
+ * areas of the source drawable, we create
+ * a new GC copying the original one and
+ * setting a new clip mask.
+ */
+
+ targetGC = GetScratchGC(pDstDrawable -> depth, pDstDrawable -> pScreen);
+
+ ValidateGC(pDstDrawable, targetGC);
+
+ CopyGC(pGC, targetGC, GCFunction | GCPlaneMask | GCSubwindowMode |
+ GCClipXOrigin | GCClipYOrigin | GCClipMask | GCForeground |
+ GCBackground | GCGraphicsExposures);
+
+ if (RegionNumRects(pClipRegion) == 1)
+ {
+ /*
+ * If the region to copy is formed by one
+ * rectangle, we change only the copy coor-
+ * dinates.
+ */
+
+ srcx = srcx + pClipRegion -> extents.x1 - dstx;
+ srcy = srcy + pClipRegion -> extents.y1 - dsty;
+
+ dstx = pClipRegion -> extents.x1;
+ dsty = pClipRegion -> extents.y1;
+
+ width = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
+ height = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
+ }
+ else
+ {
+ /*
+ * Setting the clip mask origin. This
+ * operation must precede the clip chan-
+ * ge, because the origin information is
+ * used in the XSetClipRectangles().
+ */
+
+ targetAttributes[0] = 0;
+ targetAttributes[1] = 0;
+
+ ChangeGC(targetGC, GCClipXOrigin | GCClipYOrigin, targetAttributes);
+
+ /*
+ * Setting the new clip mask.
+ */
+
+ nxagentChangeClip(targetGC, CT_REGION, pClipRegion, 0);
+
+ /*
+ * Next call to nxagentChangeClip() will destroy
+ * pClipRegion, so it has not to be freed.
+ */
+
+ pClipRegionFree = False;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Going to execute a copy area with clip mask "
+ "[%d,%d,%d,%d] and origin [%d,%d].\n", ((RegionPtr) targetGC -> clientClip) -> extents.x1,
+ ((RegionPtr) targetGC -> clientClip) -> extents.y1,
+ ((RegionPtr) targetGC -> clientClip) -> extents.x2,
+ ((RegionPtr) targetGC -> clientClip) -> extents.y2,
+ targetGC -> clipOrg.x, targetGC -> clipOrg.y);
+ #endif
+ }
+
+ XCopyArea(nxagentDisplay, nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+ nxagentGC(targetGC), srcx, srcy, width, height, dstx, dsty);
+
+ nxagentChangeClip(targetGC, CT_NONE, NullRegion, 0);
+
+ if (pClipRegionFree == True)
+ {
+ nxagentFreeRegion(pSrcDrawable, pClipRegion);
+ }
+
+ FreeScratchGC(targetGC);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDeferCopyArea: The clipped region is NIL. CopyArea skipped.\n");
+ #endif
+
+ /*
+ * The pClipRegion is destroyed calling nxagentChangeClip(),
+ * so we deallocate it explicitly only if we don't change
+ * the clip.
+ */
+
+ nxagentFreeRegion(pSrcDrawable, pClipRegion);
+ }
+
+ nxagentFreeRegion(pSrcDrawable, pCorruptedRegion);
+
+ return 1;
+ }
+ else
+ {
+ pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDeferCopyArea: Source region [%d,%d,%d,%d].\n",
+ pSrcRegion -> extents.x1, pSrcRegion -> extents.y1,
+ pSrcRegion -> extents.x2, pSrcRegion -> extents.y2);
+ #endif
+
+ RegionInit(&corruptedRegion, NullBox, 1);
+
+ RegionIntersect(&corruptedRegion,
+ pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+ if (RegionNil(&corruptedRegion) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDeferCopyArea: Forcing the synchronization of source drawable at [%p].\n",
+ (void *) pSrcDrawable);
+ #endif
+
+ nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion /*pSrcRegion*/, NEVER_BREAK, NULL);
+ }
+
+ RegionUninit(&corruptedRegion);
+
+ nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+ }
+
+ return 0;
+}
+
+RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width,
+ int height, int dstx, int dsty)
+{
+ int leftPad = 0;
+ unsigned int format;
+ unsigned long planeMask = 0xffffffff;
+
+ RegionPtr pDstRegion;
+
+ int skip = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Image src [%s:%p], dst [%s:%p] (%d,%d) -> (%d,%d) size (%d,%d)\n",
+ (pSrcDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+ (pDstDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+ (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+ #endif
+
+ /*
+ * Here, before using fbDoCopy() called by fbCopyArea(),
+ * it should be provided that the cast in fbDoCopy() from
+ * int to short int would not cut off significative bits.
+ */
+
+ if (dstx + pDstDrawable->x + width > 32767)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyArea: x2 exceeding short int.\n");
+ #endif
+
+ width = 32767 - dstx - pDstDrawable->x;
+
+ if (width <= 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Returning null on x2 check.\n");
+ #endif
+
+ return NullRegion;
+ }
+ }
+
+ if (dstx + pDstDrawable->x < -32768)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyArea: x1 exceeding short int.\n");
+ #endif
+
+ width += pDstDrawable->x + dstx + 32768;
+ srcx -= pDstDrawable->x + dstx + 32768;
+ dstx = -32768 - pDstDrawable->x;
+
+ if (width <= 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Returning null on x1 check.\n");
+ #endif
+
+ return NullRegion;
+ }
+ }
+
+ if (dsty + pDstDrawable->y + height > 32767)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyArea: y2 exceeding short int.\n");
+ #endif
+
+ height = 32767 - dsty - pDstDrawable->y;
+
+ if (height <= 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Returning null on y2 check.\n");
+ #endif
+
+ return NullRegion;
+ }
+ }
+
+ if (dsty + pDstDrawable->y < -32768)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyArea: y1 exceeding short int.\n");
+ #endif
+
+ height += 32768 + pDstDrawable->y + dsty;
+ srcy -= 32768 + pDstDrawable->y + dsty;
+ dsty = -32768 - pDstDrawable->y;
+
+ if (height <= 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Returning null on y1 check.\n");
+ #endif
+
+ return NullRegion;
+ }
+ }
+
+
+ if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
+ {
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable),
+ nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyArea(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else
+ {
+ return fbCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+
+ return NullRegion;
+ }
+
+ /*
+ * Try to detect if the copy area is to a window
+ * that is unmapped or fully covered. Similarly
+ * to the check in Image.c, this is of little use.
+ */
+
+ if (nxagentOption(IgnoreVisibility) == 0 && pDstDrawable -> type == DRAWABLE_WINDOW &&
+ (nxagentWindowIsVisible((WindowPtr) pDstDrawable) == 0 ||
+ (nxagentDefaultWindowIsVisible() == 0 && nxagentCompositeEnable == 0)))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Prevented operation on fully obscured window at [%p].\n",
+ (void *) pDstDrawable);
+ #endif
+
+ return NullRegion;
+ }
+
+ /*
+ * If the pixmap is on shared memory, we can't
+ * know if the pixmap content is changed and
+ * so have to translate the operation in a put
+ * image operation. This can seriously affect
+ * the performance.
+ */
+
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pSrcDrawable))
+ {
+ char *data;
+ int depth, length;
+
+ depth = pSrcDrawable -> depth;
+
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ length = nxagentImageLength(width, height, format, leftPad, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCopyArea: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ return NullRegion;
+ }
+
+ fbGetImage(nxagentVirtualDrawable(pSrcDrawable), srcx, srcy, width, height, format, planeMask, data);
+
+ /*
+ * If the source is a shared memory pixmap,
+ * put the image directly to the destination.
+ */
+
+ nxagentPutImage(pDstDrawable, pGC, depth, dstx, dsty,
+ width, height, leftPad, format, data);
+
+ #ifdef TEST
+ fprintf(stderr,"nxagentCopyArea: Realize Pixmap %p virtual %p x %d y %d w %d h %d\n",
+ (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pSrcDrawable),
+ srcx, srcy, width, height);
+ #endif
+
+ free(data);
+
+ /*
+ * If the source is a shared memory pixmap, the
+ * content of the framebuffer has been placed
+ * directly on the destination so we can skip
+ * the copy area operation.
+ */
+
+ skip = 1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Image src [%s:%p], dst [%s:%p] sx %d sy %d dx %d dy %d size w %d h %d\n",
+ ((pSrcDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+ ((pDstDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+ (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+ #endif
+
+ if (skip == 0 && nxagentDrawableStatus(pSrcDrawable) == NotSynchronized)
+ {
+ skip = nxagentDeferCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
+ width, height, dstx, dsty);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentCopyArea: Source drawable at [%p] already synchronized.\n",
+ (void *) pSrcDrawable);
+ }
+ #endif
+
+ if (skip == 0)
+ {
+ XCopyArea(nxagentDisplay, nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+ nxagentGC(pGC), srcx, srcy, width, height, dstx, dsty);
+
+ /*
+ * The copy area restored the synchroni-
+ * zation status of destination drawable.
+ */
+
+ if (nxagentDrawableStatus(pDstDrawable) == NotSynchronized)
+ {
+ pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+ nxagentUnmarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+ nxagentFreeRegion(pDstDrawable, pDstRegion);
+ }
+ }
+
+ if (nxagentDrawableContainGlyphs(pSrcDrawable) == 1)
+ {
+ nxagentSetDrawableContainGlyphs(pDstDrawable, 1);
+ }
+
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentIncreasePixmapUsageCounter((PixmapPtr) pSrcDrawable);
+ }
+
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Going to copy area from virtual pixmap [%p] to [%p]\n",
+ (void *) nxagentVirtualDrawable(pSrcDrawable),
+ (void *) nxagentVirtualDrawable(pDstDrawable));
+ #endif
+
+ return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable),
+ nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Going to copy area from virtual pixmap [%p] to window [%p]\n",
+ (void *) nxagentVirtualDrawable(pSrcDrawable),
+ (void *) pDstDrawable);
+ #endif
+
+ return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ /*
+ * If we are here the source drawable
+ * must be a window.
+ */
+
+ if (((WindowPtr) pSrcDrawable) -> viewable)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Going to copy area from window [%p] to virtual pixmap [%p]\n",
+ (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pDstDrawable));
+ #endif
+
+ return fbCopyArea(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ }
+ else
+ {
+ /*
+ * If we are here the source drawable
+ * must be a window.
+ */
+
+ if (((WindowPtr) pSrcDrawable) -> viewable)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyArea: Going to copy area from window [%p] to window [%p]\n",
+ (void *) pSrcDrawable, (void *) pDstDrawable);
+ #endif
+
+ return fbCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ }
+
+ return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty, 0);
+}
+
+RegionPtr nxagentCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long plane)
+{
+ unsigned int format;
+ int leftPad = 0;
+ unsigned long planeMask = 0xffffffff;
+
+ RegionPtr pSrcRegion, pDstRegion;
+ RegionRec corruptedRegion;
+
+ int skip = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyPlane: Image src [%s:%p], dst [%s:%p] (%d,%d) -> (%d,%d) size (%d,%d)\n",
+ ((pSrcDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+ ((pDstDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+ (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+ #endif
+
+ if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
+ {
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable),
+ nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyPlane(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else
+ {
+ return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
+ dstx, dsty, plane);
+ }
+
+ return NullRegion;
+ }
+
+ /*
+ * If the pixmap is on shared memory, we can't
+ * know if the pixmap content is changed and
+ * so have to translate the operation in a put
+ * image operation. This can seriously affect
+ * the performance.
+ */
+
+ if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pSrcDrawable))
+ {
+ char *data;
+ int depth, length;
+
+ depth = pSrcDrawable -> depth;
+
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ length = nxagentImageLength(width, height, format, leftPad, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCopyPlane: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ return 0;
+ }
+
+ fbGetImage(nxagentVirtualDrawable(pSrcDrawable), srcx, srcy, width, height, format, planeMask, data);
+
+ /*
+ * If the source is a shared memory pixmap,
+ * put the image directly to the destination.
+ */
+
+ nxagentPutImage(pDstDrawable, pGC, depth, dstx, dsty,
+ width, height, leftPad, format, data);
+
+ #ifdef TEST
+ fprintf(stderr,"nxagentCopyPlane: Synchronize Pixmap %p virtual %p x %d y %d w %d h %d \n",
+ (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pSrcDrawable),
+ srcx, srcy, width, height);
+ #endif
+
+ free(data);
+
+ /*
+ * If the source is a shared memory pixmap, the
+ * content of the framebuffer has been placed
+ * directly on the destination so we can skip
+ * the copy plane operation.
+ */
+
+ skip = 1;
+ }
+
+ if (skip == 0 && nxagentDrawableStatus(pSrcDrawable) == NotSynchronized)
+ {
+ if (pDstDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentOption(DeferLevel) > 0)
+ {
+ pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+ nxagentMarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+ nxagentFreeRegion(pDstDrawable, pDstRegion);
+
+ skip = 1;
+ }
+ else
+ {
+ pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+ RegionInit(&corruptedRegion, NullBox, 1);
+
+ RegionIntersect(&corruptedRegion,
+ pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+ if (RegionNil(&corruptedRegion) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyPlane: Forcing the synchronization of source drawable at [%p].\n",
+ (void *) pSrcDrawable);
+ #endif
+
+ nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion /*pSrcRegion*/, NEVER_BREAK, NULL);
+
+ pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+ nxagentUnmarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+ nxagentFreeRegion(pDstDrawable, pDstRegion);
+ }
+
+ RegionUninit(&corruptedRegion);
+
+ nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+ }
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentCopyPlane: Source drawable at [%p] already synchronized.\n",
+ (void *) pSrcDrawable);
+ }
+ #endif
+
+ if (skip == 0)
+ {
+ XCopyPlane(nxagentDisplay,
+ nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+ nxagentGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
+ }
+
+ if ((pSrcDrawable)->type == DRAWABLE_PIXMAP &&
+ (pDstDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCopyPlane: going to copy plane from FB pixmap [%p] to [%p].\n",
+ (void *) nxagentVirtualDrawable(pSrcDrawable),
+ (void *) nxagentVirtualDrawable(pDstDrawable));
+ #endif
+
+ return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable),
+ nxagentVirtualDrawable(pDstDrawable),
+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ return fbCopyPlane(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable), pGC,
+ srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else
+ {
+ return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty, plane);
+ }
+
+ return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty, plane);
+}
+
+void nxagentPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentPolyPoint: Drawable at [%p] GC at [%p] Points [%d].\n",
+ (void *) pDrawable, (void *) pGC, nPoints);
+ #endif
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ fbPolyPoint(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+ }
+ else
+ {
+ fbPolyPoint(pDrawable, pGC, mode, nPoints, pPoints);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly point on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly point enters with virtual pixmap [%p] parent is [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawPoints(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XPoint *) pPoints, nPoints, mode);
+ }
+ }
+ else
+ {
+ XDrawPoints(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, mode);
+ }
+
+ fbPolyPoint(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+
+ return;
+ }
+ else
+ {
+ XDrawPoints(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, mode);
+
+ fbPolyPoint(pDrawable, pGC, mode, nPoints, pPoints);
+ }
+}
+
+void nxagentPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints)
+{
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ fbPolyLine(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+ }
+ else
+ {
+ fbPolyLine(pDrawable, pGC, mode, nPoints, pPoints);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly line on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly lines enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawLines(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XPoint *) pPoints, nPoints, mode);
+ }
+ }
+ else
+ {
+ XDrawLines(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, mode);
+ }
+
+ fbPolyLine(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+
+ return;
+ }
+ else
+ {
+ XDrawLines(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, mode);
+
+ fbPolyLine(pDrawable, pGC, mode, nPoints, pPoints);
+ }
+}
+
+void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+ int nSegments, xSegment *pSegments)
+{
+ #ifdef TEST
+
+ if (nSegments == 1)
+ {
+ fprintf(stderr, "nxagentPolySegment: Drawable at [%p] GC at [%p] Segment [%d,%d,%d,%d].\n",
+ (void *) pDrawable, (void *) pGC,
+ pSegments -> x1, pSegments -> y1, pSegments -> x2, pSegments -> y2);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentPolySegment: Drawable at [%p] GC at [%p] Segments [%d].\n",
+ (void *) pDrawable, (void *) pGC, nSegments);
+ }
+
+ #endif
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ fbPolySegment(nxagentVirtualDrawable(pDrawable), pGC, nSegments, pSegments);
+ }
+ else
+ {
+ fbPolySegment(pDrawable, pGC, nSegments, pSegments);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly segment on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly segment enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawSegments(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XSegment *) pSegments, nSegments);
+ }
+ }
+ else
+ {
+ XDrawSegments(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XSegment *) pSegments, nSegments);
+ }
+
+ SET_GC_TRAP();
+ fbPolySegment(nxagentVirtualDrawable(pDrawable), pGC, nSegments, pSegments);
+ RESET_GC_TRAP();
+
+ return;
+ }
+ else
+ {
+ XDrawSegments(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XSegment *) pSegments, nSegments);
+
+ SET_GC_TRAP();
+ fbPolySegment(pDrawable, pGC, nSegments, pSegments);
+ RESET_GC_TRAP();
+ }
+}
+
+void nxagentPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+ int nRectangles, xRectangle *pRectangles)
+{
+ #ifdef TEST
+
+ if (nRectangles == 1)
+ {
+ fprintf(stderr, "nxagentPolyRectangle: Drawable at [%p] GC at [%p] Rectangle [%d,%d][%d,%d].\n",
+ (void *) pDrawable, (void *) pGC,
+ pRectangles -> x, pRectangles -> y, pRectangles -> width, pRectangles -> height);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentPolyRectangle: Drawable at [%p] GC at [%p] Rectangles [%d].\n",
+ (void *) pDrawable, (void *) pGC, nRectangles);
+ }
+
+ #endif
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miPolyRectangle(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+ }
+ else
+ {
+ miPolyRectangle(pDrawable, pGC, nRectangles, pRectangles);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly rectangle on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly rectangle enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawRectangles(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XRectangle *) pRectangles, nRectangles);
+ }
+ }
+ else
+ {
+ XDrawRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XRectangle *) pRectangles, nRectangles);
+ }
+
+ SET_GC_TRAP();
+
+ miPolyRectangle(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+
+ RESET_GC_TRAP();
+
+ return;
+ }
+ else
+ {
+ XDrawRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XRectangle *) pRectangles, nRectangles);
+
+ SET_GC_TRAP();
+
+ miPolyRectangle(pDrawable, pGC, nRectangles, pRectangles);
+
+ RESET_GC_TRAP();
+ }
+}
+
+void nxagentPolyArc(DrawablePtr pDrawable, GCPtr pGC,
+ int nArcs, xArc *pArcs)
+{
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ fbPolyArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+ }
+ else
+ {
+ fbPolyArc(pDrawable, pGC, nArcs, pArcs);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly arc on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly arc enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawArcs(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XArc *) pArcs, nArcs);
+ }
+ }
+ else
+ {
+ XDrawArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XArc *) pArcs, nArcs);
+ }
+
+ fbPolyArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+
+ return;
+ }
+ else
+ {
+ XDrawArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XArc *) pArcs, nArcs);
+
+ fbPolyArc(pDrawable, pGC, nArcs, pArcs);
+ }
+}
+
+void nxagentFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int nPoints, xPoint *pPoints)
+{
+ xPoint *newPoints = NULL;
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miFillPolygon(nxagentVirtualDrawable(pDrawable), pGC, shape, mode, nPoints, pPoints);
+ }
+ else
+ {
+ miFillPolygon(pDrawable, pGC, shape, mode, nPoints, pPoints);
+ }
+
+ return;
+ }
+
+ /*
+ * The coordinate-mode must be CoordModePrevious
+ * to make better use of differential encoding of
+ * X_FillPoly request by the side of proxy.
+ */
+
+ if (mode == CoordModeOrigin)
+ {
+ int i;
+
+ mode = CoordModePrevious;
+
+ newPoints = malloc(nPoints * sizeof(xPoint));
+
+ /*
+ * The first point is always relative
+ * to the drawable's origin.
+ */
+
+ newPoints[0].x = pPoints[0].x;
+ newPoints[0].y = pPoints[0].y;
+
+ /*
+ * If coordinate-mode is CoordModePrevious,
+ * the points following the first are rela-
+ * tive to the previous point.
+ */
+
+ for (i = 1; i < nPoints; i++)
+ {
+ newPoints[i].x = pPoints[i].x - pPoints[i-1].x;
+ newPoints[i].y = pPoints[i].y - pPoints[i-1].y;
+ }
+
+ pPoints = newPoints;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to fill polygon on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: fill polygon enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XFillPolygon(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XPoint *) pPoints, nPoints, shape, mode);
+ }
+ }
+ else
+ {
+ XFillPolygon(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, shape, mode);
+ }
+
+ SET_GC_TRAP();
+
+ miFillPolygon(nxagentVirtualDrawable(pDrawable), pGC, shape, mode, nPoints, pPoints);
+
+ RESET_GC_TRAP();
+ }
+ else
+ {
+ XFillPolygon(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XPoint *) pPoints, nPoints, shape, mode);
+
+ SET_GC_TRAP();
+
+ miFillPolygon(pDrawable, pGC, shape, mode, nPoints, pPoints);
+
+ RESET_GC_TRAP();
+ }
+
+ if (newPoints != NULL)
+ {
+ free(newPoints);
+ }
+}
+
+void nxagentPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nRectangles, xRectangle *pRectangles)
+{
+ RegionPtr rectRegion;
+
+ int inheritCorruptedRegion;
+
+ #ifdef TEST
+
+ if (nRectangles == 1)
+ {
+ fprintf(stderr, "nxagentPolyFillRect: Drawable at [%p] GC at [%p] FillStyle [%d] Rectangle [%d,%d][%d,%d].\n",
+ (void *) pDrawable, (void *) pGC, pGC -> fillStyle,
+ pRectangles -> x, pRectangles -> y, pRectangles -> width, pRectangles -> height);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentPolyFillRect: Drawable at [%p] GC at [%p] FillStyle [%d] Rectangles [%d].\n",
+ (void *) pDrawable, (void *) pGC, pGC -> fillStyle, nRectangles);
+ }
+
+ #endif
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ fbPolyFillRect(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+ }
+ else
+ {
+ fbPolyFillRect(pDrawable, pGC, nRectangles, pRectangles);
+ }
+
+ return;
+ }
+
+ /*
+ * The PolyFillRect acts in two ways: if the GC
+ * has a corrupted tile, the operation propagates
+ * the corrupted region on the destination. In
+ * other cases, because the PolyFillRect will
+ * cover the destination, any corrupted region
+ * intersecting the target will be cleared.
+ */
+
+ inheritCorruptedRegion = 0;
+
+ if (pGC -> fillStyle == FillTiled &&
+ pGC -> tileIsPixel == 0 && pGC -> tile.pixmap != NULL)
+ {
+ nxagentIncreasePixmapUsageCounter(pGC -> tile.pixmap);
+
+ if (nxagentDrawableStatus((DrawablePtr) pGC -> tile.pixmap) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPolyFillRect: GC at [%p] uses corrupted tile pixmap at [%p]. Going to "
+ "corrupt the destination [%s][%p].\n", (void *) pGC, (void *) pGC -> tile.pixmap,
+ (pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pDrawable);
+
+ #endif
+
+ inheritCorruptedRegion = 1;
+ }
+ }
+
+ if (inheritCorruptedRegion == 1 || nxagentDrawableStatus(pDrawable) == NotSynchronized)
+ {
+ rectRegion = RegionFromRects(nRectangles, pRectangles, CT_REGION);
+
+ if (pGC -> clientClip != NULL)
+ {
+ RegionRec tmpRegion;
+
+ RegionInit(&tmpRegion, NullBox, 1);
+
+ RegionCopy(&tmpRegion, ((RegionPtr) pGC -> clientClip));
+
+ if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+ {
+ RegionTranslate(&tmpRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+ }
+
+ RegionIntersect(rectRegion, rectRegion, &tmpRegion);
+
+ RegionUninit(&tmpRegion);
+ }
+
+ if (inheritCorruptedRegion == 1)
+ {
+ /*
+ * The fill style should affect the cor-
+ * rupted region propagation: if the tile
+ * is not completely corrupted the region
+ * should be 'tiled' over the destination.
+ */
+
+ nxagentMarkCorruptedRegion(pDrawable, rectRegion);
+ }
+ else
+ {
+ if (pGC -> fillStyle != FillStippled && pGC -> fillStyle != FillOpaqueStippled)
+ {
+ nxagentUnmarkCorruptedRegion(pDrawable, rectRegion);
+ }
+ else
+ {
+ /*
+ * The stipple mask computation could cause
+ * an high fragmentation of the destination
+ * region. An analysis should be done to exa-
+ * mine the better solution (e.g.rdesktop
+ * uses stipples to draw texts).
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPolyFillRect: Synchronizing the region [%d,%d,%d,%d] before using "
+ "the stipple at [%p].\n", rectRegion -> extents.x1, rectRegion -> extents.y1,
+ rectRegion -> extents.x2, rectRegion -> extents.y2, (void *) pGC -> stipple);
+ #endif
+
+ nxagentSynchronizeRegion(pDrawable, rectRegion, NEVER_BREAK, NULL);
+ }
+ }
+
+ RegionDestroy(rectRegion);
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly fill rect on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly fill rect enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XFillRectangles(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XRectangle *) pRectangles, nRectangles);
+ }
+ }
+ else
+ {
+ XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XRectangle *) pRectangles, nRectangles);
+ }
+
+ fbPolyFillRect(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+
+ return;
+ }
+ else
+ {
+ XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XRectangle *) pRectangles, nRectangles);
+
+ fbPolyFillRect(pDrawable, pGC, nRectangles, pRectangles);
+ }
+}
+
+void nxagentPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+ int nArcs, xArc *pArcs)
+{
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miPolyFillArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+ }
+ else
+ {
+ miPolyFillArc(pDrawable, pGC, nArcs, pArcs);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly fillarc on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly fill arc enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XFillArcs(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), (XArc *) pArcs, nArcs);
+ }
+ }
+ else
+ {
+ XFillArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ (XArc *) pArcs, nArcs);
+ }
+
+ SET_GC_TRAP();
+
+ miPolyFillArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+
+ RESET_GC_TRAP();
+
+ return;
+ }
+ else
+ {
+ XFillArcs(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), (XArc *) pArcs, nArcs);
+
+ SET_GC_TRAP();
+
+ miPolyFillArc(pDrawable, pGC, nArcs, pArcs);
+
+ RESET_GC_TRAP();
+ }
+}
+
+int nxagentPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, char *string)
+{
+ int width;
+
+ /*
+ * While the session is suspended
+ * the font structure is NULL.
+ */
+
+ if (nxagentFontStruct(pGC -> font) == NULL)
+ {
+ return x;
+ }
+
+ width = XTextWidth(nxagentFontStruct(pGC->font), string, count);
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miPolyText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+ }
+ else
+ {
+ miPolyText8(pDrawable, pGC, x, y, count, string);
+ }
+
+ return width + x;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly text8 on FB pixmap [%p] with string [%s].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly text8 enters with virtual pixmap [%p] parent is [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawString(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), x, y, string, count);
+ }
+ }
+ else
+ {
+ XDrawString(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, string, count);
+ }
+
+ miPolyText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+ return width + x;
+ }
+ else
+ {
+ XDrawString(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+ x, y, string, count);
+
+ miPolyText8(pDrawable, pGC, x, y, count, string);
+ }
+
+ return width + x;
+}
+
+int nxagentPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, unsigned short *string)
+{
+ int width;
+
+ /*
+ * While the session is suspended
+ * the font structure is NULL.
+ */
+
+ if (nxagentFontStruct(pGC -> font) == NULL)
+ {
+ return x;
+ }
+
+ width = XTextWidth16(nxagentFontStruct(pGC->font), (XChar2b *)string, count);
+
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miPolyText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+ }
+ else
+ {
+ miPolyText16(pDrawable, pGC, x, y, count, string);
+ }
+
+ return width + x;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to poly text16 on FB pixmap %p] with string [%s]\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly text16 enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawString16(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+ }
+ }
+ else
+ {
+ XDrawString16(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+ }
+
+ miPolyText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+ return width + x;
+ }
+ else
+ {
+ XDrawString16(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+
+ miPolyText16(pDrawable, pGC, x, y, count, string);
+ }
+
+ return width + x;
+}
+
+void nxagentImageText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, char *string)
+{
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miImageText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+ }
+ else
+ {
+ miImageText8(pDrawable, pGC, x, y, count, string);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to image text8 on FB pixmap [%p] with string [%s].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), string);
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly image text8 enters with virtual pixmap [%p] parent is [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawImageString(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), x, y, string, count);
+ }
+ }
+ else
+ {
+ XDrawImageString(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, string, count);
+ }
+
+ miImageText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+ return;
+ }
+ else
+ {
+ XDrawImageString(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, string, count);
+
+ miImageText8(pDrawable, pGC, x, y, count, string);
+ }
+}
+
+void nxagentImageText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, unsigned short *string)
+{
+ if (nxagentGCTrap == 1)
+ {
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ miImageText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+ }
+ else
+ {
+ miImageText16(pDrawable, pGC, x, y, count, string);
+ }
+
+ return;
+ }
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to image text16 on FB pixmap [%p] with string [%s].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+ #endif
+
+ if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: poly image text16 enters with virtual pixmap = [%p] parent is = [%p]\n",
+ (void *) nxagentVirtualDrawable(pDrawable),
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ if (nxagentRealPixmap((PixmapPtr) pDrawable))
+ {
+ XDrawImageString16(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+ }
+ }
+ else
+ {
+ XDrawImageString16(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+ }
+
+ miImageText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+ return;
+ }
+ else
+ {
+ XDrawImageString16(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), x, y, (XChar2b *)string, count);
+
+ miImageText16(pDrawable, pGC, x, y, count, string);
+ }
+}
+
+void nxagentImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+ void * pGlyphBase)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to imageGlyphBlt on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbImageGlyphBlt(nxagentVirtualDrawable(pDrawable), pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+ }
+ else
+ {
+ fbImageGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+ }
+}
+
+void nxagentPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+ void * pGlyphBase)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to PolyGlyphBlt on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbPolyGlyphBlt(nxagentVirtualDrawable(pDrawable), pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+ }
+ else
+ {
+ fbPolyGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+ }
+}
+
+void nxagentPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
+ int width, int height, int x, int y)
+{
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "GCOps: GC [%p] going to PushPixels on FB pixmap [%p].\n",
+ (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbPushPixels(pGC, nxagentVirtualPixmap(pBitmap),
+ (DrawablePtr) nxagentVirtualDrawable(pDrawable),
+ width, height, x, y);
+ }
+ else
+ {
+ fbPushPixels(pGC, nxagentVirtualPixmap(pBitmap),
+ (DrawablePtr) pDrawable, width, height, x, y);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
new file mode 100644
index 000000000..bbf7fa3df
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -0,0 +1,113 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __GCOps_H__
+#define __GCOps_H__
+
+/*
+ * Graphic operations.
+ */
+
+void nxagentFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans,
+ xPoint *pPoints, int *pWidths, int fSorted);
+
+void nxagentSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
+ xPoint *pPoints, int *pWidths, int nSpans, int fSorted);
+
+void nxagentGetSpans(DrawablePtr pDrawable, int maxWidth, xPoint *pPoints,
+ int *pWidths, int nSpans, char *pBuffer);
+
+RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width,
+ int height, int dstx, int dsty);
+
+RegionPtr nxagentCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long plane);
+
+void nxagentQueryBestSize(int class, unsigned short *pwidth,
+ unsigned short *pheight, ScreenPtr pScreen);
+
+void nxagentPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints);
+
+void nxagentPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints);
+
+void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+ int nSegments, xSegment *pSegments);
+
+void nxagentPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+ int nRectangles, xRectangle *pRectangles);
+
+void nxagentPolyArc(DrawablePtr pDrawable, GCPtr pGC,
+ int nArcs, xArc *pArcs);
+
+void nxagentFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int nPoints, xPoint *pPoints);
+
+void nxagentPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nRectangles, xRectangle *pRectangles);
+
+void nxagentPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+ int nArcs, xArc *pArcs);
+
+int nxagentPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, char *string);
+
+int nxagentPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, unsigned short *string);
+
+void nxagentImageText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, char *string);
+
+void nxagentImageText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+ int y, int count, unsigned short *string);
+
+void nxagentImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo, void * pGlyphBase);
+
+void nxagentPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo, void * pGlyphBase);
+
+void nxagentPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
+ int width, int height, int x, int y);
+
+#endif /* __GCOps_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
new file mode 100644
index 000000000..84b0063ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __GC_H__
+#define __GC_H__
+
+extern RESTYPE RT_NX_GC;
+
+/* This file uses the GC definition form Xlib.h as XlibGC. */
+
+typedef struct {
+ XlibGC gc;
+
+ int nClipRects;
+
+ XGCValues lastServerValues;
+
+ XID mid;
+
+ PixmapPtr pPixmap;
+
+} nxagentPrivGC;
+
+extern int nxagentGCPrivateIndex;
+
+typedef struct _nxagentGraphicContextsRec
+{
+ int depth;
+ GCPtr pGC;
+ int dirty;
+
+} nxagentGraphicContextsRec;
+
+typedef nxagentGraphicContextsRec *nxagentGraphicContextsPtr;
+extern nxagentGraphicContextsPtr nxagentGraphicContexts;
+extern int nxagentGraphicContextsSize;
+
+#define nxagentGCPriv(pGC) \
+ ((nxagentPrivGC *)((pGC) -> devPrivates[nxagentGCPrivateIndex].ptr))
+
+#define nxagentGC(pGC) (nxagentGCPriv(pGC) -> gc)
+
+#define nxagentCopyGCPriv(valueMask, valueField, src, mask, dst) \
+\
+ if (mask & valueMask) \
+ { \
+ nxagentGCPriv(dst) -> lastServerValues.valueField = \
+ nxagentGCPriv(src) -> lastServerValues.valueField; \
+ }
+
+#define nxagentTestGC(newValue, pvalue) \
+\
+ ((nxagentGCPriv(pGC) -> lastServerValues.pvalue == newValue) ? 0 : 1); \
+\
+ nxagentGCPriv(pGC) -> lastServerValues.pvalue = newValue
+
+Bool nxagentCreateGC(GCPtr pGC);
+void nxagentValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+void nxagentChangeGC(GCPtr pGC, unsigned long mask);
+void nxagentCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+void nxagentDestroyGC(GCPtr pGC);
+void nxagentChangeClip(GCPtr pGC, int type, void * pValue, int nRects);
+void nxagentDestroyClip(GCPtr pGC);
+void nxagentDestroyClipHelper(GCPtr pGC);
+void nxagentCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
+void nxagentDisconnectGC(void * p0, XID x1, void * p2);
+Bool nxagentDisconnectAllGCs(void);
+
+Bool nxagentReconnectAllGCs(void *p0);
+
+int nxagentDestroyNewGCResourceType(void * p, XID id);
+
+void nxagentFreeGCList(void);
+void nxagentInitGCSafeVector(void);
+
+GCPtr nxagentGetScratchGC(unsigned depth, ScreenPtr pScreen);
+void nxagentFreeScratchGC(GCPtr pGC);
+
+GCPtr nxagentGetGraphicContext(DrawablePtr pDrawable);
+void nxagentAllocateGraphicContexts(void);
+
+#endif /* __GC_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
new file mode 100644
index 000000000..634f7aafd
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -0,0 +1,1325 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "osdep.h"
+
+#include "Agent.h"
+#include "Handlers.h"
+#include "Display.h"
+#include "Events.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Dialog.h"
+#include "Drawable.h"
+#include "Splash.h"
+#include "Screen.h"
+#include "Millis.h"
+
+#define Window XlibWindow
+#include "compext/Compext.h"
+#undef Window
+
+#include <nx/Shadow.h>
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/*
+ * Log begin and end of the important
+ * handlers.
+ */
+
+#undef BLOCKS
+
+/*
+ * If not defined, flush immediately
+ * upon entering the block handler.
+ */
+
+#define FLUSH_AFTER_MULTIPLE_READS
+
+/*
+ * The soft limit should roughly match
+ * the size of the Xlib I/O buffer.
+ */
+
+#define BYTES_BEFORE_SOFT_TOKEN 2048
+#define BYTES_BEFORE_HARD_TOKEN 65536
+
+/*
+ * Maximum number of synchronization
+ * requests before waiting for the
+ * remote.
+ */
+
+#define TOKENS_PENDING_LIMIT 8
+
+/*
+ * Limits are very unobtrusive. We don't
+ * want to interfere with the normal
+ * dispatching.
+ */
+
+#define BYTES_BEFORE_YIELD 1048576
+#define TIME_BEFORE_YIELD 500
+
+/*
+ * Dinamically reduce the display buffer
+ * size after a congestion.
+ */
+
+#undef DYNAMIC_DISPLAY_BUFFER
+
+/*
+ * Minimum display buffer size.
+ */
+
+#define MINIMUM_DISPLAY_BUFFER 512
+
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInputDevices;
+extern unsigned long nxagentLastInputDevicesDumpTime;
+
+extern void nxagentDumpInputDevicesState(void);
+#endif
+
+/*
+ * Used in the handling of the X desktop
+ * manager protocol.
+ */
+
+int nxagentXdmcpUp = 0;
+int nxagentXdmcpAlertUp = 0;
+
+/*
+ * Also used in the block, wakeup and
+ * sync handlers.
+ */
+
+int nxagentBuffer;
+int nxagentBlocking;
+int nxagentCongestion;
+
+double nxagentBytesIn;
+double nxagentBytesOut;
+
+/*
+ * Total number of descriptors ready
+ * as reported by the wakeup handler.
+ */
+
+int nxagentReady;
+
+/*
+ * Timestamp of the last write to the
+ * remote display.
+ */
+
+int nxagentFlush;
+
+/*
+ * Arbitrate the bandwidth among our
+ * clients.
+ */
+
+struct _TokensRec nxagentTokens = { 0, 0, 0 };
+struct _DispatchRec nxagentDispatch = { UNDEFINED, 0, 0, 0 };
+
+/*
+ * Called just before blocking, waiting
+ * for our clients or the X server.
+ */
+
+extern int nxagentSkipImage;
+
+void nxagentBlockHandler(void * data, struct timeval **timeout, void * mask)
+{
+ /*
+ * Zero timeout.
+ */
+
+ static struct timeval zero;
+
+ /*
+ * Current timestamp.
+ */
+
+ static int now;
+
+ /*
+ * Pending bytes to write to the
+ * network.
+ */
+
+ static int flushable;
+
+ /*
+ * Set if we need to synchronize
+ * any drawable.
+ */
+
+ static int synchronize;
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin block]\n");
+ #endif
+
+ now = GetTimeInMillis();
+
+ #ifdef NX_DEBUG_INPUT
+
+ if (nxagentDebugInputDevices == 1 &&
+ now - nxagentLastInputDevicesDumpTime > 5000)
+ {
+ nxagentLastInputDevicesDumpTime = now;
+
+ nxagentDumpInputDevicesState();
+ }
+
+ #endif
+
+ if (nxagentNeedConnectionChange() == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionChanges "
+ "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+ #endif
+
+ nxagentHandleConnectionChanges();
+ }
+
+ if (nxagentOption(Rootless) &&
+ nxagentLastWindowDestroyed && nxagentRootlessDialogPid == 0 &&
+ now > nxagentLastWindowDestroyedTime + 30 * 1000 && !nxagentOption(NoRootlessExit))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentBlockHandler: No application running. Closing the session.\n");
+ #endif
+
+ nxagentTerminateSession();
+ }
+
+ #ifdef TEST
+
+ if (nxagentLastWindowDestroyed == 1)
+ {
+ fprintf(stderr, "nxagentBlockHandler: Elapsed time [%lu].\n",
+ now - nxagentLastWindowDestroyedTime);
+ }
+
+ #endif
+
+ /*
+ * Slow down the agent if the session is
+ * not connected to a valid display.
+ */
+
+ if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0 && nxagentOption(SleepTime) > 0)
+ {
+#ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: sleeping for %d milliseconds for slowdown.\n",
+ nxagentOption(SleepTime));
+#endif
+ usleep(nxagentOption(SleepTime) * 1000);
+
+ now = GetTimeInMillis();
+ }
+#ifdef TEST
+ else if (0 == nxagentOption(SleepTime)) {
+ fprintf(stderr, "nxagentBlockHandler: not sleeping for slowdown.\n");
+ }
+#endif
+
+ /*
+ * Update the shadow display. This is
+ * only for test purposes.
+ */
+
+ #ifdef DUMP
+
+ nxagentPixmapOnShadowDisplay(NULL);
+
+ nxagentFbOnShadowDisplay();
+
+ #endif
+
+ /*
+ * We need this here because some window
+ * configuration changes can be generated
+ * by the X server outside the control of
+ * the DIX.
+ */
+
+ nxagentFlushConfigureWindow();
+
+ /*
+ * Check whether there is any drawable to
+ * synchronize.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Checking synchronization at %s with "
+ "[%d][%d][%d].\n", GetTimeInMillisAsString(), nxagentCorruptedWindows,
+ nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps);
+ #endif
+
+ synchronize = (nxagentCorruptedWindows > 0 ||
+ nxagentCorruptedBackgrounds > 0 ||
+ nxagentCorruptedPixmaps > 0);
+
+ /*
+ * The synchronization function requires a mask as
+ * parameter:
+ *
+ * EVENT_BREAK Breaks if an user input, like
+ * a key press or a mouse move,
+ * is detected.
+ *
+ * CONGESTION_BREAK Breaks if the congestion beco-
+ * mes greater than 4.
+ *
+ * BLOCKING_BREAK Breaks if the display descript-
+ * or becomes blocked for write
+ * during the loop.
+ *
+ * ALWAYS_BREAK Any of the previous conditions
+ * is met.
+ *
+ * NEVER_BREAK The loop continues until all
+ * the drawables are synchronized.
+ */
+
+ if (synchronize == 1)
+ {
+ /*
+ * We should not enter the synchronization
+ * loop if there is any user input pending,
+ * i.e. if we are in the middle of a scroll
+ * operation.
+ */
+
+ if (nxagentForceSynchronization == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Going to force a synchronization at %s.\n",
+ GetTimeInMillisAsString());
+ #endif
+
+ nxagentSynchronizationLoop(NEVER_BREAK);
+
+ nxagentForceSynchronization = 0;
+ }
+ else if (nxagentUserInput(NULL) == 0 &&
+ nxagentBlocking == 0 &&
+ nxagentCongestion <= 4)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Going to synchronize at %s.\n",
+ GetTimeInMillisAsString());
+ #endif
+
+ nxagentSynchronizationLoop(ALWAYS_BREAK);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentBlockHandler: Not synchronizing with [%d][%d].\n",
+ nxagentBlocking, nxagentCongestion);
+ }
+ #endif
+
+ /*
+ * Check if we have more corrupted resources
+ * and whether the conditions are satisfied
+ * to continue with the synchronization.
+ */
+
+ synchronize = (nxagentCongestion <= 4 &&
+ (nxagentCorruptedWindows > 0 ||
+ nxagentCorruptedBackgrounds > 0 ||
+ nxagentCorruptedPixmaps > 0));
+
+ if (nxagentSkipImage == 0 && synchronize == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Setting a zero timeout with [%d][%d][%d] and "
+ "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
+ nxagentCorruptedPixmaps, nxagentCongestion);
+ #endif
+
+ zero.tv_sec = 0;
+ zero.tv_usec = 0;
+
+ *timeout = &zero;
+ }
+ #ifdef TEST
+ else
+ {
+ if (nxagentCorruptedWindows == 0 &&
+ nxagentCorruptedBackgrounds == 0 &&
+ nxagentCorruptedPixmaps == 0)
+ {
+ fprintf(stderr, "nxagentBlockHandler: Nothing more to synchronize at %s.\n",
+ GetTimeInMillisAsString());
+ }
+ else
+ {
+ fprintf(stderr, "nxagentBlockHandler: Delaying synchronization with [%d][%d][%d] and "
+ "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
+ nxagentCorruptedPixmaps, nxagentCongestion);
+ }
+ }
+ #endif
+ }
+
+ /*
+ * If the remote X server is blocking, reduce the
+ * amount of data sent in a single display update
+ * by reducing the size of the display buffer.
+ */
+
+ #ifdef DYNAMIC_DISPLAY_BUFFER
+
+ if (nxagentBlocking == 1 &&
+ nxagentBuffer > MINIMUM_DISPLAY_BUFFER)
+ {
+ nxagentBuffer >>= 1;
+
+ if (nxagentBuffer < MINIMUM_DISPLAY_BUFFER)
+ {
+ nxagentBuffer = MINIMUM_DISPLAY_BUFFER;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchHandler: Reducing the display buffer to [%d] bytes.\n",
+ nxagentBuffer);
+ #endif
+
+ NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer);
+ }
+ else if (nxagentBuffer < nxagentOption(DisplayBuffer) &&
+ nxagentCongestion == 0)
+ {
+ nxagentBuffer = nxagentOption(DisplayBuffer);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchHandler: Increasing the display buffer to [%d] bytes.\n",
+ nxagentBuffer);
+ #endif
+
+ NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer);
+ }
+
+ #endif /* #ifdef DYNAMIC_DISPLAY_BUFFER */
+
+ /*
+ * Dispatch to the clients the events that
+ * may have become available.
+ */
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ /*
+ * Check if there is any data remaining,
+ * either in the display buffer or in
+ * the NX transport.
+ */
+
+ flushable = NXDisplayFlushable(nxagentDisplay);
+
+ if (flushable > 0)
+ {
+ #ifdef FLUSH_AFTER_MULTIPLE_READS
+
+ /*
+ * Flush all the outstanding data if
+ * the wakeup handler didn't detect
+ * any activity.
+ */
+
+ if (nxagentReady == 0 || now - nxagentFlush >=
+ nxagentOption(DisplayCoalescence))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBlockHandler: Flushing the display with [%d] bytes to flush.\n",
+ flushable);
+ #endif
+
+ NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+ /*
+ * New events may have become available
+ * after the flush.
+ */
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBlockHandler: Delaying flush with [%d][%d] and [%d] bytes.\n",
+ synchronize, nxagentReady, flushable);
+ #endif
+
+ zero.tv_sec = 0;
+ zero.tv_usec = 0;
+
+ *timeout = &zero;
+ }
+
+ #else /* #ifdef FLUSH_AFTER_MULTIPLE_READS */
+
+ /*
+ * We are entering the select. Tell the NX
+ * transport to write any produced data to
+ * the remote end.
+ */
+
+ NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ #endif /* #ifdef FLUSH_AFTER_MULTIPLE_READS */
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBlockHandler: Nothing to flush with [%d][%d].\n",
+ synchronize, nxagentReady);
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 0 &&
+ nxagentQueuedEvents(nxagentDisplay) > 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentBlockHandler: WARNING! Forcing a null timeout with events queued.\n");
+ #endif
+
+ zero.tv_sec = 0;
+ zero.tv_usec = 0;
+
+ *timeout = &zero;
+ }
+ }
+
+ /*
+ * WaitForSomething() sets a zero timeout if there
+ * are clients with input, but doesn't stop the
+ * timer. The select is then interrupted to update
+ * the schedule time even if, what the dispatcher
+ * cares, is only the number of ticks at the time
+ * the client is scheduled in.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentBlockHandler: Stopping the smart schedule timer.\n");
+ #endif
+
+ nxagentStopTimer();
+
+ nxagentPrintGeometry();
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End block]\n");
+ #endif
+}
+
+void nxagentWakeupHandler(void * data, int count, void * mask)
+{
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin wakeup]\n");
+ #endif
+
+ if (nxagentException.sigHup || nxagentException.ioError)
+ {
+ #ifdef TEST
+ fprintf(stderr,"nxagentWakeupHandler: Got SIGHUP or I/O error.\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionStates "
+ "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+ #endif
+
+ nxagentHandleConnectionStates();
+ }
+
+ if (!SmartScheduleSignalEnable)
+ {
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWakeupHandler: Resetting the dispatch state after wakeup.\n");
+ #endif
+
+ nxagentDispatch.start = GetTimeInMillis();
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+
+ }
+
+ /*
+ * Can become true during the dispatch loop.
+ */
+
+ nxagentBlocking = 0;
+
+ /*
+ * Check if we got new events.
+ */
+
+ if (count > 0 && FD_ISSET(nxagentXConnectionNumber, (fd_set *) mask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentWakeupHandler: Reading the X events with count [%d].\n",
+ count);
+ #endif
+
+ nxagentDispatchEvents(NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWakeupHandler: Removing the X descriptor from the count.\n");
+ #endif
+
+ FD_CLR(nxagentXConnectionNumber, (fd_set *) mask);
+
+ count--;
+ }
+ else if (nxagentQueuedEvents(nxagentDisplay) == 1)
+ {
+ /*
+ * We may have left some events in
+ * the queue.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWakeupHandler: Reading the queued X events with count [%d].\n",
+ count);
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ /*
+ * Save the number of descriptors ready.
+ */
+
+ if (count <= 0)
+ {
+ count = (XFD_ANYSET(&ClientsWithInput) ? 1 : 0);
+ }
+
+ nxagentReady = count;
+
+ #ifdef TEST
+
+ if (nxagentReady == 0)
+ {
+ fprintf(stderr, "nxagentWakeupHandler: No X clients found to be processed.\n");
+ }
+
+ #endif
+
+ /*
+ * If the XDM connection can't be established
+ * we'll need to create a dialog to notify the
+ * user and give him/her a chance to terminate
+ * the session.
+ */
+
+ if (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWakeupHandler: XdmcpState [%d].\n", XdmcpState);
+ #endif
+
+ if (XdmcpState == XDM_RUN_SESSION)
+ {
+ nxagentXdmcpUp = 1;
+ }
+
+ if (nxagentXdmcpUp == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWakeupHandler: XdmcpTime [%lu].\n",
+ GetTimeInMillis() - XdmcpStartTime);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentWakeupHandler: XdmcpTimeOutRtx [%d].\n",
+ XdmcpTimeOutRtx);
+ #endif
+
+ if (nxagentXdmcpAlertUp == 0 &&
+ GetTimeInMillis() - XdmcpStartTime >= XDM_TIMEOUT)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentWakeupHandler: WARNING! The XDM session seems to be "
+ "unable to start after [%ld] ms.\n",(long int)(GetTimeInMillis() - XdmcpStartTime));
+ #endif
+
+ NXTransAlert(FAILED_XDMCP_CONNECTION_ALERT, NX_ALERT_REMOTE);
+
+ nxagentXdmcpAlertUp = 1;
+ }
+ }
+ }
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End wakeup]\n");
+ #endif
+}
+
+void nxagentShadowBlockHandler(void * data, struct timeval **timeout, void * mask)
+{
+ static struct timeval zero;
+
+ int changed;
+ int suspended = 0;
+ int width_, height_;
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin block]\n");
+ #endif
+
+ if (nxagentNeedConnectionChange() == 1)
+ {
+ nxagentHandleConnectionChanges();
+ }
+
+ if (nxagentSessionState == SESSION_DOWN && nxagentOption(SleepTime) > 0)
+ {
+#ifdef TEST
+ fprintf(stderr, "nxagentBlockHandler: sleeping for %d milliseconds for slowdown.\n",
+ nxagentOption(SleepTime));
+#endif
+ usleep(nxagentOption(SleepTime) * 1000);
+ }
+#ifdef TEST
+ else if (0 == nxagentOption(SleepTime)) {
+ fprintf(stderr, "nxagentBlockHandler: not sleeping for slowdown.\n");
+ }
+#endif
+
+ #ifndef __CYGWIN32__
+
+ if (nxagentReadEvents(nxagentDisplay) > 0 ||
+ nxagentReadEvents(nxagentShadowDisplay) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowBlockHandler: Reading X events queued.\n");
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ if (nxagentShadowResize == 1)
+ {
+ nxagentShadowResize = 0;
+
+ nxagentShadowAdaptToRatio();
+ }
+
+ #else
+
+ if (nxagentReadEvents(nxagentDisplay) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowBlockHandler: Reading X events queued.\n");
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ #endif
+
+ changed = 0;
+
+ NXShadowGetScreenSize(&width_, &height_);
+
+ if (width_ != nxagentShadowWidth || height_ != nxagentShadowHeight)
+ {
+ /*
+ * The master session has been resized.
+ */
+
+ NXShadowSetScreenSize(&nxagentShadowWidth, &nxagentShadowHeight);
+
+ nxagentShadowAdaptToRatio();
+ }
+
+ nxagentShadowPoll(nxagentShadowPixmapPtr, nxagentShadowGCPtr, nxagentShadowDepth, nxagentShadowWidth,
+ nxagentShadowHeight, nxagentShadowBuffer, &changed, &suspended);
+
+ nxagentShadowSendUpdates(&suspended);
+
+ if (nxagentBlocking == 0)
+ {
+ nxagentSynchronizeDrawable((DrawablePtr) nxagentShadowPixmapPtr, DONT_WAIT,
+ ALWAYS_BREAK, nxagentShadowWindowPtr);
+ }
+
+ /*
+ * We are entering the select. Tell the NX
+ * transport to write any produced data to
+ * the remote end.
+ */
+/*
+FIXME: Must queue multiple writes and handle
+ the events by resembling the ordinary
+ block handler.
+*/
+
+ NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+ if (*timeout == NULL)
+ {
+ *timeout = &zero;
+ }
+
+ #ifdef __CYGWIN32__
+
+ if (nxagentOption(SleepTime) > 0) {
+#ifdef TEST
+ fprintf(stderr, "nxagentShadowBlockHandler: sleeping for %d milliseconds for slowdown.\n",
+ nxagentOption(SleepTime));
+#endif
+ usleep(nxagentOption(SleepTime) * 1000);
+ }
+#ifdef TEST
+ else if (0 == nxagentOption(SleepTime)) {
+ fprintf(stderr, "nxagentShadowBlockHandler: not sleeping for slowdown.\n");
+ }
+#endif
+
+ (*timeout) -> tv_sec = 0;
+ (*timeout) -> tv_usec = 50 * 1000;
+
+ #else
+
+ if (changed == 0)
+ {
+ (*timeout) -> tv_sec = 0;
+ (*timeout) -> tv_usec = 50 * 1000;
+ }
+ else
+ {
+ (*timeout) -> tv_sec = 0;
+ (*timeout) -> tv_usec = 0;
+ }
+
+ #endif
+
+ nxagentPrintGeometry();
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End block]\n");
+ #endif
+}
+
+void nxagentShadowWakeupHandler(void * data, int count, void * mask)
+{
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin wakeup]\n");
+ #endif
+
+ if (nxagentException.sigHup || nxagentException.ioError)
+ {
+ #ifdef TEST
+ fprintf(stderr,"nxagentShadowWakeupHandler: Got SIGHUP or I/O error.\n");
+ #endif
+
+ nxagentHandleConnectionStates();
+ }
+
+ if (!SmartScheduleSignalEnable)
+ {
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShadowWakeupHandler: Resetting the dispatch state after wakeup.\n");
+ #endif
+
+ nxagentDispatch.start = GetTimeInMillis();
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+
+ }
+
+ /*
+ * Can become true during the dispatch loop.
+ */
+
+ nxagentBlocking = 0;
+
+ /*
+ * Check if we got new events.
+ */
+
+ if (count > 0 && FD_ISSET(nxagentXConnectionNumber, (fd_set *) mask))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowWakeupHandler: Reading the X events with count [%d].\n",
+ count);
+ #endif
+
+ nxagentDispatchEvents(NULL);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowWakeupHandler: Removing the X descriptor from the count.\n");
+ #endif
+
+ FD_CLR(nxagentXConnectionNumber, (fd_set *) mask);
+
+ count--;
+ }
+ else if (nxagentQueuedEvents(nxagentDisplay) == 1)
+ {
+ /*
+ * We may have left some events in
+ * the queue.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowWakeupHandler: Reading the queued X events with count [%d].\n",
+ count);
+ #endif
+
+ nxagentDispatchEvents(NULL);
+ }
+
+ /*
+ * Save the number of descriptors ready.
+ */
+
+ if (count <= 0)
+ {
+ count = (XFD_ANYSET(&ClientsWithInput) ? 1 : 0);
+ }
+
+ nxagentReady = count;
+
+ #ifdef TEST
+
+ if (nxagentReady == 0)
+ {
+ fprintf(stderr, "nxagentShadowWakeupHandler: No X clients found to be processed.\n");
+ }
+
+ #endif
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End wakeup]\n");
+ #endif
+}
+
+void nxagentHandleCollectInputFocusEvent(int resource)
+{
+ /*
+ * While we don't even need window or revert_to later on, a discrepancy in
+ * data type sizes between the X server (Window being a 32bit ID) and
+ * the Xlib (Window being a 64bit ID) will lead to stack corruption here.
+ * Calling functions from CompExt from nxagent sounds like a very bad idea
+ * to begin with, but let's assume that's necessary for now and work around
+ * the corruption issue.
+ *
+ * Even though the CompExt header shows that the function expects a Window-sized
+ * parameter, it's not the Window type as defined and used within the X.Org
+ * Server, but an Xlib type. Hence, we'll be using the "XlibWindow" type here
+ * and to avoid compiler warnings, "rewrite" the CompExt.h header file via
+ * overriding the original "Window" type with the XlibWindow type, including
+ * the header file and undefining the macro again, essentially unshadowing
+ * the original type.
+ */
+ XlibWindow window;
+
+ int revert_to;
+
+ if (NXGetCollectedInputFocus(nxagentDisplay, resource, &window, &revert_to) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleCollectInputFocusEvent: PANIC! Failed to get the input focus "
+ "reply for resource [%d].\n", resource);
+ #endif
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentHandleCollectInputFocusEvent: Received a sync reply with [%d] pending.\n",
+ nxagentTokens.pending);
+ #endif
+
+ nxagentTokens.pending--;
+
+ nxagentCongestion = (nxagentTokens.pending >= TOKENS_PENDING_LIMIT / 2);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleCollectInputFocusEvent: Current congestion level is [%d].\n",
+ nxagentCongestion);
+ #endif
+}
+
+Bool nxagentCollectInputFocusPredicate(Display *display, XEvent *X, XPointer ptr)
+{
+ return (X -> xclient.window == 0 &&
+ X -> xclient.message_type == 0 &&
+ X -> xclient.format == 32 &&
+ X -> xclient.data.l[0] == NXCollectInputFocusNotify);
+}
+
+void nxagentDispatchHandler(ClientPtr client, int in, int out)
+{
+ /*
+ * This function is called by the dispatcher (with 0
+ * bytes out) after a new request has been processed.
+ * It is also called by the write handler (with 0
+ * bytes in) after more data has been written to the
+ * display. It may be optionally called in the block
+ * and wakeup handlers. In this case both in and out
+ * must be 0.
+ */
+
+ if (out > 0)
+ {
+ /*
+ * Called by the display write callback.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Called with [%d] bytes written.\n",
+ out);
+ #endif
+
+ nxagentBytesOut += out;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Total bytes are [%.0f] in [%.0f] out.\n",
+ nxagentBytesIn, nxagentBytesOut);
+ #endif
+
+ /*
+ * Don't take care of the synchronization if
+ * the NX transport is running. The NX trans-
+ * port has its own token-based control flow.
+ *
+ * We can't produce more output here because
+ * we are in the middle of the flush. We will
+ * take care of the sync requests when called
+ * by the dispatcher.
+ */
+
+ if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+ {
+ nxagentTokens.soft += out;
+
+ if (out > BYTES_BEFORE_HARD_TOKEN)
+ {
+ nxagentTokens.hard += out;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Sync bytes accumulated are [%d] and [%d].\n",
+ nxagentTokens.soft, nxagentTokens.hard);
+ #endif
+ }
+
+ if (!SmartScheduleSignalEnable)
+ {
+
+ /*
+ * Pay attention to the next client if this
+ * client produced enough output.
+ */
+
+ if (nxagentBytesOut - nxagentDispatch.out > BYTES_BEFORE_YIELD)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Yielding with [%ld][%.0f][%.0f] for client [%d].\n",
+ GetTimeInMillis() - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in,
+ nxagentBytesOut - nxagentDispatch.out, nxagentDispatch.client);
+ #endif
+
+ nxagentDispatch.start = GetTimeInMillis();
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+
+ isItTimeToYield = 1;
+ }
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "nxagentDispatchHandler: Dispatching with [%ld][%.0f][%.0f] for client [%d].\n",
+ GetTimeInMillis() - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in,
+ nxagentBytesOut - nxagentDispatch.out, nxagentDispatch.client);
+ }
+ #endif
+
+ }
+
+ return;
+ }
+ else if (in > 0)
+ {
+ /*
+ * Called by the dispatcher.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Called with [%d] bytes processed for client [%d].\n",
+ in, client -> index);
+ #endif
+
+ /*
+ * This is presently unused.
+ *
+ * nxagentClientAddBytes(client, in);
+ *
+ * #ifdef DEBUG
+ * fprintf(stderr, "nxagentDispatchHandler: Bytes processed for client [%d] are [%ld].\n",
+ * client -> index, nxagentClientBytes(client));
+ * #endif
+ *
+ */
+
+ nxagentBytesIn += in;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Total bytes are [%.0f] in [%.0f] out.\n",
+ nxagentBytesIn, nxagentBytesOut);
+ #endif
+
+ /*
+ * When using the dumb scheduler, before reading from
+ * another client, the dispatcher tries to drain all
+ * the input from the client being processed. This
+ * means that, if isItTimeToYield is never set and the
+ * client never produces any output, we'll stick into
+ * the inner dispatch loop forever.
+ */
+
+ if (!SmartScheduleSignalEnable)
+ {
+
+ if (client -> index != nxagentDispatch.client)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Resetting the dispatch state with [%d][%d].\n",
+ nxagentDispatch.client, client -> index);
+ #endif
+
+ nxagentDispatch.client = client -> index;
+ nxagentDispatch.start = GetTimeInMillis();
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+ }
+ else
+ {
+ static unsigned long int now;
+
+ now = GetTimeInMillis();
+
+ if (now - nxagentDispatch.start > TIME_BEFORE_YIELD ||
+ nxagentBytesIn - nxagentDispatch.in > BYTES_BEFORE_YIELD)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Yielding with [%ld][%.0f][%.0f] for client [%d].\n",
+ now - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in, nxagentBytesOut -
+ nxagentDispatch.out, nxagentDispatch.client);
+ #endif
+
+ nxagentDispatch.start = now;
+
+ nxagentDispatch.in = nxagentBytesIn;
+ nxagentDispatch.out = nxagentBytesOut;
+
+ isItTimeToYield = 1;
+ }
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "nxagentDispatchHandler: Dispatching with [%ld][%.0f][%.0f] for client [%d].\n",
+ now - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in, nxagentBytesOut -
+ nxagentDispatch.out, nxagentDispatch.client);
+ }
+ #endif
+ }
+
+ }
+
+ }
+
+ /*
+ * Let's see if it's time to sync.
+ */
+
+ if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+ {
+ if (nxagentTokens.hard > BYTES_BEFORE_HARD_TOKEN)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Requesting a hard sync reply with [%d] bytes.\n",
+ nxagentTokens.hard);
+ #endif
+
+ XSync(nxagentDisplay, 0);
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ nxagentDispatchEvents(NULL);
+ }
+
+ nxagentTokens.soft = 0;
+ nxagentTokens.hard = 0;
+ }
+ else if (nxagentTokens.soft > BYTES_BEFORE_SOFT_TOKEN)
+ {
+ /*
+ * Alternatively, the amounts of bytes
+ * accounted for each sync request may
+ * be decreased according to the number
+ * of pending replies already awaited.
+ *
+ * else if (nxagentTokens.soft > (BYTES_BEFORE_SOFT_TOKEN / (nxagentTokens.pending + 1)))
+ */
+
+ int resource;
+
+ /*
+ * Wait eventually for the number of
+ * synchronization requests to return
+ * below the limit.
+ */
+
+ #ifdef TEST
+
+ if (nxagentTokens.pending == TOKENS_PENDING_LIMIT)
+ {
+ fprintf(stderr, "nxagentDispatchHandler: WARNING! Waiting for the synchronization reply.\n");
+ }
+
+ #endif
+
+ while (nxagentTokens.pending == TOKENS_PENDING_LIMIT)
+ {
+ if (nxagentWaitEvents(nxagentDisplay, NULL) == -1)
+ {
+ nxagentTokens.pending = 0;
+
+ nxagentTokens.soft = 0;
+
+ return;
+ }
+
+ nxagentDispatchEvents(NULL);
+
+ nxagentBlocking = 1;
+ }
+
+ /*
+ * Send a new synchronization request.
+ */
+
+ resource = nxagentWaitForResource(NXGetCollectInputFocusResource,
+ nxagentCollectInputFocusPredicate);
+
+ if (resource == -1)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentDispatchHandler: PANIC! Cannot allocate any valid resource.\n");
+ #endif
+
+ nxagentTokens.soft = 0;
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDispatchHandler: Requesting a sync reply with [%d] bytes "
+ "and [%d] pending.\n", nxagentTokens.soft, nxagentTokens.pending);
+ #endif
+
+ NXCollectInputFocus(nxagentDisplay, resource);
+
+ NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ nxagentDispatchEvents(NULL);
+ }
+
+ nxagentTokens.pending++;
+
+ nxagentCongestion = (nxagentTokens.pending >= TOKENS_PENDING_LIMIT / 2);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDispatchHandler: Current congestion level is [%d].\n",
+ nxagentCongestion);
+ #endif
+
+ nxagentTokens.soft = 0;
+ }
+ }
+
+ /*
+ * Check if there are events to read.
+ */
+
+ if (nxagentPendingEvents(nxagentDisplay) > 0)
+ {
+ nxagentDispatchEvents(NULL);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
new file mode 100644
index 000000000..ddae097da
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -0,0 +1,129 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Handlers_H__
+#define __Handlers_H__
+
+/*
+ * Current size of the display buffer.
+ */
+
+extern int nxagentBuffer;
+
+/*
+ * Set if we had to block waiting for
+ * the display to become writable.
+ */
+
+extern int nxagentBlocking;
+
+/*
+ * Current congestion level based on
+ * the sync requests awaited or the
+ * proxy tokens.
+ */
+
+extern int nxagentCongestion;
+
+/*
+ * Bytes read from the agent's clients
+ * and written to the display socket.
+ */
+
+extern double nxagentBytesIn;
+extern double nxagentBytesOut;
+
+/*
+ * Total number of descriptors ready
+ * as reported by the wakeup handler.
+ */
+
+extern int nxagentReady;
+
+/*
+ * Timestamp of the last write to the
+ * remote display.
+ */
+
+extern int nxagentFlush;
+
+/*
+ * Let the dispatch loop yield control to
+ * a different client after a fair amount
+ * of time or after enough data has been
+ * processed.
+ */
+
+struct _DispatchRec
+{
+ int client;
+
+ double in;
+ double out;
+
+ unsigned long start;
+};
+
+extern struct _DispatchRec nxagentDispatch;
+
+/*
+ * Ensure that we synchronize with the X
+ * server after a given amount of output
+ * is produced.
+ */
+
+struct _TokensRec
+{
+ int soft;
+ int hard;
+
+ int pending;
+};
+
+extern struct _TokensRec nxagentTokens;
+
+/*
+ * The agent's block and wakeup handlers.
+ */
+
+void nxagentBlockHandler(void * data, struct timeval **timeout, void * mask);
+void nxagentWakeupHandler(void * data, int count, void * mask);
+
+/*
+ * Executed after each request processed.
+ */
+
+void nxagentDispatchHandler(ClientPtr client, int in, int out);
+
+void nxagentShadowBlockHandler(void * data, struct timeval **timeout, void * mask);
+void nxagentShadowWakeupHandler(void * data, int count, void * mask);
+
+extern GCPtr nxagentShadowGCPtr;
+extern unsigned char nxagentShadowDepth;
+extern int nxagentShadowWidth;
+extern int nxagentShadowHeight;
+extern char *nxagentShadowBuffer;
+
+#endif /* __Handlers_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
new file mode 100644
index 000000000..aae48471b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -0,0 +1,235 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef _XSERVER64
+
+#include "scrnintstr.h"
+#include "Agent.h"
+#define GC XlibGC
+#define Pixmap XlibPixmap
+#define PIXEL_ALREADY_TYPEDEFED
+
+#endif /* _XSERVER64 */
+
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "resource.h"
+#include "../../include/gc.h"
+#include "../../include/window.h"
+
+#include "X11/include/xpm_nxagent.h"
+
+#include "Agent.h"
+#include "Pixmaps.h"
+#include "Display.h"
+#include "Holder.h"
+#include "Icons.h"
+
+#include NXAGENT_PLACEHOLDER_NAME
+
+#define MAXDEPTH 32
+
+#define PLACEHOLDER_WIDTH 14
+#define PLACEHOLDER_HEIGHT 16
+
+#define PLACEHOLDER_BORDER_COLOR_DARK 0x000000
+#define PLACEHOLDER_BORDER_COLOR_LIGHT 0xB2B2B2
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+static Pixmap nxagentPlaceholderPixmaps[MAXDEPTH + 1];
+
+void nxagentMarkPlaceholderNotLoaded(int depth)
+{
+ nxagentPlaceholderPixmaps[depth] = 0;
+}
+
+void nxagentInitPlaceholder(int depth)
+{
+ int status;
+ XpmAttributes attributes;
+
+ attributes.valuemask = XpmDepth | XpmSize;
+ attributes.depth = depth;
+
+ status = XpmCreatePixmapFromData(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ placeholderXpm, nxagentPlaceholderPixmaps + depth, NULL, &attributes);
+
+ if (status != Success)
+ {
+ FatalError("Error: Failed to create the placeholder pixmap.\n");
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitPlaceholder: Created pixmap [0x%lx] with geometry [%d,%d] for depth [%d].\n",
+ nxagentPlaceholderPixmaps[depth], attributes.width, attributes.height, depth);
+ #endif
+}
+
+void nxagentApplyPlaceholder(Drawable drawable, int x, int y,
+ int w, int h, int depth)
+{
+ /*
+ * Instead of the image, a white rectangle that
+ * covers the pixmap area is drawn, alongside
+ * with a black and grey line that outlines the
+ * boundaries of the affected area.
+ */
+
+ GC gc;
+ XGCValues value;
+ XPoint points[3];
+
+ value.foreground = 0xffffffff;
+ value.background = 0x00000000;
+ value.plane_mask = 0xffffffff;
+ value.fill_style = FillSolid;
+
+ /*
+ * FIXME: Should we use a gc cache to save
+ * some bandwidth?
+ */
+
+ gc = XCreateGC(nxagentDisplay, drawable, GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+ XFillRectangle(nxagentDisplay, drawable, gc, x, y, w, h);
+
+ if (depth == 1)
+ {
+ return;
+ }
+
+ value.foreground = PLACEHOLDER_BORDER_COLOR_DARK;
+ value.line_style = LineSolid;
+ value.line_width = 1;
+
+ points[0].x = x;
+ points[0].y = y + h - 1;
+ points[1].x = x;
+ points[1].y = y;
+ points[2].x = x + w - 1;
+ points[2].y = y;
+
+ XChangeGC(nxagentDisplay, gc, GCForeground | GCLineWidth | GCLineStyle, &value);
+ XDrawLines(nxagentDisplay, drawable, gc, points, 3, CoordModeOrigin);
+
+ value.foreground = PLACEHOLDER_BORDER_COLOR_LIGHT;
+ value.line_style = LineSolid;
+ value.line_width = 1;
+
+ points[0].x = x;
+ points[0].y = y + h - 1;
+ points[1].x = x + w - 1;
+ points[1].y = y + h - 1;
+ points[2].x = x + w - 1;
+ points[2].y = y;
+
+ XChangeGC(nxagentDisplay, gc, GCForeground | GCLineWidth | GCLineStyle, &value);
+ XDrawLines(nxagentDisplay, drawable, gc, points, 3, CoordModeOrigin);
+
+ /*
+ * We are going to apply place holder only if on region
+ * we have enough space for the placeholder plus three
+ * pixel for spacing and one for region border.
+ */
+
+ if ((w >= PLACEHOLDER_WIDTH + 8) && (h >= PLACEHOLDER_HEIGHT + 8))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentApplyPlaceholder: drawable %lx placeholder %lx from %d %d pixmap size is %d %d "
+ "depth %d\n", drawable, nxagentPlaceholderPixmaps[depth], x, y, w, h, depth);
+ #endif
+
+ if (nxagentPlaceholderPixmaps[depth] == 0)
+ {
+ nxagentInitPlaceholder(depth);
+ }
+
+ XCopyArea(nxagentDisplay, nxagentPlaceholderPixmaps[depth],
+ drawable, gc, 0, 0, PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, x + 4, y + 4);
+
+ }
+
+ XFreeGC(nxagentDisplay, gc);
+
+ return;
+}
+
+#ifdef DUMP
+
+static char hexdigit(char c)
+{
+ char map[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '?'};
+
+ return map[c];
+}
+
+/*
+FIXME: Please, check the implementation of the same
+ function in nxcomp.
+*/
+char *nxagentChecksum(char *string, int length)
+{
+ static char md5_output[MD5_DIGEST_LENGTH * 2 + 1];
+ static char md5[MD5_DIGEST_LENGTH];
+ char * ret;
+ int i;
+
+ memset(md5, 0, sizeof(md5));
+ memset(md5_output, 0, sizeof(md5_output));
+
+ ret = MD5(string, length, md5);
+
+ for (i = 0; i < MD5_DIGEST_LENGTH; i++)
+ {
+ char c = md5[i];
+
+ md5_output[i * 2 + 0] = hexdigit((c >> 0) & 0xF);
+ md5_output[i * 2 + 1] = hexdigit((c >> 4) & 0xF);
+ }
+
+ return md5_output;
+}
+
+#else
+
+const char *nxagentChecksum(char *data, int size)
+{
+ return "";
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
new file mode 100644
index 000000000..d1378ee03
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -0,0 +1,35 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Holder_H__
+#define __Holder_H__
+
+void nxagentMarkPlaceholderNotLoaded(int depth);
+void nxagentInitPlaceholder(int depth);
+void nxagentApplyPlaceholder(Drawable drawable, int x, int y, int w, int h, int depth);
+
+const char *nxagentChecksum(char *data, int size);
+
+#endif /* __Holder_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
new file mode 100644
index 000000000..a87a5a112
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -0,0 +1,39 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Icons_H__
+#define __Icons_H__
+
+#define Pixel XpmPixel
+#include "X11/include/xpm_nxagent.h"
+#undef Pixel
+
+#define NXAGENT_ICON_NAME "nxagent.xpm"
+
+#define X2GOAGENT_ICON_NAME "x2go.xpm"
+
+#define NXAGENT_PLACEHOLDER_NAME "nxmissing.xpm"
+
+#endif /* __Icons_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
new file mode 100644
index 000000000..590f0b249
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -0,0 +1,1828 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Composite.h"
+#include "Display.h"
+#include "Visual.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Image.h"
+#include "Events.h"
+#include "Client.h"
+#include "Trap.h"
+#include "Split.h"
+#include "Args.h"
+#include "Screen.h"
+#include "Pixels.h"
+#include "Utils.h"
+
+#include "compext/Compext.h"
+#include <nx/NXpack.h>
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/*
+ * Don't pack the images having a width, a
+ * height or a data size smaller or equal
+ * to these thresholds.
+ */
+
+#define IMAGE_PACK_WIDTH 2
+#define IMAGE_PACK_HEIGHT 2
+#define IMAGE_PACK_LENGTH 512
+
+/*
+ * Compress the image with a lossless encoder
+ * if the percentage of discrete pixels in the
+ * image is below this threshold.
+ */
+
+#define IMAGE_UNIQUE_RATIO 10
+
+/*
+ * Preferred pack and split parameters we
+ * got from the NX transport.
+ */
+
+int nxagentPackLossless = -1;
+int nxagentPackMethod = -1;
+int nxagentPackQuality = -1;
+int nxagentSplitThreshold = -1;
+
+/*
+ * Set if images can use the alpha channel.
+ */
+
+int nxagentAlphaEnabled = 0;
+int nxagentAlphaCompat = 0;
+
+/*
+ * Used to reformat image when connecting to
+ * displays having different byte order.
+ */
+
+extern void nxagentBitOrderInvert(unsigned char *, int);
+extern void nxagentTwoByteSwap(unsigned char *, register int);
+extern void nxagentFourByteSwap(register unsigned char *, register int);
+
+/*
+ * Store the last visual used to unpack
+ * the images for the given client.
+ */
+
+static VisualID nxagentUnpackVisualId[MAX_CONNECTIONS];
+
+/*
+ * Store the last alpha data set for the
+ * client.
+ */
+
+typedef struct _UnpackAlpha
+{
+ char *data;
+ int size;
+
+} UnpackAlphaRec;
+
+typedef UnpackAlphaRec *UnpackAlphaPtr;
+
+static UnpackAlphaPtr nxagentUnpackAlpha[MAX_CONNECTIONS];
+
+/*
+ * Encode the imade alpha channel by using
+ * a specific encoding, separating it from
+ * the rest of the RGB data.
+ */
+
+static char *nxagentImageAlpha(XImage *ximage);
+static void nxagentSetUnpackAlpha(DrawablePtr pDrawable, XImage *pImage, ClientPtr pClient);
+
+/*
+ * Copy the source data to the destination.
+ */
+
+static char *nxagentImageCopy(XImage *source, XImage *destination);
+
+/*
+ * Return true if the image can be cached.
+ * Don't cache the images packed with the
+ * bitmap method as the encoding is little
+ * more expensive than a copy.
+ */
+
+#define nxagentNeedCache(image, method) \
+\
+ ((method) != PACK_BITMAP_16M_COLORS)
+
+/*
+ * With the bitmap encoding, if the image
+ * is 32 bits-per-pixel the 4th byte is not
+ * transmitted, so we don't need to clean
+ * the image.
+ */
+
+#define nxagentNeedClean(image, method) \
+\
+ ((method) == PACK_RLE_16M_COLORS || \
+ (method) == PACK_RGB_16M_COLORS || \
+ ((method) == PACK_BITMAP_16M_COLORS && \
+ image -> bits_per_pixel != 32))
+
+/*
+ * Collect the image cache statistics.
+ */
+
+typedef struct _ImageStatisticsRec
+{
+ double partialLookups;
+ double partialMatches;
+ double partialEncoded;
+ double partialAdded;
+
+ double totalLookups;
+ double totalMatches;
+ double totalEncoded;
+ double totalAdded;
+
+} ImageStatisticsRec;
+
+ImageStatisticsRec nxagentImageStatistics;
+
+int nxagentImageReformat(char *base, int nbytes, int bpp, int order)
+{
+ /*
+ * This is used whenever we need to swap the image data.
+ * If we got an image from a X server having a different
+ * endianess, we will need to redormat the image to match
+ * our own image-order so that ProcGetImage can return
+ * the expected format to the client.
+ */
+
+ switch (bpp)
+ {
+ case 1:
+ {
+ if (BITMAP_BIT_ORDER != order)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImageReformat: Bit order invert with size [%d] "
+ "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+ #endif
+
+ nxagentBitOrderInvert((unsigned char *) base, nbytes);
+ }
+
+ #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+
+ nxagentImageReformat(base, nbytes, BITMAP_SCANLINE_UNIT, order);
+
+ #endif
+
+ break;
+ }
+ case 4:
+ case 8:
+ {
+ break;
+ }
+ case 16:
+ {
+ if (IMAGE_BYTE_ORDER != order)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImageReformat: Two bytes swap with size [%d] "
+ "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+ #endif
+
+ nxagentTwoByteSwap((unsigned char *) base, nbytes);
+ }
+
+ break;
+ }
+ case 32:
+ {
+ if (IMAGE_BYTE_ORDER != order)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImageReformat: Four bytes swap with size [%d] "
+ "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+ #endif
+
+ nxagentFourByteSwap((unsigned char *) base, nbytes);
+ }
+
+ break;
+ }
+ }
+
+ return 1;
+}
+
+int nxagentImageLength(int width, int height, int format, int leftPad, int depth)
+{
+ int line = 0;
+
+ if (format == XYBitmap)
+ {
+ line = BitmapBytePad(width + leftPad);
+ }
+ else if (format == XYPixmap)
+ {
+ line = BitmapBytePad(width + leftPad);
+
+ line *= depth;
+ }
+ else if (format == ZPixmap)
+ {
+ line = PixmapBytePad(width, depth);
+ }
+
+ return line * height;
+}
+
+int nxagentImagePad(int width, int format, int leftPad, int depth)
+{
+ int line = 0;
+
+ if (format == XYBitmap)
+ {
+ line = BitmapBytePad(width + leftPad);
+ }
+ else if (format == XYPixmap)
+ {
+ line = BitmapBytePad(width + leftPad);
+ }
+ else if (format == ZPixmap)
+ {
+ line = PixmapBytePad(width, depth);
+ }
+
+ return line;
+}
+
+/*
+ * Only copy the data, not the structure.
+ * The data pointed by the destination is
+ * lost. Used to clone two images that
+ * point to the same data.
+ */
+
+char *nxagentImageCopy(XImage *source, XImage *destination)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentImageClone: Copying [%d] bytes of data from the source.\n",
+ source -> bytes_per_line * source -> height);
+ #endif
+
+ destination -> data = Xmalloc(source -> bytes_per_line * source -> height);
+
+ if (destination -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentImageCopy: PANIC! Cannot allocate memory for the copy.\n");
+ #endif
+ }
+ else
+ {
+ memcpy(destination -> data, source -> data,
+ source -> bytes_per_line * source -> height);
+ }
+
+ return destination -> data;
+}
+
+char *nxagentImageAlpha(XImage *image)
+{
+ char *pData;
+
+ char *pSrcData;
+ char *pDstData;
+
+ int size;
+ int offset;
+
+ /*
+ * Use one byte per pixel.
+ */
+
+ size = (image -> bytes_per_line * image -> height) >> 2;
+
+ pData = Xmalloc(size);
+
+ if (pData == NULL)
+ {
+ return NULL;
+ }
+
+ /*
+ * The image is supposed to be in
+ * server order.
+ */
+
+ offset = (image -> byte_order == MSBFirst) ? 0 : 3;
+
+ pSrcData = image -> data;
+ pDstData = pData;
+
+ while (size-- > 0)
+ {
+ *pDstData++ = *(pSrcData + offset);
+
+ pSrcData += 4;
+ }
+
+ return pData;
+}
+
+/*
+ * Write down the image cache statistics
+ * to the buffer.
+ */
+
+void nxagentImageStatisticsHandler(char **buffer, int type)
+{
+/*
+FIXME: Agent cache statistics have to be implemented.
+*/
+ #ifdef TEST
+ fprintf(stderr, "nxagentImageStatisticsHandler: STATISTICS! Statistics requested to the agent.\n");
+ #endif
+
+ *buffer = NULL;
+}
+
+/*
+ * This should be called only for drawables
+ * having a depth of 32. In the other cases,
+ * it would only generate useless traffic.
+ */
+
+void nxagentSetUnpackAlpha(DrawablePtr pDrawable, XImage *pImage, ClientPtr pClient)
+{
+ int resource = pClient -> index;
+
+ unsigned int size = (pImage -> bytes_per_line * pImage -> height) >> 2;
+
+ char *data = nxagentImageAlpha(pImage);
+
+ if (data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentSetUnpackAlpha: PANIC! Can't allocate data for the alpha channel.\n");
+ #endif
+
+ return;
+ }
+
+ /*
+ * If we are synchronizing the drawable, discard
+ * any unpack alpha stored for the client. The
+ * alpha data, in fact, may be still traveling
+ * and so we either wait until the end of the
+ * split or send a fresh copy.
+ */
+/*
+FIXME: Here the split trap is always set and so the caching of
+ the alpha channel is useless. I remember we set the trap
+ because of the cursor but why is it always set now?
+*/
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetUnpackAlpha: Checking alpha channel for client [%d] with trap [%d].\n",
+ resource, nxagentSplitTrap);
+ #endif
+
+ if (nxagentSplitTrap == 1 || nxagentUnpackAlpha[resource] == NULL ||
+ nxagentUnpackAlpha[resource] -> size != size ||
+ memcmp(nxagentUnpackAlpha[resource] -> data, data, size) != 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetUnpackAlpha: Sending alpha channel with width [%d] height [%d] "
+ "bytes per line [%d] size [%d].\n", pImage -> width, pImage -> height,
+ pImage -> bytes_per_line, size);
+ #endif
+
+ /*
+ * Check if we are connected to a newer proxy
+ * version and so can send the alpha data in
+ * compressed form.
+ */
+
+ if (nxagentAlphaCompat == 0)
+ {
+ NXSetUnpackAlpha(nxagentDisplay, resource, PACK_NONE, size, data, size);
+ }
+ else
+ {
+ NXSetUnpackAlphaCompat(nxagentDisplay, resource, size, data);
+ }
+
+ if (nxagentUnpackAlpha[resource] != NULL)
+ {
+ free(nxagentUnpackAlpha[resource] -> data);
+ }
+ else if ((nxagentUnpackAlpha[resource] = Xmalloc(sizeof(UnpackAlphaRec))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentSetUnpackAlpha: PANIC! Can't allocate data for the alpha structure.\n");
+ #endif
+
+ free(data);
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetUnpackAlpha: Saved alpha channel for client [%d] with size [%d].\n",
+ resource, size);
+ #endif
+
+ nxagentUnpackAlpha[resource] -> size = size;
+ nxagentUnpackAlpha[resource] -> data = data;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSetUnpackAlpha: Matched alpha channel for client [%d] with size [%d].\n",
+ resource, size);
+ #endif
+
+ free(data);
+ }
+}
+
+/*
+ * The NX agent's implementation of the
+ * X server's image functions.
+ */
+
+void nxagentPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int dstX, int dstY, int dstWidth, int dstHeight,
+ int leftPad, int format, char *data)
+{
+ int length;
+
+ RegionPtr pRegion = NullRegion;
+
+ int resource = 0;
+ int split = 0;
+ int cache = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Image data at [%p] drawable [%s][%p] geometry [%d,%d,%d,%d].\n",
+ data, (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
+ (void *) pDrawable, dstX, dstY, dstWidth, dstHeight);
+ #endif
+
+ /*
+ * If the display is down and there is not an
+ * nxagent attached, sleep for a while but
+ * still give a chance to the client to write
+ * to the framebuffer.
+ */
+
+ length = nxagentImageLength(dstWidth, dstHeight, format, leftPad, depth);
+
+ if (nxagentShadowCounter == 0 &&
+ NXDisplayError(nxagentDisplay) == 1 &&
+ nxagentOption(SleepTime) > 0)
+ {
+ int us;
+
+ us = nxagentOption(SleepTime) * 4 * (length / 1024);
+
+ us = (us < 10000 ? 10000 : (us > 1000000 ? 1000000 : us));
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutImage: Sleeping for [%d] milliseconds with length [%d] and link down.\n",
+ us / 1000, length);
+ #endif
+
+ usleep(us);
+ }
+
+ /*
+ * This is of little use because clients usually write
+ * to windows only after an expose event, and, in the
+ * rare case they use a direct put image to the window
+ * (for a media player it should be a necessity), they
+ * are likely to monitor the visibility of the window.
+ */
+
+ if (nxagentOption(IgnoreVisibility) == 0 && pDrawable -> type == DRAWABLE_WINDOW &&
+ (nxagentWindowIsVisible((WindowPtr) pDrawable) == 0 ||
+ (nxagentDefaultWindowIsVisible() == 0 && nxagentCompositeEnable == 0)))
+ {
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on fully obscured "
+ "window at [%p].\n", (void *) pDrawable);
+ #endif
+
+ goto nxagentPutImageEnd;
+ }
+
+ /*
+ * This is more interesting. Check if the operation
+ * will produce a visible result based on the clip
+ * list of the window and the GC.
+ */
+
+ pRegion = nxagentCreateRegion(pDrawable, pGC, dstX, dstY, dstWidth, dstHeight);
+
+ if (RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on fully clipped "
+ "region [%d,%d,%d,%d] for drawable at [%p].\n", pRegion -> extents.x1,
+ pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+ (void *) pDrawable);
+ #endif
+
+ goto nxagentPutImageEnd;
+ }
+
+/*
+FIXME: Should use these.
+
+ int framebuffer = 1;
+ int realize = 1;
+*/
+ if (nxagentGCTrap == 1 && nxagentReconnectTrap == 0 &&
+ nxagentFBTrap == 0 && nxagentShmTrap == 0)
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ fbPutImage(nxagentVirtualDrawable(pDrawable), pGC, depth,
+ dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+ }
+ else
+ {
+ fbPutImage(pDrawable, pGC, depth,
+ dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+ }
+
+ goto nxagentPutImageEnd;
+ }
+
+ if (nxagentReconnectTrap == 0 &&
+ nxagentSplitTrap == 0)
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentFBTrap == 0 && nxagentShmTrap == 0)
+ {
+ fbPutImage(nxagentVirtualDrawable(pDrawable), pGC, depth,
+ dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+ }
+ else if (pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ fbPutImage(pDrawable, pGC, depth,
+ dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+ }
+ }
+
+ /*
+ * We are going to realize the operation
+ * on the real display. Let's check if
+ * the link is down.
+ */
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ goto nxagentPutImageEnd;
+ }
+
+ /*
+ * Mark the region as corrupted and skip the operation
+ * if we went out of bandwidth. The drawable will be
+ * synchronized at later time. Don't do that if the
+ * image is likely to be a shape or a clip mask, if we
+ * are here because we are actually synchronizing the
+ * drawable or if the drawable's corrupted region is
+ * over-age.
+ */
+
+ if (NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable))
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP &&
+ pDrawable -> depth != 1 &&
+ nxagentOption(DeferLevel) >= 1)
+ {
+ /* -- changed by dimbor (small "bed-sheets" never need be prevented - always put) --*/
+ if (dstHeight > 16)
+ {
+ /* -------------------------------------------------------------------------------- */
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+ "for drawable at [%p] with drawable pixmap.\n", pRegion -> extents.x1,
+ pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+ (void *) pDrawable);
+ #endif
+
+ nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+ goto nxagentPutImageEnd;
+ /* --- changed by dimbor ---*/
+ }
+ /* ------------------------- */
+ }
+
+ if (pDrawable -> type == DRAWABLE_WINDOW &&
+ nxagentOption(DeferLevel) >= 2)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+ "for drawable at [%p] with drawable window.\n", pRegion -> extents.x1,
+ pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+ (void *) pDrawable);
+ #endif
+
+ nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+ goto nxagentPutImageEnd;
+ }
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentPutImage: Operation on drawable [%p] not skipped with nxagentSplitTrap [%d].\n",
+ (void *) pDrawable, nxagentSplitTrap);
+ }
+ #endif
+
+ /*
+ * Check whether we need to enclose the
+ * image in a split sequence.
+ */
+/*
+FIXME: Should we disable the split with link LAN?
+
+ split = (nxagentOption(Streaming) == 1 &&
+ nxagentOption(LinkType) != LINK_TYPE_NONE &&
+ nxagentOption(LinkType) != LINK_TYPE_LAN
+*/
+ split = (nxagentOption(Streaming) == 1 &&
+ nxagentOption(LinkType) != LINK_TYPE_NONE
+/*
+FIXME: Do we stream the images from GLX or Xv? If we do that,
+ we should also write on the frame buffer, including the
+ images put on windows, to be able to reconstruct the
+ region that is out of sync. Surely we should not try to
+ cache the GLX and Xv images in memory or save them in
+ the image cache on disk.
+*/
+/*
+FIXME: Temporarily stream the GLX data.
+
+ && nxagentGlxTrap == 0
+ && nxagentXvTrap == 0
+*/
+);
+
+ /*
+ * Never split images whose depth
+ * is less than 15.
+ */
+
+ if (split == 1 && (nxagentSplitTrap == 1 || depth < 15))
+ {
+ #ifdef TEST
+
+ if (nxagentSplitTrap == 1 ||
+ nxagentReconnectTrap == 1)
+ {
+ fprintf(stderr, "nxagentPutImage: Not splitting with reconnection [%d] trap [%d] "
+ "depth [%d].\n", nxagentSplitTrap, nxagentReconnectTrap, depth);
+ }
+
+ #endif
+
+ split = 0;
+ }
+ #ifdef TEST
+ else if (split == 1)
+ {
+ fprintf(stderr, "nxagentPutImage: Splitting with reconnection [%d] trap [%d] "
+ "depth [%d].\n", nxagentSplitTrap, nxagentReconnectTrap, depth);
+ }
+ #endif
+
+ #ifdef TEST
+
+ if (split == 1)
+ {
+ fprintf(stderr, "nxagentPutImage: Splitting the image with size [%d] "
+ "link [%d] GLX [%d] Xv [%d].\n", length, nxagentOption(LinkType),
+ nxagentGlxTrap, nxagentXvTrap);
+ }
+ else if (nxagentOption(LinkType) != LINK_TYPE_NONE)
+ {
+ fprintf(stderr, "nxagentPutImage: Not splitting the image with size [%d] "
+ "link [%d] GLX [%d] Xv [%d].\n", length, nxagentOption(LinkType),
+ nxagentGlxTrap, nxagentXvTrap);
+ }
+
+ #endif
+
+ /*
+ * If the image was originated by a GLX
+ * or Xvideo request, temporarily disable
+ * the use of the cache.
+ */
+
+ if (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+ (nxagentGlxTrap == 1 || nxagentXvTrap == 1))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Disabling the use of the cache with GLX or Xvideo.\n");
+ #endif
+
+ NXSetCacheParameters(nxagentDisplay, 0, 1, 0, 0);
+
+ cache = 0;
+ }
+
+ /*
+ * Enclose the next messages in a split
+ * sequence. The proxy will tell us if
+ * the split took place.
+ */
+
+ if (split == 1)
+ {
+ /*
+ * If the drawable is already being split,
+ * expand the region. Currently drawables
+ * can't have more than a single split
+ * region.
+ */
+
+ if (nxagentSplitResource(pDrawable) != NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPutImage: WARNING! Expanding the region with drawable at [%p] streaming.\n",
+ (void *) pDrawable);
+ #endif
+/*
+FIXME: Should probably intersect the region with
+ the region being split to also invalidate
+ the commits.
+*/
+ nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+ goto nxagentPutImageEnd;
+ }
+ else
+ {
+ /*
+ * Assign a new resource to the drawable.
+ * Will also assign the GC to use for the
+ * operation.
+ */
+
+ resource = nxagentCreateSplit(pDrawable, &pGC);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Resource [%d] assigned to drawable at [%p].\n",
+ resource, (void *) pDrawable);
+ #endif
+ }
+
+ NXStartSplit(nxagentDisplay, resource, NXSplitModeDefault);
+ }
+
+ nxagentRealizeImage(pDrawable, pGC, depth, dstX, dstY,
+ dstWidth, dstHeight, leftPad, format, data);
+
+ if (split == 1)
+ {
+ NXEndSplit(nxagentDisplay, resource);
+
+ /*
+ * Now we need to check if all the messages went
+ * straight through the output stream or any of
+ * them required a split. If no split will take
+ * place, we will remove the association with the
+ * drawable and release the resource at the time
+ * we will handle the no-split event.
+ */
+
+ split = nxagentWaitSplitEvent(resource);
+
+ if (split == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Marking corrupted region [%d,%d,%d,%d] for drawable at [%p].\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+ pRegion -> extents.y2, (void *) pDrawable);
+ #endif
+
+ /*
+ * Marking the corrupted region we will check
+ * if the region intersects the split region,
+ * therefore the split region must be added
+ * later.
+ */
+
+ nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+ /*
+ * Assign the region to the drawable.
+ */
+
+ nxagentRegionSplit(pDrawable, pRegion);
+
+ pRegion = NullRegion;
+ }
+ }
+
+ /*
+ * The split value could be changed by a
+ * no-split event in the block above, so
+ * here we have to check the value again.
+ */
+
+ if (split == 0)
+ {
+ if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+ {
+ /*
+ * We just covered the drawable with
+ * a solid image. We can consider the
+ * overlapping region as synchronized.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Marking synchronized region [%d,%d,%d,%d] for drawable at [%p].\n",
+ pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+ pRegion -> extents.y2, (void *) pDrawable);
+ #endif
+
+ nxagentUnmarkCorruptedRegion(pDrawable, pRegion);
+ }
+ }
+
+nxagentPutImageEnd:
+
+ /*
+ * Check if we disabled caching.
+ */
+
+ if (cache == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutImage: Reenabling the use of the cache.\n");
+ #endif
+
+ NXSetCacheParameters(nxagentDisplay, 1, 1, 1, 1);
+ }
+
+ if (pRegion != NullRegion)
+ {
+ nxagentFreeRegion(pDrawable, pRegion);
+ }
+}
+
+void nxagentRealizeImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad,
+ int format, char *data)
+{
+ int length;
+
+ int bytesPerLine;
+ int numSubImages;
+ int totalHeight;
+
+ /*
+ * NXPutPackedImage is longer than PutPackedImage
+ * so that we subtract the bigger one to be sure.
+ */
+
+ const int subSize = (MAX_REQUEST_SIZE << 2) - sizeof(xNXPutPackedImageReq);
+
+ Visual *pVisual = NULL;
+
+ RegionPtr clipRegion = NullRegion;
+
+ XImage *image = NULL;
+
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRealizeImage: Returning on display error.\n");
+ #endif
+
+ goto nxagentRealizeImageEnd;
+ }
+
+ /*
+ * Get the visual according to the
+ * drawable and depth.
+ */
+
+ pVisual = nxagentImageVisual(pDrawable, depth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRealizeImage: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ /*
+ * Get bytes per line according to format.
+ */
+
+ bytesPerLine = nxagentImagePad(w, format, leftPad, depth);
+
+ if (nxagentOption(Shadow) == 1 && format == ZPixmap &&
+ (nxagentOption(XRatio) != DONT_SCALE ||
+ nxagentOption(YRatio) != DONT_SCALE) &&
+ pDrawable == (DrawablePtr) nxagentShadowPixmapPtr)
+ {
+ int scaledx;
+ int scaledy;
+
+ image = XCreateImage(nxagentDisplay, pVisual, depth, ZPixmap,
+ 0, data, w, h, BitmapPad(nxagentDisplay), bytesPerLine);
+
+ if (image != NULL)
+ {
+ image -> byte_order = IMAGE_BYTE_ORDER;
+
+ image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+ nxagentScaleImage(x, y, nxagentOption(XRatio), nxagentOption(YRatio),
+ &image, &scaledx, &scaledy);
+
+ x = scaledx;
+ y = scaledy;
+
+ w = image -> width;
+ h = image -> height;
+
+ data = image -> data;
+
+ /*
+ * Width of image has changed.
+ */
+
+ bytesPerLine = nxagentImagePad(w, format, leftPad, depth);
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "nxagentRealizeImage: Failed to create XImage for scaling.\n");
+ }
+ #endif
+ }
+
+ if (w == 0 || h == 0)
+ {
+ goto nxagentRealizeImageEnd;
+ }
+
+ totalHeight = h;
+
+ length = bytesPerLine * h;
+
+ h = (subSize < length ? subSize : length) / bytesPerLine;
+
+ numSubImages = totalHeight / h + 1;
+
+ while (numSubImages > 0)
+ {
+ if (pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ clipRegion = nxagentCreateRegion(pDrawable, pGC, x, y, w, h);
+ }
+
+ if (clipRegion == NullRegion || RegionNil(clipRegion) == 0)
+ {
+ nxagentPutSubImage(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, data, pVisual);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentRealizeImage: Skipping the put sub image with geometry "
+ "[%d,%d,%d,%d] on hidden window at [%p].\n", x, y, w, h, (void *) pDrawable);
+ }
+ #endif
+
+ if (clipRegion != NullRegion)
+ {
+ nxagentFreeRegion(pDrawable, clipRegion);
+ }
+
+ y += h;
+
+ data += h * bytesPerLine;
+
+ if (--numSubImages == 1)
+ {
+ h = totalHeight % h;
+
+ if (h == 0)
+ {
+ break;
+ }
+ }
+ }
+
+nxagentRealizeImageEnd:
+
+ if (image != NULL)
+ {
+ XDestroyImage(image);
+ }
+}
+
+void nxagentPutSubImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *data, Visual *pVisual)
+{
+ NXPackedImage *packedImage = NULL;
+ XImage *plainImage = NULL;
+ unsigned char *packedChecksum = NULL;
+
+ unsigned int packMethod = nxagentPackMethod;
+ unsigned int packQuality = nxagentPackQuality;
+
+ ClientPtr client;
+
+ int lossless = 0;
+ int clean = 0;
+ int pack = 0;
+
+ /*
+ * XCreateImage is the place where the leftPad should be passed.
+ * The image data is received from our client unmodified. In
+ * theory what we would need to do is just creating an appropri-
+ * ate XImage structure based on the incoming data and let Xlib
+ * do the rest. Probably we don't have to pass leftPad again in
+ * the src_x of XPutImage otherwise the src_x would make Xlib
+ * to take into account the xoffset field twice. Unfortunately
+ * passing the leftPad doesn't work.
+ *
+ * plainImage = XCreateImage(nxagentDisplay, pVisual,
+ * depth, format, leftPad, data,
+ * w, h, BitmapPad(nxagentDisplay),
+ * nxagentImagePad(w, format, leftPad, depth));
+ */
+
+ if ((plainImage = XCreateImage(nxagentDisplay, pVisual,
+ depth, format, leftPad, data,
+ w, h, BitmapPad(nxagentDisplay),
+ nxagentImagePad(w, format, leftPad, depth))) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPutSubImage: WARNING! Failed to create image.\n");
+ #endif
+
+ goto nxagentPutSubImageEnd;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Handling image with geometry [%d,%d] depth [%d].\n",
+ w, h, depth);
+
+ fprintf(stderr, "nxagentPutSubImage: Default pack method is [%d] quality is [%d].\n",
+ packMethod, packQuality);
+ #endif
+
+/*
+FIXME: Should use an unpack resource here.
+*/
+ client = requestingClient;
+
+ if (client == NULL)
+ {
+ client = serverClient;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: WARNING! Using the server client with index [%d].\n",
+ client -> index);
+ #endif
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Server order is [%d] client order is [%d].\n",
+ nxagentServerOrder(), nxagentClientOrder(client));
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Display image order is [%d] bitmap order is [%d].\n",
+ ImageByteOrder(nxagentDisplay), nxagentBitmapBitOrder(nxagentDisplay));
+ #endif
+
+ /*
+ * We got the image data from the X client or
+ * from the frame-buffer with our own endianess.
+ * Byte swap the image data if the display has
+ * a different endianess than our own.
+ */
+
+ if (nxagentImageNormalize(plainImage) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: WARNING! Reformatted the image with remote order [%d/%d].\n",
+ plainImage -> byte_order, plainImage -> bitmap_bit_order);
+ #endif
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Image has visual with RGB color masks [%0lx][%0lx][%0lx].\n",
+ pVisual -> red_mask, pVisual -> green_mask, pVisual -> blue_mask);
+ #endif
+
+ /*
+ * Check if the user requested to pack the
+ * image but don't pack it if we are not
+ * connected to a proxy or if the depth is
+ * less than 15 bpp.
+ */
+
+ pack = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+ packMethod != PACK_NONE && depth > 8 && format == ZPixmap);
+
+ lossless = (packMethod == nxagentPackLossless);
+
+ if (pack == 1 && lossless == 0)
+ {
+ /*
+ * Force the image to be sent as a plain
+ * bitmap if we don't have any lossless
+ * encoder available.
+ */
+
+ if (w <= IMAGE_PACK_WIDTH || h <= IMAGE_PACK_HEIGHT ||
+ nxagentImageLength(w, h, format, leftPad, depth) <=
+ IMAGE_PACK_LENGTH || nxagentLosslessTrap == 1)
+ {
+ if (nxagentPackLossless == PACK_NONE)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Disabling pack with lossless method [%d] "
+ "trap [%d] size [%d].\n", nxagentPackLossless, nxagentLosslessTrap,
+ nxagentImageLength(w, h, format, leftPad, depth));
+ #endif
+
+ pack = 0;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Lossless encoder with geometry [%d,%d] "
+ "trap [%d] size [%d].\n", w, h, nxagentLosslessTrap,
+ nxagentImageLength(w, h, format, leftPad, depth));
+ #endif
+
+ packMethod = nxagentPackLossless;
+
+ lossless = 1;
+ }
+ }
+ }
+
+ /*
+ * Do we still want to pack the image?
+ */
+
+ if (pack == 1)
+ {
+ /*
+ * Set the geometry and alpha channel
+ * to be used for the unpacked image.
+ */
+
+ if (nxagentUnpackVisualId[client -> index] != pVisual -> visualid)
+ {
+ nxagentUnpackVisualId[client -> index] = pVisual -> visualid;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Sending new geometry for client [%d].\n",
+ client -> index);
+ #endif
+
+ NXSetUnpackGeometry(nxagentDisplay, client -> index, pVisual);
+ }
+
+ /*
+ * Check if the image is supposed to carry
+ * the alpha data in the fourth byte and,
+ * if so, send the alpha channel using the
+ * specific encoding.
+ */
+
+ if (plainImage -> depth == 32)
+ {
+ nxagentSetUnpackAlpha(pDrawable, plainImage, client);
+ }
+
+ /*
+ * If the image doesn't come from the XVideo or the
+ * GLX extension try to locate it in the cache. The
+ * case of the lossless trap is also special, as we
+ * want to eventually encode the image again using
+ * a lossless compression.
+ */
+/*
+FIXME: Should try to locate the image anyway, if the lossless
+ trap is set, and if the image was encoded by a lossy
+ compressor, roll back the changes and encode the image
+ again using the preferred method.
+*/
+ if (nxagentNeedCache(plainImage, packMethod) &&
+ nxagentGlxTrap == 0 && nxagentXvTrap == 0 &&
+ nxagentLosslessTrap == 0 && NXImageCacheSize > 0)
+ {
+ /*
+ * Be sure that the padding bits are
+ * cleaned before calculating the MD5
+ * checksum.
+ */
+/*
+FIXME: There should be a callback registered by the agent that
+ provides a statistics report, in text format, telling
+ for example how many images were searched in the cache,
+ how many were found, how many drawables are to be synch-
+ ronized, etc. This statistics report would be included
+ by the proxy in its stat output.
+*/
+ clean = 1;
+
+ NXCleanImage(plainImage);
+
+ /*
+ * Will return a pointer to the image and checksum
+ * taken from the cache, if found. If the image is
+ * not found, the function returns a null image and
+ * a pointer to the calculated checksum. It is up
+ * to the application to free the memory. We will
+ * use the checksum to add the image in the cache.
+ */
+
+ packedImage = NXCacheFindImage(plainImage, &packMethod, &packedChecksum);
+
+ nxagentImageStatistics.partialLookups++;
+ nxagentImageStatistics.totalLookups++;
+
+ if (packedImage != NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Matched image of geometry [%d,%d] data size [%d] in cache.\n",
+ w, h, packedImage -> xoffset);
+ #endif
+
+ NXPutPackedImage(nxagentDisplay, client -> index, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), packedImage, packMethod, depth,
+ 0, 0, x, y, w, h);
+
+ nxagentImageStatistics.partialMatches++;
+ nxagentImageStatistics.totalMatches++;
+
+ packedChecksum = NULL;
+ packedImage = NULL;
+
+ goto nxagentPutSubImageEnd;
+ }
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "nxagentPutSubImage: WARNING! Missed image of geometry [%d,%d] in cache.\n",
+ w, h);
+ }
+ #endif
+ }
+
+ /*
+ * If a specific encoder was not mandated,
+ * try to guess if a lossless encoder will
+ * compress better.
+ */
+
+ if (lossless == 0 && nxagentOption(Adaptive) == 1)
+ {
+ int ratio = nxagentUniquePixels(plainImage);
+
+ if (ratio <= IMAGE_UNIQUE_RATIO)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Lossless encoder with geometry [%d,%d] ratio [%d%%].\n",
+ w, h, ratio);
+ #endif
+
+ packMethod = nxagentPackLossless;
+
+ lossless = 1;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentPutSubImage: Default encoder with geometry [%d,%d] ratio [%d%%].\n",
+ w, h, ratio);
+ }
+ #endif
+ }
+
+ /*
+ * Encode the image using the selected
+ * pack method.
+ */
+
+ if (packMethod == PACK_RLE_16M_COLORS ||
+ packMethod == PACK_RGB_16M_COLORS ||
+ packMethod == PACK_BITMAP_16M_COLORS)
+ {
+ /*
+ * Cleanup the image if we didn't do that yet.
+ * We assume that the JPEG and PNG compression
+ * methods will actually ignore the padding
+ * bytes. In other words, bitmap images prod-
+ * ucing the same visual output should produce
+ * compressed images that are bitwise the same
+ * regardless the padding bits.
+ */
+
+ if (clean == 0)
+ {
+ if (nxagentNeedClean(plainImage, packMethod) == 1)
+ {
+ clean = 1;
+
+ NXCleanImage(plainImage);
+ }
+ }
+
+ switch (packMethod)
+ {
+ /*
+ * If nothing is done by the bitmap encoder,
+ * it saves an allocation and a memory copy
+ * by setting the data field of the packed
+ * image to the original data. We need to
+ * check this at the time we will free the
+ * packed image.
+ */
+
+ case PACK_BITMAP_16M_COLORS:
+ {
+ packedImage = NXEncodeBitmap(plainImage, packMethod, packQuality);
+
+ break;
+ }
+ case PACK_RGB_16M_COLORS:
+ {
+ packedImage = NXEncodeRgb(plainImage, packMethod, packQuality);
+
+ break;
+ }
+ default:
+ {
+ packedImage = NXEncodeRle(plainImage, packMethod, packQuality);
+
+ break;
+ }
+ }
+ }
+ else if (packMethod >= PACK_JPEG_8_COLORS &&
+ packMethod <= PACK_JPEG_16M_COLORS)
+ {
+ packedImage = NXEncodeJpeg(plainImage, packMethod, packQuality);
+ }
+ else if (packMethod >= PACK_PNG_8_COLORS &&
+ packMethod <= PACK_PNG_16M_COLORS)
+ {
+ packedImage = NXEncodePng(plainImage, packMethod, packQuality);
+ }
+ else if (packMethod != PACK_NONE)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPutSubImage: WARNING! Ignoring deprecated pack method [%d].\n",
+ packMethod);
+ #endif
+
+ packMethod = PACK_NONE;
+ }
+ }
+
+ /*
+ * If we didn't produce a valid packed
+ * image, send the image as a X bitmap.
+ */
+
+ if (packedImage != NULL)
+ {
+ nxagentImageStatistics.partialEncoded++;
+ nxagentImageStatistics.totalEncoded++;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Using packed image with method [%d] quality [%d] "
+ "geometry [%d,%d] data size [%d].\n", packMethod, packQuality,
+ w, h, packedImage -> xoffset);
+ #endif
+
+ NXPutPackedImage(nxagentDisplay, client -> index, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), packedImage, packMethod, depth,
+ 0, 0, x, y, w, h);
+
+ /*
+ * Add the image only if we have a valid
+ * checksum. This is the case only if we
+ * originally tried to find the image in
+ * cache.
+ */
+
+ if (NXImageCacheSize > 0 && packedChecksum != NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Adding image with geometry [%d,%d] data size [%d] "
+ "to the cache.\n", w, h, packedImage -> xoffset);
+ #endif
+
+ /*
+ * Check if both the plain and the packed
+ * image point to the same data. In this
+ * case we need a copy.
+ */
+
+ if (packedImage -> data == plainImage -> data &&
+ nxagentImageCopy(plainImage, packedImage) == NULL)
+ {
+ goto nxagentPutSubImageEnd;
+ }
+
+ NXCacheAddImage(packedImage, packMethod, packedChecksum);
+
+ nxagentImageStatistics.partialAdded++;
+ nxagentImageStatistics.totalAdded++;
+
+ packedChecksum = NULL;
+ packedImage = NULL;
+ }
+ }
+ else
+ {
+ /*
+ * Clean the image to help the proxy to match
+ * the checksum in its cache. Do that only if
+ * the differential compression is enabled and
+ * if the image is not supposed to carry the
+ * alpha data in the fourth byte of the pixel.
+ */
+/*
+FIXME: If we failed to encode the image by any of the available
+ methods, for example if we couldn't allocate memory, we
+ may need to ripristinate the alpha channel, that in the
+ meanwhile was sent in the unpack alpha message. This can
+ be done here, if the clean flag is true and we are going
+ to send a plain image.
+*/
+ if (clean == 0)
+ {
+ clean = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+ nxagentOption(LinkType) != LINK_TYPE_LAN && depth != 32);
+
+ if (clean == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Cleaning the image with link type [%d] and depth [%d].\n",
+ nxagentOption(LinkType), depth);
+ #endif
+
+ NXCleanImage(plainImage);
+ }
+ #ifdef DEBUG
+ else
+ {
+ fprintf(stderr, "nxagentPutSubImage: Not cleaning the image with link type [%d] and depth [%d].\n",
+ nxagentOption(LinkType), depth);
+ }
+ #endif
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPutSubImage: Calling XPutImage with geometry [%d,%d] and data size [%d].\n",
+ w, h, plainImage -> bytes_per_line * plainImage -> height);
+ #endif
+
+ /*
+ * Passing the leftPad value in src_x doesn't work.
+ *
+ * XPutImage(nxagentDisplay, nxagentDrawable(pDrawable),
+ * nxagentGC(pGC), plainImage, leftPad, 0, x, y, w, h);
+ */
+
+ XPutImage(nxagentDisplay, nxagentDrawable(pDrawable),
+ nxagentGC(pGC), plainImage, 0, 0, x, y, w, h);
+ }
+
+nxagentPutSubImageEnd:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPutSubImage: Performed [%.0f] lookups in the cache with [%.0f] matches.\n",
+ nxagentImageStatistics.totalLookups, nxagentImageStatistics.totalMatches);
+
+ fprintf(stderr, "nxagentPutSubImage: Encoded [%.0f] images with [%.0f] added to the cache.\n",
+ nxagentImageStatistics.totalEncoded, nxagentImageStatistics.totalAdded);
+ #endif
+
+ if (packedChecksum != NULL)
+ {
+ free(packedChecksum);
+ }
+
+ if (packedImage != NULL)
+ {
+ if (packedImage -> data != NULL &&
+ packedImage -> data != plainImage -> data)
+ {
+ free(packedImage -> data);
+ }
+
+ free(packedImage);
+ }
+
+ free(plainImage);
+}
+
+void nxagentGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *data)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetImage: Called with drawable at [%p] geometry [%d,%d,%d,%d].\n",
+ (void *) pDrawable, x, y, w, h);
+
+ fprintf(stderr, "nxagentGetImage: Format is [%d] plane mask is [%lx].\n",
+ format, planeMask);
+ #endif
+
+ if ((pDrawable)->type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGetImage: Going to get image from virtual pixmap at [%p].\n",
+ (void *) nxagentVirtualDrawable(pDrawable));
+ #endif
+
+ fbGetImage(nxagentVirtualDrawable(pDrawable), x, y, w, h, format, planeMask, data);
+ }
+ else
+ {
+ fbGetImage(pDrawable, x, y, w, h, format, planeMask, data);
+ }
+}
+
+/*
+ * We have to reset the visual cache before
+ * connecting to another display, so that a
+ * new unpack geometry can be communicated
+ * to the new proxy.
+ */
+
+void nxagentResetVisualCache()
+{
+ int i;
+
+ for (i = 0; i < MAX_CONNECTIONS; i++)
+ {
+ nxagentUnpackVisualId[i] = None;
+ }
+}
+
+void nxagentResetAlphaCache()
+{
+ int i;
+
+ for (i = 0; i < MAX_CONNECTIONS; i++)
+ {
+ if (nxagentUnpackAlpha[i])
+ {
+ free(nxagentUnpackAlpha[i] -> data);
+
+ free(nxagentUnpackAlpha[i]);
+
+ nxagentUnpackAlpha[i] = NULL;
+ }
+ }
+}
+
+int nxagentScaleImage(int x, int y, unsigned xRatio, unsigned yRatio,
+ XImage **pImage, int *scaledx, int *scaledy)
+{
+ int x1;
+ int x2;
+ int y1;
+ int y2;
+
+ int xx1;
+ int xx2;
+ int yy1;
+ int yy2;
+
+ int newWidth;
+ int newHeight;
+
+ int i;
+ int j;
+ int k;
+ int l;
+
+ unsigned long val;
+
+ XImage *newImage;
+ XImage *image = *pImage;
+
+ #ifdef FAST_GET_PUT_PIXEL
+
+ register char *srcPixel;
+ register char *dstPixel;
+
+ int i;
+
+ #endif
+
+ if (image == NULL)
+ {
+ return 0;
+ }
+
+ x1 = (xRatio * x) >> PRECISION;
+ x2 = (xRatio * (x + image -> width)) >> PRECISION;
+
+ y1 = (yRatio * y) >> PRECISION;
+ y2 = (yRatio * (y + image -> height)) >> PRECISION;
+
+ newWidth = x2 - x1;
+ newHeight = y2 - y1;
+
+ newImage = XCreateImage(nxagentDisplay, NULL, image -> depth, image -> format, 0, NULL,
+ newWidth, newHeight, BitmapPad(nxagentDisplay),
+ PixmapBytePad(newWidth, image -> depth));
+
+ if (newImage == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentScaleImage: PANIC! Failed to create the target image.\n");
+ #endif
+
+ return 0;
+ }
+
+ newImage -> red_mask = image -> red_mask;
+ newImage -> green_mask = image -> green_mask;
+ newImage -> blue_mask = image -> blue_mask;
+
+ newImage -> byte_order = IMAGE_BYTE_ORDER;
+ newImage -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+ newImage -> data = Xmalloc(newImage -> bytes_per_line * newHeight);
+
+ if (newImage -> data == NULL)
+ {
+ free(newImage);
+
+ #ifdef PANIC
+ fprintf(stderr, "nxagentScaleImage: PANIC! Failed to create the target image data.\n");
+ #endif
+
+ return 0;
+ }
+
+ newImage -> width = newWidth;
+ newImage -> height = newHeight;
+
+ for (j = y; j < y + image -> height; j++)
+ {
+ yy1 = (yRatio * j) >> PRECISION;
+ yy2 = (yRatio * (j + 1)) >> PRECISION;
+
+ for (i = x; i < x + image -> width; i++)
+ {
+ #ifndef FAST_GET_PUT_PIXEL
+
+ val = XGetPixel(image, i - x, j - y);
+
+ #else
+
+ srcPixel = &image -> data[(j * image -> bytes_per_line) +
+ ((i * image -> bits_per_pixel) >> 3)];
+
+ dstPixel = (char *) &val;
+
+ val = 0;
+
+ for (i = (image -> bits_per_pixel + 7) >> 3; --i >= 0; )
+ {
+ *dstPixel++ = *srcPixel++;
+ }
+
+ #endif
+
+ xx1 = (xRatio * i) >> PRECISION;
+ xx2 = (xRatio * (i + 1)) >> PRECISION;
+
+ for (l = yy1; l < yy2; l++)
+ {
+ for (k = xx1; k < xx2; k++)
+ {
+ #ifndef FAST_GET_PUT_PIXEL
+
+ XPutPixel(newImage, k - x1, l - y1, val);
+
+ #else
+
+ dstPixel = &newImage -> data[((l - y1) * newImage -> bytes_per_line) +
+ (((k - x1) * newImage -> bits_per_pixel) >> 3)];
+
+ srcPixel = (char *) &val;
+
+ for (i = (newImage -> bits_per_pixel + 7) >> 3; --i >= 0; )
+ {
+ *dstPixel++ = *srcPixel++;
+ }
+
+ #endif
+ }
+ }
+ }
+ }
+
+ if (image -> obdata != NULL)
+ {
+ free((char *) image -> obdata);
+ }
+
+ free((char *) image);
+
+ *pImage = newImage;
+
+ *scaledx = x1;
+ *scaledy = y1;
+
+ return 1;
+}
+
+char *nxagentAllocateImageData(int width, int height, int depth, int *length, int *format)
+{
+ char *data;
+
+ int leftPad;
+
+ leftPad = 0;
+
+ *format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ *length = nxagentImageLength(width, height, *format, leftPad, depth);
+
+ data = NULL;
+
+ if ((data = malloc(*length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentAllocateImageData: WARNING! Failed to allocate [%d] bytes of memory.\n", *length);
+ #endif
+ }
+
+ return data;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
new file mode 100644
index 000000000..771c0dbe1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Image_H__
+#define __Image_H__
+
+/*
+ * Graphic operations.
+ */
+
+void nxagentPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int dstX, int dstY, int dstWidth, int dstHeight,
+ int leftPad, int format, char *data);
+
+void nxagentRealizeImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad,
+ int format, char *data);
+
+void nxagentPutSubImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *data, Visual *pVisual);
+
+void nxagentGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *data);
+
+/*
+ * Pack and split parameters we get
+ * from the NX transport.
+ */
+
+extern int nxagentPackLossless;
+extern int nxagentPackMethod;
+extern int nxagentPackQuality;
+extern int nxagentSplitThreshold;
+
+/*
+ * Set if images can use the alpha
+ * channel and if the alpha channel
+ * can be sent in compressed form.
+ */
+
+extern int nxagentAlphaEnabled;
+extern int nxagentAlphaCompat;
+
+/*
+ * Reset the visual and alpha cache
+ * before closing the screen or con-
+ * necting to a different display.
+ */
+
+void nxagentResetVisualCache(void);
+void nxagentResetAlphaCache(void);
+
+/*
+ * Always use the default visual for the
+ * image related functions.
+ */
+
+#define nxagentImageVisual(pDrawable, depth) \
+ ((depth) == 32 ? &nxagentAlphaVisual : \
+ nxagentDefaultVisual(((pDrawable) -> pScreen)))
+
+/*
+ * Byte swap the image if the display
+ * uses a different endianess.
+ */
+
+#define nxagentImageNormalize(image) \
+ ((image) -> byte_order != IMAGE_BYTE_ORDER || \
+ (image) -> bitmap_bit_order != BITMAP_BIT_ORDER ? \
+ nxagentImageReformat((image) -> data, (image) -> bytes_per_line * \
+ (image) -> height * ((image) -> format == XYPixmap ? (image) -> depth : 1), \
+ ((image) -> format == ZPixmap ? \
+ BitsPerPixel((image) -> depth) : 1), \
+ (image) -> byte_order) : 0)
+
+/*
+ * Other image related functions.
+ */
+
+int nxagentImageLength(int width, int height, int format, int leftPad, int depth);
+
+int nxagentImagePad(int width, int format, int leftPad, int depth);
+
+int nxagentImageReformat(char *base, int nbytes, int bpp, int order);
+
+void nxagentImageStatisticsHandler(char **buffer, int type);
+
+int nxagentScaleImage(int x, int y, unsigned xRatio, unsigned yRatio, XImage **pImage, int *scaledx, int *scaledy);
+
+char *nxagentAllocateImageData(int width, int height, int depth, int *length, int *format);
+
+#endif /* __Image_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
new file mode 100644
index 000000000..a1b059cae
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -0,0 +1,270 @@
+#include <Server.tmpl>
+
+
+NULL =
+
+SUBDIRS = compext \
+ $(NULL)
+
+SRCS = \
+ NXwindow.c \
+ NXevents.c \
+ NXproperty.c \
+ NXdixfonts.c \
+ NXglyphcurs.c \
+ NXdispatch.c \
+ NXrender.c \
+ NXglyph.c \
+ NXpicture.c \
+ NXextension.c \
+ NXshm.c \
+ NXglxext.c \
+ NXxvdisp.c \
+ NXmiexpose.c \
+ NXresource.c \
+ NXdamage.c \
+ NXmitrap.c \
+ Args.c \
+ Binder.c \
+ BitmapUtils.c \
+ Colormap.c \
+ Cursor.c \
+ Dialog.c \
+ Display.c \
+ Events.c \
+ Font.c \
+ GC.c \
+ GCOps.c \
+ Millis.c \
+ Handlers.c \
+ Init.c \
+ Keyboard.c \
+ Keystroke.c \
+ Pointer.c \
+ Screen.c \
+ TestExt.c \
+ Visual.c \
+ Drawable.c \
+ Window.c \
+ Pixmap.c \
+ Render.c \
+ Client.c \
+ Rootless.c \
+ Extensions.c \
+ Options.c \
+ Clipboard.c \
+ Splash.c \
+ Split.c \
+ Holder.c \
+ Reconnect.c \
+ Error.c \
+ Atoms.c \
+ Trap.c \
+ Image.c \
+ Composite.c \
+ Pixels.c \
+ stubs.c \
+ xpstubs.c \
+ miinitext.c \
+ $(NULL)
+
+OBJS = \
+ NXwindow.o \
+ NXevents.o \
+ NXproperty.o \
+ NXdixfonts.o \
+ NXglyphcurs.o \
+ NXdispatch.o \
+ NXrender.o \
+ NXglyph.o \
+ NXpicture.o \
+ NXextension.o \
+ NXshm.o \
+ NXglxext.o \
+ NXxvdisp.o \
+ NXmiexpose.o \
+ NXresource.o \
+ NXdamage.o \
+ NXmitrap.o \
+ Args.o \
+ Binder.o \
+ BitmapUtils.o \
+ Colormap.o \
+ Cursor.o \
+ Dialog.o \
+ Display.o \
+ Events.o \
+ Font.o \
+ GC.o \
+ GCOps.o \
+ Millis.o \
+ Handlers.o \
+ Init.o \
+ Keyboard.o \
+ Keystroke.o \
+ Pointer.o \
+ Screen.o \
+ TestExt.o \
+ Visual.o \
+ Drawable.o \
+ Window.o \
+ Pixmap.o \
+ Render.o \
+ Client.o \
+ Rootless.o \
+ Extensions.o \
+ Options.o \
+ Clipboard.o \
+ Splash.o \
+ Split.o \
+ Holder.o \
+ Reconnect.o \
+ Error.o \
+ Atoms.o \
+ Trap.o \
+ Image.o \
+ Composite.o \
+ Pixels.o \
+ stubs.o \
+ xpstubs.o \
+ miinitext.o \
+ $(NULL)
+
+VFBINCLUDES = \
+ -I../../fb \
+ -I../../mfb \
+ -I../../render \
+ $(NULL)
+
+INCLUDES = \
+ -I. \
+ -I../../../../extras/Mesa/include \
+ -I$(XBUILDINCDIR) \
+ -I../../mi \
+ -I../../include \
+ -I../../os \
+ -I../../miext/damage \
+ -I../../miext/cw \
+ -I../../GL/glx \
+ -I../../GL/include \
+ -I../../../../lib/GL/include \
+ -I../../Xext \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ $(VFBINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0` \
+ `pkg-config --cflags-only-I pixman-1` \
+ $(NULL)
+#ifdef SunArchitecture
+INCLUDES = \
+ -I. \
+ -I../../../../extras/Mesa/include \
+ -I$(XBUILDINCDIR) \
+ -I/usr/sfw/include \
+ -I../../mi \
+ -I../../include \
+ -I../../os \
+ -I../../GL/glx \
+ -I../../GL/include \
+ -I../../../../lib/GL/include \
+ -I../../Xext \
+ -I../../miext/damage \
+ -I../../miext/cw \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ $(VFBINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0` \
+ `pkg-config --cflags-only-I pixman-1` \
+ `pkg-config --cflags-only-I zlib` \
+ `pkg-config --cflags-only-I libpng` \
+ $(NULL)
+#else
+#ifdef cygwinArchitecture
+INCLUDES = \
+ -I. -I$(XBUILDINCDIR) \
+ -I../../mi \
+ -I../../include \
+ -I../../os \
+ -I../../GL/glx \
+ -I../../GL/include \
+ -I../../../../lib/GL/include \
+ -I../../Xext \
+ -I../../miext/damage \
+ -I../../miext/cw \
+ -I../../../../../nxcomp \
+ -I../../../../../nxcompshad \
+ -I../../../../extras/Mesa/include \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ $(VFBINCLUDES) \
+ `pkg-config --cflags-only-I libxml-2.0` \
+ `pkg-config --cflags-only-I pixman-1` \
+ `pkg-config --cflags-only-I zlib` \
+ `pkg-config --cflags-only-I libpng` \
+ $(NULL)
+#endif
+#endif
+
+### NXAGENT Defines:
+#
+# NXAGENT_FONTCACHE_SIZE Number of cache slots
+# NXAGENT_SHAPE Old shape code
+# NXAGENT_GLYPHCACHE
+# NXAGENT_GLYPHCACHE_SIZE Slots for glyph cache
+# NXAGENT_SHAPE2 New shape code
+# NXAGENT_FIXKEYS Force the release of pressed key when loosing focus
+# NXAGENT_EXPOSURES Manage expose events
+# NXAGENT_CLIPBOARD Enables clipboard cut and paste function between X servers.
+# NXAGENT_FONTEXCLUDE Exclude some specific font names (only "-ult1mo" at this moment).
+# NXAGENT FULLSCREEN Fullscreen mode
+# NXAGENT_RANDR_MODE_PREFIX Use prefixed (i.e., nx_<x>x<y>) RandR modes
+# NXAGENT_RANDR_XINERAMA_CLIPPING cut off invisible window parts in xinerama mode (you probably do not want this)
+
+#if nxVersion
+NX_DEFINES = \
+ -DNX_VERSION_CURRENT="$(NX_VERSION_CURRENT)" \
+ -DNX_VERSION_CURRENT_STRING="\"$(NX_VERSION_CURRENT_STRING)\"" \
+ $(NULL)
+#endif
+
+DEFINES = \
+ -g $(OS_DEFINES) $(EXT_DEFINES) $(NX_DEFINES) \
+ -UXF86VIDMODE -UXFreeXDGA -UXF86MISC -UXF86DRI \
+ -DNXAGENT_SERVER \
+ -DNXAGENT_CONSTRAINCURSOR \
+ -DNXAGENT_FONTCACHE_SIZE=50 \
+ -DNXAGENT_GLYPHCACHE -DNXAGENT_GLYPHCACHE_SIZE=50 \
+ -DNXAGENT_SHAPE2 \
+ -DNXAGENT_FIXKEYS \
+ -DNXAGENT_CLIPBOARD \
+ -DNXAGENT_EXPOSURES \
+ -DNXAGENT_FONTEXCLUDE \
+ -DNXAGENT_PACKEDIMAGES \
+ -DNXAGENT_VISIBILITY \
+ -DNXAGENT_WAKEUP=1000 \
+ -DNXAGENT_ONSTART \
+ -DNXAGENT_SPLASH \
+ -DNXAGENT_ARTSD \
+ -DNXAGENT_RANDR_MODE_PREFIX \
+ -UNX_DEBUG_INPUT \
+ -DRANDR_10_INTERFACE=1 \
+ -DRANDR_12_INTERFACE=1 \
+ -DRANDR_13_INTERFACE=1 \
+ -DRANDR_14_INTERFACE=1 \
+ -DRANDR_15_INTERFACE=1 \
+ -DPANORAMIX \
+ -UDEBUG_TREE \
+ $(NULL)
+
+all:: $(OBJS)
+
+LinkSourceFile(stubs.c,$(SERVERSRC)/Xi)
+LinkSourceFile(xpstubs.c,$(SERVERSRC)/dix)
+LinkSourceFile(miinitext.c,$(SERVERSRC)/mi)
+SpecialCObjectRule(miinitext,$(ICONFIGFILES), $(_NOOP_))
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(nxagent,$(OBJS))
+
+DependTarget()
+
+#define IHaveSubdirs
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
new file mode 100644
index 000000000..a35e3d5a8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -0,0 +1,581 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Keyboard.h"
+#include "Handlers.h"
+#include "Events.h"
+#include "Init.h"
+#include "Args.h"
+#include "Client.h"
+#include "Options.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Font.h"
+#include "Millis.h"
+#include "Error.h"
+#include "Keystroke.h"
+
+#include <nx/NX.h>
+#include "compext/Compext.h"
+#include "Reconnect.h"
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+#define NXAGENT_VERSION NX_VERSION_CURRENT
+#define NXAGENT_VERSION_STRING NX_VERSION_CURRENT_STRING
+
+/*
+ * ProcVector array defined in tables.c.
+ */
+
+extern int (*ProcVector[256])(ClientPtr);
+
+/*
+ * From the fb code.
+ */
+
+extern int fbGCPrivateIndex;
+
+/*
+ * Stubs for the DPMS extension.
+ */
+
+#ifdef DPMSExtension
+
+void DPMSSet(int level);
+int DPMSGet(int *level);
+Bool DPMSSupported(void);
+
+#endif
+
+/*
+ * Our error logging function.
+ */
+
+void OsVendorVErrorFFunction(const char *f, va_list args);
+
+/*
+ * True if this is a fatal error.
+ */
+
+extern int OsVendorVErrorFFatal;
+
+/*
+ * Redirect the error output to a
+ * different file
+ */
+
+extern void (*OsVendorStartRedirectErrorFProc)();
+extern void (*OsVendorEndRedirectErrorFProc)();
+
+extern void SetVendorRelease(int release);
+
+void OsVendorStartRedirectErrorFFunction();
+void OsVendorEndRedirectErrorFFunction();
+
+/*
+ * Called by InitGlobals() in the
+ * new X server tree.
+ */
+
+
+static void nxagentGrabServerCallback(CallbackListPtr *callbacks, void *data,
+ void *args);
+
+void ddxInitGlobals(void)
+{
+ /*
+ * Install our error logging function.
+ */
+
+ OsVendorVErrorFProc = OsVendorVErrorFFunction;
+
+ OsVendorStartRedirectErrorFProc = OsVendorStartRedirectErrorFFunction;
+ OsVendorEndRedirectErrorFProc = OsVendorEndRedirectErrorFFunction;
+}
+
+/*
+ * Set if the remote display supports
+ * backing store.
+ */
+/*
+FIXME: These, if not removed, should at least
+ be moved to Display.h and Display.c.
+*/
+int nxagentBackingStore;
+int nxagentSaveUnder;
+
+/*
+ * This is true at startup and set to the value of
+ * nxagentFullGeneration at the end of InitInput.
+ *
+ * InitOutput
+ * nxagentOpenDisplay (if nxagentDoFullGeneration)
+ * nxagentCloseDisplay (if (nxagentDoFullGeneration && nxagentDisplay))
+ * nxagentFree*
+ * nxagentListRemoteFonts
+ * AddScreen
+ * nxagentOpenScreen
+ * InitInput
+ */
+
+int nxagentDoFullGeneration = 1;
+
+ /*
+ * 1 if agent running as X2goAgent
+ * 0 if NX Agent
+ */
+int nxagentX2go;
+
+/*
+ * Checking if agent is x2go agent
+ */
+
+void checkX2goAgent()
+{
+ extern const char *__progname;
+ if( strcasecmp(__progname,"x2goagent") == 0)
+ {
+ fprintf(stderr, "\nrunning as X2Go Agent\n");
+ nxagentX2go=1;
+ }
+ else
+ nxagentX2go=0;
+}
+
+
+/*
+ * Called at X server's initialization.
+ */
+
+void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
+{
+ char *authority;
+ int i;
+
+ #ifdef __sun
+
+ char *environment;
+
+ #endif
+
+ /*
+ * Check if we running as X2Go Agent
+ */
+ checkX2goAgent();
+
+ /*
+ * Print our pid and version information.
+ */
+
+ if (serverGeneration <= 1)
+ {
+ fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION_STRING "\n\n");
+ fprintf(stderr, "Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com)\n");
+ fprintf(stderr, "Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de>\n");
+ fprintf(stderr, "Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>\n");
+ fprintf(stderr, "Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de>\n");
+ fprintf(stderr, "Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de>\n");
+ fprintf(stderr, "Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com)\n");
+ fprintf(stderr, "See https://github.com/ArcticaProject/nx-libs for more information.\n\n");
+
+ fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
+
+ fprintf(stderr, "Session: Starting session at '%s'.\n", GetTimeAsString());
+ saveAgentState("STARTING");
+ }
+
+ /*
+ * Avoid slowness due to buggy_repeat workaround
+ * in libcairo versions >= 1.10.
+ */
+
+ SetVendorRelease(70000000);
+
+ /*
+ * Init the time count for image rate.
+ */
+
+ if (nxagentOption(ImageRateLimit) != 0)
+ {
+ fprintf(stderr, "Info: Image rate limit set to %u kB/s.\n", nxagentOption(ImageRateLimit));
+ }
+
+ /*
+ * Unset the LD_LIBRARY_PATH variable in
+ * Popen() before calling execl() in the
+ * child process.
+ */
+
+ NXUnsetLibraryPath(1);
+
+ if (serverGeneration == 1)
+ {
+ AddCallback(&ServerGrabCallback, nxagentGrabServerCallback, NULL);
+ }
+
+ if (nxagentUserDefinedFontPath == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "InitOutput: Calling nxagentVerifyDefaultFontPath.\n");
+ #endif
+
+ nxagentVerifyDefaultFontPath();
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "InitOutput: User defined font path. Skipping the check on the fonts dir.\n");
+ }
+ #endif
+
+ if ((authority = getenv("NX_XAUTHORITY")))
+ {
+ #ifdef __sun
+
+ environment = malloc(15 + strlen(authority));
+
+ sprintf(environment, "XAUTHORITY=%s", authority);
+
+ if (putenv(environment) < 0)
+
+ #else
+
+ if (setenv("XAUTHORITY", authority, True) < 0)
+
+ #endif
+
+ {
+ fprintf(stderr, "Warning: Couldn't set the XAUTHORITY environment to [%s]\n",
+ authority);
+ }
+ }
+
+ nxagentInitBSPixmapList();
+
+ /*
+ * Open the display. We are at the early startup and
+ * the information we'll get from the remote X server
+ * will mandate some of the characteristics of the
+ * session, like the screen depth. Note that this re-
+ * liance on the remote display at session startup
+ * should be removed. We should always operate at 32
+ * bpp, internally, and do the required translations
+ * as soon as the graphic operation needs to be real-
+ * ized on the remote display.
+ */
+
+ nxagentOpenDisplay(argc, argv);
+
+/*
+FIXME: These variables, if not removed at all because have probably
+ become useless, should be moved to Display.h and Display.c.
+*/
+ nxagentBackingStore = XDoesBackingStore(DefaultScreenOfDisplay(nxagentDisplay));
+
+ #ifdef TEST
+ fprintf(stderr, "InitOutput: Remote display backing store support [%d].\n",
+ nxagentBackingStore);
+ #endif
+
+ nxagentSaveUnder = XDoesSaveUnders(DefaultScreenOfDisplay(nxagentDisplay));
+
+ #ifdef TEST
+ fprintf(stderr, "InitOutput: Remote display save under support [%d].\n",
+ nxagentSaveUnder);
+ #endif
+
+ /*
+ * Initialize the basic screen info.
+ */
+
+ nxagentSetScreenInfo(screenInfo);
+
+ /*
+ * Initialize pixmap formats for this screen.
+ */
+
+ nxagentSetPixmapFormats(screenInfo);
+
+ /*
+ * Get our own privates' index.
+ */
+
+ nxagentWindowPrivateIndex = AllocateWindowPrivateIndex();
+ nxagentGCPrivateIndex = AllocateGCPrivateIndex();
+ RT_NX_GC = CreateNewResourceType(nxagentDestroyNewGCResourceType);
+#ifdef HAS_XFONT2
+ nxagentFontPrivateIndex = xfont2_allocate_font_private_index();
+#else
+ nxagentFontPrivateIndex = AllocateFontPrivateIndex();
+#endif /* HAS_XFONT2 */
+ RT_NX_FONT = CreateNewResourceType(nxagentDestroyNewFontResourceType);
+ nxagentClientPrivateIndex = AllocateClientPrivateIndex();
+ nxagentPixmapPrivateIndex = AllocatePixmapPrivateIndex();
+ RT_NX_PIXMAP = CreateNewResourceType(nxagentDestroyNewPixmapResourceType);
+
+ RT_NX_CORR_BACKGROUND = CreateNewResourceType(nxagentDestroyCorruptedBackgroundResource);
+ RT_NX_CORR_WINDOW = CreateNewResourceType(nxagentDestroyCorruptedWindowResource);
+ RT_NX_CORR_PIXMAP = CreateNewResourceType(nxagentDestroyCorruptedPixmapResource);
+
+ fbGCPrivateIndex = AllocateGCPrivateIndex();
+
+ if (nxagentNumScreens == 0)
+ {
+ nxagentNumScreens = 1;
+ }
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ AddScreen(nxagentOpenScreen, argc, argv);
+ }
+
+ nxagentNumScreens = screenInfo->numScreens;
+
+ /*
+ * Initialize the GCs used by the synchro-
+ * nization put images. We do it here beca-
+ * use we use the nxagentDefaultScreen.
+ */
+
+ nxagentAllocateGraphicContexts();
+
+ nxagentDoFullGeneration = nxagentFullGeneration;
+
+ /*
+ * Use a solid black root window
+ * background.
+ */
+
+ blackRoot = TRUE;
+
+ nxagentInitKeystrokes(False);
+}
+
+void
+nxagentNotifyConnection(int fd, int ready, void *data)
+{
+ nxagentDispatchEvents(NULL);
+}
+
+void InitInput(argc, argv)
+ int argc;
+ char *argv[];
+{
+ void *ptr, *kbd;
+
+ ptr = AddInputDevice(nxagentPointerProc, True);
+ kbd = AddInputDevice(nxagentKeyboardProc, True);
+
+ RegisterPointerDevice(ptr);
+ RegisterKeyboardDevice(kbd);
+
+ mieqInit(kbd, ptr);
+
+ /*
+ * Add the display descriptor to the
+ * set of descriptors awaited by the
+ * dispatcher.
+ */
+
+ nxagentAddXConnection();
+
+ if (nxagentOption(Shadow))
+ {
+ RegisterBlockAndWakeupHandlers(nxagentShadowBlockHandler, nxagentShadowWakeupHandler, NULL);
+ }
+ else
+ {
+ RegisterBlockAndWakeupHandlers(nxagentBlockHandler, nxagentWakeupHandler, NULL);
+ }
+
+ /*
+ * We let the proxy flush the link on our behalf
+ * after having opened the display. We are now
+ * entering the dispatcher. From now on we'll
+ * flush the proxy link explicitly.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitInput: Setting the NX flush policy to deferred.\n");
+ #endif
+
+ NXSetDisplayPolicy(nxagentDisplay, NXPolicyDeferred);
+}
+
+/*
+ * DDX specific abort routine. This is called
+ * by AbortServer() that, in turn, is called
+ * by FatalError().
+ */
+
+void AbortDDX()
+{
+ nxagentDoFullGeneration = True;
+
+ nxagentCloseDisplay();
+
+ /*
+ * Do the required finalization if we
+ * are not going through the normal
+ * X server shutdown.
+ */
+
+ if ((dispatchException & DE_TERMINATE) == 0)
+ {
+ nxagentAbortDisplay();
+ }
+}
+
+/*
+ * Called by GiveUp().
+ */
+
+void ddxGiveUp()
+{
+ AbortDDX();
+}
+
+void ddxBeforeReset(void)
+{
+}
+
+void OsVendorInit()
+{
+ return;
+}
+
+void OsVendorFatalError()
+{
+ /*
+ * Let the session terminate gracely
+ * from an user's standpoint.
+ */
+
+ fprintf(stderr, "Session: Aborting session at '%s'.\n", GetTimeAsString());
+
+ fprintf(stderr, "Session: Session aborted at '%s'.\n", GetTimeAsString());
+}
+
+void OsVendorVErrorFFunction(const char *f, va_list args)
+{
+ if (OsVendorVErrorFFatal == 0)
+ {
+ char buffer[1024];
+
+ vsnprintf(buffer, sizeof(buffer), f, args);
+
+ nxagentStartRedirectToClientsLog();
+
+ fprintf(stderr, "%s", buffer);
+
+ nxagentEndRedirectToClientsLog();
+ }
+ else
+ {
+ LogVWrite(-1, f, args);
+ }
+}
+
+void OsVendorStartRedirectErrorFFunction()
+{
+ nxagentStartRedirectToClientsLog();
+}
+
+void OsVendorEndRedirectErrorFFunction()
+{
+ nxagentEndRedirectToClientsLog();
+}
+
+ServerGrabInfoRec nxagentGrabServerInfo;
+
+static void nxagentGrabServerCallback(CallbackListPtr *callbacks, void *data,
+ void *args)
+{
+ ServerGrabInfoRec *grab = (ServerGrabInfoRec*)args;
+
+ nxagentGrabServerInfo.client = grab->client;
+ nxagentGrabServerInfo.grabstate = grab->grabstate;
+}
+
+#ifdef DPMSExtension
+
+void DPMSSet(int level)
+{
+}
+
+int DPMSGet(int *level)
+{
+ return -1;
+}
+
+Bool DPMSSupported(void)
+{
+ return 1;
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
new file mode 100644
index 000000000..34a17067f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -0,0 +1,54 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Init_H__
+#define __Init_H__
+
+extern int nxagentDoFullGeneration;
+
+extern int nxagentBackingStore;
+extern int nxagentSaveUnder;
+
+extern int nxagentX2go;
+
+extern ServerGrabInfoRec nxagentGrabServerInfo;
+
+void nxagentNotifyConnection(int fd, int ready, void *data);
+
+#endif /* __Init_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
new file mode 100644
index 000000000..02b60bef4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -0,0 +1,1930 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "keysym.h"
+#include "screenint.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Keyboard.h"
+#include "Events.h"
+#include "Options.h"
+#include "Error.h"
+
+#include "compext/Compext.h"
+
+#include <nx/Shadow.h>
+
+#ifdef XKB
+
+#include "globals.h"
+#include "property.h"
+#include "Init.h"
+
+#include <nx-X11/extensions/XKB.h>
+
+/*
+ we need the client side header here, xkbsrv.h will not work because
+ server and libX11 have different struct sizes on
+ 64bit. Interestingly upstream xnest does not take care of this.
+*/
+#include <nx-X11/extensions/XKBsrv.h>
+#include <nx-X11/extensions/XKBconfig.h>
+
+#include "Xatom.h"
+
+#include <errno.h>
+
+static int nxagentXkbGetNames(char **rules, char **model, char **layout,
+ char **variant, char **options);
+
+static void nxagentKeycodeConversionSetup(void);
+
+#endif /* XKB */
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef WATCH
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+/*
+ * Unfortunately we cannot just include XKBlib.h.
+ * It conflicts with the server side definitions
+ * of the same symbols. This is more a X problem
+ * than our.
+ */
+
+#ifdef XKB
+
+extern Bool XkbQueryExtension(
+#if NeedFunctionPrototypes
+ Display * /* dpy */,
+ int * /* opcodeReturn */,
+ int * /* eventBaseReturn */,
+ int * /* errorBaseReturn */,
+ int * /* majorRtrn */,
+ int * /* minorRtrn */
+#endif
+);
+
+extern XkbDescPtr XkbGetKeyboard(
+#if NeedFunctionPrototypes
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */
+#endif
+);
+
+extern Status XkbGetControls(
+#if NeedFunctionPrototypes
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+#endif
+);
+
+#ifndef XKB_BASE_DIRECTORY
+#define XKB_BASE_DIRECTORY "/usr/share/X11/xkb"
+#endif
+#ifndef XKB_ALTERNATE_BASE_DIRECTORY
+#define XKB_ALTERNATE_BASE_DIRECTORY "/usr/X11R6/lib/X11/xkb"
+#endif
+#ifndef XKB_CONFIG_FILE_NX
+#define XKB_CONFIG_FILE_NX "/etc/nxagent/nxagent.keyboard"
+#endif
+#ifndef XKB_CONFIG_FILE_X2GO
+#define XKB_CONFIG_FILE_X2GO "/etc/x2go/x2goagent.keyboard"
+#endif
+#ifndef XKB_DFLT_RULES_FILE
+#define XKB_DFLT_RULES_FILE "xfree86"
+#endif
+#ifndef XKB_ALTS_RULES_FILE
+#define XKB_ALTS_RULES_FILE "xorg"
+#endif
+#ifndef XKB_DFLT_KB_LAYOUT
+#define XKB_DFLT_KB_LAYOUT "us"
+#endif
+#ifndef XKB_DFLT_KB_MODEL
+#define XKB_DFLT_KB_MODEL "pc102"
+#endif
+#ifndef XKB_DFLT_KB_VARIANT
+#define XKB_DFLT_KB_VARIANT NULL
+#endif
+#ifndef XKB_DFLT_KB_OPTIONS
+#define XKB_DFLT_KB_OPTIONS NULL
+#endif
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+#endif /* XKB */
+
+/*
+ * Save the values queried from X server.
+ */
+
+XkbAgentInfoRec nxagentXkbInfo = { -1, -1, -1, -1, -1 };
+
+/*
+ * Keyboard status, updated through XKB
+ * events.
+ */
+
+XkbAgentStateRec nxagentXkbState = { 0, 0, 0, 0, 0 };
+
+/*
+ * Info for disabling/enabling Xkb extension.
+ */
+
+XkbWrapperRec nxagentXkbWrapper;
+
+extern char *nxagentKeyboard;
+
+static char *nxagentXkbGetRules(void);
+
+unsigned int nxagentAltMetaMask;
+unsigned int nxagentAltMask;
+unsigned int nxagentMetaMask;
+unsigned int nxagentCapsMask;
+unsigned int nxagentNumlockMask;
+
+static void nxagentCheckModifierMasks(CARD8, int);
+
+CARD8 nxagentCapsLockKeycode = 66;
+CARD8 nxagentNumLockKeycode = 77;
+
+static void nxagentCheckRemoteKeycodes(void);
+
+static CARD8 nxagentConvertedKeycodes[] =
+{
+ /* evdev pc105*/
+ /* 0 */ 0,
+ /* 1 */ 1,
+ /* 2 */ 2,
+ /* 3 */ 3,
+ /* 4 */ 4,
+ /* 5 */ 5,
+ /* 6 */ 6,
+ /* 7 */ 7,
+ /* 8 */ 8,
+ /* 9 */ 9,
+ /* 10 */ 10,
+ /* 11 */ 11,
+ /* 12 */ 12,
+ /* 13 */ 13,
+ /* 14 */ 14,
+ /* 15 */ 15,
+ /* 16 */ 16,
+ /* 17 */ 17,
+ /* 18 */ 18,
+ /* 19 */ 19,
+ /* 20 */ 20,
+ /* 21 */ 21,
+ /* 22 */ 22,
+ /* 23 */ 23,
+ /* 24 */ 24,
+ /* 25 */ 25,
+ /* 26 */ 26,
+ /* 27 */ 27,
+ /* 28 */ 28,
+ /* 29 */ 29,
+ /* 30 */ 30,
+ /* 31 */ 31,
+ /* 32 */ 32,
+ /* 33 */ 33,
+ /* 34 */ 34,
+ /* 35 */ 35,
+ /* 36 */ 36,
+ /* 37 */ 37,
+ /* 38 */ 38,
+ /* 39 */ 39,
+ /* 40 */ 40,
+ /* 41 */ 41,
+ /* 42 */ 42,
+ /* 43 */ 43,
+ /* 44 */ 44,
+ /* 45 */ 45,
+ /* 46 */ 46,
+ /* 47 */ 47,
+ /* 48 */ 48,
+ /* 49 */ 49,
+ /* 50 */ 50,
+ /* 51 */ 51,
+ /* 52 */ 52,
+ /* 53 */ 53,
+ /* 54 */ 54,
+ /* 55 */ 55,
+ /* 56 */ 56,
+ /* 57 */ 57,
+ /* 58 */ 58,
+ /* 59 */ 59,
+ /* 60 */ 60,
+ /* 61 */ 61,
+ /* 62 */ 62,
+ /* 63 */ 63,
+ /* 64 */ 64,
+ /* 65 */ 65,
+ /* 66 */ 66,
+ /* 67 */ 67,
+ /* 68 */ 68,
+ /* 69 */ 69,
+ /* 70 */ 70,
+ /* 71 */ 71,
+ /* 72 */ 72,
+ /* 73 */ 73,
+ /* 74 */ 74,
+ /* 75 */ 75,
+ /* 76 */ 76,
+ /* 77 */ 77,
+ /* 78 */ 78,
+ /* 79 */ 79,
+ /* 80 */ 80,
+ /* 81 */ 81,
+ /* 82 */ 82,
+ /* 83 */ 83,
+ /* 84 */ 84,
+ /* 85 */ 85,
+ /* 86 */ 86,
+ /* 87 */ 87,
+ /* 88 */ 88,
+ /* 89 */ 89,
+ /* 90 */ 90,
+ /* 91 */ 91,
+ /* 92 */ 124,
+ /* 93 */ 93,
+ /* 94 */ 94,
+ /* 95 */ 95,
+ /* 96 */ 96,
+ /* 97 */ 211,
+ /* 98 */ 98,
+ /* 99 */ 99,
+ /* 100 */ 100,
+ /* 101 */ 208,
+ /* 102 */ 102,
+ /* 103 */ 103,
+ /* 104 */ 108,
+ /* 105 */ 109,
+ /* 106 */ 112,
+ /* 107 */ 111,
+ /* 108 */ 113,
+ /* 109 */ 109,
+ /* 110 */ 97,
+ /* 111 */ 98,
+ /* 112 */ 99,
+ /* 113 */ 100,
+ /* 114 */ 102,
+ /* 115 */ 103,
+ /* 116 */ 104,
+ /* 117 */ 105,
+ /* 118 */ 106,
+ /* 119 */ 107,
+ /* 120 */ 120,
+ /* 121 */ 121,
+ /* 122 */ 122,
+ /* 123 */ 123,
+ /* 124 */ 124,
+ /* 125 */ 126,
+ /* 126 */ 126,
+ /* 127 */ 110,
+ /* 128 */ 128,
+ /* 129 */ 129,
+ /* 130 */ 130,
+ /* 131 */ 131,
+ /* 132 */ 133,
+ /* 133 */ 115,
+ /* 134 */ 116,
+ /* 135 */ 117,
+ /* 136 */ 136,
+ /* 137 */ 137,
+ /* 138 */ 138,
+ /* 139 */ 139,
+ /* 140 */ 140,
+ /* 141 */ 141,
+ /* 142 */ 142,
+ /* 143 */ 143,
+ /* 144 */ 144,
+ /* 145 */ 145,
+ /* 146 */ 146,
+ /* 147 */ 147,
+ /* 148 */ 148,
+ /* 149 */ 149,
+ /* 150 */ 150,
+ /* 151 */ 151,
+ /* 152 */ 152,
+ /* 153 */ 153,
+ /* 154 */ 154,
+ /* 155 */ 155,
+ /* 156 */ 156,
+ /* 157 */ 157,
+ /* 158 */ 158,
+ /* 159 */ 159,
+ /* 160 */ 160,
+ /* 161 */ 161,
+ /* 162 */ 162,
+ /* 163 */ 163,
+ /* 164 */ 164,
+ /* 165 */ 165,
+ /* 166 */ 166,
+ /* 167 */ 167,
+ /* 168 */ 168,
+ /* 169 */ 169,
+ /* 170 */ 170,
+ /* 171 */ 171,
+ /* 172 */ 172,
+ /* 173 */ 173,
+ /* 174 */ 174,
+ /* 175 */ 175,
+ /* 176 */ 176,
+ /* 177 */ 177,
+ /* 178 */ 178,
+ /* 179 */ 179,
+ /* 180 */ 180,
+ /* 181 */ 181,
+ /* 182 */ 182,
+ /* 183 */ 183,
+ /* 184 */ 184,
+ /* 185 */ 185,
+ /* 186 */ 186,
+ /* 187 */ 187,
+ /* 188 */ 188,
+ /* 189 */ 189,
+ /* 190 */ 190,
+ /* 191 */ 118,
+ /* 192 */ 119,
+ /* 193 */ 120,
+ /* 194 */ 121,
+ /* 195 */ 122,
+ /* 196 */ 196,
+ /* 197 */ 197,
+ /* 198 */ 198,
+ /* 199 */ 199,
+ /* 200 */ 200,
+ /* 201 */ 201,
+ /* 202 */ 202,
+ /* 203 */ 93,
+ /* 204 */ 125,
+ /* 205 */ 156,
+ /* 206 */ 127,
+ /* 207 */ 128,
+ /* 208 */ 208,
+ /* 209 */ 209,
+ /* 210 */ 210,
+ /* 211 */ 211,
+ /* 212 */ 212,
+ /* 213 */ 213,
+ /* 214 */ 214,
+ /* 215 */ 215,
+ /* 216 */ 216,
+ /* 217 */ 217,
+ /* 218 */ 218,
+ /* 219 */ 219,
+ /* 220 */ 220,
+ /* 221 */ 221,
+ /* 222 */ 222,
+ /* 223 */ 223,
+ /* 224 */ 224,
+ /* 225 */ 225,
+ /* 226 */ 226,
+ /* 227 */ 227,
+ /* 228 */ 228,
+ /* 229 */ 229,
+ /* 230 */ 230,
+ /* 231 */ 231,
+ /* 232 */ 232,
+ /* 233 */ 233,
+ /* 234 */ 234,
+ /* 235 */ 235,
+ /* 236 */ 236,
+ /* 237 */ 237,
+ /* 238 */ 238,
+ /* 239 */ 239,
+ /* 240 */ 240,
+ /* 241 */ 241,
+ /* 242 */ 242,
+ /* 243 */ 243,
+ /* 244 */ 244,
+ /* 245 */ 245,
+ /* 246 */ 246,
+ /* 247 */ 247,
+ /* 248 */ 248,
+ /* 249 */ 249,
+ /* 250 */ 250,
+ /* 251 */ 251,
+ /* 252 */ 252,
+ /* 253 */ 253,
+ /* 254 */ 254,
+ /* 255 */ 255
+};
+
+static int nxagentKeycodeConversion = 0;
+
+CARD8 nxagentConvertKeycode(CARD8 k)
+{
+ if (nxagentKeycodeConversion != 0)
+ {
+ #ifdef DEBUG
+ if (k != nxagentConvertedKeycodes[k])
+ fprintf(stderr, "nxagentConvertKeycode: converting keycode [%d] to [%d]\n", k, nxagentConvertedKeycodes[k]);
+ #endif
+
+ return nxagentConvertedKeycodes[k];
+ }
+ else
+ {
+ return k;
+ }
+}
+
+static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup);
+
+static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev);
+
+static int nxagentFreeKeyboardDeviceData(DeviceIntPtr dev);
+
+static void nxagentCheckXkbBaseDirectory(void)
+{
+
+ /*
+ * Set XkbBaseDirectory global
+ * variable appropriately.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+ "Before calling _NXGetXkbBasePath:\n");
+
+ fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+ "XkbBaseDirectory variable [%s].\n",
+ XkbBaseDirectory);
+ #endif
+
+ XkbBaseDirectory = _NXGetXkbBasePath(XkbBaseDirectory);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+ "After calling _NXGetXkbBasePath:\n");
+
+ fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+ "XkbBaseDirectory variable [%s].\n",
+ XkbBaseDirectory);
+ #endif
+
+ return;
+}
+
+static char *nxagentXkbGetRules()
+{
+ int ret;
+ int size, sizeDflt, sizeAlt;
+ char *path;
+ struct stat buf;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentXkbGetRules: XkbBaseDirectory [%s].\n",
+ XkbBaseDirectory);
+ #endif
+
+ sizeDflt = strlen(XKB_DFLT_RULES_FILE);
+ sizeAlt = strlen(XKB_ALTS_RULES_FILE);
+ size = strlen(XkbBaseDirectory) + strlen("/rules/");
+ size += (sizeDflt > sizeAlt) ? sizeDflt : sizeAlt;
+
+ if ((path = malloc((size + 1) * sizeof(char))) == NULL)
+ {
+ FatalError("nxagentXkbGetRules: malloc failed.");
+ }
+
+ strcpy(path, XkbBaseDirectory);
+ strcat(path, "/rules/");
+ strcat(path, XKB_DFLT_RULES_FILE);
+ ret = stat(path, &buf);
+
+ if (ret == 0)
+ {
+ free(path);
+ return XKB_DFLT_RULES_FILE;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentXkbGetRules: WARNING! Failed to stat file [%s]: %s.\n", path, strerror(ret));
+ #endif
+
+ strcpy(path, XkbBaseDirectory);
+ strcat(path, "/rules/");
+ strcat(path, XKB_ALTS_RULES_FILE);
+ ret = stat(path, &buf);
+
+ if (ret == 0)
+ {
+ free(path);
+ return XKB_ALTS_RULES_FILE;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentXkbGetRules: WARNING! Failed to stat file [%s]: %s.\n", path, strerror(ret));
+ #endif
+
+ free(path);
+ return XKB_DFLT_RULES_FILE;
+}
+
+void nxagentBell(int volume, DeviceIntPtr pDev, void * ctrl, int cls)
+{
+ XBell(nxagentDisplay, volume);
+}
+
+void nxagentChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+ #ifdef XKB
+
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr xkbc;
+
+ if (!noXkbExtension)
+ {
+ xkbi = pDev -> key -> xkbInfo;
+ xkbc = xkbi -> desc -> ctrls;
+
+ /*
+ * We want to prevent agent generating auto-repeated
+ * keystrokes. Let's intercept any attempt by appli-
+ * cations to change the default timeouts on the
+ * nxagent device.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeKeyboardControl: Repeat delay was [%d] interval was [%d].\n",
+ xkbc -> repeat_delay, xkbc -> repeat_interval);
+ #endif
+
+ xkbc -> repeat_delay = ~ 0;
+ xkbc -> repeat_interval = ~ 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeKeyboardControl: Repeat delay is now [%d] interval is now [%d].\n",
+ xkbc -> repeat_delay, xkbc -> repeat_interval);
+ #endif
+ }
+
+ #endif
+
+ /*
+ * If enabled, propagate the changes to the
+ * devices attached to the real X server.
+ */
+
+ if (nxagentOption(DeviceControl) == True)
+ {
+ unsigned long value_mask;
+ XKeyboardControl values;
+ int i;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeKeyboardControl: WARNING! Propagating changes to keyboard settings.\n");
+ #endif
+
+ value_mask = KBKeyClickPercent |
+ KBBellPercent |
+ KBBellPitch |
+ KBBellDuration;
+
+ values.key_click_percent = ctrl->click;
+ values.bell_percent = ctrl->bell;
+ values.bell_pitch = ctrl->bell_pitch;
+ values.bell_duration = ctrl->bell_duration;
+
+ /*
+ * Don't propagate the auto repeat mode. It is forced to be
+ * off in the agent server.
+ *
+ * value_mask |= KBAutoRepeatMode;
+ * values.auto_repeat_mode = ctrl->autoRepeat ?
+ * AutoRepeatModeOn : AutoRepeatModeOff;
+ */
+
+ XChangeKeyboardControl(nxagentDisplay, value_mask, &values);
+
+ /*
+ * At this point, we need to walk through the vector and
+ * compare it to the current server vector. If there are
+ * differences, report them.
+ */
+
+ value_mask = KBLed | KBLedMode;
+
+ for (i = 1; i <= 32; i++)
+ {
+ values.led = i;
+ values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
+
+ XChangeKeyboardControl(nxagentDisplay, value_mask, &values);
+ }
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeKeyboardControl: WARNING! Not propagating changes to keyboard settings.\n");
+ #endif
+}
+
+int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
+{
+ XModifierKeymap *modifier_keymap;
+ KeySym *keymap;
+ int mapWidth;
+ int min_keycode, max_keycode;
+ KeySymsRec keySyms;
+ CARD8 modmap[256];
+ int i, j;
+ XKeyboardState values;
+ char *model = NULL, *layout = NULL;
+ int free_model = 0, free_layout = 0;
+ XkbDescPtr xkb = NULL;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_INIT].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentKeyboardProc: Watchpoint 9.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ /*
+ * Prevent agent from generating auto-repeat keystroke.
+ * Note that this is working only if XKB is enabled.
+ * A better solution should account cases where XKB is
+ * not available. Check also the behaviour of the
+ * DeviceControl nxagent option.
+ */
+
+ XkbDfltRepeatDelay = ~ 0;
+ XkbDfltRepeatInterval = ~ 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Set repeat delay to [%u] interval to [%u].\n",
+ XkbDfltRepeatDelay, XkbDfltRepeatInterval);
+ #endif
+
+ modifier_keymap = XGetModifierMapping(nxagentDisplay);
+
+ if (modifier_keymap == NULL)
+ {
+ return -1;
+ }
+
+ XDisplayKeycodes(nxagentDisplay, &min_keycode, &max_keycode);
+#ifdef _XSERVER64
+ {
+ KeySym64 *keymap64;
+ int i, len;
+ keymap64 = XGetKeyboardMapping(nxagentDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+
+ if (keymap64 == NULL)
+ {
+ XFreeModifiermap(modifier_keymap);
+
+ return -1;
+ }
+
+ len = (max_keycode - min_keycode + 1) * mapWidth;
+ keymap = (KeySym *)malloc(len * sizeof(KeySym));
+ for(i = 0; i < len; ++i)
+ keymap[i] = keymap64[i];
+ XFree(keymap64);
+ }
+
+#else /* #ifdef _XSERVER64 */
+
+ keymap = XGetKeyboardMapping(nxagentDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+
+ if (keymap == NULL)
+ {
+ XFreeModifiermap(modifier_keymap);
+
+ return -1;
+ }
+
+#endif /* #ifdef _XSERVER64 */
+
+ nxagentAltMetaMask = 0;
+ nxagentAltMask = 0;
+ nxagentMetaMask = 0;
+ nxagentCapsMask = 0;
+ nxagentNumlockMask = 0;
+
+ for (i = 0; i < 256; i++)
+ modmap[i] = 0;
+ for (j = 0; j < 8; j++)
+ for(i = 0; i < modifier_keymap->max_keypermod; i++) {
+ CARD8 keycode;
+ if ((keycode =
+ modifier_keymap->
+ modifiermap[j * modifier_keymap->max_keypermod + i]))
+ modmap[keycode] |= 1<<j;
+
+ if (keycode > 0)
+ {
+ nxagentCheckModifierMasks(keycode, j);
+ }
+ }
+ XFreeModifiermap(modifier_keymap);
+
+ nxagentCheckRemoteKeycodes();
+
+ keySyms.minKeyCode = min_keycode;
+ keySyms.maxKeyCode = max_keycode;
+ keySyms.mapWidth = mapWidth;
+ keySyms.map = keymap;
+
+#ifdef XKB
+
+ /*
+ * First of all the validity
+ * of XkbBaseDirectory global
+ * variable is checked.
+ */
+
+ nxagentCheckXkbBaseDirectory();
+
+ if (noXkbExtension) {
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: No XKB extension.\n");
+ #endif
+
+XkbError:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: XKB error.\n");
+ #endif
+
+ XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+ xkb = NULL;
+ if (free_model)
+ {
+ free_model = 0;
+ free(model);
+ }
+ if (free_layout)
+ {
+ free_layout = 0;
+ free(layout);
+ }
+#endif
+ XGetKeyboardControl(nxagentDisplay, &values);
+
+ memmove((char *) defaultKeyboardControl.autoRepeats,
+ (char *) values.auto_repeats, sizeof(values.auto_repeats));
+
+ #ifdef TEST
+ {
+ int ret =
+ #endif
+ InitKeyboardDeviceStruct((DevicePtr) pDev, &keySyms, modmap,
+ nxagentBell, nxagentChangeKeyboardControl);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: InitKeyboardDeviceStruct returns [%d].\n", ret);
+ }
+ #endif
+
+#ifdef XKB
+ } else {
+ FILE *file;
+ XkbConfigRtrnRec config;
+
+ char *nxagentXkbConfigFilePath;
+
+ XkbComponentNamesRec names;
+ char *rules, *variants, *options;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Using XKB extension.\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: nxagentKeyboard is [%s].\n", nxagentKeyboard ? nxagentKeyboard : "NULL");
+ #endif
+
+ memset(&names, 0, sizeof(XkbComponentNamesRec));
+
+ rules = nxagentXkbGetRules();
+
+ if ((nxagentKeyboard != NULL) && (strcmp(nxagentKeyboard, "query") != 0))
+ {
+ for (i = 0; nxagentKeyboard[i] != '/' && nxagentKeyboard[i] != 0; i++);
+
+ if(nxagentKeyboard[i] == 0 || nxagentKeyboard[i + 1] == 0 || i == 0)
+ {
+ ErrorF("Warning: Wrong keyboard type: %s.\n", nxagentKeyboard);
+
+ goto XkbError;
+ }
+
+ free_model = 1;
+ model = strndup(nxagentKeyboard, i);
+
+ free_layout = 1;
+ layout = strdup(&nxagentKeyboard[i + 1]);
+
+ /*
+ * There is no description for pc105 on Solaris.
+ * Need to revert to the closest approximation.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Using keyboard model [%s] with layout [%s].\n",
+ model, layout);
+ #endif
+
+ #ifdef __sun
+
+ if (strcmp(model, "pc105") == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: WARNING! Keyboard model 'pc105' unsupported on Solaris.\n");
+
+ fprintf(stderr, "nxagentKeyboardProc: WARNING! Forcing keyboard model to 'pc104'.\n");
+ #endif
+
+ strcpy(model, "pc104");
+ }
+
+ #endif
+ }
+ else
+ {
+ layout = XKB_DFLT_KB_LAYOUT;
+ model = XKB_DFLT_KB_MODEL;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Using default keyboard: model [%s] layout [%s].\n",
+ model, layout);
+ #endif
+ }
+
+ variants = XKB_DFLT_KB_VARIANT;
+ options = XKB_DFLT_KB_OPTIONS;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: XkbInitialMap [%s]\n", XkbInitialMap ? XkbInitialMap : "NULL");
+ #endif
+
+ if (XkbInitialMap) {
+ if ((names.keymap = strchr(XkbInitialMap, '/')) != NULL)
+ ++names.keymap;
+ else
+ names.keymap = XkbInitialMap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Init XKB extension.\n");
+ #endif
+
+ if (XkbQueryExtension(nxagentDisplay,
+ &nxagentXkbInfo.Opcode,
+ &nxagentXkbInfo.EventBase,
+ &nxagentXkbInfo.ErrorBase,
+ &nxagentXkbInfo.MajorVersion,
+ &nxagentXkbInfo.MinorVersion) == 0)
+ {
+ ErrorF("Unable to initialize XKEYBOARD extension.\n");
+
+ goto XkbError;
+ }
+
+ xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+
+ nxagentKeycodeConversionSetup();
+
+ if (xkb == NULL || xkb->geom == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: No current keyboard.\n");
+ if (xkb == NULL)
+ {
+ fprintf(stderr, "nxagentKeyboardProc: xkb is null.\n");
+ }
+ else
+ {
+ fprintf(stderr, "nxagentKeyboardProc: xkb->geom is null.\n");
+ }
+ fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
+ #endif
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device: "
+ "[rules='%s',model='%s',layout='%s',variants='%s',options='%s'].\n",
+ rules, model, layout, variants, options);
+ #endif
+
+ XkbSetRulesDflts(rules, model, layout, variants, options);
+ XkbInitKeyboardDeviceStruct((void *)pDev, &names, &keySyms, modmap,
+ nxagentBell, nxagentChangeKeyboardControl);
+
+ if (!nxagentKeyboard || strcmp(nxagentKeyboard, "query") == 0)
+ {
+ goto XkbError;
+ }
+
+ goto XkbEnd;
+ }
+
+ XkbGetControls(nxagentDisplay, XkbAllControlsMask, xkb);
+
+ if (nxagentX2go)
+ nxagentXkbConfigFilePath = strdup(XKB_CONFIG_FILE_X2GO);
+ else
+ nxagentXkbConfigFilePath = strdup(XKB_CONFIG_FILE_NX);
+
+ if (nxagentXkbConfigFilePath == NULL)
+ {
+ FatalError("nxagentKeyboardProc: malloc failed.");
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: nxagentXkbConfigFilePath [%s].\n",
+ nxagentXkbConfigFilePath);
+ #endif
+
+ if ((file = fopen(nxagentXkbConfigFilePath, "r")) != NULL) {
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Going to parse config file.\n");
+ #endif
+
+ if (XkbCFParse(file, XkbCFDflts, xkb, &config) == 0) {
+ ErrorF("Error parsing config file.\n");
+
+ free(nxagentXkbConfigFilePath);
+
+ fclose(file);
+ goto XkbError;
+ }
+ if (config.rules_file)
+ rules = config.rules_file;
+ if (config.model)
+ {
+ if (free_model)
+ {
+ free_model = 0;
+ free(model);
+ }
+ model = config.model;
+ }
+ if (config.layout)
+ {
+ if (free_layout)
+ {
+ free_layout = 0;
+ free(layout);
+ }
+ layout = config.layout;
+ }
+ if (config.variant)
+ variants = config.variant;
+ if (config.options)
+ options = config.options;
+
+ free(nxagentXkbConfigFilePath);
+
+ fclose(file);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: No config file, going to set rules and init device.\n");
+ #endif
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device: "
+ "[rules='%s',model='%s',layout='%s',variants='%s',options='%s'].\n",
+ rules, model, layout, variants, options);
+ #endif
+
+ XkbSetRulesDflts(rules, model, layout, variants, options);
+ XkbInitKeyboardDeviceStruct((void *)pDev, &names, &keySyms, modmap,
+ nxagentBell, nxagentChangeKeyboardControl);
+
+ free(nxagentXkbConfigFilePath);
+
+ if (!nxagentKeyboard || strcmp(nxagentKeyboard, "query") == 0)
+ {
+ goto XkbError;
+ }
+
+ goto XkbEnd;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
+ #endif
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device: "
+ "[rules='%s',model='%s',layout='%s',variants='%s',options='%s'].\n",
+ rules, model, layout, variants, options);
+ #endif
+
+ XkbSetRulesDflts(rules, model, layout, variants, options);
+ XkbInitKeyboardDeviceStruct((void *)pDev, &names, &keySyms, modmap,
+ nxagentBell, nxagentChangeKeyboardControl);
+ XkbDDXChangeControls((void *)pDev, xkb->ctrls, xkb->ctrls);
+
+XkbEnd:
+
+ if (nxagentOption(Shadow) == 1 && pDev && pDev->key)
+ {
+ NXShadowInitKeymap(&(pDev->key->curKeySyms));
+ }
+
+ if (free_model)
+ {
+ free_model = 0;
+ free(model);
+ }
+
+ if (free_layout)
+ {
+ free_layout = 0;
+ free(layout);
+ }
+
+ XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+ xkb = NULL;
+ }
+#endif
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentKeyboardProc: Watchpoint 10.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#1 U 3 2 80320 bits (10 KB) -> 28621 bits (3 KB) -> 26773/1 -> 9540/1 = 2.806:1
+#98 1 256 bits (0 KB) -> 27 bits (0 KB) -> 256/1 -> 27/1 = 9.481:1
+#101 1 32000 bits (4 KB) -> 2940 bits (0 KB) -> 32000/1 -> 2940/1 = 10.884:1
+#119 1 384 bits (0 KB) -> 126 bits (0 KB) -> 384/1 -> 126/1 = 3.048:1
+*/
+
+ sleep(30);
+
+ #endif
+
+#ifdef _XSERVER64
+ free(keymap);
+#else
+ XFree(keymap);
+#endif
+ break;
+ case DEVICE_ON:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_ON].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentKeyboardProc: Watchpoint 11.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#117 1 320 bits (0 KB) -> 52 bits (0 KB) -> 320/1 -> 52/1 = 6.154:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ nxagentEnableKeyboardEvents();
+
+ break;
+
+ case DEVICE_OFF:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_OFF].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ nxagentDisableKeyboardEvents();
+
+ break;
+
+ case DEVICE_CLOSE:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_CLOSE].\n");
+ #endif
+
+ break;
+ }
+
+ return Success;
+}
+
+Bool LegalModifier(key, pDev)
+ unsigned int key;
+ DevicePtr pDev;
+{
+ return TRUE;
+}
+
+void nxagentNotifyKeyboardChanges(int oldMinKeycode, int oldMaxKeycode)
+{
+ #ifdef XKB
+
+ if (!noXkbExtension)
+ {
+ DeviceIntPtr dev;
+ xkbNewKeyboardNotify nkn;
+
+ dev = inputInfo.keyboard;
+
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.deviceID = nkn.oldDeviceID = dev -> id;
+ nkn.minKeyCode = 8;
+ nkn.maxKeyCode = 255;
+ nkn.oldMinKeyCode = oldMinKeycode;
+ nkn.oldMaxKeyCode = oldMaxKeycode;
+ nkn.requestMajor = XkbReqCode;
+ nkn.requestMinor = X_kbGetKbdByName;
+ nkn.changed = XkbNKN_KeycodesMask;
+
+ XkbSendNewKeyboardNotify(dev, &nkn);
+ }
+ else
+ {
+
+ #endif
+
+ int i;
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MappingNotify;
+ event.u.mappingNotify.request = MappingKeyboard;
+ event.u.mappingNotify.firstKeyCode = inputInfo.keyboard -> key -> curKeySyms.minKeyCode;
+ event.u.mappingNotify.count = inputInfo.keyboard -> key -> curKeySyms.maxKeyCode -
+ inputInfo.keyboard -> key -> curKeySyms.minKeyCode;
+
+ /*
+ * 0 is the server client
+ */
+
+ for (i = 1; i < currentMaxClients; i++)
+ {
+ if (clients[i] && clients[i] -> clientState == ClientStateRunning)
+ {
+ event.u.u.sequenceNumber = clients[i] -> sequence;
+ WriteEventsToClient(clients[i], 1, &event);
+ }
+ }
+
+ #ifdef XKB
+
+ }
+
+ #endif
+
+}
+
+int nxagentResetKeyboard(void)
+{
+ DeviceIntPtr dev = inputInfo.keyboard;
+ DeviceIntPtr devBackup;
+
+ int result;
+ int oldMinKeycode = 8;
+ int oldMaxKeycode = 255;
+
+ int savedBellPercent;
+ int savedBellPitch;
+ int savedBellDuration;
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return 0;
+ }
+
+ /*
+ * Save bell settings.
+ */
+
+ savedBellPercent = inputInfo.keyboard -> kbdfeed -> ctrl.bell;
+ savedBellPitch = inputInfo.keyboard -> kbdfeed -> ctrl.bell_pitch;
+ savedBellDuration = inputInfo.keyboard -> kbdfeed -> ctrl.bell_duration;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetKeyboard: bellPercent [%d] bellPitch [%d] bellDuration [%d].\n",
+ savedBellPercent, savedBellPitch, savedBellDuration);
+ #endif
+
+ devBackup = malloc(sizeof(DeviceIntRec));
+
+ if (devBackup == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentSaveKeyboardDeviceData: PANIC! Can't allocate backup structure.\n");
+ #endif
+ }
+ else
+ {
+ memset(devBackup, 0, sizeof(DeviceIntRec));
+ }
+
+ nxagentSaveKeyboardDeviceData(dev, devBackup);
+
+ if (dev->key)
+ {
+ #ifdef XKB
+ if (noXkbExtension == 0 && dev->key->xkbInfo)
+ {
+ oldMinKeycode = dev->key->xkbInfo -> desc -> min_key_code;
+ oldMaxKeycode = dev->key->xkbInfo -> desc -> max_key_code;
+ }
+ #endif
+
+ dev->key=NULL;
+ }
+
+ dev->focus=NULL;
+
+ dev->kbdfeed=NULL;
+
+ #ifdef XKB
+ nxagentTuneXkbWrapper();
+ #endif
+
+ result = (*inputInfo.keyboard -> deviceProc)(inputInfo.keyboard, DEVICE_INIT);
+
+ if (result == Success && inputInfo.keyboard -> key != NULL)
+ {
+
+ /*
+ * Restore bell settings.
+ */
+
+ inputInfo.keyboard -> kbdfeed -> ctrl.bell = savedBellPercent;
+ inputInfo.keyboard -> kbdfeed -> ctrl.bell_pitch = savedBellPitch;
+ inputInfo.keyboard -> kbdfeed -> ctrl.bell_duration = savedBellDuration;
+
+ nxagentNotifyKeyboardChanges(oldMinKeycode, oldMaxKeycode);
+
+ nxagentFreeKeyboardDeviceData(devBackup);
+
+ free(devBackup);
+
+ return 1;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentResetKeyboard: Can't initialize the keyboard device.\n");
+ #endif
+
+ nxagentRestoreKeyboardDeviceData(devBackup, dev);
+
+ return 0;
+ }
+}
+
+void nxagentCheckModifierMasks(CARD8 keycode, int j)
+{
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_L))
+ {
+ nxagentAltMetaMask |= 1 << j;
+ nxagentMetaMask |= 1 << j;
+ }
+
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_R))
+ {
+ nxagentAltMetaMask |= 1 << j;
+ nxagentMetaMask |= 1 << j;
+ }
+
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_L))
+ {
+ nxagentAltMetaMask |= 1 << j;
+ nxagentAltMask |= 1 << j;
+ }
+
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_R))
+ {
+ nxagentAltMetaMask |= 1 << j;
+ nxagentAltMask |= 1 << j;
+ }
+
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Num_Lock))
+ {
+ nxagentNumlockMask |= 1 << j;
+ }
+
+ if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Caps_Lock) ||
+ keycode == XKeysymToKeycode(nxagentDisplay, XK_Shift_Lock) )
+ {
+ nxagentCapsMask |= 1 << j;
+ }
+
+}
+
+void nxagentCheckRemoteKeycodes()
+{
+ nxagentCapsLockKeycode = XKeysymToKeycode(nxagentDisplay, XK_Caps_Lock);
+
+ nxagentNumLockKeycode = XKeysymToKeycode(nxagentDisplay, XK_Num_Lock);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCheckRemoteKeycodes: Remote keycodes: CapsLock "
+ "[%d] NumLock [%d].\n", nxagentCapsLockKeycode,
+ nxagentNumLockKeycode);
+ #endif
+}
+
+static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup)
+{
+ if (devBackup == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentSaveKeyboardDeviceData: PANIC! Pointer to backup structure is null.\n");
+ #endif
+
+ return -1;
+ }
+
+ devBackup -> key = dev -> key;
+
+ devBackup -> focus = dev -> focus;
+
+ devBackup -> kbdfeed = dev -> kbdfeed;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentSaveKeyboardDeviceData: Saved device data.\n");
+ #endif
+
+ return 1;
+}
+
+static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev)
+{
+ if (devBackup == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentRestoreKeyboardDeviceData: PANIC! Pointer to backup structure is null.\n");
+ #endif
+
+ return -1;
+ }
+
+ dev -> key = devBackup -> key;
+
+ dev -> focus = devBackup -> focus;
+
+ dev -> kbdfeed = devBackup -> kbdfeed;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRestoreKeyboardDeviceData: Restored device data.\n");
+ #endif
+
+ return 1;
+}
+
+
+static int nxagentFreeKeyboardDeviceData(DeviceIntPtr dev)
+{
+ KbdFeedbackPtr k, knext;
+
+ if (dev == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentFreeKeyboardDeviceData: PANIC! Pointer to device structure is null.\n");
+ #endif
+
+ return -1;
+ }
+
+ if (dev->key)
+ {
+ #ifdef XKB
+ if (noXkbExtension == 0 && dev->key->xkbInfo)
+ {
+ XkbFreeInfo(dev->key->xkbInfo);
+ dev->key->xkbInfo = NULL;
+ }
+ #endif
+
+ free(dev->key->curKeySyms.map);
+ free(dev->key->modifierKeyMap);
+ free(dev->key);
+
+ dev->key=NULL;
+ }
+
+ if (dev->focus)
+ {
+ free(dev->focus->trace);
+ free(dev->focus);
+ dev->focus=NULL;
+ }
+
+ for (k = dev->kbdfeed; k; k = knext)
+ {
+ knext = k->next;
+ #ifdef XKB
+ if (k->xkb_sli)
+ XkbFreeSrvLedInfo(k->xkb_sli);
+ #endif
+ free(k);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentFreeKeyboardDeviceData: Freed device data.\n");
+ #endif
+
+ return 1;
+}
+
+#if XKB
+
+int ProcXkbInhibited(register ClientPtr client)
+{
+ unsigned char majorop;
+ unsigned char minorop;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXkbInhibited: Called.\n");
+ #endif
+
+ majorop = ((xReq *)client->requestBuffer)->reqType;
+
+ #ifdef PANIC
+ if (majorop != (unsigned char)nxagentXkbWrapper.base)
+ {
+ fprintf(stderr, "ProcXkbInhibited: MAJOROP is [%d] but should be [%d].\n",
+ majorop, nxagentXkbWrapper.base);
+ }
+ #endif
+
+ minorop = *((unsigned char *) client->requestBuffer + 1);
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXkbInhibited: MAJOROP is [%d] MINOROP is [%d].\n",
+ majorop, minorop);
+ #endif
+
+ switch (minorop)
+ {
+ case X_kbLatchLockState:
+ case X_kbSetControls:
+ case X_kbSetCompatMap:
+ case X_kbSetIndicatorMap:
+ case X_kbSetNamedIndicator:
+ case X_kbSetNames:
+ case X_kbSetGeometry:
+ case X_kbSetDebuggingFlags:
+ case X_kbSetMap:
+ {
+ return client->noClientException;
+ }
+ case X_kbGetKbdByName:
+ {
+ return BadAccess;
+ }
+ default:
+ {
+ return (client->swapped ? nxagentXkbWrapper.SProcXkbDispatchBackup(client) :
+ nxagentXkbWrapper.ProcXkbDispatchBackup(client));
+ }
+ }
+}
+
+void nxagentInitXkbWrapper(void)
+{
+ ExtensionEntry * extension;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitXkbWrapper: Called.\n");
+ #endif
+
+ if (nxagentOption(InhibitXkb) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitXkbWrapper: Nothing to do.\n");
+ #endif
+
+ return;
+ }
+
+ memset(&nxagentXkbWrapper, 0, sizeof(XkbWrapperRec));
+
+ extension = CheckExtension("XKEYBOARD");
+
+ if (extension != NULL)
+ {
+ nxagentXkbWrapper.base = extension -> base;
+ nxagentXkbWrapper.eventBase = extension -> eventBase;
+ nxagentXkbWrapper.errorBase = extension -> errorBase;
+ nxagentXkbWrapper.ProcXkbDispatchBackup = NULL;
+ nxagentXkbWrapper.SProcXkbDispatchBackup = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitXkbWrapper: base [%d] eventBase [%d] errorBase [%d].\n",
+ extension -> base, extension -> eventBase, extension -> errorBase);
+ #endif
+ }
+ else
+ {
+ nxagentXkbWrapper.base = -1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitXkbWrapper: XKEYBOARD extension not found.\n");
+ #endif
+ }
+}
+
+void nxagentDisableXkbExtension(void)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisableXkbExtension: Called.\n");
+ #endif
+
+ if (nxagentXkbWrapper.base > 0)
+ {
+ if (nxagentXkbWrapper.ProcXkbDispatchBackup == NULL)
+ {
+ nxagentXkbWrapper.ProcXkbDispatchBackup = ProcVector[nxagentXkbWrapper.base];
+
+ ProcVector[nxagentXkbWrapper.base] = ProcXkbInhibited;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentDisableXkbExtension: Nothing to be done for ProcXkbDispatch.\n");
+ }
+ #endif
+
+ if (nxagentXkbWrapper.SProcXkbDispatchBackup == NULL)
+ {
+ nxagentXkbWrapper.SProcXkbDispatchBackup = SwappedProcVector[nxagentXkbWrapper.base];
+
+ SwappedProcVector[nxagentXkbWrapper.base] = ProcXkbInhibited;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentDisableXkbExtension: Nothing to be done for SProcXkbDispatch.\n");
+ }
+ #endif
+ }
+}
+
+void nxagentEnableXkbExtension(void)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentEnableXkbExtension: Called.\n");
+ #endif
+
+ if (nxagentXkbWrapper.base > 0)
+ {
+ if (nxagentXkbWrapper.ProcXkbDispatchBackup != NULL)
+ {
+ ProcVector[nxagentXkbWrapper.base] = nxagentXkbWrapper.ProcXkbDispatchBackup;
+
+ nxagentXkbWrapper.ProcXkbDispatchBackup = NULL;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentEnableXkbExtension: Nothing to be done for ProcXkbDispatch.\n");
+ }
+ #endif
+
+ if (nxagentXkbWrapper.SProcXkbDispatchBackup != NULL)
+ {
+ SwappedProcVector[nxagentXkbWrapper.base] = nxagentXkbWrapper.SProcXkbDispatchBackup;
+
+ nxagentXkbWrapper.SProcXkbDispatchBackup = NULL;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentEnableXkbExtension: Nothing to be done for SProcXkbDispatch.\n");
+ }
+ #endif
+ }
+}
+
+void nxagentTuneXkbWrapper(void)
+{
+ if (nxagentOption(InhibitXkb) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTuneXkbWrapper: Nothing to do.\n");
+ #endif
+
+ return;
+ }
+
+ if (nxagentKeyboard != NULL &&
+ strcmp(nxagentKeyboard, "query") == 0)
+ {
+ nxagentDisableXkbExtension();
+ }
+ else
+ {
+ nxagentEnableXkbExtension();
+ }
+}
+
+static int nxagentXkbGetNames(char **rules, char **model, char **layout,
+ char **variant, char **options)
+{
+ Atom atom;
+ #ifdef _XSERVER64
+ Atom64 type;
+ #else
+ Atom type;
+ #endif
+ int format;
+ unsigned long n;
+ unsigned long after;
+ char *data;
+ char *name;
+ Status result;
+
+ data = name = NULL;
+
+ *rules = NULL;
+ *model = NULL;
+ *layout = NULL;
+ *variant = NULL;
+ *options = NULL;
+
+ atom = XInternAtom(nxagentDisplay, "_XKB_RULES_NAMES", 1);
+
+ if (atom == 0)
+ {
+ return 0;
+ }
+
+ result = XGetWindowProperty(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ atom, 0, 256, 0, XA_STRING, &type, &format,
+ &n, &after, (unsigned char **)&data);
+
+ if (result !=Success || data == NULL)
+ {
+ return 0;
+ }
+
+ if ((after > 0) || (type != XA_STRING) || (format != 8))
+ {
+ if (data != NULL)
+ {
+ XFree(data);
+ return 0;
+ }
+ }
+
+ name = data;
+
+ if (name < data + n)
+ {
+ *rules = name;
+ name += strlen(name) + 1;
+ }
+
+ if (name < data + n)
+ {
+ *model = name;
+ name += strlen(name) + 1;
+ }
+
+ if (name < data + n)
+ {
+ *layout = name;
+ name += strlen(name) + 1;
+ }
+
+ if (name < data + n)
+ {
+ *variant = name;
+ name += strlen(name) + 1;
+ }
+
+ if (name < data + n)
+ {
+ *options = name;
+ name += strlen(name) + 1;
+ }
+
+ return n;
+}
+
+void nxagentKeycodeConversionSetup(void)
+{
+ char *drules = NULL;
+ char *dmodel = NULL;
+ char *dlayout = NULL;
+ char *dvariant = NULL;
+ char *doptions = NULL;
+ unsigned int drulesLen;
+
+ nxagentKeycodeConversion = 0;
+
+ drulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
+ &dvariant, &doptions);
+
+ #ifdef DEBUG
+ if (drulesLen != 0 && drules != NULL && dmodel != NULL)
+ {
+ fprintf(stderr, "nxagentKeycodeConversionSetup: "
+ "Remote: [rules='%s',model='%s',layout='%s',variant='%s',options='%s'].\n",
+ drules, dmodel, dlayout, dvariant, doptions);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentKeycodeConversionSetup: "
+ "Failed to retrieve remote rules.\n");
+ }
+ #endif
+
+ if (drulesLen != 0)
+ {
+ char *sessionpath = nxagentGetSessionPath();
+ if (sessionpath != NULL)
+ {
+ int keyboard_file_path_size = strlen(sessionpath) + strlen("/keyboard");
+ char *keyboard_file_path = malloc((keyboard_file_path_size + 1) * sizeof(char));
+ FILE *keyboard_file;
+ if (keyboard_file_path == NULL)
+ {
+ FatalError("nxagentKeycodeConversionSetup: malloc failed.");
+ }
+ strcpy(keyboard_file_path, sessionpath);
+ strcat(keyboard_file_path, "/keyboard");
+ if ((keyboard_file = fopen(keyboard_file_path, "w")) != NULL) {
+ if (drules != NULL)
+ fprintf(keyboard_file, "rules=\"%s\"\n", drules[0] == '\0' ? "," : drules);
+ if (dmodel != NULL)
+ fprintf(keyboard_file, "model=\"%s\"\n", dmodel[0] == '\0' ? "," : dmodel);
+ if (dlayout != NULL)
+ fprintf(keyboard_file, "layout=\"%s\"\n", dlayout[0] == '\0' ? "," : dlayout);
+ if (dvariant != NULL)
+ fprintf(keyboard_file, "variant=\"%s\"\n", dvariant[0] == '\0' ? "," : dvariant);
+ if (doptions != NULL)
+ fprintf(keyboard_file, "options=\"%s\"\n", doptions[0] == '\0' ? "," : doptions);
+ fclose(keyboard_file);
+ fprintf(stderr, "keyboard file created\n");
+ }
+ else
+ {
+ int save_err = errno;
+ fprintf(stderr, "keyboard file not created: %s\n", strerror(save_err));
+ }
+ free(keyboard_file_path);
+ }
+ else
+ {
+ fprintf(stderr, "SessionPath not defined\n");
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Failed to create the keyboard file\n");
+ }
+
+ if (drules != NULL && dmodel != NULL &&
+ (strcmp(drules, "evdev") == 0 ||
+ strcmp(dmodel, "evdev") == 0))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentKeycodeConversionSetup: "
+ "Activating KeyCode conversion.\n");
+ #endif
+
+ nxagentKeycodeConversion = 1;
+ }
+
+ if (drules != NULL)
+ {
+ XFree(drules);
+ }
+}
+
+void nxagentResetKeycodeConversion(void)
+{
+ int result;
+ XkbAgentInfoRec info;
+
+ result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
+ &info.ErrorBase, &info.MajorVersion,
+ &info.MinorVersion);
+
+ if (result != 0)
+ {
+ nxagentKeycodeConversionSetup();
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentResetKeycodeConversion: "
+ "WARNING! Failed to query XKB extension.\n");
+ #endif
+
+ nxagentKeycodeConversion = 0;
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
new file mode 100644
index 000000000..ba95a3a22
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -0,0 +1,135 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Keyboard_H__
+#define __Keyboard_H__
+
+#define NXAGENT_KEYBOARD_EVENT_MASK \
+ (KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask)
+
+#define NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK \
+ (XkbStateNotifyMask)
+
+/*
+ * Queried at XKB initialization.
+ */
+
+typedef struct _XkbAgentInfo
+{
+ int Opcode;
+ int EventBase;
+ int ErrorBase;
+ int MajorVersion;
+ int MinorVersion;
+
+} XkbAgentInfoRec;
+
+extern XkbAgentInfoRec nxagentXkbInfo;
+
+typedef struct _XkbAgentState
+{
+ int Locked;
+ int Caps;
+ int Num;
+ int Focus;
+ int Initialized;
+
+} XkbAgentStateRec;
+
+extern XkbAgentStateRec nxagentXkbState;
+
+/*
+ * Info for enabling/disabling Xkb.
+ */
+
+typedef struct _XkbWrapper
+{
+ int base;
+ int eventBase;
+ int errorBase;
+ int (* ProcXkbDispatchBackup)(ClientPtr);
+ int (* SProcXkbDispatchBackup)(ClientPtr);
+
+} XkbWrapperRec;
+
+extern XkbWrapperRec nxagentXkbWrapper;
+
+extern char *nxagentKeyboard;
+
+/*
+ * Keyboard device procedure
+ * and utility functions.
+ */
+
+void nxagentBell(int volume, DeviceIntPtr pDev, void * ctrl, int cls);
+
+int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff);
+
+void nxagentChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl);
+
+void nxagentNotifyKeyboardChanges(int oldMinKeycode, int oldMaxKeycode);
+
+int nxagentResetKeyboard(void);
+
+#ifdef XKB
+
+void nxagentInitXkbWrapper(void);
+
+void nxagentDisableXkbExtension(void);
+
+void nxagentEnableXkbExtension(void);
+
+void nxagentTuneXkbWrapper(void);
+
+void nxagentResetKeycodeConversion(void);
+
+#endif
+
+CARD8 nxagentConvertKeycode(CARD8 k);
+
+extern CARD8 nxagentCapsLockKeycode;
+extern CARD8 nxagentNumLockKeycode;
+
+extern unsigned int nxagentAltMetaMask;
+extern unsigned int nxagentAltMask;
+extern unsigned int nxagentMetaMask;
+extern unsigned int nxagentCapsMask;
+extern unsigned int nxagentNumlockMask;
+
+#endif /* __Keyboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
new file mode 100644
index 000000000..1e3ebca8f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -0,0 +1,662 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "X.h"
+#include "keysym.h"
+
+#include "screenint.h"
+#include "scrnintstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Events.h"
+#include "Options.h"
+#include "Keyboard.h"
+#include "Drawable.h"
+#include "Init.h" /* extern int nxagentX2go */
+#include "Utils.h"
+
+#include <unistd.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentIpaq;
+extern char *nxagentKeystrokeFile;
+
+#ifdef NX_DEBUG_INPUT
+int nxagentDebugInputDevices = False;
+unsigned long nxagentLastInputDevicesDumpTime = 0;
+extern void nxagentDeactivateInputDevicesGrabs();
+#endif
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/* must be included _after_ DUMP */
+#include "Keystroke.h"
+
+
+/* this table is used to parse actions given on the command line or in the
+ * config file, therefore indices have to match the enum in Keystroke.h */
+char * nxagentSpecialKeystrokeNames[] = {
+ "end_marker",
+ "close_session",
+ "switch_all_screens",
+ "fullscreen",
+ "minimize",
+ "defer",
+ "ignore",
+ "force_synchronization",
+
+#ifdef DEBUG_TREE
+ "debug_tree",
+#endif
+#ifdef DUMP
+ "regions_on_screen",
+#endif
+#ifdef NX_DEBUG_INPUT
+ "test_input",
+ "deactivate_input_devices_grab",
+#endif
+ "resize",
+ "viewport_move_left",
+ "viewport_move_up",
+ "viewport_move_right",
+ "viewport_move_down",
+ "viewport_scroll_left",
+ "viewport_scroll_up",
+ "viewport_scroll_right",
+ "viewport_scroll_down",
+
+ "reread_keystrokes",
+ NULL,
+};
+
+struct nxagentSpecialKeystrokeMap default_map[] = {
+ /* stroke, modifierMask, modifierAltMeta, keysym */
+#ifdef DEBUG_TREE
+ {KEYSTROKE_DEBUG_TREE, ControlMask, True, XK_q},
+#endif
+ {KEYSTROKE_CLOSE_SESSION, ControlMask, True, XK_t},
+ {KEYSTROKE_SWITCH_ALL_SCREENS, ControlMask, True, XK_f},
+ {KEYSTROKE_FULLSCREEN, ControlMask | ShiftMask, True, XK_f},
+ {KEYSTROKE_MINIMIZE, ControlMask, True, XK_m},
+ {KEYSTROKE_DEFER, ControlMask, True, XK_e},
+ {KEYSTROKE_IGNORE, ControlMask, True, XK_BackSpace},
+ {KEYSTROKE_IGNORE, 0, False, XK_Terminate_Server},
+ {KEYSTROKE_FORCE_SYNCHRONIZATION, ControlMask, True, XK_j},
+#ifdef DUMP
+ {KEYSTROKE_REGIONS_ON_SCREEN, ControlMask, True, XK_a},
+#endif
+#ifdef NX_DEBUG_INPUT
+ {KEYSTROKE_TEST_INPUT, ControlMask, True, XK_x},
+ {KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB, ControlMask, True, XK_y},
+#endif
+ {KEYSTROKE_RESIZE, ControlMask, True, XK_r},
+ {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_Left},
+ {KEYSTROKE_VIEWPORT_MOVE_LEFT, ControlMask | ShiftMask, True, XK_KP_Left},
+ {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, True, XK_Up},
+ {KEYSTROKE_VIEWPORT_MOVE_UP, ControlMask | ShiftMask, True, XK_KP_Up},
+ {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, True, XK_Right},
+ {KEYSTROKE_VIEWPORT_MOVE_RIGHT, ControlMask | ShiftMask, True, XK_KP_Right},
+ {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_Down},
+ {KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_KP_Down},
+ {KEYSTROKE_VIEWPORT_SCROLL_LEFT, ControlMask, True, XK_Left},
+ {KEYSTROKE_VIEWPORT_SCROLL_LEFT, ControlMask, True, XK_KP_Left},
+ {KEYSTROKE_VIEWPORT_SCROLL_UP, ControlMask, True, XK_Up},
+ {KEYSTROKE_VIEWPORT_SCROLL_UP, ControlMask, True, XK_KP_Up},
+ {KEYSTROKE_VIEWPORT_SCROLL_RIGHT, ControlMask, True, XK_Right},
+ {KEYSTROKE_VIEWPORT_SCROLL_RIGHT, ControlMask, True, XK_KP_Right},
+ {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_Down},
+ {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
+ {KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
+ {KEYSTROKE_END_MARKER, 0, False, NoSymbol},
+};
+struct nxagentSpecialKeystrokeMap *map = default_map;
+
+static Bool modifier_matches(unsigned int mask, int compare_alt_meta, unsigned int state)
+{
+ /* nxagentAltMetaMask needs special handling
+ * it seems to me its an and-ed mask of all possible meta and alt keys
+ * somehow...
+ *
+ * otherwise this function would be just a simple bitop
+ */
+ Bool ret = True;
+
+ if (compare_alt_meta) {
+ if (! (state & nxagentAltMetaMask)) {
+ ret = False;
+ }
+
+ mask &= ~nxagentAltMetaMask;
+ state &= ~nxagentAltMetaMask;
+ }
+
+ /* ignore CapsLock and/or Numlock if the keystroke does not
+ explicitly require them */
+
+ if ( !(mask & nxagentCapsMask) )
+ state &= ~nxagentCapsMask;
+
+ if ( !(mask & nxagentNumlockMask) )
+ state &= ~nxagentNumlockMask;
+
+ /* all modifiers except meta/alt have to match exactly, extra bits are evil */
+ if (mask != state) {
+ ret = False;
+ }
+
+ return ret;
+}
+
+static Bool read_binding_from_xmlnode(xmlNode *node, struct nxagentSpecialKeystrokeMap *ret)
+{
+ /* init the struct to have proper values in case not all attributes are found */
+ struct nxagentSpecialKeystrokeMap newkm = {
+ .stroke = KEYSTROKE_NOTHING,
+ .modifierMask = 0,
+ .modifierAltMeta = False,
+ .keysym = NoSymbol
+ };
+
+ for (xmlAttr *attr = node->properties; attr; attr = attr->next)
+ {
+ /* ignore attributes without data (which should never happen anyways) */
+ if (attr->children->content == NULL)
+ {
+ #ifdef DEBUG
+ char *aname = (attr->name)?((char *)attr->name):"unknown";
+ fprintf(stderr, "attribute %s with NULL value", aname);
+ #endif
+ continue;
+ }
+
+ if (strcmp((char *)attr->name, "action") == 0)
+ {
+ newkm.stroke = KEYSTROKE_NOTHING;
+ for (int i = 0; nxagentSpecialKeystrokeNames[i] != NULL; i++)
+ {
+ if (strcmp(nxagentSpecialKeystrokeNames[i], (char *)attr->children->content) == 0)
+ {
+ /* this relies on the values of enum nxagentSpecialKeystroke and the
+ * indices of nxagentSpecialKeystrokeNames being in sync */
+ newkm.stroke = i;
+ break;
+ }
+ }
+ if (newkm.stroke == KEYSTROKE_NOTHING)
+ fprintf(stderr, "Info: ignoring unknown keystroke action '%s'.\n", (char *)attr->children->content);
+ continue;
+ }
+ else if (strcmp((char *)attr->name, "key") == 0)
+ {
+ newkm.keysym = XStringToKeysym((char *)attr->children->content);
+ continue;
+ }
+ else
+ {
+ /* ignore attributes with value="0" or "false", everything else is interpreted as true */
+ if (strcmp((char *)attr->children->content, "0") == 0 || strcmp((char *)attr->children->content, "false") == 0)
+ continue;
+
+ if (strcmp((char *)attr->name, "Mod1") == 0) { newkm.modifierMask |= Mod1Mask; }
+ else if (strcmp((char *)attr->name, "Mod2") == 0) { newkm.modifierMask |= Mod2Mask; }
+ else if (strcmp((char *)attr->name, "Mod3") == 0) { newkm.modifierMask |= Mod3Mask; }
+ else if (strcmp((char *)attr->name, "Mod4") == 0) { newkm.modifierMask |= Mod4Mask; }
+ else if (strcmp((char *)attr->name, "Mod5") == 0) { newkm.modifierMask |= Mod5Mask; }
+ else if (strcmp((char *)attr->name, "Control") == 0) { newkm.modifierMask |= ControlMask; }
+ else if (strcmp((char *)attr->name, "Shift") == 0) { newkm.modifierMask |= ShiftMask; }
+ else if (strcmp((char *)attr->name, "Lock") == 0) { newkm.modifierMask |= LockMask; }
+ else if (strcmp((char *)attr->name, "AltMeta") == 0) { newkm.modifierAltMeta = True; }
+ }
+ }
+
+ if (newkm.stroke != KEYSTROKE_NOTHING && newkm.keysym != NoSymbol)
+ {
+ /* keysym and stroke are required, everything else is optional */
+ memcpy(ret, &newkm, sizeof(struct nxagentSpecialKeystrokeMap));
+ return True;
+ }
+ else
+ return False;
+}
+
+/*
+ * searches a keystroke xml file
+ *
+ * search order:
+ * - '-keystrokefile' commandline parameter
+ * - $NXAGENT_KEYSTROKEFILE environment variable
+ * - $HOME/.nx/config/keystrokes.cfg
+ * - /etc/nxagent/keystrokes.cfg
+ * - hardcoded traditional NX default settings
+ * If run in x2go flavour different filenames and varnames are used.
+ */
+void nxagentInitKeystrokes(Bool force)
+{
+ char *filename = NULL;
+
+ char *homefile;
+ char *etcfile;
+ char *envvar;
+
+ /* used for tracking if the config file parsing has already been
+ done (regardless of the result) */
+ static Bool done = False;
+
+ if (force) {
+ if (map != default_map)
+ {
+ free(map);
+ map = default_map;
+ }
+ fprintf(stderr, "Info: re-reading keystrokes configuration\n");
+ }
+ else
+ {
+ if (done)
+ return;
+ }
+
+ done = True;
+
+ if (nxagentX2go) {
+ homefile = "/.x2go/config/keystrokes.cfg";
+ etcfile = "/etc/x2go/keystrokes.cfg";
+ envvar = "X2GO_KEYSTROKEFILE";
+ } else {
+ homefile = "/.nx/config/keystrokes.cfg";
+ etcfile = "/etc/nxagent/keystrokes.cfg";
+ envvar = "NXAGENT_KEYSTROKEFILE";
+ }
+
+ if (nxagentKeystrokeFile && access(nxagentKeystrokeFile, R_OK) == 0)
+ {
+ if (!(filename = strdup(nxagentKeystrokeFile)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else if (nxagentKeystrokeFile)
+ {
+ fprintf(stderr, "Warning: Cannot read keystroke file '%s'.\n", nxagentKeystrokeFile);
+ if ((filename = getenv(envvar)) && access(filename, R_OK) == 0)
+ {
+ if (!(filename = strdup(filename)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ char *homedir = getenv("HOME");
+ filename = NULL;
+ if (homedir)
+ {
+ if (!(filename = calloc(1, strlen(homefile) + strlen(homedir) + 1)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ strcpy(filename, homedir);
+ strcpy(filename + strlen(homedir), homefile);
+ }
+
+ if (access(filename, R_OK) == 0)
+ {
+ /* empty */
+ }
+ else if (access(etcfile, R_OK) == 0)
+ {
+ free(filename);
+ if (!(filename = strdup(etcfile)))
+ {
+ fprintf(stderr, "malloc failed");
+ exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ free(filename);
+ filename = NULL;
+ }
+ }
+ }
+
+ /* now we know which file to read, if any */
+ if (filename)
+ {
+ LIBXML_TEST_VERSION
+ xmlDoc *doc = xmlReadFile(filename, NULL, 0);
+ if (doc)
+ {
+ fprintf(stderr, "Info: using keystrokes file '%s'\n", filename);
+ for (xmlNode *cur = xmlDocGetRootElement(doc); cur; cur = cur->next)
+ {
+ if (cur->type == XML_ELEMENT_NODE && strcmp((char *)cur->name, "keystrokes") == 0)
+ {
+ xmlNode *bindings;
+ int num = 0;
+ int idx = 0;
+
+ for (bindings = cur->children; bindings; bindings = bindings->next)
+ {
+ if (bindings->type == XML_ELEMENT_NODE && strcmp((char *)bindings->name, "keystroke") == 0)
+ {
+ num++;
+ }
+ }
+ #ifdef DEBUG
+ fprintf(stderr, "%s: found %d keystrokes in %s\n", __func__, num, filename);
+ #endif
+ if (!(map = calloc(num+1, sizeof(struct nxagentSpecialKeystrokeMap))))
+ {
+ fprintf(stderr, "calloc failed");
+ exit(EXIT_FAILURE);
+ }
+
+ for (bindings = cur->children; bindings; bindings = bindings->next)
+ {
+ map[idx].stroke = KEYSTROKE_NOTHING;
+ if (bindings->type == XML_ELEMENT_NODE &&
+ strcmp((char *)bindings->name, "keystroke") == 0 &&
+ read_binding_from_xmlnode(bindings, &(map[idx])))
+ {
+ Bool store = True;
+ for (int j = 0; j < idx; j++)
+ {
+ if (map[j].stroke != KEYSTROKE_NOTHING &&
+ map[idx].keysym != NoSymbol &&
+ map[j].keysym == map[idx].keysym &&
+ map[j].modifierMask == map[idx].modifierMask &&
+ map[j].modifierAltMeta == map[idx].modifierAltMeta)
+ {
+ fprintf(stderr, "Warning: ignoring keystroke '%s' (already in use by '%s')\n",
+ nxagentSpecialKeystrokeNames[map[idx].stroke],
+ nxagentSpecialKeystrokeNames[map[j].stroke]);
+ store = False;
+ break;
+ }
+ }
+
+ if (store)
+ idx++;
+ else
+ map[idx].stroke = KEYSTROKE_NOTHING;
+ }
+ }
+ #ifdef DEBUG
+ fprintf(stderr, "%s: read %d keystrokes", __func__, idx);
+ #endif
+
+ map[idx].stroke = KEYSTROKE_END_MARKER;
+ }
+ }
+
+ xmlFreeDoc(doc);
+ xmlCleanupParser();
+ }
+ else
+ {
+ fprintf(stderr, "Warning: could not read/parse keystrokes file '%s'\n", filename);
+ }
+ free(filename);
+ filename = NULL;
+ }
+
+ if (map == default_map)
+ {
+ fprintf(stderr, "Info: Using builtin keystrokes.\n");
+ }
+
+ nxagentDumpKeystrokes();
+}
+
+void nxagentDumpKeystrokes(void)
+{
+ int maxlen = 0;
+ for (int i = 0; nxagentSpecialKeystrokeNames[i]; i++)
+ maxlen = MAX(maxlen, strlen(nxagentSpecialKeystrokeNames[i]));
+
+ fprintf(stderr, "Current known keystrokes:\n");
+
+ for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) {
+ unsigned int mask = cur->modifierMask;
+ fprintf(stderr, " %-*s ", maxlen, nxagentSpecialKeystrokeNames[cur->stroke]);
+ if (mask & ControlMask) {fprintf(stderr, "Ctrl+"); mask &= ~ControlMask;}
+ if (mask & ShiftMask) {fprintf(stderr, "Shift+"); mask &= ~ShiftMask;}
+
+ /* these are only here for better readable modifier
+ names. Normally they are covered by the Mod<n> and Lock lines
+ below */
+ if (cur->modifierAltMeta) {fprintf(stderr, "Alt+"); mask &= ~(cur->modifierAltMeta);}
+ if (mask & nxagentCapsMask) {fprintf(stderr, "CapsLock+"); mask &= ~nxagentCapsMask;}
+ if (mask & nxagentNumlockMask) {fprintf(stderr, "NumLock+"); mask &= ~nxagentNumlockMask;}
+
+ if (mask & Mod1Mask) {fprintf(stderr, "Mod1+"); mask &= ~Mod1Mask;}
+ if (mask & Mod2Mask) {fprintf(stderr, "Mod2+"); mask &= ~Mod2Mask;}
+ if (mask & Mod3Mask) {fprintf(stderr, "Mod3+"); mask &= ~Mod3Mask;}
+ if (mask & Mod4Mask) {fprintf(stderr, "Mod4+"); mask &= ~Mod4Mask;}
+ if (mask & Mod5Mask) {fprintf(stderr, "Mod5+"); mask &= ~Mod5Mask;}
+ if (mask & LockMask) {fprintf(stderr, "Lock+"); mask &= ~LockMask;}
+ fprintf(stderr, "%s\n", XKeysymToString(cur->keysym));
+ }
+}
+
+static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
+{
+ enum nxagentSpecialKeystroke ret = KEYSTROKE_NOTHING;
+
+ KeySym keysym = XKeycodeToKeysym(nxagentDisplay, X->keycode, 0);
+
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: got keysym '%c' (%d)\n", __func__, keysym, keysym);
+ #endif
+ for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: checking keysym '%c' (%d)\n", __func__, cur->keysym, cur->keysym);
+ #endif
+ if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: match including modifiers for keysym '%c' (%d), stroke %d (%s)\n", __func__, cur->keysym, cur->keysym, cur->stroke, nxagentSpecialKeystrokeNames[cur->stroke]);
+ #endif
+ return cur->stroke;
+ }
+ }
+
+ return ret;
+}
+
+Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
+{
+ enum nxagentSpecialKeystroke stroke = find_keystroke(X);
+ *result = doNothing;
+
+ #ifdef TEST
+ if (stroke != KEYSTROKE_NOTHING && stroke != KEYSTROKE_END_MARKER)
+ fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - stroke %d (%s)\n",
+ X -> keycode, X -> state, stroke, nxagentSpecialKeystrokeNames[stroke]);
+ else
+ fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - stroke %d (unused)\n",
+ X -> keycode, X -> state, stroke);
+ #endif
+
+ if (stroke == KEYSTROKE_NOTHING)
+ return False;
+
+ /*
+ * Check special keys.
+ */
+
+ /*
+ * FIXME: We should use the keysym instead that the keycode
+ * here.
+ */
+
+ if (X -> keycode == 130 && nxagentIpaq)
+ {
+ *result = doStartKbd;
+
+ return True;
+ }
+
+ switch (stroke) {
+#ifdef DEBUG_TREE
+ case KEYSTROKE_DEBUG_TREE:
+ *result = doDebugTree;
+ break;
+#endif
+ case KEYSTROKE_CLOSE_SESSION:
+ *result = doCloseSession;
+ break;
+ case KEYSTROKE_SWITCH_ALL_SCREENS:
+ if (!nxagentOption(Rootless)) {
+ *result = doSwitchAllScreens;
+ }
+ break;
+ case KEYSTROKE_MINIMIZE:
+ if (!nxagentOption(Rootless)) {
+ *result = doMinimize;
+ }
+ break;
+ case KEYSTROKE_DEFER:
+ *result = doSwitchDeferMode;
+ break;
+ case KEYSTROKE_IGNORE:
+ /* this is used e.g. to ignore C-A-Backspace aka XK_Terminate_Server */
+ return True;
+ break;
+ case KEYSTROKE_FORCE_SYNCHRONIZATION:
+ nxagentForceSynchronization = 1;
+ break;
+#ifdef DUMP
+ case KEYSTROKE_REGIONS_ON_SCREEN:
+ nxagentRegionsOnScreen();
+ break;
+#endif
+#ifdef NX_DEBUG_INPUT
+ case KEYSTROKE_TEST_INPUT:
+ /*
+ * Used to test the input devices state.
+ */
+ if (X -> type == KeyPress) {
+ if (!nxagentDebugInputDevices) {
+ fprintf(stderr, "Info: Turning input devices debug ON.\n");
+ nxagentDebugInputDevices = True;
+ } else {
+ fprintf(stderr, "Info: Turning input devices debug OFF.\n");
+ nxagentDebugInputDevices = False;
+ nxagentLastInputDevicesDumpTime = 0;
+ }
+ }
+ return True;
+ break;
+ case KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB:
+ if (X->type == KeyPress) {
+ nxagentDeactivateInputDevicesGrab();
+ }
+ return True;
+ break;
+#endif
+ case KEYSTROKE_FULLSCREEN:
+ if (!nxagentOption(Rootless)) {
+ *result = doSwitchFullscreen;
+ }
+ break;
+ case KEYSTROKE_RESIZE:
+ if (!nxagentOption(Rootless)) {
+ *result = doSwitchResizeMode;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_LEFT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportMoveLeft;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_UP:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportMoveUp;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_RIGHT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportMoveRight;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_MOVE_DOWN:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportMoveDown;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_LEFT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportLeft;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_UP:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportUp;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_RIGHT:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportRight;
+ }
+ break;
+ case KEYSTROKE_VIEWPORT_SCROLL_DOWN:
+ if (!nxagentOption(Rootless) && !nxagentOption(DesktopResize)) {
+ *result = doViewportDown;
+ }
+ break;
+ case KEYSTROKE_REREAD_KEYSTROKES:
+ /* two reasons to check on KeyRelease:
+ - this code is called for KeyPress and KeyRelease, so we
+ would read the keystroke file twice
+ - if the keystroke file changes settings for this key this
+ might lead to unexpected behaviour
+ */
+ if (X->type == KeyRelease)
+ nxagentInitKeystrokes(True);
+ break;
+ case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
+ case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
+ case KEYSTROKE_MAX:
+ break;
+ }
+ return (*result == doNothing);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
new file mode 100644
index 000000000..13a83d0fe
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -0,0 +1,90 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Keystroke_H__
+#define __Keystroke_H__
+
+#include "Events.h"
+
+extern Bool nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
+extern void nxagentDumpKeystrokes(void);
+extern void nxagentInitKeystrokes(Bool force);
+
+/* keep this sorted, do not rely on any numerical value in this enum, and be aware
+ * that KEYSTROKE_MAX may be used in a malloc */
+
+/* also be aware that if changing any numerical values, you also need to change values
+ * Keystroke.c nxagentSpecialKeystrokeNames */
+enum nxagentSpecialKeystroke {
+ /* 0 is used as end marker */
+ KEYSTROKE_END_MARKER,
+ KEYSTROKE_CLOSE_SESSION,
+ KEYSTROKE_SWITCH_ALL_SCREENS,
+ KEYSTROKE_FULLSCREEN,
+ KEYSTROKE_MINIMIZE,
+ KEYSTROKE_DEFER,
+ KEYSTROKE_IGNORE,
+ KEYSTROKE_FORCE_SYNCHRONIZATION,
+
+ /* stuff used for debugging, probably not useful for most people */
+#ifdef DEBUG_TREE
+ KEYSTROKE_DEBUG_TREE,
+#endif
+#ifdef DUMP
+ KEYSTROKE_REGIONS_ON_SCREEN,
+#endif
+#ifdef NX_DEBUG_INPUT
+ KEYSTROKE_TEST_INPUT,
+ KEYSTROKE_DEACTIVATE_INPUT_DEVICES_GRAB,
+#endif
+
+ /* all the viewport stuff */
+ KEYSTROKE_RESIZE,
+ KEYSTROKE_VIEWPORT_MOVE_LEFT,
+ KEYSTROKE_VIEWPORT_MOVE_UP,
+ KEYSTROKE_VIEWPORT_MOVE_RIGHT,
+ KEYSTROKE_VIEWPORT_MOVE_DOWN,
+ KEYSTROKE_VIEWPORT_SCROLL_LEFT,
+ KEYSTROKE_VIEWPORT_SCROLL_UP,
+ KEYSTROKE_VIEWPORT_SCROLL_RIGHT,
+ KEYSTROKE_VIEWPORT_SCROLL_DOWN,
+
+ KEYSTROKE_REREAD_KEYSTROKES,
+
+ KEYSTROKE_NOTHING,
+
+ /* insert more here and in the string translation */
+
+ KEYSTROKE_MAX,
+};
+
+struct nxagentSpecialKeystrokeMap {
+ enum nxagentSpecialKeystroke stroke;
+ unsigned int modifierMask; /* everything except alt/meta */
+ Bool modifierAltMeta; /* modifier combination should include alt/meta */
+ KeySym keysym;
+};
+
+#endif /* __Keystroke_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
new file mode 100644
index 000000000..c0bb8c5d7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -0,0 +1,213 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Simple table used to translate a request
+ * opcode to the name of the X request.
+ */
+
+static char *nxagentRequestLiteral[] =
+{
+ "None",
+ "CreateWindow",
+ "ChangeWindowAttributes",
+ "GetWindowAttributes",
+ "DestroyWindow",
+ "DestroySubwindows",
+ "ChangeSaveSet",
+ "ReparentWindow",
+ "MapWindow",
+ "MapSubwindows",
+ "UnmapWindow",
+ "UnmapSubwindows",
+ "ConfigureWindow",
+ "CirculateWindow",
+ "GetGeometry",
+ "QueryTree",
+ "InternAtom",
+ "GetAtomName",
+ "ChangeProperty",
+ "DeleteProperty",
+ "GetProperty",
+ "ListProperties",
+ "SetSelectionOwner",
+ "GetSelectionOwner",
+ "ConvertSelection",
+ "SendEvent",
+ "GrabPointer",
+ "UngrabPointer",
+ "GrabButton",
+ "UngrabButton",
+ "ChangeActivePointerGrab",
+ "GrabKeyboard",
+ "UngrabKeyboard",
+ "GrabKey",
+ "UngrabKey",
+ "AllowEvents",
+ "GrabServer",
+ "UngrabServer",
+ "QueryPointer",
+ "GetMotionEvents",
+ "TranslateCoords",
+ "WarpPointer",
+ "SetInputFocus",
+ "GetInputFocus",
+ "QueryKeymap",
+ "OpenFont",
+ "CloseFont",
+ "QueryFont",
+ "QueryTextExtents",
+ "ListFonts",
+ "ListFontsWithInfo",
+ "SetFontPath",
+ "GetFontPath",
+ "CreatePixmap",
+ "FreePixmap",
+ "CreateGC",
+ "ChangeGC",
+ "CopyGC",
+ "SetDashes",
+ "SetClipRectangles",
+ "FreeGC",
+ "ClearArea",
+ "CopyArea",
+ "CopyPlane",
+ "PolyPoint",
+ "PolyLine",
+ "PolySegment",
+ "PolyRectangle",
+ "PolyArc",
+ "FillPoly",
+ "PolyFillRectangle",
+ "PolyFillArc",
+ "PutImage",
+ "GetImage",
+ "PolyText8",
+ "PolyText16",
+ "ImageText8",
+ "ImageText16",
+ "CreateColormap",
+ "FreeColormap",
+ "CopyColormapAndFree",
+ "InstallColormap",
+ "UninstallColormap",
+ "ListInstalledColormaps",
+ "AllocColor",
+ "AllocNamedColor",
+ "AllocColorCells",
+ "AllocColorPlanes",
+ "FreeColors",
+ "StoreColors",
+ "StoreNamedColor",
+ "QueryColors",
+ "LookupColor",
+ "CreateCursor",
+ "CreateGlyphCursor",
+ "FreeCursor",
+ "RecolorCursor",
+ "QueryBestSize",
+ "QueryExtension",
+ "ListExtensions",
+ "ChangeKeyboardMapping",
+ "GetKeyboardMapping",
+ "ChangeKeyboardControl",
+ "GetKeyboardControl",
+ "Bell",
+ "ChangePointerControl",
+ "GetPointerControl",
+ "SetScreenSaver",
+ "GetScreenSaver",
+ "ChangeHosts",
+ "ListHosts",
+ "SetAccessControl",
+ "SetCloseDownMode",
+ "KillClient",
+ "RotateProperties",
+ "ForceScreenSaver",
+ "SetPointerMapping",
+ "GetPointerMapping",
+ "SetModifierMapping",
+ "GetModifierMapping",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "NoOperation"
+};
+
+static char *nxagentRenderRequestLiteral[] =
+{
+ "RenderQueryVersion",
+ "RenderQueryPictFormats",
+ "RenderQueryPictIndexValues",
+ "RenderQueryDithers",
+ "RenderCreatePicture",
+ "RenderChangePicture",
+ "RenderSetPictureClipRectangles",
+ "RenderFreePicture",
+ "RenderComposite",
+ "RenderScale",
+ "RenderTrapezoids",
+ "RenderTriangles",
+ "RenderTriStrip",
+ "RenderTriFan",
+ "RenderColorTrapezoids",
+ "RenderColorTriangles",
+ "RenderTransform",
+ "RenderCreateGlyphSet",
+ "RenderReferenceGlyphSet",
+ "RenderFreeGlyphSet",
+ "RenderAddGlyphs",
+ "RenderAddGlyphsFromPicture",
+ "RenderFreeGlyphs",
+ "RenderCompositeGlyphs",
+ "RenderCompositeGlyphs",
+ "RenderCompositeGlyphs",
+ "RenderFillRectangles",
+ "RenderCreateCursor",
+ "RenderSetPictureTransform",
+ "RenderQueryFilters",
+ "RenderSetPictureFilter",
+ "RenderCreateAnimCursor",
+ "RenderAddTraps",
+ "RenderCreateSolidFill",
+ "RenderCreateLinearGradient",
+ "RenderCreateRadialGradient",
+ "RenderCreateConicalGradient"
+};
+
+static char *nxagentShmRequestLiteral[] =
+{
+ "ShmQueryVersion",
+ "ShmAttach",
+ "ShmDetach",
+ "ShmPutImage",
+ "ShmGetImage",
+ "ShmCreatePixmap"
+};
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
new file mode 100644
index 000000000..ba801b62a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -0,0 +1,78 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <time.h>
+#include <stdio.h>
+
+#include "Xos.h"
+#include "Millis.h"
+
+#ifdef DDXTIME
+
+CARD32 GetTimeInMillis()
+{
+ struct timeval ts;
+
+ X_GETTIMEOFDAY(&ts);
+
+ return(ts.tv_sec * 1000) + (ts.tv_usec / 1000);
+}
+
+#endif
+
+const char *GetTimeAsString()
+{
+ char *value;
+
+ struct timeval ts;
+
+ X_GETTIMEOFDAY(&ts);
+
+ value = ctime((time_t *) &ts.tv_sec);
+
+ *(value + strlen(value) - 1) = '\0';
+
+ return value;
+}
+
+const char *GetTimeInMillisAsString()
+{
+ char *value;
+
+ char tb[25];
+
+ struct timeval ts;
+
+ X_GETTIMEOFDAY(&ts);
+
+ value = ctime((time_t *) &ts.tv_sec);
+
+ sprintf(tb, "%.8s:%3.3f", value + 11,
+ (float) ts.tv_usec / 1000);
+
+ strncpy(value, tb, 24);
+
+ return value;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
new file mode 100644
index 000000000..1e76ccbfb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -0,0 +1,38 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Millis_H__
+#define __Millis_H__
+
+#include "Xmd.h"
+
+CARD32 GetTimeInMillis(void);
+
+const char *GetTimeInMillisAsString(void);
+
+const char *GetTimeAsString(void);
+
+#endif /* __Millis_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c
new file mode 100644
index 000000000..ad02e13a8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c
@@ -0,0 +1,225 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "regionstr.h"
+#include "../../miext/damage/damage.h"
+#include <X11/fonts/font.h>
+
+/* prototypes */
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType);
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars);
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars);
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars);
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars);
+
+#include "../../miext/damage/damage.c"
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) malloc(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+
+#ifndef NXAGENT_SERVER
+
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+#endif
+
+ }
+ free(charinfo);
+ return x + w;
+}
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
new file mode 100644
index 000000000..5792a41c5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -0,0 +1,1362 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#include <X11/fonts/fontstruct.h>
+
+#define GC XlibGC
+#include <nx-X11/Xlib.h>
+#undef GC
+
+#include "../../dix/dispatch.c"
+
+#include "windowstr.h"
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include <nx/Shadow.h>
+#include "Handlers.h"
+#include "Keyboard.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+ */
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool nxagentWMPassed = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#ifdef VIEWPORT_FRAME
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+ (pWin) == nxagentViewportFrameRight || \
+ (pWin) == nxagentViewportFrameAbove || \
+ (pWin) == nxagentViewportFrameBelow)
+
+#else
+
+#define IsViewportFrame(pWin) (0)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, void *);
+
+
+void
+InitSelections()
+{
+ if (CurrentSelections)
+ free(CurrentSelections);
+ CurrentSelections = (Selection *)NULL;
+ NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ Selection *newsels;
+ newsels = (Selection *)malloc(2 * sizeof(Selection));
+ if (!newsels)
+ return;
+ NumCurrentSelections += 2;
+ CurrentSelections = newsels;
+
+ CurrentSelections[0].selection = XA_PRIMARY;
+ CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[0].window = screenInfo.screens[0]->root->drawable.id;
+ CurrentSelections[0].pWin = NULL;
+ CurrentSelections[0].client = NullClient;
+
+ CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+ CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+ CurrentSelections[1].window = screenInfo.screens[0]->root->drawable.id;
+ CurrentSelections[1].pWin = NULL;
+ CurrentSelections[1].client = NullClient;
+ }
+#endif
+
+}
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ register int *clientReady; /* array of request ready clients */
+ register int result;
+ register ClientPtr client;
+ register int nready;
+ register HWEventQueuePtr* icheck = checkForInput;
+ long start_tick;
+
+ unsigned long currentDispatch = 0;
+
+ nextFreeClientID = 1;
+ InitSelections();
+ nClients = 0;
+
+ /*
+ * The agent initialization was successfully
+ * completed. We can now handle our clients.
+ */
+
+ #ifdef XKB
+
+ nxagentInitXkbWrapper();
+
+ nxagentTuneXkbWrapper();
+
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ /*
+ * Set NX_WM property (used by NX client to identify
+ * the agent's window) three seconds since the first
+ * client connects.
+ */
+
+ nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+ #endif
+
+ clientReady = (int *) malloc(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ #ifdef WATCH
+
+ fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#3 1 352 bits (0 KB) -> 236 bits (0 KB) -> 352/1 -> 236/1 = 1.492:1
+#14 1 256 bits (0 KB) -> 101 bits (0 KB) -> 256/1 -> 101/1 = 2.535:1
+#16 1 256 bits (0 KB) -> 26 bits (0 KB) -> 256/1 -> 26/1 = 9.846:1
+#20 2 2 12256 bits (1 KB) -> 56 bits (0 KB) -> 6128/1 -> 28/1 = 218.857:1
+#43 1 256 bits (0 KB) -> 45 bits (0 KB) -> 256/1 -> 45/1 = 5.689:1
+#47 2 2 42304 bits (5 KB) -> 49 bits (0 KB) -> 21152/1 -> 24/1 = 863.347:1
+#98 1 256 bits (0 KB) -> 34 bits (0 KB) -> 256/1 -> 34/1 = 7.529:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+ dispatchException);
+
+ fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+ dispatchExceptionAtReset);
+ #endif
+
+ if (!(dispatchException & DE_TERMINATE))
+ dispatchException = 0;
+
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ /*
+ * Ensure we remove the splash after the timeout.
+ * Initializing clientReady[0] to -1 will tell
+ * WaitForSomething() to yield control after the
+ * timeout set in clientReady[1].
+ */
+
+ clientReady[0] = 0;
+
+ if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+ NXAGENT_WAKEUP);
+ #endif
+
+ clientReady[0] = -1;
+ clientReady[1] = NXAGENT_WAKEUP;
+ }
+
+ if (serverGeneration > nxagentMaxAllowedResets &&
+ nxagentSessionState == SESSION_STARTING &&
+ (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
+ {
+ #ifdef NX_DEBUG_INPUT
+ fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
+ GetTimeAsString(), GetTimeInMillis());
+ #else
+ fprintf(stderr, "Session: Session started at '%s'.\n",
+ GetTimeAsString());
+ #endif
+
+ nxagentSessionState = SESSION_UP;
+ saveAgentState("RUNNING");
+ }
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[End dispatch]\n");
+ #endif
+
+ nready = WaitForSomething(clientReady);
+
+ #ifdef BLOCKS
+ fprintf(stderr, "[Begin dispatch]\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+ nready);
+ #endif
+
+ #ifdef NXAGENT_ONSTART
+
+ currentDispatch = GetTimeInMillis();
+
+ /*
+ * If the timeout is expired set the
+ * selection informing the NX client
+ * that the agent is ready.
+ */
+
+ if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+ {
+ nxagentRemoveSplashWindow(NULL);
+ }
+
+ nxagentClients = nClients;
+
+ #endif
+
+ if (nready)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ requestingClient = client;
+ start_tick = SmartScheduleTime;
+ while (!isItTimeToYield)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+ if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+ /* now, finally, deal with client requests */
+
+ #ifdef TEST
+ fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+ client->index);
+ #endif
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+
+ else
+ {
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+ client->req_len << 2, client->index);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+ nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+ client->index);
+ }
+ }
+
+ #endif
+#endif
+
+ client->sequence++;
+#ifdef DEBUG
+ if ((client->requestLogIndex >= MAX_REQUEST_LOG) || (client->requestLogIndex <= 0))
+ client->requestLogIndex = 0;
+ client->requestLog[client->requestLogIndex] = MAJOROP;
+ client->requestLogIndex++;
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else
+#ifdef NXAGENT_SERVER
+ {
+ result = (* client->requestVector[MAJOROP])(client);
+
+ #ifdef TEST
+
+ if (MAJOROP > 127)
+ {
+ fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+ "size [%d] client [%d] result [%d].\n", MAJOROP,
+ *((char *) client->requestBuffer + 1), client->req_len << 2,
+ client->index, result);
+ }
+ else
+ {
+ fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+ "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+ client->req_len << 2, client->index, result);
+ }
+
+ #endif
+
+ /*
+ * Can set isItTimeToYield to force
+ * the dispatcher to pay attention
+ * to another client.
+ */
+
+ nxagentDispatchHandler(client, client->req_len << 2, 0);
+ }
+#else
+ result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+
+ if (!SmartScheduleSignalEnable)
+ SmartScheduleTime = GetTimeInMillis();
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+#ifdef DAMAGEEXT
+ FlushIfCriticalOutputPending ();
+#endif
+ }
+ FlushAllOutput();
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+ requestingClient = NULL;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ if ((dispatchException & DE_RESET) &&
+ (serverGeneration > nxagentMaxAllowedResets))
+ {
+ dispatchException &= ~DE_RESET;
+ dispatchException |= DE_TERMINATE;
+
+ fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+ }
+
+ nxagentResetAtomMap();
+
+ if (serverGeneration > nxagentMaxAllowedResets)
+ {
+ /*
+ * The session is terminating. Force an I/O
+ * error on the display and wait until the
+ * NX transport is gone.
+ */
+
+ fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+ saveAgentState("TERMINATING");
+
+ nxagentWaitDisplay();
+
+ fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+ }
+
+ if (nxagentOption(Shadow) == 1)
+ {
+ NXShadowDestroy();
+ }
+ saveAgentState("TERMINATED");
+
+ KillAllClients();
+ free(clientReady);
+ dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+
+ if (!nxagentWMPassed)
+ {
+ nxagentRemoveSplashWindow(pWin);
+ }
+
+ pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ DixWriteAccess);
+ if (!pParent)
+ return(BadWindow);
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int numChildren = 0;
+ register WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ memset(&reply, 0, sizeof(xQueryTreeReply));
+ reply.type = X_Reply;
+ reply.root = pWin->drawable.pScreen->root->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ numChildren++;
+ }
+ }
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = (Window *) malloc(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+ {
+ if (!IsViewportFrame(pChild))
+ {
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+ }
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = (numChildren * sizeof(Window)) >> 2;
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ free(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+ WindowPtr pWin;
+ TimeStamp time;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+ UpdateCurrentTime();
+ time = ClientTimeToServerTime(stuff->time);
+
+ /* If the client's time stamp is in the future relative to the server's
+ time stamp, do not set the selection, just return success. */
+ if (CompareTimeStamps(time, currentTime) == LATER)
+ return Success;
+ if (stuff->window != None)
+ {
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ }
+ else
+ pWin = (WindowPtr)None;
+ if (ValidAtom(stuff->selection))
+ {
+ int i = 0;
+
+ /*
+ * First, see if the selection is already set...
+ */
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection)
+ i++;
+ if (i < NumCurrentSelections)
+ {
+ xEvent event;
+
+ /* If the timestamp in client's request is in the past relative
+ to the time stamp indicating the last time the owner of the
+ selection was set, do not set the selection, just return
+ success. */
+ if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+ == EARLIER)
+ return Success;
+ if (CurrentSelections[i].client &&
+ (!pWin || (CurrentSelections[i].client != client)))
+ {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = time.milliseconds;
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+ NoEventMask, NoEventMask /* CantBeFiltered */,
+ NullGrab);
+ }
+ }
+ else
+ {
+ /*
+ * It doesn't exist, so add it...
+ */
+ Selection *newsels;
+
+ if (i == 0)
+ newsels = (Selection *)malloc(sizeof(Selection));
+ else
+ newsels = (Selection *)realloc(CurrentSelections,
+ (NumCurrentSelections + 1) * sizeof(Selection));
+ if (!newsels)
+ return BadAlloc;
+ NumCurrentSelections++;
+ CurrentSelections = newsels;
+ CurrentSelections[i].selection = stuff->selection;
+ }
+ CurrentSelections[i].lastTimeChanged = time;
+ CurrentSelections[i].window = stuff->window;
+ CurrentSelections[i].pWin = pWin;
+ CurrentSelections[i].client = (pWin ? client : NullClient);
+ if (SelectionCallback)
+ {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.kind= SelectionSetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
+
+#ifdef NXAGENT_CLIPBOARD
+ if ((CurrentSelections[i].pWin != NULL) &&
+ (nxagentOption(Clipboard) != ClipboardNone) &&
+ ((CurrentSelections[i].selection == XA_PRIMARY) ||
+ (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+ {
+ nxagentSetSelectionOwner(&CurrentSelections[i]);
+ }
+#endif
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->selection;
+ return (BadAtom);
+ }
+}
+
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+ Bool paramsOkay;
+ xEvent event;
+ WindowPtr pWin;
+ REQUEST(xConvertSelectionReq);
+
+ REQUEST_SIZE_MATCH(xConvertSelectionReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+ if (((stuff->selection == XA_PRIMARY) ||
+ (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+ nxagentOption(Clipboard) != ClipboardNone)
+ {
+ int i = 0;
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+
+ if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+ {
+ if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+ stuff->property, stuff->target, stuff->time))
+ {
+ return (client->noClientException);
+ }
+ }
+ }
+#endif
+
+ paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+ if (stuff->property != None)
+ paramsOkay &= ValidAtom(stuff->property);
+ if (paramsOkay)
+ {
+ int i;
+
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->selection) i++;
+ if ((i < NumCurrentSelections) &&
+ (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+ && (!client->CheckAccess ||
+ (* client->CheckAccess)(client, CurrentSelections[i].window,
+ RT_WINDOW, DixReadAccess,
+ CurrentSelections[i].pWin))
+#endif
+ )
+
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = SelectionRequest;
+ event.u.selectionRequest.time = stuff->time;
+ event.u.selectionRequest.owner =
+ CurrentSelections[i].window;
+ event.u.selectionRequest.requestor = stuff->requestor;
+ event.u.selectionRequest.selection = stuff->selection;
+ event.u.selectionRequest.target = stuff->target;
+ event.u.selectionRequest.property = stuff->property;
+ if (TryClientEvents(
+ CurrentSelections[i].client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab))
+ return (client->noClientException);
+ }
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = SelectionNotify;
+ event.u.selectionNotify.time = stuff->time;
+ event.u.selectionNotify.requestor = stuff->requestor;
+ event.u.selectionNotify.selection = stuff->selection;
+ event.u.selectionNotify.target = stuff->target;
+ event.u.selectionNotify.property = None;
+ (void) TryClientEvents(client, &event, 1, NoEventMask,
+ NoEventMask /* CantBeFiltered */, NullGrab);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+}
+
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+ int err;
+ char fontReq[256];
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+ memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ fontReq[stuff->nbytes]=0;
+ if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+ {
+ extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+ nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+ err = nxOpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ }
+ else
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+ FontPtr pFont;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ DixDestroyAccess);
+ if (pFont != (FontPtr)NULL)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client closes a font the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this font looping through the
+ * resources.
+ */
+
+ if (pFont -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+ (void *) pFont);
+ #endif
+
+ nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+ "resource switching skipped.\n", (void *) pFont);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadFont);
+ }
+}
+
+
+int
+ProcListFonts(register ClientPtr client)
+{
+ char tmp[256];
+
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+ char tmp[256];
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+ tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+ nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+ DixDestroyAccess);
+ if (pMap)
+ {
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * When a client releases a pixmap the resource
+ * should not be lost if the reference counter
+ * is not 0, otherwise the server will not be
+ * able to find this pixmap looping through the
+ * resources.
+ */
+
+ if (pMap -> refcnt > 0)
+ {
+ if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+ (void *) pMap);
+ #endif
+
+ nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+ AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+ "resource switching skipped.\n", (void *) pMap);
+ }
+ #endif
+ }
+
+ #endif
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadPixmap);
+ }
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+ int blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to change our values.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+ stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+ #endif
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ if (blankingOption == DefaultBlanking)
+ {
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ }
+ else
+ {
+ ScreenSaverBlanking = blankingOption;
+ }
+
+ if (exposureOption == DefaultExposures)
+ {
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ }
+ else
+ {
+ ScreenSaverAllowExposures = exposureOption;
+ }
+
+ if (stuff->timeout >= 0)
+ {
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverTime = defaultScreenSaverTime;
+ }
+
+ if (stuff->interval >= 0)
+ {
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ }
+ else
+ {
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ }
+
+ SetScreenSaverTimer();
+ }
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+ nxagentOption(Timeout));
+ }
+
+ #endif
+
+ return (client->noClientException);
+}
+
+
+int ProcForceScreenSaver(register ClientPtr client)
+{
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+
+ /*
+ * The NX agent uses the screen saver procedure
+ * to monitor the user activities and launch its
+ * handlers (like timeout feature), so we can't
+ * always allow the clients to force the screen
+ * saver handler execution.
+ */
+
+ if (nxagentOption(Timeout) == 0)
+ {
+ SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+ }
+
+ #ifdef TEST
+
+ else
+ {
+ fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+ stuff -> mode);
+ }
+
+ #endif
+
+ return client->noClientException;
+}
+
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(register ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ /*
+ * There must be a better way to hook a
+ * call-back function to be called any
+ * time a client is going to be closed.
+ */
+
+ nxagentClearClipboard(client, NULL);
+
+ /*
+ * Need to reset the karma counter and
+ * get rid of the pending sync replies.
+ */
+
+ nxagentWakeupByReset(client);
+
+ /*
+ * Check if the client
+ * is a shadow nxagent.
+ */
+
+ nxagentCheckIfShadowAgent(client);
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
+ }
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+ SmartLastClient = NullClient;
+ free(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+int
+InitClientPrivates(ClientPtr client)
+{
+ register char *ptr;
+ DevUnion *ppriv;
+ register unsigned *sizes;
+ register unsigned size;
+ register int i;
+
+ if (totalClientSize == sizeof(ClientRec))
+ ppriv = (DevUnion *)NULL;
+ else if (client->index)
+ ppriv = (DevUnion *)(client + 1);
+ else
+ {
+ ppriv = (DevUnion *)malloc(totalClientSize - sizeof(ClientRec));
+ if (!ppriv)
+ return 0;
+ }
+ client->devPrivates = ppriv;
+ sizes = clientPrivateSizes;
+ ptr = (char *)(ppriv + clientPrivateLen);
+ for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+
+ /*
+ * Initialize the private members.
+ */
+
+ nxagentInitClientPrivates(client);
+
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
new file mode 100644
index 000000000..49d864887
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -0,0 +1,1543 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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.
+
+******************************************************************/
+
+#include "dixstruct.h"
+#include "dixfontstr.h"
+
+static Bool doOpenFont(ClientPtr client, OFclosurePtr c);
+static Bool doListFontsAndAliases(ClientPtr client, LFclosurePtr c);
+
+#include "../../dix/dixfonts.c"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+ const char *fontEnv;
+
+ /*
+ * Check the environment only once.
+ */
+
+ if (*_NXFontPath != '\0')
+ {
+ return _NXFontPath;
+ }
+
+ fontEnv = getenv("NX_FONT");
+
+ if (fontEnv != NULL && *fontEnv != '\0')
+ {
+ if (strlen(fontEnv) + 1 > 1024)
+ {
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+ goto _NXGetFontPathError;
+ }
+
+ strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+ }
+
+_NXGetFontPathError:
+
+ strncpy(_NXFontPath, path, 1023);
+ _NXFontPath[1023] = '\0';
+
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+ return _NXFontPath;
+}
+
+#endif
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ char nxagentOrigFontName[256];
+ int nxagentOrigFontNameLen;
+
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+
+ nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+ memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+ nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->open_font)
+#else
+ err = (*fpe_functions[fpe->type].open_font)
+#endif /* HAS_XFONT2 */
+ ((void *) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) realloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0)
+ break;
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (void *) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ /* check values for firstCol, lastCol, firstRow, and lastRow */
+ if (pfont->info.firstCol > pfont->info.lastCol ||
+ pfont->info.firstRow > pfont->info.lastRow ||
+ pfont->info.lastCol - pfont->info.firstCol > 255) {
+ err = AllocError;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+
+ /* NXAGENT uses useless screen pointer to pass the original font name
+ * to realizeFont, could be a source of problems in the future.
+ */
+
+ if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err=BadFontName;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (void *) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+ {
+ extern RESTYPE RT_NX_FONT;
+
+ nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+ if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (void *) pfont)) {
+ FreeResource(c->fontid, RT_NONE);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+#ifdef HAS_XFONT2
+ xfont2_cache_font_pattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+#else
+ CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+#endif /* HAS_XFONT2 */
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ free(c->fpe_list);
+ free(c->fontname);
+ free(c);
+ return TRUE;
+}
+
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+#ifdef HAS_XFONT2
+ if (!fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_fonts)
+#else
+ err = (*fpe_functions[fpe->type].list_fonts)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (void *) c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) free(resolved);
+ resolved = (char *) malloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+#ifdef HAS_XFONT2
+ (void)xfont2_add_font_names_name(c->names, c->savedName,
+#else
+ (void)AddFontNamesName(c->names, c->savedName,
+#endif /* HAS_XFONT2 */
+ c->savedNameLen);
+ }
+ else
+#ifdef HAS_XFONT2
+ (void)xfont2_add_font_names_name(c->names, name, namelen);
+#else
+ (void)AddFontNamesName(c->names, name, namelen);
+#endif /* HAS_XFONT2 */
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ free(c->savedName);
+ c->savedName = (char *)malloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ memset(&reply, 0, sizeof(xListFontsReply));
+ reply.type = X_Reply;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) malloc(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ {
+ /* dirty hack: don't list to client fonts not existing on the remote side */
+ char tmp[256];
+
+ memcpy(tmp, names->names[i], names->length[i]);
+ tmp[ names->length[i] ] = 0;
+
+ if (nxagentFontLookUp(tmp) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases:\n");
+ fprintf(stderr, " removing font: %s \n", tmp);
+#endif
+ reply.nFonts--;
+ stringLens -= names->length[i];
+ continue;
+ }
+ }
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (stringLens + nnames + 3) >> 2;
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ WriteToClient(client, stringLens + nnames, bufferStart);
+ free(bufferStart);
+
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ if (c->savedName) free(c->savedName);
+#ifdef HAS_XFONT2
+ xfont2_free_font_names(names);
+#else
+ FreeFontNames(names);
+#endif /* HAS_XFONT2 */
+ free(c);
+ if (resolved) free(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) malloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ free(c);
+ return BadAlloc;
+ }
+#ifdef HAS_XFONT2
+ c->names = xfont2_make_font_names_record(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+#else
+ c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+#endif /* HAS_XFONT2 */
+ if (!c->names)
+ {
+ free(c->fpe_list);
+ free(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->start_list_fonts_with_info)
+#else
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_next_font_with_info)
+#else
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->list_next_font_with_info)
+#else
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+#endif /* HAS_XFONT2 */
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ free(c->savedName);
+ c->savedName = (char *)malloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+
+ if (nxagentFontLookUp(name) == 0)
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "doListFontsAndAliases (with info):\n");
+ fprintf(stderr, " removing font: %s \n", name);
+#endif
+ continue;
+ }
+
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) realloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ memset(reply + c->length, 0, length - c->length);
+ c->reply = reply;
+ c->length = length;
+ }
+ reply->type = X_Reply;
+ reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ free(fontInfo.props);
+ free(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = (sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply)) >> 2;
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->reply);
+ free(c->fpe_list);
+ if (c->savedName) free(c->savedName);
+ free(c);
+ return TRUE;
+}
+
+
+int
+SetDefaultFontPath(char *path)
+{
+ char *temp_path,
+ *start,
+ *end;
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+#ifdef NX_TRANS_SOCKET
+ path = (char *) _NXGetFontPath(path);
+#endif /* NX_TRANS_SOCKET */
+
+ start = path;
+
+ /* ensure temp_path contains "built-ins" */
+ while (1) {
+ start = strstr(start, "built-ins");
+ if (start == NULL)
+ break;
+ end = start + strlen("built-ins");
+ if ((start == path || start[-1] == ',') && (!*end || *end == ','))
+ break;
+ start = end;
+ }
+ if (!start) {
+ if (asprintf(&temp_path, "%s%sbuilt-ins", path, *path ? "," : "")
+ == -1)
+ temp_path = NULL;
+ }
+ else {
+ temp_path = strdup(path);
+ }
+ if (!temp_path)
+ return BadAlloc;
+
+ /* get enough for string, plus values -- use up commas */
+ len = strlen(temp_path) + 1;
+ nump = cp = newpath = (unsigned char *) malloc(len);
+ if (!newpath) {
+ free(temp_path);
+ return BadAlloc;
+ }
+ pp = (unsigned char *) temp_path;
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ free(newpath);
+ free(temp_path);
+
+ return err;
+}
+
+
+typedef struct
+{
+ LFclosurePtr c;
+ OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+ ClientPtr client;
+ nxFsPtr fss;
+#endif
+{
+ LFclosurePtr c=fss->c;
+ OFclosurePtr oc=fss->oc;
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int i;
+ int aliascount = 0;
+ char tmp[256];
+ tmp[0]=0;
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+#ifdef HAS_XFONT2
+ (*fpe_functions[fpe->type]->client_died) ((void *) client, fpe);
+#else
+ (*fpe_functions[fpe->type].client_died) ((void *) client, fpe);
+#endif /* HAS_XFONT2 */
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+#ifdef HAS_XFONT2
+ if (!fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_fonts)
+#else
+ err = (*fpe_functions[fpe->type].list_fonts)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (void *) fss);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->start_list_fonts_and_aliases)
+#else
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (void *) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+#ifdef HAS_XFONT2
+ err = (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)nxdoListFontsAndAliases,
+ (void *) fss);
+ c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) free(resolved);
+ resolved = (char *) malloc(resolvedlen + 1);
+ if (resolved)
+ {
+ memmove(resolved, tmpname, resolvedlen);
+ resolved[resolvedlen] = '\0';
+ }
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ {
+ memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+ tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+ else
+ {
+ memcpy(tmp,name,namelen>255?255:namelen);
+ tmp[namelen>255?256:namelen]=0;
+ if (nxagentFontLookUp(tmp))
+ break;
+ else tmp[0]=0;
+ }
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+#ifdef HAS_XFONT2
+ (void) (*fpe_functions[fpe->type]->list_next_font_or_alias)
+#else
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+#endif /* HAS_XFONT2 */
+ ((void *) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ free(c->savedName);
+ c->savedName = (char *)malloc(namelen + 1);
+ if (c->savedName)
+ {
+ memmove(c->savedName, name, namelen);
+ c->savedName[namelen] = '\0';
+ }
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+bail:
+finish:
+ if (strlen(tmp))
+ {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+ }
+ else
+ {
+ for (i = 0; i < c->names->nnames; i++)
+ {
+ if (c->names->length[i] > 255)
+ continue;
+ else
+ {
+ memcpy(tmp, c->names->names[i], c->names->length[i]);
+ tmp[ c->names->length[i] ] = 0;
+ if (nxagentFontLookUp(tmp) == 0)
+ continue;
+ memcpy(oc->fontname, tmp, strlen(tmp));
+ oc->fnamelen = strlen(tmp);
+
+ oc->origFontName = oc->fontname;
+ oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+ fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+ break;
+ }
+ }
+ }
+
+ if (c->slept)
+ {
+ ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+ fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ if (c->savedName) free(c->savedName);
+#ifdef HAS_XFONT2
+ xfont2_free_font_names(c->names);
+#else
+ FreeFontNames(c->names);
+#endif /* HAS_XFONT2 */
+ free(c);
+ free(fss);
+ if (resolved) free(resolved);
+
+ return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+ ClientPtr client;
+ XID fid;
+ Mask flags;
+ unsigned lenfname;
+ char *pfontname;
+{
+ nxFsPtr fss;
+ LFclosurePtr c;
+ OFclosurePtr oc;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = (char *)malloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("OpenFont: fontname is \"%s\"\n", f);
+ free(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+#ifdef HAS_XFONT2
+ cached = xfont2_find_cached_font_pattern(patternCache, pfontname, lenfname);
+#else
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+#endif /* HAS_XFONT2 */
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (void *) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ if (!(fss = (nxFsPtr) malloc(sizeof(nxFs))))
+ return BadAlloc;
+
+ if (!(c = (LFclosurePtr) malloc(sizeof *c)))
+ {
+ free(fss);
+ return BadAlloc;
+ }
+ c->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ free(c);
+ free(fss);
+ return BadAlloc;
+ }
+#ifdef HAS_XFONT2
+ c->names = xfont2_make_font_names_record(100);
+#else
+ c->names = MakeFontNamesRecord(100);
+#endif /* HAS_XFONT2 */
+ if (!c->names)
+ {
+ free(c->fpe_list);
+ free(c);
+ free(fss);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = lenfname;
+ c->current.current_fpe = 0;
+ c->current.max_names = nxagentMaxFontNames;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+
+ oc = (OFclosurePtr) malloc(sizeof(OFclosureRec));
+ if (!oc)
+ {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ free(c);
+ free(fss);
+ return BadAlloc;
+ }
+ oc->fontname = (char *) malloc(256);/* I don't want to deal with future reallocs errors */
+ oc->origFontName = pfontname;
+ oc->origFontNameLen = lenfname;
+ if (!oc->fontname) {
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ free(c);
+ free(oc);
+ free(fss);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ oc->fpe_list = (FontPathElementPtr *)
+ malloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!oc->fpe_list) {
+ free(oc->fontname);
+ free(oc);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ free(c->fpe_list);
+ free(c);
+ free(fss);
+ return BadAlloc;
+ }
+ memmove(oc->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ oc->fpe_list[i] = font_path_elements[i];
+ UseFPE(oc->fpe_list[i]);
+ }
+ oc->client = client;
+ oc->fontid = fid;
+ oc->current_fpe = 0;
+ oc->num_fpes = num_fpes;
+ oc->fnamelen = lenfname;
+ oc->slept = FALSE;
+ oc->flags = flags;
+ oc->non_cachable_font = cached;
+ fss->c=c;
+ fss->oc=oc;
+ nxdoListFontsAndAliases(client, fss);
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
new file mode 100644
index 000000000..43cb806e7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -0,0 +1,613 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+
+#include <nx-X11/Xlib.h>
+
+#include "../../dix/events.c"
+
+#include "compext/Compext.h"
+
+#include "Events.h"
+#include "Windows.h"
+#include "Args.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+ : sprite.win;
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+ sprite.hotPhys.x = sprite.hotPhys.y = 0;
+ ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ mouse->grabTime = syncEvents.time;
+ else
+ mouse->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ mouse->activeGrab = *grab;
+ mouse->grab = &mouse->activeGrab;
+ mouse->fromPassiveGrab = autoGrab;
+ PostNewCursor();
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * If grab is synchronous, events are delivered to clients only if they send
+ * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the
+ * delivered event is saved in a queue and replayed later, when grab is released.
+ * We should export sync grab to X as async in order to avoid events to be
+ * queued twice, in the agent and in the X server. This solution have a drawback:
+ * replayed events are not delivered to that application that are not clients of
+ * the agent.
+ * A different solution could be to make the grab asynchronous in the agent and
+ * to export it as synchronous. But this seems to be less safe.
+ *
+ * To make internal grab asynchronous, change previous line as follows.
+ *
+ * if (nxagentOption(Rootless))
+ * {
+ * CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+ * }
+ * else
+ * {
+ * CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+ * }
+ */
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ /*
+ * FIXME: We should use the correct value
+ * for the cursor. Temporarily we set it
+ * to None.
+ */
+
+ int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+ nxagentCollectGrabPointerPredicate);
+
+ NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+ 1, grab -> eventMask & PointerGrabMask,
+ GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+ nxagentWindow(grab -> confineTo) : None,
+ None, CurrentTime);
+ }
+
+ #endif
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+ register GrabPtr grab = mouse->grab;
+ register DeviceIntPtr dev;
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->grab = NullGrab;
+ mouse->sync.state = NOT_GRABBED;
+ mouse->fromPassiveGrab = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->sync.other == grab)
+ dev->sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(ROOT, FALSE, FALSE);
+ PostNewCursor();
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+ ComputeFreezes();
+
+ #ifdef NXAGENT_SERVER
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ XUngrabPointer(nxagentDisplay, CurrentTime);
+
+ if (sprite.win == ROOT)
+ {
+ mouse -> button -> state &=
+ ~(Button1Mask | Button2Mask | Button3Mask |
+ Button4Mask | Button5Mask);
+ }
+ }
+
+ #endif
+}
+
+// int
+// ProcAllowEvents(register ClientPtr client)
+// {
+// TimeStamp time;
+// DeviceIntPtr mouse = inputInfo.pointer;
+// DeviceIntPtr keybd = inputInfo.keyboard;
+// REQUEST(xAllowEventsReq);
+//
+// REQUEST_SIZE_MATCH(xAllowEventsReq);
+// time = ClientTimeToServerTime(stuff->time);
+// switch (stuff->mode)
+// {
+// case ReplayPointer:
+// AllowSome(client, time, mouse, NOT_GRABBED);
+// break;
+// case SyncPointer:
+// AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+// break;
+// case AsyncPointer:
+// AllowSome(client, time, mouse, THAWED);
+// break;
+// case ReplayKeyboard:
+// AllowSome(client, time, keybd, NOT_GRABBED);
+// break;
+// case SyncKeyboard:
+// AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+// break;
+// case AsyncKeyboard:
+// AllowSome(client, time, keybd, THAWED);
+// break;
+// case SyncBoth:
+// AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+// break;
+// case AsyncBoth:
+// AllowSome(client, time, keybd, THAWED_BOTH);
+// break;
+// default:
+// client->errorValue = stuff->mode;
+// return BadValue;
+// }
+//
+// /*
+// * This is not necessary if we export grab to X as asynchronous.
+// *
+// * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+// * stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+// * {
+// * XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+// * }
+// */
+//
+// return Success;
+// }
+
+static WindowPtr
+XYToWindow(int x, int y)
+{
+ register WindowPtr pWin;
+ BoxRec box;
+
+ spriteTraceGood = 1; /* root window still there */
+
+ if (nxagentOption(Rootless))
+ {
+ if (nxagentLastEnteredWindow == NULL)
+ {
+ return ROOT;
+ }
+
+ pWin = ROOT->lastChild;
+
+ while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+ {
+ pWin = pWin->prevSib;
+ }
+ }
+ else
+ {
+ pWin = ROOT->firstChild;
+ }
+
+ while (pWin)
+ {
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+#ifdef SHAPE
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ RegionContainsPoint(
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#endif
+ )
+ {
+ if (spriteTraceGood >= spriteTraceSize)
+ {
+ spriteTraceSize += 10;
+ Must_have_memory = TRUE; /* XXX */
+ spriteTrace = (WindowPtr *)realloc(
+ spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+ Must_have_memory = FALSE; /* XXX */
+ }
+ spriteTrace[spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return spriteTrace[spriteTraceGood-1];
+}
+
+// static Bool
+// CheckMotion(xEvent *xE)
+// {
+// WindowPtr prevSpriteWin = sprite.win;
+//
+#ifdef PANORAMIX
+// if(!noPanoramiXExtension)
+// return XineramaCheckMotion(xE);
+#endif
+
+// if (xE && !syncEvents.playingEvents)
+// {
+// if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+// {
+// sprite.hot.pScreen = sprite.hotPhys.pScreen;
+// ROOT = sprite.hot.pScreen->root;
+// }
+// sprite.hot.x = XE_KBPTR.rootX;
+// sprite.hot.y = XE_KBPTR.rootY;
+// if (sprite.hot.x < sprite.physLimits.x1)
+// sprite.hot.x = sprite.physLimits.x1;
+// else if (sprite.hot.x >= sprite.physLimits.x2)
+// sprite.hot.x = sprite.physLimits.x2 - 1;
+// if (sprite.hot.y < sprite.physLimits.y1)
+// sprite.hot.y = sprite.physLimits.y1;
+// else if (sprite.hot.y >= sprite.physLimits.y2)
+// sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+// if (sprite.hotShape)
+// ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+// sprite.hotPhys = sprite.hot;
+//
+// /*
+// * This code force cursor position to be inside the
+// * root window of the agent. We can't view a reason
+// * to do this and it interacts in an undesirable way
+// * with toggling fullscreen.
+// *
+// * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+// * (sprite.hotPhys.y != XE_KBPTR.rootY))
+// * {
+// * (*sprite.hotPhys.pScreen->SetCursorPosition)(
+// * sprite.hotPhys.pScreen,
+// * sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+// * }
+// */
+//
+// XE_KBPTR.rootX = sprite.hot.x;
+// XE_KBPTR.rootY = sprite.hot.y;
+// }
+//
+// sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+// if (!(sprite.win->deliverableEvents &
+// Motion_Filter(inputInfo.pointer->button))
+// !syncEvents.playingEvents)
+// {
+// /* XXX Do PointerNonInterestBox here */
+// }
+#endif
+// if (sprite.win != prevSpriteWin)
+// {
+// if (prevSpriteWin != NullWindow) {
+// if (!xE)
+// UpdateCurrentTimeIf();
+// DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+// }
+// PostNewCursor();
+// return FALSE;
+// }
+// return TRUE;
+// }
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+ register ScreenPtr pScreen = win->drawable.pScreen;
+ #ifdef VIEWPORT_FRAME
+ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+ #endif
+ extern int nxagentShadowInit(ScreenPtr, WindowPtr);
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hotPhys.x = pScreen->width / 2;
+ sprite.hotPhys.y = pScreen->height / 2;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (
+ pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.confineWin = NullWindow;
+#ifdef SHAPE
+ sprite.hotShape = NullRegion;
+#endif
+ sprite.screen = pScreen;
+ /* gotta UNINIT these someplace */
+ RegionNull(&sprite.Reg1);
+ RegionNull(&sprite.Reg2);
+ }
+#endif
+
+ #ifdef VIEWPORT_FRAME
+ nxagentInitViewportFrame(pScreen, win);
+ #endif
+
+ if (nxagentOption(Shadow))
+ {
+ if (nxagentShadowInit(pScreen, win) == -1)
+ {
+ FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
+ }
+ }
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+ if (stuff -> event.u.u.type == SelectionNotify)
+ {
+ extern int nxagentSendNotify(xEvent*);
+ if (nxagentSendNotify(&stuff->event) == 1)
+ return Success;
+ }
+#endif
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32 &&
+ !permitOldBugs)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = sprite.win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = ROOT;
+
+ if (IsParent(inputFocus, sprite.win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = sprite.win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ pWin = SecurityLookupWindow(stuff->destination, client,
+ DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else
+ (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+ NullGrab, 0);
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
new file mode 100644
index 000000000..9ec6be8ef
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -0,0 +1,195 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#include "Trap.h"
+
+#include "../../dix/extension.c"
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ xQueryExtensionReply reply;
+ int i;
+ REQUEST(xQueryExtensionReq);
+
+ REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+
+ memset(&reply, 0, sizeof(xQueryExtensionReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if ( ! NumExtensions )
+ reply.present = xFalse;
+ else
+ {
+ i = FindExtension((char *)&stuff[1], stuff->nbytes);
+ if (i < 0
+
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+#endif
+ )
+ reply.present = xFalse;
+ else
+ {
+ reply.present = xTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+ }
+ WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ xListExtensionsReply reply;
+ char *bufptr, *buffer;
+ int total_length = 0;
+
+ REQUEST_SIZE_MATCH(xReq);
+
+ memset(&reply, 0, sizeof(xListExtensionsReply));
+ reply.type = X_Reply;
+ reply.nExtensions = 0;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if ( NumExtensions )
+ {
+ register int i, j;
+
+ for (i=0; i<NumExtensions; i++)
+ {
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ /*
+ * Hide RENDER if our implementation
+ * is faulty.
+ */
+
+ if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+ continue;
+
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += 1 + extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length = (total_length + 3) >> 2;
+ buffer = bufptr = (char *)malloc(total_length);
+ if (!buffer)
+ return(BadAlloc);
+ for (i=0; i<NumExtensions; i++)
+ {
+ int len;
+#ifdef XCSECURITY
+ if (client->trustLevel == XSecurityClientUntrusted &&
+ !extensions[i]->secure)
+ continue;
+#endif
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove(bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove(bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+ if (reply.length)
+ {
+ WriteToClient(client, total_length, buffer);
+ free(buffer);
+ }
+ return(client->noClientException);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
new file mode 100644
index 000000000..5512cae1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
@@ -0,0 +1,204 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#include "../../GL/glx/glxext.c"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) malloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ memset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (void *)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** If we're expecting a glXRenderLarge request, this better be one.
+ */
+ if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+ client->errorValue = stuff->glxCode;
+ return __glXBadLargeRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = (__GLXclientState *) malloc(sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+ memset(cl, 0, sizeof(__GLXclientState));
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (void *)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+
+ /*
+ * Report upstream that we are
+ * dispatching a GLX operation.
+ */
+
+ nxagentGlxTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ result = (*proc)(cl, (GLbyte *) stuff);
+
+ nxagentGlxTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n",
+ opcode, client -> index);
+ #endif
+
+ return result;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
new file mode 100644
index 000000000..35dcbc132
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -0,0 +1,381 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include "../../render/glyph.c"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef DEBUG
+#undef TEST
+
+#endif
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+ GlyphRefPtr gr;
+ CARD32 hash;
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+ /* Locate existing matching glyph */
+ hash = HashGlyph (glyph);
+ gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ free (glyph);
+ glyph = gr->glyph;
+ }
+ else
+ {
+ gr->glyph = glyph;
+ gr->signature = hash;
+ globalGlyphs[glyphSet->fdepth].tableEntries++;
+ }
+
+ /* Insert/replace glyphset value */
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ ++glyph->refcnt;
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ FreeGlyph (gr->glyph, glyphSet->fdepth);
+ else
+ glyphSet->hash.tableEntries++;
+ gr->glyph = glyph;
+ gr->signature = id;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = 1;
+
+ #endif
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr -> glyph;
+
+ if (glyph == DeletedGlyph)
+ {
+ glyph = 0;
+ }
+ else if (gr -> corruptedGlyph == 1)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+ (void *) glyph, (void *) glyphSet);
+ #endif
+
+ nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+ (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+ }
+
+ return glyph;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+ CARD32 tableEntries;
+ GlyphHashSetPtr hashSet;
+ GlyphHashRec newHash;
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+ int i;
+ int oldSize;
+ CARD32 s;
+
+ #ifdef NXAGENT_SERVER
+
+ CARD32 c;
+
+ #endif
+
+ tableEntries = hash->tableEntries + change;
+ hashSet = FindGlyphHashSet (tableEntries);
+ if (hashSet == hash->hashSet)
+ return TRUE;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash top");
+ if (!AllocateGlyphHash (&newHash, hashSet))
+ return FALSE;
+ if (hash->table)
+ {
+ oldSize = hash->hashSet->size;
+ for (i = 0; i < oldSize; i++)
+ {
+ glyph = hash->table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ s = hash->table[i].signature;
+
+ #ifdef NXAGENT_SERVER
+
+ c = hash->table[i].corruptedGlyph;
+
+ #endif
+
+ gr = FindGlyphRef (&newHash, s, global, glyph);
+ gr->signature = s;
+ gr->glyph = glyph;
+
+ #ifdef NXAGENT_SERVER
+
+ gr -> corruptedGlyph = c;
+
+ #endif
+
+ ++newHash.tableEntries;
+ }
+ }
+ free (hash->table);
+ }
+ *hash = newHash;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash bottom");
+ return TRUE;
+}
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ PixmapPtr pPixmap = 0;
+ PicturePtr pPicture;
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int xDst = list->xOff, yDst = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents;
+ CARD32 component_alpha;
+
+ /*
+ * Get rid of the warning.
+ */
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+
+ if (maskFormat)
+ {
+ GCPtr pGC;
+ xRectangle rect;
+
+ if (nxagentGlyphsExtents != NullBox)
+ {
+ memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentGlyphsExtents = (BoxPtr) malloc(sizeof(BoxRec));
+
+ GlyphExtents (nlist, list, glyphs, &extents);
+
+ memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+ }
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ maskFormat->depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+
+ if (!pMaskPixmap)
+ return;
+
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture (0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+
+ if (!pMask)
+ {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC (&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else
+ {
+ pMask = pDst;
+ x = 0;
+ y = 0;
+ }
+ pPicture = 0;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+
+ while (n--)
+ {
+ glyph = *glyphs++;
+ if (!pPicture)
+ {
+ pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
+ list->format->depth,
+ list->format->depth,
+ 0, (void *) (glyph + 1));
+ if (!pPixmap)
+ return;
+ component_alpha = NeedsComponent(list->format->format);
+ pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+ CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ return;
+ }
+ }
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width, glyph->info.height,
+ 0, 0, -1, (void *) (glyph + 1));
+
+ /*
+ * The following line fixes a problem with glyphs that appeared
+ * as clipped. It was a side effect due the validate function
+ * "ValidatePicture" that makes a check on the Drawable serial
+ * number instead of the picture serial number, failing thus
+ * the clip mask update.
+ */
+
+ pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (maskFormat)
+ {
+ CompositePicture (PictOpAdd,
+ pPicture,
+ None,
+ pMask,
+ 0, 0,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ else
+ {
+ CompositePicture (op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (x - glyph->info.x) - xDst,
+ ySrc + (y - glyph->info.y) - yDst,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+
+ list++;
+ if (pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ FreePicture ((void *) pPicture, 0);
+ pPicture = 0;
+ pPixmap = 0;
+ }
+ }
+ if (maskFormat)
+ {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - xDst,
+ ySrc + y - yDst,
+ 0, 0,
+ x, y,
+ width, height);
+
+ FreePicture ((void *) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
new file mode 100644
index 000000000..549ab4333
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -0,0 +1,180 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+
+
+#include "../../dix/glyphcurs.c"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True 1
+#endif
+
+/*
+ get the bits out of the font in a portable way. to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+ since all screens return the same bitmap format, we'll just use
+the first one we find.
+ the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+ register ScreenPtr pScreen;
+ register GCPtr pGC;
+ xRectangle rect;
+ PixmapPtr ppix;
+ long nby;
+ char *pbits;
+ unsigned char char2b[2];
+
+ /* turn glyph index into a protocol-format char2b */
+ char2b[0] = (unsigned char)(ch >> 8);
+ char2b[1] = (unsigned char)(ch & 0xff);
+
+ pScreen = screenInfo.screens[0];
+ nby = BitmapBytePad(cm->width) * (long)cm->height;
+ pbits = (char *)malloc(nby);
+ if (!pbits)
+ return BadAlloc;
+ /* zeroing the (pad) bits seems to help some ddx cursor handling */
+ bzero(pbits, nby);
+
+ ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ pGC = GetScratchGC(1, pScreen);
+ if (!ppix || !pGC)
+ {
+ if (ppix)
+ fbDestroyPixmap(ppix);
+ if (pGC)
+ FreeScratchGC(pGC);
+ free(pbits);
+ return BadAlloc;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+ (void *) ppix, cm->width, cm->height, 1);
+ #endif
+
+ nxagentPixmapPriv(ppix) -> id = 0;
+ nxagentPixmapPriv(ppix) -> mid = 0;
+ nxagentPixmapPriv(ppix) -> isVirtual = True;
+ nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+ nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = cm->width;
+ rect.height = cm->height;
+
+ pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+ pGC->alu = GXcopy;
+
+ pGC->fgPixel = 0;
+
+ pfont->refcnt++;
+
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+
+ pGC->font = pfont;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+ /* draw the glyph */
+ pGC->fgPixel = 1;
+
+ pGC->stateChanges |= GCForeground;
+
+ ValidateGC((DrawablePtr)ppix, pGC);
+ miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+ fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+ XYPixmap, 1, pbits);
+ *ppbits = (unsigned char *)pbits;
+ FreeScratchGC(pGC);
+ fbDestroyPixmap(ppix);
+
+ #ifdef TEST
+ fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+ (void *) ppix);
+ #endif
+
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphRef.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphRef.h
new file mode 100644
index 000000000..eef2da8dd
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphRef.h
@@ -0,0 +1,60 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/* this header file gets included into Xserver/render/glyphstr.h */
+
+#ifndef NX_GLYPHSTR_GLYPHREF_H
+#define NX_GLYPHSTR_GLYPHREF_H 1
+
+typedef struct _GlyphRef {
+ CARD32 signature;
+ GlyphPtr glyph;
+ CARD16 corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#endif /* NX_GLYPHSTR_GLYPHREF_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphSet.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphSet.h
new file mode 100644
index 000000000..98f331dd7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr_GlyphSet.h
@@ -0,0 +1,64 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/* this header file gets included into Xserver/render/glyphstr.h */
+
+#ifndef NX_GLYPHSTR_GLYPHSET_H
+#define NX_GLYPHSTR_GLYPHSET_H 1
+
+typedef struct _GlyphSet {
+ CARD32 refcnt;
+ PictFormatPtr format;
+ int fdepth;
+ GlyphHashRec hash;
+ int maxPrivate;
+ void **devPrivates;
+ CARD32 remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+#endif /* NX_GLYPHSTR_GLYPHSET_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
new file mode 100644
index 000000000..bcb88d42d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
@@ -0,0 +1,743 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#include "Windows.h"
+
+#include "../../mi/miexpose.c"
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ expBox.x1 = 0;
+ expBox.y1 = 0;
+ expBox.x2 = 0;
+ expBox.y2 = 0;
+
+ /* This prevents warning about pscr not being used. */
+ pGC->pScreen = pscr = pGC->pScreen;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ RegionDestroy(prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ RegionNull(prgnSrcClip);
+ RegionCopy(prgnSrcClip, &pSrcWin->clipList);
+ }
+ RegionTranslate(prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ RegionInit(prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ RegionNull(prgnDstClip);
+ RegionCopy(prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ RegionTranslate(prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ RegionInit(prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ RegionInit(&rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RegionContainsRect(region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *RegionExtents(&rgnExposed);
+ RegionReset(&rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ RegionTranslate(&rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ RegionReset(&rgnExposed, &expBox);
+ }
+ else
+ RegionTranslate(&rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ RegionUninit(prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ RegionDestroy(prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ RegionUninit(prgnSrcClip);
+ }
+ else
+ {
+ RegionDestroy(prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = RegionCreate(NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ RegionUninit(&rgnExposed);
+ return NULL;
+ }
+}
+
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+
+ int total;
+
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !RegionNil(prgn)) ||
+ (exposures && !RegionNil(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ RegionUnion(other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ RegionDestroy(exposures);
+ }
+ exposures = other_exposed;
+ }
+
+ /*
+ * If the number of rectangles is greater
+ * than 4, let the function decide.
+ */
+
+ total = RegionNumRects(exposures);
+
+ if (clientInterested && exposures && (total > RECTLIMIT ||
+ (total > 4 && nxagentExtentsPredicate(total) == 1)))
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *RegionExtents(exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ RegionInit(exposures, &box, 1);
+ RegionReset(prgn, &box);
+ } else {
+ RegionReset(exposures, &box);
+ RegionUnion(prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ RegionIntersect(prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !RegionNil(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !RegionNil(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ RegionUninit(exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ RegionDestroy(exposures);
+ if (prgn)
+ RegionEmpty(prgn);
+ }
+ else if (exposures && exposures != prgn)
+ RegionDestroy(exposures);
+}
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS] = {{ 0 }};
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ /*
+ * Set the elements reported by the compiler
+ * as uninitialized.
+ */
+
+ prgnWin.extents.x1 = 0;
+ prgnWin.extents.y1 = 0;
+ prgnWin.extents.x2 = 0;
+ prgnWin.extents.y2 = 0;
+
+ prgnWin.data = NULL;
+
+ oldCorner.x = 0;
+ oldCorner.y = 0;
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (void *)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (void *)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)malloc(RegionNumRects(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = screenInfo.screens[i]->root;
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ free(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ RegionInit(&pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (void *)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = RegionNumRects(prgn);
+ pbox = RegionRects(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ free(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ RegionUninit(&pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
new file mode 100644
index 000000000..1988ca102
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
@@ -0,0 +1,123 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "Render.h"
+
+#include "../../render/mitrap.c"
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
+ }
+ else
+ {
+ nxagentTrapezoidExtents = (BoxPtr) malloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
+ }
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
new file mode 100644
index 000000000..4ea7d2d73
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -0,0 +1,654 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include "picturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+#include "Render.h"
+
+/* prototypes */
+
+PictFormatPtr PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+PicturePtr AllocatePicture (ScreenPtr pScreen);
+PicturePtr CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error);
+static PicturePtr createSourcePicture(void);
+int FreePicture (void *value, XID pid);
+
+#include "../../render/picture.c"
+
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+ int nformats, f;
+ PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+
+ nformats = 0;
+
+ nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+ pFormats = (PictFormatPtr) calloc (nformats, sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ break;
+ }
+
+ if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+ pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+ pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+ pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+ #endif
+ }
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PicturePtr pPicture;
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned int *sizes;
+ unsigned int size;
+ int i;
+
+ pPicture = (PicturePtr) calloc(1, ps->totalPictureSize);
+ if (!pPicture)
+ return 0;
+ ppriv = (DevUnion *)(pPicture + 1);
+ pPicture->devPrivates = ppriv;
+ sizes = ps->PicturePrivateSizes;
+ ptr = (char *)(ppriv + ps->PicturePrivateLen);
+ for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+
+ nxagentPicturePriv(pPicture) -> picture = 0;
+
+ return pPicture;
+}
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error)
+{
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
+
+ pPicture = AllocatePicture (pDrawable->pScreen);
+ if (!pPicture)
+ {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pDrawable = pDrawable;
+ pPicture->pFormat = pFormat;
+ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ /*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+ pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+ ++((PixmapPtr)pDrawable)->refcnt;
+ pPicture->pNext = 0;
+ }
+ else
+ {
+ pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+ SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+ }
+
+ SetPictureToDefaults (pPicture);
+
+ if (vmask)
+ *error = ChangePicture (pPicture, vmask, vlist, 0, client);
+ else
+ *error = Success;
+ if (*error == Success)
+ *error = (*ps->CreatePicture) (pPicture);
+ if (*error != Success)
+ {
+ FreePicture (pPicture, (XID) 0);
+ pPicture = 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) calloc(1, sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ free(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+ pPicture->pSourcePict->solidFill.fullColor.alpha=color->alpha;
+ pPicture->pSourcePict->solidFill.fullColor.red=color->red;
+ pPicture->pSourcePict->solidFill.fullColor.green=color->green;
+ pPicture->pSourcePict->solidFill.fullColor.blue=color->blue;
+ return pPicture;
+}
+
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+
+ extern int nxagentPicturePrivateIndex;
+
+ unsigned int totalPictureSize;
+
+ DevUnion *ppriv;
+
+ char *privPictureRecAddr;
+
+ int i;
+
+ /*
+ * Compute size of entire PictureRect, plus privates.
+ */
+
+ totalPictureSize = sizeof(PictureRec) +
+ picturePrivateCount * sizeof(DevUnion) +
+ sizeof(nxagentPrivPictureRec);
+
+ pPicture = (PicturePtr) calloc(1, totalPictureSize);
+
+ if (pPicture != NULL)
+ {
+ ppriv = (DevUnion *) (pPicture + 1);
+
+ for (i = 0; i < picturePrivateCount; ++i)
+ {
+ /*
+ * Other privates are inaccessible.
+ */
+
+ ppriv[i].ptr = NULL;
+ }
+
+ privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+ ppriv[nxagentPicturePrivateIndex].ptr = (void *) privPictureRecAddr;
+
+ pPicture -> devPrivates = ppriv;
+
+ nxagentPicturePriv(pPicture) -> picture = 0;
+ }
+
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+int
+FreePicture (void * value,
+ XID pid)
+{
+ PicturePtr pPicture = (PicturePtr) value;
+
+ if (--pPicture->refcnt == 0)
+ {
+ nxagentDestroyPicture(pPicture);
+
+ if (pPicture->transform)
+ free (pPicture->transform);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ free(pPicture->pSourcePict->linear.stops);
+ free(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ if (pPicture->alphaMap)
+ FreePicture ((void *) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
+
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
+ free (pPicture);
+ }
+ return Success;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+ PictFormatPtr formats_old, formats;
+ int nformats, nformats_old;
+ VisualPtr pVisual;
+ Bool success = True;
+ Bool matched;
+ int i, n;
+ CARD32 type, a, r, g, b;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+ #endif
+
+ formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+ nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+ /*
+ * TODO: We could copy PictureCreateDefaultFormats,
+ * in order not to waste ID with FakeClientID().
+ */
+ formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+ if (!formats)
+ return False;
+
+ for (n = 0; n < nformats; n++)
+ {
+ if (formats[n].type == PictTypeIndexed)
+ {
+ pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+
+ for (n = 0; n < nformats_old; n++)
+ {
+ for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+ {
+ if (formats_old[n].format == formats[i].format &&
+ formats_old[n].type == formats[i].type &&
+ formats_old[n].direct.red == formats[i].direct.red &&
+ formats_old[n].direct.green == formats[i].direct.green &&
+ formats_old[n].direct.blue == formats[i].direct.blue &&
+ formats_old[n].direct.redMask == formats[i].direct.redMask &&
+ formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+ formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+ formats_old[n].direct.alpha == formats[i].direct.alpha &&
+ formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+ {
+ /*
+ * Regard depth 16 and 15 as were the same, if all other values match.
+ */
+
+ if ((formats_old[n].depth == formats[i].depth) ||
+ ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+ (formats[i].depth == 15 || formats[i].depth == 16)))
+ {
+ matched = True;
+ }
+ }
+ }
+
+ if (!matched)
+ {
+ return False;
+ }
+ }
+
+ free(formats);
+
+ /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+ /* TODO: We have to check for new Render protocol version. */
+
+ for (i = 0; (i < MAXCLIENTS) && (success); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+ }
+ }
+
+ return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+ fprintf(stderr, "nxagentReconnectPictFormat.\n");
+ #endif
+}
+
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ CARD32 format;
+ CARD8 depth;
+
+ int r, g, b;
+ int bpp;
+ int d;
+ int v;
+
+
+ formats[*nformats].format = PICT_a1;
+ formats[*nformats].depth = 1;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a4;
+ formats[*nformats].depth = 4;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8;
+ formats[*nformats].depth = 8;
+ *nformats += 1;
+ formats[*nformats].format = PICT_a8r8g8b8;
+ formats[*nformats].depth = 32;
+ *nformats += 1;
+
+ /*
+ * This format should be required by the
+ * protocol, but it's not used by Xgl.
+ *
+ * formats[*nformats].format = PICT_x8r8g8b8;
+ * formats[*nformats].depth = 32;
+ * *nformats += 1;
+ */
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+
+ bpp = BitsPerPixel (depth);
+
+ switch (pVisual->class)
+ {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+ *nformats = addFormat (formats, *nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case StaticGray:
+ case GrayScale:
+ break;
+ }
+ }
+
+ for (d = 0; d < pScreen -> numDepths; d++)
+ {
+ pDepth = &pScreen -> allowedDepths[d];
+ bpp = BitsPerPixel(pDepth -> depth);
+
+ switch (bpp) {
+ case 16:
+ if (pDepth->depth == 15)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ }
+
+ if (pDepth->depth == 16)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r5g6b5, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_r8g8b8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth == 24)
+ {
+ *nformats = addFormat (formats, *nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ }
+ break;
+ }
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr_PictSolidFill.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr_PictSolidFill.h
new file mode 100644
index 000000000..9cd73db5c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr_PictSolidFill.h
@@ -0,0 +1,63 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+/* this header file gets included into Xserver/render/picturestr.h */
+
+#ifndef NX_PICTURESTR_PICTSOLIDFILL_H
+#define NX_PICTURESTR_PICTSOLIDFILL_H 1
+
+
+typedef struct _PictSolidFill {
+ unsigned int type;
+ CARD32 color;
+ xRenderColor fullColor;
+} PictSolidFill, *PictSolidFillPtr;
+
+#endif /* NX_PICTURESTR_PICTSOLIDFILL_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
new file mode 100644
index 000000000..ee77eb64e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -0,0 +1,653 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#include "../../dix/property.c"
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+#include "Windows.h"
+
+extern Atom clientCutProperty;
+
+#ifdef NXAGENT_SERVER
+typedef struct
+{
+ CARD32 state;
+ Window icon;
+}
+nxagentWMStateRec;
+#endif
+
+int
+ProcChangeProperty(ClientPtr client)
+{
+ WindowPtr pWin;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+ REQUEST(xChangePropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend))
+ {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32))
+ {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+ {
+ extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+ pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+ }
+
+ if (pWin == NULL)
+#endif
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixWriteAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if (!ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ DixWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ return Success;
+ }
+#endif
+
+#ifdef NXAGENT_ARTSD
+ {
+ /* Do not process MCOPGLOBALS property changes,
+ they are already set reflecting the server side settings.
+ Just return success.
+ */
+ extern Atom mcop_local_atom;
+ if (stuff->property == mcop_local_atom)
+ return client->noClientException;
+ }
+#endif
+
+ err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+ (int)mode, len, (void *)&stuff[1], TRUE);
+ if (err != Success)
+ return err;
+ else
+ {
+ if (nxagentOption(Rootless) == 1)
+ {
+ nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+ (int) mode, len, (void *) &stuff[1]);
+ }
+
+ nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+ nxagentGuessShadowHint(client, stuff->property);
+
+ #ifdef NX_DEBUG_INPUT
+ nxagentGuessDumpInputInfo(client, stuff->property, (char *) &stuff[1]);
+ #endif
+
+ return client->noClientException;
+ }
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long len, void * value,
+ Bool sendevent)
+{
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ void * data;
+ int copySize;
+
+ memset(&event, 0, sizeof(xEvent));
+
+ sizeInBytes = format>>3;
+ totalSize = len * sizeInBytes;
+
+ copySize = nxagentOption(CopyBufferSize);
+
+ if (copySize != COPY_UNLIMITED && property == clientCutProperty)
+ {
+ if (totalSize > copySize)
+ {
+ totalSize = copySize;
+ totalSize = totalSize - (totalSize % sizeInBytes);
+ len = totalSize / sizeInBytes;
+ }
+ }
+
+ /* first see if property already exists */
+
+ pProp = wUserProps (pWin);
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) /* just add to list */
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return(BadAlloc);
+ pProp = (PropertyPtr)malloc(sizeof(PropertyRec));
+ if (!pProp)
+ return(BadAlloc);
+ data = (void *)malloc(totalSize);
+ if (!data && len)
+ {
+ free(pProp);
+ return(BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (len)
+ memmove((char *)data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ }
+ else
+ {
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return(BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return(BadMatch);
+ if (mode == PropModeReplace)
+ {
+ if (totalSize != pProp->size * (pProp->format >> 3))
+ {
+ data = (void *)realloc(pProp->data, totalSize);
+ if (!data && len)
+ return(BadAlloc);
+ pProp->data = data;
+ }
+ if (len)
+ memmove((char *)pProp->data, (char *)value, totalSize);
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ }
+ else if (len == 0)
+ {
+ /* do nothing */
+ }
+ else if (mode == PropModeAppend)
+ {
+ data = (void *)realloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ pProp->data = data;
+ memmove(&((char *)data)[pProp->size * sizeInBytes],
+ (char *)value,
+ totalSize);
+ pProp->size += len;
+ }
+ else if (mode == PropModePrepend)
+ {
+ data = (void *)malloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return(BadAlloc);
+ memmove(&((char *)data)[totalSize], (char *)pProp->data,
+ (int)(pProp->size * sizeInBytes));
+ memmove((char *)data, (char *)value, totalSize);
+ free(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent)
+ {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+ return(Success);
+}
+
+/*****************
+ * GetProperty
+ * If type Any is specified, returns the property from the specified
+ * window regardless of its type. If a type is specified, returns the
+ * property only if its type equals the specified type.
+ * If delete is True and a property is returned, the property is also
+ * deleted from the window and a PropertyNotify event is generated on the
+ * window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+ WindowPtr pWin;
+ xGetPropertyReply reply;
+ REQUEST(xGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xGetPropertyReq);
+
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return BadWindow;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return(BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
+ {
+ client->errorValue = stuff->delete;
+ return(BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+ while (pProp)
+ {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+ memset(&reply, 0, sizeof(xGetPropertyReply));
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ #ifdef NXAGENT_SERVER
+
+ /*
+ * Creating a reply for WM_STATE property if it doesn't exist.
+ * This is intended to allow drag & drop work in JAva 1.6 when
+ * the agent is connected to NXWin in multiwindow mode.
+ */
+
+ if (nxagentOption(Rootless) &&
+ nxagentWindowTopLevel(pWin) &&
+ (!pProp) &&
+ strcmp(NameForAtom(stuff->property), "WM_STATE") == 0)
+ {
+ nxagentWMStateRec wmState;
+ nxagentWMStateRec *wmsP = &wmState;
+
+ memset(&wmState, 0, sizeof(nxagentWMStateRec));
+ wmState.state = 1;
+ wmState.icon = None;
+
+ if (ChangeWindowProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState, 1) == Success)
+ {
+ nxagentExportProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState);
+ }
+
+ n = 8;
+ ind = stuff->longOffset << 2;
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.length = (len + 3) >> 2;
+
+ reply.format = 32;
+ reply.nItems = len / 4;
+ reply.propertyType = stuff->property;
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+
+ if (len)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
+
+ WriteSwappedDataToClient(client, len, (char *)wmsP + ind);
+ }
+
+ return(client->noClientException);
+ }
+ #endif
+
+ if (!pProp)
+ return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+ {
+ Mask access_mode = DixReadAccess;
+
+ if (stuff->delete)
+ access_mode |= DixDestroyAccess;
+ switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ access_mode))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;;
+ case SecurityIgnoreOperation:
+ return NullPropertyReply(client, pProp->type, pProp->format,
+ &reply);
+ }
+ }
+#endif
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType))
+ )
+ {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.length = (len + 3) >> 2;
+ reply.nItems = len / (pProp->format / 8 );
+ reply.propertyType = pProp->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+ if (len)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *)pProp->data + ind);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0))
+ { /* delete the Property */
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ free(pProp->data);
+ free(pProp);
+ }
+ return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+ type, actualType, format, nItems, bytesAfter, propData )
+ WindowPtr pWin;
+ Atom property;
+ long longOffset;
+ long longLength;
+ Bool delete;
+ Atom type;
+ Atom *actualType;
+ int *format;
+ unsigned long *nItems;
+ unsigned long *bytesAfter;
+ unsigned char **propData;
+{
+ PropertyPtr pProp, prevProp;
+ unsigned long n, len, ind;
+
+ if (!pWin)
+ return BadWindow;
+
+
+ if (!ValidAtom(property))
+ {
+ return(BadAtom);
+ }
+ if ((type != AnyPropertyType) && !ValidAtom(type))
+ {
+ return(BadAtom);
+ }
+
+ pProp = wUserProps (pWin);
+ prevProp = (PropertyPtr)NULL;
+
+ while (pProp)
+ {
+ if (pProp->propertyName == property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+
+
+ if (!pProp)
+ return (BadAtom);
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((type != pProp->type) &&
+ (type != AnyPropertyType))
+ )
+ {
+ *bytesAfter = pProp->size;
+ *format = pProp->format;
+ *nItems = 0;
+ *actualType = pProp->type;
+ return(Success);
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ ind = longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind)
+ {
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * longLength);
+
+ *bytesAfter = n - (ind + len);
+ *format = pProp->format;
+ *nItems = len / (pProp->format / 8 );
+ *actualType = pProp->type;
+
+ if (delete && (*bytesAfter == 0))
+ { /* send the event */
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+ }
+
+ if (len)
+ {
+ *propData = (unsigned char *)(pProp->data) + ind;
+ }
+
+ if (delete && (*bytesAfter == 0))
+ { /* delete the Property */
+ if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+ {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ else
+ prevProp->next = pProp->next;
+ free(pProp->data);
+ free(pProp);
+ }
+ return(Success);
+}
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
new file mode 100644
index 000000000..691b260cf
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -0,0 +1,1730 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include "../render/render.c"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+/*
+ * From NXglyph.c.
+ */
+
+extern
+void GlyphExtents(int nlist, GlyphListPtr list,
+ GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * From NXmitrap.c.
+ */
+
+extern
+void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+/*
+ * Functions from Render.c.
+ */
+
+extern int nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+extern void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+extern int nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+extern int nxagentCreatePicture(PicturePtr, Mask);
+extern void nxagentChangePicture(PicturePtr, Mask);
+extern int nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+extern void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+ INT16, INT16, INT16, INT16, CARD16, CARD16);
+extern void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+extern void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+extern void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+extern void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+extern void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+extern void nxagentSetPictureTransform(PicturePtr pPicture, void * transform);
+extern void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+ void * params, int nparams);
+extern void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+ INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+extern void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
+extern void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+ xPointFixed *p2, int nStops,
+ xFixed *stops,
+ xRenderColor *colors);
+extern void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors);
+extern void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+ xPointFixed *center,
+ xFixed angle, int nStops,
+ xFixed *stops,
+ xRenderColor *colors);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+ INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryVersionReply rep;
+ REQUEST(xRenderQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+
+ pRenderClient->major_version = stuff->majorVersion;
+ pRenderClient->minor_version = stuff->minorVersion;
+
+ memset(&rep, 0, sizeof(xRenderQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = nxagentRenderVersionMajor;
+ rep.minorVersion = nxagentRenderVersionMinor;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryPictFormatsReply *reply;
+ xPictScreen *pictScreen;
+ xPictDepth *pictDepth;
+ xPictVisual *pictVisual;
+ xPictFormInfo *pictForm;
+ CARD32 *pictSubpixel;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ DepthPtr pDepth;
+ int v, d;
+ PictureScreenPtr ps;
+ PictFormatPtr pFormat;
+ int nformat;
+ int ndepth;
+ int nvisual;
+ int rlength;
+ int s;
+ int numScreens;
+ int numSubpixel;
+
+ extern int nxagentAlphaEnabled;
+/* REQUEST(xRenderQueryPictFormatsReq); */
+
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+ numScreens = screenInfo.numScreens;
+#endif
+ ndepth = nformat = nvisual = 0;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ ++ndepth;
+
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+ ++nvisual;
+ }
+ }
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ nformat += ps->nformats;
+ }
+ if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+ numSubpixel = 0;
+ else
+ numSubpixel = numScreens;
+
+ rlength = (sizeof (xRenderQueryPictFormatsReply) +
+ nformat * sizeof (xPictFormInfo) +
+ numScreens * sizeof (xPictScreen) +
+ ndepth * sizeof (xPictDepth) +
+ nvisual * sizeof (xPictVisual) +
+ numSubpixel * sizeof (CARD32));
+ reply = (xRenderQueryPictFormatsReply *) calloc (1, rlength);
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numFormats = nformat;
+ reply->numScreens = numScreens;
+ reply->numDepths = ndepth;
+ reply->numVisuals = nvisual;
+ reply->numSubpixel = numSubpixel;
+
+ pictForm = (xPictFormInfo *) (reply + 1);
+
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (nformat = 0, pFormat = ps->formats;
+ nformat < ps->nformats;
+ nformat++, pFormat++)
+ {
+ pictForm->id = pFormat->id;
+ pictForm->type = pFormat->type;
+ pictForm->depth = pFormat->depth;
+ pictForm->direct.red = pFormat->direct.red;
+ pictForm->direct.redMask = pFormat->direct.redMask;
+ pictForm->direct.green = pFormat->direct.green;
+ pictForm->direct.greenMask = pFormat->direct.greenMask;
+ pictForm->direct.blue = pFormat->direct.blue;
+ pictForm->direct.blueMask = pFormat->direct.blueMask;
+ pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+ pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ pictForm->colormap = pFormat->index.pColormap->mid;
+ else
+ pictForm->colormap = None;
+ if (client->swapped)
+ {
+ swapl (&pictForm->id);
+ swaps (&pictForm->direct.red);
+ swaps (&pictForm->direct.redMask);
+ swaps (&pictForm->direct.green);
+ swaps (&pictForm->direct.greenMask);
+ swaps (&pictForm->direct.blue);
+ swaps (&pictForm->direct.blueMask);
+ swaps (&pictForm->direct.alpha);
+ swaps (&pictForm->direct.alphaMask);
+ swapl (&pictForm->colormap);
+ }
+ pictForm++;
+ }
+ }
+ }
+
+ pictScreen = (xPictScreen *) pictForm;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ pictDepth = (xPictDepth *) (pictScreen + 1);
+ ndepth = 0;
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pictVisual = (xPictVisual *) (pictDepth + 1);
+ pDepth = pScreen->allowedDepths + d;
+
+ nvisual = 0;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && (pFormat = PictureMatchVisual (pScreen,
+ pDepth->depth,
+ pVisual)))
+ {
+ pictVisual->visual = pVisual->vid;
+ pictVisual->format = pFormat->id;
+ if (client->swapped)
+ {
+ swapl (&pictVisual->visual);
+ swapl (&pictVisual->format);
+ }
+ pictVisual++;
+ nvisual++;
+ }
+ }
+ pictDepth->depth = pDepth->depth;
+ pictDepth->nPictVisuals = nvisual;
+ if (client->swapped)
+ {
+ swaps (&pictDepth->nPictVisuals);
+ }
+ ndepth++;
+ pictDepth = (xPictDepth *) pictVisual;
+ }
+ pictScreen->nDepth = ndepth;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ pictScreen->fallback = ps->fallback->id;
+ else
+ pictScreen->fallback = 0;
+ if (client->swapped)
+ {
+ swapl (&pictScreen->nDepth);
+ swapl (&pictScreen->fallback);
+ }
+ pictScreen = (xPictScreen *) pictDepth;
+ }
+ pictSubpixel = (CARD32 *) pictScreen;
+
+ for (s = 0; s < numSubpixel; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ *pictSubpixel = ps->subpixel;
+ else
+ *pictSubpixel = SubPixelUnknown;
+ if (client->swapped)
+ {
+ swapl (pictSubpixel);
+ }
+ ++pictSubpixel;
+ }
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber);
+ swapl (&reply->length);
+ swapl (&reply->numFormats);
+ swapl (&reply->numScreens);
+ swapl (&reply->numDepths);
+ swapl (&reply->numVisuals);
+ swapl (&reply->numSubpixel);
+ }
+ WriteToClient(client, rlength, reply);
+ free (reply);
+ return client->noClientException;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ int len;
+ int error;
+ REQUEST(xRenderCreatePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+ DixWriteAccess);
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->depth != pDrawable->depth)
+ return BadMatch;
+ len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ pPicture = CreatePicture (stuff->pid,
+ pDrawable,
+ pFormat,
+ stuff->mask,
+ (XID *) (stuff + 1),
+ client,
+ &error);
+ if (!pPicture)
+ return error;
+ nxagentCreatePicture(pPicture, stuff -> mask);
+
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderChangePictureReq);
+ int len;
+ int error;
+
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ (DevUnion *) 0, client);
+
+ nxagentChangePicture(pPicture, stuff->mask);
+
+ return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ PicturePtr pPicture;
+ int nr;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
+ /*
+ * The original code used sizeof(xRenderChangePictureReq).
+ * This was harmless, as both structures have the same size.
+ *
+ * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+ */
+ nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+ if (nr & 4)
+ return BadLength;
+ nr >>= 3;
+ result = SetPictureClipRects (pPicture,
+ stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *) &stuff[1]);
+ nxagentChangePictureClip (pPicture,
+ CT_NONE,
+ nr,
+ (xRectangle *) &stuff[1],
+ (int)stuff -> xOrigin,
+ (int)stuff -> yOrigin);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst) TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+ PixmapPtr pPixmap1;
+ PixmapPtr pPixmap2;
+
+ pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+ pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+ ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+ if (pPixmap1 == NULL || pPixmap2 == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+ #endif
+
+ return FALSE;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+ #endif
+
+ if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+ nxagentPixmapIsVirtual(pPixmap2) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+ #endif
+
+ return TRUE;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+ #endif
+
+ return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+ PicturePtr pSrc, pMask, pDst;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ return BadMatch;
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+
+ #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+ if (nxagentCompositePredicate(pSrc, pDst))
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pMask, (void *) pDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+
+ #else
+
+ if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+ {
+ PixmapPtr pVirtualPixmapSrc;
+ PixmapPtr pVirtualPixmapDst;
+ PixmapPtr pVirtualPixmapMask;
+
+ PicturePtr pVirtualPictureSrc;
+ PicturePtr pVirtualPictureDst;
+ PicturePtr pVirtualPictureMask;
+
+ pVirtualPixmapSrc = (PixmapPtr) pSrc -> pDrawable;
+ pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+ pVirtualPixmapDst = (PixmapPtr) pDst -> pDrawable;
+ pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+ if (pMask)
+ {
+ pVirtualPixmapMask = (PixmapPtr) pMask -> pDrawable;
+ pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+ }
+ else
+ {
+ pVirtualPixmapMask = NULL;
+ pVirtualPictureMask = NULL;
+ }
+
+ if (pVirtualPictureSrc && pVirtualPictureDst)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderComposite: Going to composite with "
+ "source at [%p] mask at [%p] and destination at [%p].\n",
+ (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+ (void *) pVirtualPixmapDst);
+ #endif
+
+ CompositePicture (stuff->op,
+ pVirtualPictureSrc,
+ pVirtualPictureMask,
+ pVirtualPictureDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ }
+ }
+
+ #endif
+
+ nxagentComposite (stuff -> op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ stuff -> xMask,
+ stuff -> yMask,
+ stuff -> xDst,
+ stuff -> yDst,
+ stuff -> width,
+ stuff -> height);
+
+ return Success;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+ if (ntraps % sizeof (xTrapezoid))
+ return BadLength;
+ ntraps /= sizeof (xTrapezoid);
+ if (ntraps)
+ {
+ if (pFormat != NULL)
+ {
+ nxagentTrapezoidExtents = (BoxPtr) malloc(sizeof(BoxRec));
+
+ miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
+ }
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+ }
+
+ nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+
+ if (nxagentTrapezoidExtents != NullBox)
+ {
+ free(nxagentTrapezoidExtents);
+
+ nxagentTrapezoidExtents = NullBox;
+ }
+ }
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ PictFormatPtr format;
+ int f;
+ REQUEST(xRenderCreateGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+ format = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ DixReadAccess);
+ if (!format)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ switch (format->depth) {
+ case 1:
+ f = GlyphFormat1;
+ break;
+ case 4:
+ f = GlyphFormat4;
+ break;
+ case 8:
+ f = GlyphFormat8;
+ break;
+ case 16:
+ f = GlyphFormat16;
+ break;
+ case 32:
+ f = GlyphFormat32;
+ break;
+ default:
+ return BadMatch;
+ }
+ if (format->type != PictTypeDirect)
+ return BadMatch;
+ glyphSet = AllocateGlyphSet (f, format);
+ if (!glyphSet)
+ return BadAlloc;
+ if (!AddResource (stuff->gsid, GlyphSetType, (void *)glyphSet))
+ return BadAlloc;
+
+ nxagentCreateGlyphSet(glyphSet);
+
+ return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderReferenceGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->existing,
+ GlyphSetType,
+ DixWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->existing;
+ return RenderErrBase + BadGlyphSet;
+ }
+ glyphSet->refcnt++;
+
+ nxagentReferenceGlyphSet(glyphSet);
+
+ if (!AddResource (stuff->gsid, GlyphSetType, (void *)glyphSet))
+ return BadAlloc;
+ return client->noClientException;
+}
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderFreeGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixDestroyAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nxagentFreeGlyphSet(glyphSet);
+
+ FreeResource (stuff->glyphset, RT_NONE);
+ return client->noClientException;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ GlyphSetPtr glyphSet;
+ int nglyph;
+ CARD32 *gids;
+ CARD32 glyph;
+
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+ gids = (CARD32 *) (stuff + 1);
+
+ nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+ while (nglyph-- > 0)
+ {
+ glyph = *gids++;
+ if (!DeleteGlyph (glyphSet, glyph))
+ {
+ client->errorValue = glyph;
+ return RenderErrBase + BadGlyph;
+ }
+ }
+ return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+ GlyphSet glyphset;
+ _Xconst char *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ GlyphSet gs;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ GlyphListRec listsLocal[NLOCALDELTA];
+ GlyphListPtr lists, listsBase;
+ GlyphPtr glyphsLocal[NLOCALGLYPH];
+ Glyph glyph;
+ GlyphPtr *glyphs, *glyphsBase;
+ xGlyphElt *elt;
+ CARD8 *buffer, *end;
+ int nglyph;
+ int nlist;
+ int space;
+ int size;
+ int n;
+
+ XGlyphElt8 *elements, *elementsBase;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ nglyph = 0;
+ nlist = 0;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ buffer += 4;
+ }
+ else
+ {
+ nlist++;
+ nglyph += elt->len;
+ space = size * elt->len;
+ if (space & 3)
+ space += 4 - (space & 3);
+ buffer += space;
+ }
+ }
+ if (nglyph <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphPtr *) malloc (nglyph * sizeof (GlyphPtr));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+ if (nlist <= NLOCALDELTA)
+ listsBase = listsLocal;
+ else
+ {
+ listsBase = (GlyphListPtr) malloc (nlist * sizeof (GlyphListRec));
+ if (!listsBase)
+ return BadAlloc;
+ }
+
+ elementsBase = malloc(nlist * sizeof(XGlyphElt8));
+ if (!elementsBase)
+ return BadAlloc;
+
+ buffer = (CARD8 *) (stuff + 1);
+ glyphs = glyphsBase;
+ lists = listsBase;
+ elements = elementsBase;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+ size);
+ #endif
+
+ if (buffer + sizeof (GlyphSet) < end)
+ {
+ memcpy(&gs, buffer, sizeof(GlyphSet));
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ gs,
+ GlyphSetType,
+ DixReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = gs;
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ if (listsBase != listsLocal)
+ free (listsBase);
+ return RenderErrBase + BadGlyphSet;
+ }
+ }
+ buffer += 4;
+ }
+ else
+ {
+ lists->xOff = elt->deltax;
+ lists->yOff = elt->deltay;
+ lists->format = glyphSet->format;
+ lists->len = 0;
+
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
+ (void *) glyphSet);
+ #endif
+
+ nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+ }
+
+ elements -> glyphset = glyphSet -> remoteID;
+ elements -> chars = (char *) buffer;
+ elements -> nchars = elt->len;
+ elements -> xOff = elt->deltax;
+ elements -> yOff = elt->deltay;
+ n = elt->len;
+ while (n--)
+ {
+ if (buffer + size <= end)
+ {
+ switch (size) {
+ case 1:
+ glyph = *((CARD8 *)buffer); break;
+ case 2:
+ glyph = *((CARD16 *)buffer); break;
+ case 4:
+ default:
+ glyph = *((CARD32 *)buffer); break;
+ }
+ if ((*glyphs = FindGlyph (glyphSet, glyph)))
+ {
+ lists->len++;
+ glyphs++;
+ }
+ }
+ buffer += size;
+ }
+ space = size * elt->len;
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ lists++;
+ elements++;
+ }
+ }
+ if (buffer > end)
+ return BadLength;
+
+ /*
+ * We need to know the glyphs extents to synchronize
+ * the drawables involved in the composite text ope-
+ * ration. Also we need to synchronize only the back-
+ * ground of the text we are going to render, so the
+ * operations on the framebuffer must be executed
+ * after the X requests.
+ */
+
+ nxagentGlyphsExtents = (BoxPtr) malloc(sizeof(BoxRec));
+
+ GlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+
+ nxagentGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ elementsBase,
+ size,
+ glyphsBase);
+
+ if (nxagentCompositePredicate(pSrc, pDst) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+ "source at [%p] and destination at [%p].\n",
+ (void *) pSrc, (void *) pDst);
+ #endif
+
+ CompositeGlyphs(stuff -> op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff -> xSrc,
+ stuff -> ySrc,
+ nlist,
+ listsBase,
+ glyphsBase);
+ }
+
+ free(nxagentGlyphsExtents);
+ nxagentGlyphsExtents = NullBox;
+
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ if (listsBase != listsLocal)
+ free (listsBase);
+
+ free(elementsBase);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+ PicturePtr pDst;
+ int things;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+
+ things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ CompositeRects (stuff->op,
+ pDst,
+ &stuff->color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ ValidatePicture (pDst);
+ nxagentCompositeRects(stuff -> op,
+ pDst,
+ &stuff -> color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ PicturePtr pSrc;
+ ScreenPtr pScreen;
+ unsigned short width, height;
+ CARD32 *argbbits, *argb;
+ unsigned char *srcbits, *srcline;
+ unsigned char *mskbits, *mskline;
+ int stride;
+ int x, y;
+ int nbytes_mono;
+ CursorMetricRec cm;
+ CursorPtr pCursor;
+ CARD32 twocolor[3];
+ int ncolor;
+
+ RealizeCursorProcPtr saveRealizeCursor;
+
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
+ pScreen = pSrc->pDrawable->pScreen;
+ width = pSrc->pDrawable->width;
+ height = pSrc->pDrawable->height;
+ if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+ return BadAlloc;
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+ argbbits = malloc (width * height * sizeof (CARD32));
+ if (!argbbits)
+ return (BadAlloc);
+
+ stride = BitmapBytePad(width);
+ nbytes_mono = stride*height;
+ srcbits = (unsigned char *)malloc(nbytes_mono);
+ if (!srcbits)
+ {
+ free (argbbits);
+ return (BadAlloc);
+ }
+ mskbits = (unsigned char *)malloc(nbytes_mono);
+ if (!mskbits)
+ {
+ free(argbbits);
+ free(srcbits);
+ return (BadAlloc);
+ }
+ bzero ((char *) mskbits, nbytes_mono);
+ bzero ((char *) srcbits, nbytes_mono);
+
+ if (pSrc->format == PICT_a8r8g8b8)
+ {
+ (*pScreen->GetImage) (pSrc->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (void *) argbbits);
+ }
+ else
+ {
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return (BadImplementation);
+ }
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return (BadAlloc);
+ }
+ pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
+ client, &error);
+ if (!pPicture)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return error;
+ }
+ (*pScreen->DestroyPixmap) (pPixmap);
+ CompositePicture (PictOpSrc,
+ pSrc, 0, pPicture,
+ 0, 0, 0, 0, 0, 0, width, height);
+ (*pScreen->GetImage) (pPicture->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (void *) argbbits);
+ FreePicture (pPicture, 0);
+ }
+ /*
+ * Check whether the cursor can be directly supported by
+ * the core cursor code
+ */
+ ncolor = 0;
+ argb = argbbits;
+ for (y = 0; ncolor <= 2 && y < height; y++)
+ {
+ for (x = 0; ncolor <= 2 && x < width; x++)
+ {
+ CARD32 p = *argb++;
+ CARD32 a = (p >> 24);
+
+ if (a == 0) /* transparent */
+ continue;
+ if (a == 0xff) /* opaque */
+ {
+ int n;
+ for (n = 0; n < ncolor; n++)
+ if (p == twocolor[n])
+ break;
+ if (n == ncolor)
+ twocolor[ncolor++] = p;
+ }
+ else
+ ncolor = 3;
+ }
+ }
+
+ /*
+ * Convert argb image to two plane cursor
+ */
+ srcline = srcbits;
+ mskline = mskbits;
+ argb = argbbits;
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ CARD32 p = *argb++;
+
+ if (ncolor <= 2)
+ {
+ CARD32 a = ((p >> 24));
+
+ SetBit (mskline, x, a != 0);
+ SetBit (srcline, x, a != 0 && p == twocolor[0]);
+ }
+ else
+ {
+ CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+ CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+ CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+ /* Set mask from dithered alpha value */
+ SetBit(mskline, x, a > d);
+ /* Set src from dithered intensity value */
+ SetBit(srcline, x, a > d && i <= d);
+ }
+ }
+ srcline += stride;
+ mskline += stride;
+ }
+ /*
+ * Dither to white and black if the cursor has more than two colors
+ */
+ if (ncolor > 2)
+ {
+ twocolor[0] = 0xff000000;
+ twocolor[1] = 0xffffffff;
+ }
+ else
+ {
+ free (argbbits);
+ argbbits = 0;
+ }
+
+#define GetByte(p,s) (((p) >> (s)) & 0xff)
+#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
+
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+
+ /*
+ * This cursor uses RENDER, so we make sure
+ * that it is allocated in a way that allows
+ * the mi and dix layers to handle it but we
+ * later create it on the server by mirror-
+ * ing the RENDER operation we got from the
+ * client.
+ */
+
+ saveRealizeCursor = pScreen -> RealizeCursor;
+
+ pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+ pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ GetColor(twocolor[0], 16),
+ GetColor(twocolor[0], 8),
+ GetColor(twocolor[0], 0),
+ GetColor(twocolor[1], 16),
+ GetColor(twocolor[1], 8),
+ GetColor(twocolor[1], 0));
+
+ pScreen -> RealizeCursor = saveRealizeCursor;
+
+ /*
+ * Store into the private data members the
+ * information needed to recreate it at
+ * reconnection. This is done in two steps
+ * as in the first step we don't have the
+ * picture info.
+ */
+
+ if (pCursor == NULL)
+ {
+ return BadAlloc;
+ }
+
+ nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+ nxagentRenderRealizeCursor(pScreen, pCursor);
+
+ if (AddResource(stuff->cid, RT_CURSOR, (void *)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ PicturePtr pPicture;
+ int result;
+
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+ nxagentSetPictureTransform(pPicture, &stuff->transform);
+
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ PicturePtr pPicture;
+ int result;
+ xFixed *params;
+ int nparams;
+ char *name;
+
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ name = (char *) (stuff + 1);
+ params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+ nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+ return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateAnimCursorReq);
+ CursorPtr *cursors;
+ CARD32 *deltas;
+ CursorPtr pCursor;
+ int ncursor;
+ xAnimCursorElt *elt;
+ int i;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+ if (client->req_len & 1)
+ return BadLength;
+ ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+ cursors = malloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+ if (!cursors)
+ return BadAlloc;
+ deltas = (CARD32 *) (cursors + ncursor);
+ elt = (xAnimCursorElt *) (stuff + 1);
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+ RT_CURSOR, DixReadAccess);
+ if (!cursors[i])
+ {
+ free (cursors);
+ client->errorValue = elt->cursor;
+ return BadCursor;
+ }
+ deltas[i] = elt->delay;
+ elt++;
+ }
+ ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+ free (cursors);
+ if (ret != Success)
+ return ret;
+
+ nxagentAnimCursorBits = pCursor -> bits;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ pCursor -> devPriv[i] = NULL;
+ }
+
+ if (AddResource (stuff->cid, RT_CURSOR, (void *)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ /* AGENT SERVER */
+
+ nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
+
+ /* AGENT SERVER */
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ /* AGENT SERVER */
+
+ nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors);
+
+ /* AGENT SERVER */
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ /* AGENT SERVER */
+
+ nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
+ stuff->inner_radius,
+ stuff->outer_radius,
+ stuff->nStops, stops, colors);
+
+ /* AGENT SERVER */
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ /* AGENT SERVER */
+
+ nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
+ stuff->angle, stuff->nStops, stops,
+ colors);
+
+ /* AGENT SERVER */
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ #ifdef TEST
+ fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentRenderRequestLiteral[stuff->data], stuff->data);
+ #endif
+
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*ProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ /*
+ * Let the client fail if we are
+ * hiding the RENDER extension.
+ */
+
+ if (nxagentRenderTrap)
+ {
+ return BadRequest;
+ }
+
+ if (stuff->data < RenderNumberRequests)
+ {
+ /*
+ * Set the nxagentGCTrap flag while
+ * dispatching a render operation to
+ * avoid reentrancy in GCOps.c.
+ */
+
+ nxagentGCTrap = 1;
+
+ result = (*SProcRenderVector[stuff->data]) (client);
+
+ nxagentGCTrap = 0;
+
+ return result;
+ }
+ else
+ return BadRequest;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c
new file mode 100644
index 000000000..a564d84b9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c
@@ -0,0 +1,595 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/* Routines to manage various kinds of resources:
+ *
+ * CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ * FakeClientID, AddResource, FreeResource, FreeClientResources,
+ * FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/*
+ * A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ * off-limits for client-visible resources. The next 8 bits are
+ * used as client ID, and the low 22 bits come from the client.
+ * A resource ID is "hashed" by extracting and xoring subfields
+ * (varying with the size of the hash table).
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 31st bit of the ID is reserved for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ * resource "owned" by the client.
+ */
+
+#include "../../dix/resource.c"
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
+#ifdef NXAGENT_SERVER
+int nxagentFindClientResource(int client, RESTYPE type, void * value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ int i;
+
+ for (i = 0; i < clientTable[client].buckets; i++)
+ {
+ resources = clientTable[client].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == type && pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+ "for client [%d].\n", (void *) value,
+ pResource -> type, client);
+ #endif
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, void * value)
+{
+ ResourcePtr pResource;
+ ResourcePtr *resources;
+
+ RESTYPE internalType = 0;
+
+ int i;
+
+ if (type == RT_PIXMAP)
+ {
+ internalType = RT_NX_PIXMAP;
+ }
+ else if (type == RT_GC)
+ {
+ internalType = RT_NX_GC;
+ }
+ else if (type == RT_FONT)
+ {
+ internalType = RT_NX_FONT;
+ }
+ else
+ {
+ return 0;
+ }
+
+ if (client == serverClient -> index)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+ client);
+ #endif
+
+ return 0;
+ }
+
+ for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+ {
+ resources = clientTable[serverClient -> index].resources;
+
+ for (pResource = resources[i]; pResource; pResource = pResource -> next)
+ {
+ if (pResource -> type == internalType &&
+ pResource -> value == value)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+ "[%lu] for server client [%d].\n", (void *) value,
+ (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+ #endif
+
+ FreeResource(pResource -> id, RT_NONE);
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+#endif /* NXAGENT_SERVER */
+
+Bool
+AddResource(XID id, RESTYPE type, void * value)
+{
+ int client;
+ register ClientResourceRec *rrec;
+ register ResourcePtr res, *head;
+
+ client = CLIENT_ID(id);
+ rrec = &clientTable[client];
+ if (!rrec->buckets)
+ {
+ ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+ (unsigned long)id, type, (unsigned long)value, client);
+ FatalError("client not in use\n");
+ }
+
+#ifdef NXAGENT_SERVER
+
+ nxagentSwitchResourceType(client, type, value);
+
+ #ifdef TEST
+ fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+ client, (unsigned long) type, (void *) value, (unsigned long) id);
+ #endif
+
+#endif
+
+ if ((rrec->elements >= 4*rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ RebuildTable(client);
+ head = &rrec->resources[Hash(client, id)];
+ res = (ResourcePtr)malloc(sizeof(ResourceRec));
+ if (!res)
+ {
+ (*DeleteFuncs[type & TypeMask])(value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ #ifdef NXAGENT_SERVER
+ nxagentResChangedFlag = 1;
+ #endif
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+ #ifdef TEST
+ fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+ #endif
+
+#endif
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id)
+ {
+ RESTYPE rtype = res->type;
+ *prev = res->next;
+ elements = --*eltptr;
+ #ifdef NXAGENT_SERVER
+ nxagentResChangedFlag = 1;
+ #endif
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ free(res);
+ if (*eltptr != elements)
+ prev = head; /* prev may no longer be valid */
+ gotOne = TRUE;
+ }
+ else
+ prev = &res->next;
+ }
+ }
+ if (!gotOne)
+ ErrorF("Freeing resource id=%lX which isn't there.\n",
+ (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+ int cid;
+ register ResourcePtr res;
+ register ResourcePtr *prev, *head;
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+ {
+ head = &clientTable[cid].resources[Hash(cid, id)];
+
+ prev = head;
+ while ( (res = *prev) )
+ {
+ if (res->id == id && res->type == type)
+ {
+ *prev = res->next;
+ #ifdef NXAGENT_SERVER
+ nxagentResChangedFlag = 1;
+ #endif
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ free(res);
+ break;
+ }
+ else
+ prev = &res->next;
+ }
+ }
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources. If func adds new resources,
+ * func might or might not get called for them. func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+ ClientPtr client,
+ RESTYPE type,
+ FindResType func,
+ void * cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ if (!type || this->type == type) {
+ elements = *eltptr;
+
+ /*
+ * FIXME:
+ * It is not safe to let a function change the resource
+ * table we are reading!
+ */
+
+ #ifdef NXAGENT_SERVER
+ nxagentResChangedFlag = 0;
+ #endif
+ (*func)(this->value, this->id, cdata);
+
+ /*
+ * Avoid that a call to RebuildTable() could invalidate the
+ * pointer. This is safe enough, because in RebuildTable()
+ * the new pointer is allocated just before the old one is
+ * freed, so it can't point to the same address.
+ */
+
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+
+ /*
+ * It's not enough to check if the number of elements has
+ * changed, beacause it could happen that the number of
+ * resources that have been added matches the number of
+ * the freed ones.
+ * 'nxagentResChangedFlag' is set if a resource has been
+ * added or freed.
+ */
+
+ #ifdef NXAGENT_SERVER
+ if (*eltptr != elements || nxagentResChangedFlag)
+ #else
+ if (*eltptr != elements)
+ #endif
+ next = resources[i]; /* start over */
+ }
+ }
+ }
+}
+
+void
+FindAllClientResources(
+ ClientPtr client,
+ FindAllRes func,
+ void * cdata
+){
+ register ResourcePtr *resources;
+ register ResourcePtr this, next;
+ int i, elements;
+ register int *eltptr;
+
+ #ifdef NXAGENT_SERVER
+ register ResourcePtr **resptr;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ eltptr = &clientTable[client->index].elements;
+ for (i = 0; i < clientTable[client->index].buckets; i++)
+ {
+ for (this = resources[i]; this; this = next)
+ {
+ next = this->next;
+ elements = *eltptr;
+
+ /*
+ * FIXME:
+ * It is not safe to let a function change the resource
+ * table we are reading!
+ */
+
+ #ifdef NXAGENT_SERVER
+ nxagentResChangedFlag = 0;
+ #endif
+ (*func)(this->value, this->id, this->type, cdata);
+
+ /*
+ * Avoid that a call to RebuildTable() could invalidate the
+ * pointer. This is safe enough, because in RebuildTable()
+ * the new pointer is allocated just before the old one is
+ * freed, so it can't point to the same address.
+ */
+
+ #ifdef NXAGENT_SERVER
+ if (*resptr != resources)
+ goto RestartLoop;
+ #endif
+
+ /*
+ * It's not enough to check if the number of elements has
+ * changed, beacause it could happen that the number of
+ * resources that have been added matches the number of
+ * the freed ones.
+ * 'nxagentResChangedFlag' is set if a resource has been
+ * added or freed.
+ */
+
+ #ifdef NXAGENT_SERVER
+ if (*eltptr != elements || nxagentResChangedFlag)
+ #else
+ if (*eltptr != elements)
+ #endif
+ next = resources[i]; /* start over */
+ }
+ }
+}
+
+
+void *
+LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ void * cdata
+){
+ ResourcePtr *resources;
+ ResourcePtr this;
+ int i;
+
+ #ifdef NXAGENT_SERVER
+ ResourcePtr **resptr;
+ Bool res;
+ #endif
+
+ if (!client)
+ client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+ resources = clientTable[client->index].resources;
+
+ #ifdef NXAGENT_SERVER
+ resptr = &clientTable[client->index].resources;
+ #endif
+
+ for (i = 0; i < clientTable[client->index].buckets; i++) {
+ for (this = resources[i]; this; this = this->next) {
+ if (!type || this->type == type) {
+ #ifdef NXAGENT_SERVER
+ res = (*func)(this->value, this->id, cdata);
+
+ if (*resptr != resources)
+ goto RestartLoop;
+
+ if (res)
+ return this->value;
+ #else
+ if((*func)(this->value, this->id, cdata))
+ return this->value;
+ #endif
+ }
+ }
+ }
+ return NULL;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c
new file mode 100644
index 000000000..2ffca8066
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c
@@ -0,0 +1,547 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/************************************************************
+
+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.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+
+#include <nx-X11/X.h>
+#include "Trap.h"
+#include "Agent.h"
+
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+#include "../../Xext/shm.c"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pImage);
+
+void
+ShmExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+ if (!CheckForShmSyscall())
+ {
+ ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+ return;
+ }
+#endif
+
+ if (nxagentOption(SharedMemory) == False)
+ {
+ return;
+ }
+
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ {
+ sharedPixmaps = nxagentOption(SharedPixmaps);
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ {
+ #ifdef TEST
+ fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+ #endif
+ shmFuncs[i] = &miFuncs;
+ }
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+ if (sharedPixmaps)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+#ifdef PIXPRIV
+ shmPixmapPrivate = AllocatePixmapPrivateIndex();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!AllocatePixmapPrivate(screenInfo.screens[i],
+ shmPixmapPrivate, 0))
+ return;
+ }
+#endif
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ nxagentShmTrap = 0;
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ {
+ nxagentShmTrap = 1;
+ return;
+ }
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pmap)
+ {
+ nxagentShmTrap = 1;
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+ nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ int length;
+ char *newdata;
+ extern int nxagentImageLength(int, int, int, int, int);
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+ (void *) dst, (void *) pGC, (void *) data);
+ #endif
+
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (void *)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+
+ /*
+ * We updated the internal framebuffer,
+ * now we want to go on the real X.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+ " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+ " sh [%d] dx [%d].\n", depth, format, w, h,
+ sx, sy, sw, sh, dx);
+ #endif
+
+ length = nxagentImageLength(sw, sh, format, 0, depth);
+
+ if ((newdata = calloc(1, length)) != NULL)
+ {
+ fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+ (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+ free(newdata);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+ #endif
+ }
+
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+ #endif
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+ }
+}
+
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+ if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+ return BadValue;
+ if (stuff->format == XYBitmap)
+ {
+ if (stuff->depth != 1)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ /*
+ * There's a potential integer overflow in this check:
+ * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ * client);
+ * the version below ought to avoid it
+ */
+ if (stuff->totalHeight != 0 &&
+ length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+ client->errorValue = stuff->totalWidth;
+ return BadValue;
+ }
+ if (stuff->srcX > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcX;
+ return BadValue;
+ }
+ if (stuff->srcY > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcY;
+ return BadValue;
+ }
+ if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcWidth;
+ return BadValue;
+ }
+ if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcHeight;
+ return BadValue;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+ "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+ stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+ #endif
+
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ pDraw, pGC, stuff->depth, stuff->format,
+ stuff->totalWidth, stuff->totalHeight,
+ stuff->srcX, stuff->srcY,
+ stuff->srcWidth, stuff->srcHeight,
+ stuff->dstX, stuff->dstY,
+ shmdesc->addr + stuff->offset);
+
+ if (stuff->sendEvent)
+ {
+ xShmCompletionEvent ev;
+
+ memset(&ev, 0, sizeof(xShmCompletionEvent));
+ ev.type = ShmCompletionCode;
+ ev.drawable = stuff->drawable;
+ ev.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ nxagentShmPixmapTrap = 1;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth, 0);
+
+ if (!pPixmap)
+ {
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d] Hint[%d]\n", width, height, depth, 0);
+ #endif
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ BitsPerPixel(depth), PixmapBytePad(width, depth), (void *)addr))
+ {
+ #ifdef WARNING
+ fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+ #endif
+
+ (*pScreen->DestroyPixmap)(pPixmap);
+
+ nxagentShmPixmapTrap = 0;
+
+ return NullPixmap;
+ }
+
+ nxagentShmPixmapTrap = 0;
+
+ return pPixmap;
+}
+
+
+static int
+ProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+
+ if (stuff->data <= X_ShmCreatePixmap)
+ {
+ fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
+ nxagentShmRequestLiteral[stuff->data], stuff->data);
+ }
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ {
+ result = ProcPanoramiXShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ return result;
+ }
+#endif
+
+ result = ProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ case X_ShmGetImage:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmGetImage(client);
+#endif
+ return ProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmCreatePixmap(client);
+#endif
+ return ProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n",
+ stuff -> data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ {
+ int result;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ nxagentShmTrap = 1;
+
+ result = SProcShmPutImage(client);
+
+ nxagentShmTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n",
+ client -> index);
+ #endif
+
+ return result;
+ }
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
new file mode 100644
index 000000000..7de25ca28
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -0,0 +1,1127 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#include "selection.h"
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+/* prototypes (only MakeRootTile() required here) */
+
+static void MakeRootTile(WindowPtr pWin);
+
+#include "../../dix/window.c"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+WindowPtr nxagentRootTileWindow;
+
+void nxagentClearSplash(WindowPtr pW)
+{
+ ScreenPtr pScreen;
+
+ pScreen = pW->drawable.pScreen;
+
+ if (pW->backgroundState == BackgroundPixmap)
+ {
+ (*pScreen->DestroyPixmap)(pW->background.pixmap);
+ }
+
+ pW->backgroundState = BackgroundPixel;
+ pW->background.pixel = nxagentLogoBlack;
+
+ (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ GCPtr pGC;
+ unsigned char back[128];
+ int len = BitmapBytePad(sizeof(long));
+ register unsigned char *from, *to;
+ register int i, j;
+
+ pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+ pScreen->rootDepth, 0);
+
+ pWin->backgroundState = BackgroundPixmap;
+ pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+ if (!pWin->background.pixmap || !pGC)
+ FatalError("could not create root tile");
+
+ {
+ CARD32 attributes[2];
+
+ attributes[0] = pScreen->whitePixel;
+ attributes[1] = pScreen->blackPixel;
+
+ (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+ }
+
+ ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+ from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+ to = back;
+
+ for (i = 4; i > 0; i--, from++)
+ for (j = len; j > 0; j--)
+ *to++ = *from;
+
+ if (blackRoot)
+ bzero(back, sizeof(back));
+
+ (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+ 0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+ FreeScratchGC(pGC);
+
+ nxagentRootTileWindow = pWin;
+}
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen;
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (nxagentOption(Rootless))
+ {
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ nxagentRootlessWindow = pWin;
+ }
+
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * A root window is created for each screen by main
+ * and the pointer is saved in screenInfo.screens as
+ * in the following snippet:
+ *
+ * for (i = 0; i < screenInfo.numScreens; i++)
+ * InitRootWindow(screenInfo.screens[i]->root);
+ *
+ * Our root window on the real display was already
+ * created at the time the screen was opened, so it
+ * is unclear how this window (or the other window,
+ * if you prefer) fits in the big picture.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ if (!(*pScreen->CreateWindow)(pWin))
+ return; /* XXX */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+ #endif
+
+ (*pScreen->PositionWindow)(pWin, 0, 0);
+
+ pWin->cursorIsNone = FALSE;
+ pWin->optional->cursor = rootCursor;
+ rootCursor->refcnt++;
+ pWin->backingStore = defaultBackingStore;
+ pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+ #ifdef NXAGENT_SPLASH
+ /* We SHOULD check for an error value here XXX */
+ pWin -> background.pixel = pScreen -> blackPixel;
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+ #else
+ (*pScreen->ChangeWindowAttributes)(pWin,
+ CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+ #endif
+
+ MakeRootTile(pWin);
+
+ /*
+ * Map both the root and the default agent window.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+ #endif
+
+ nxagentInitAtoms(pWin);
+
+ nxagentInitClipboard(pWin);
+
+ nxagentMapDefaultWindows();
+
+ nxagentRedirectDefaultWindows();
+
+ #ifdef NXAGENT_ARTSD
+ {
+ char artsd_port[10];
+ int nPort;
+ extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+ nPort = atoi(display) + 7000;
+ sprintf(artsd_port,"%d", nPort);
+ nxagentPropagateArtsdProperties(pScreen, artsd_port);
+ }
+ #endif
+}
+
+/*****
+ * DeleteWindow
+ * Deletes child of window then window itself
+ * If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(void * value, XID wid)
+ {
+ register WindowPtr pParent;
+ register WindowPtr pWin = (WindowPtr)value;
+ xEvent event;
+
+ UnmapWindow(pWin, FALSE);
+
+ CrushTree(pWin);
+
+ pParent = pWin->parent;
+ if (wid && pParent && SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = DestroyNotify;
+ event.u.destroyNotify.window = pWin->drawable.id;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ FreeWindowResources(pWin);
+ if (pParent)
+ {
+ if (pParent->firstChild == pWin)
+ pParent->firstChild = pWin->nextSib;
+ if (pParent->lastChild == pWin)
+ pParent->lastChild = pWin->prevSib;
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+ }
+
+ if (pWin -> optional &&
+ pWin -> optional -> colormap &&
+ pWin -> parent)
+ {
+ nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+ }
+
+ free(pWin);
+ return Success;
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+ register ScreenPtr pScreen;
+ register WindowPtr pSib, pChild;
+ Bool resized = (dw || dh);
+
+ pScreen = pWin->drawable.pScreen;
+
+ for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+ {
+ if (resized && (pSib->winGravity > NorthWestGravity))
+ {
+ int cwsx, cwsy;
+
+ cwsx = pSib->origin.x;
+ cwsy = pSib->origin.y;
+ GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+ pSib->winGravity, &cwsx, &cwsy);
+ if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+ {
+ xEvent event;
+
+ event.u.u.type = GravityNotify;
+ event.u.gravity.window = pSib->drawable.id;
+ event.u.gravity.x = cwsx - wBorderWidth (pSib);
+ event.u.gravity.y = cwsy - wBorderWidth (pSib);
+ DeliverEvents (pSib, &event, 1, NullWindow);
+ pSib->origin.x = cwsx;
+ pSib->origin.y = cwsy;
+ }
+ }
+ pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+ pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ SetWinSize (pSib);
+ SetBorderSize (pSib);
+
+ /*
+ * Don't force X to move children. It will position them
+ * according with gravity.
+ *
+ * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+ */
+
+ /*
+ * Update pSib privates, as this window is moved by X.
+ */
+
+ nxagentAddConfiguredWindow(pSib, CW_Update);
+
+ if ( (pChild = pSib->firstChild) )
+ {
+ while (1)
+ {
+ pChild->drawable.x = pChild->parent->drawable.x +
+ pChild->origin.x;
+ pChild->drawable.y = pChild->parent->drawable.y +
+ pChild->origin.y;
+ SetWinSize (pChild);
+ SetBorderSize (pChild);
+
+ (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+ pChild->drawable.y);
+
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pSib))
+ pChild = pChild->parent;
+ if (pChild == pSib)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ }
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN 0
+#define MOVE_WIN 1
+#define RESIZE_WIN 2
+#define REBORDER_WIN 3
+ register WindowPtr pSib = NullWindow;
+ register WindowPtr pParent = pWin->parent;
+ Window sibwid = 0;
+ Mask index2, tmask;
+ register XID *pVlist;
+ short x, y, beforeX, beforeY;
+ unsigned short w = pWin->drawable.width,
+ h = pWin->drawable.height,
+ bw = pWin->borderWidth;
+ int action, smode = Above;
+ xEvent event;
+
+ if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+ return(BadMatch);
+
+ if ((mask & CWSibling) && !(mask & CWStackMode))
+ return(BadMatch);
+
+ pVlist = vlist;
+
+ if (pParent)
+ {
+ x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+ y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+ }
+ else
+ {
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ }
+ beforeX = x;
+ beforeY = y;
+ action = RESTACK_WIN;
+ if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ action = MOVE_WIN;
+ }
+ /* or should be resized */
+ else if (mask & (CWX | CWY | CWWidth | CWHeight))
+ {
+ GET_INT16(CWX, x);
+ GET_INT16(CWY, y);
+ GET_CARD16(CWWidth, w);
+ GET_CARD16 (CWHeight, h);
+ if (!w || !h)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ action = RESIZE_WIN;
+ }
+ tmask = mask & ~ChangeMask;
+ while (tmask)
+ {
+ index2 = (Mask)lowbit (tmask);
+ tmask &= ~index2;
+ switch (index2)
+ {
+ case CWBorderWidth:
+ GET_CARD16(CWBorderWidth, bw);
+ break;
+ case CWSibling:
+ sibwid = (Window ) *pVlist;
+ pVlist++;
+ pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+ RT_WINDOW, DixReadAccess);
+ if (!pSib)
+ {
+ client->errorValue = sibwid;
+ return(BadWindow);
+ }
+ if (pSib->parent != pParent)
+ return(BadMatch);
+ if (pSib == pWin)
+ return(BadMatch);
+ break;
+ case CWStackMode:
+ GET_CARD8(CWStackMode, smode);
+ if ((smode != TopIf) && (smode != BottomIf) &&
+ (smode != Opposite) && (smode != Above) && (smode != Below))
+ {
+ client->errorValue = smode;
+ return(BadValue);
+ }
+ break;
+ default:
+ client->errorValue = mask;
+ return(BadValue);
+ }
+ }
+ /* root really can't be reconfigured, so just return */
+ if (!pParent)
+ return Success;
+
+ /* Figure out if the window should be moved. Doesnt
+ make the changes to the window if event sent */
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+
+ fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+ pWin, mask, client);
+
+ fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+ "smode [%d] pSib [%p]\n",
+ x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+ }
+ #endif
+
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+ pWin -> overrideRedirect == 0 &&
+ nxagentScreenTrap == 0)
+ {
+ nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+ return Success;
+ }
+
+ if (mask & CWStackMode)
+ pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ pParent->drawable.y + y,
+ w + (bw << 1), h + (bw << 1), smode);
+ else
+ pSib = pWin->nextSib;
+
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+ ))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ConfigureRequest;
+ event.u.configureRequest.window = pWin->drawable.id;
+ if (mask & CWSibling)
+ event.u.configureRequest.sibling = sibwid;
+ else
+ event.u.configureRequest.sibling = None;
+ if (mask & CWStackMode)
+ event.u.u.detail = smode;
+ else
+ event.u.u.detail = Above;
+ event.u.configureRequest.x = x;
+ event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureRequest.x += panoramiXdataPtr[0].x;
+ event.u.configureRequest.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureRequest.width = w;
+ event.u.configureRequest.height = h;
+ event.u.configureRequest.borderWidth = bw;
+ event.u.configureRequest.valueMask = mask;
+ event.u.configureRequest.parent = pParent->drawable.id;
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+ if (action == RESIZE_WIN)
+ {
+ Bool size_change = (w != pWin->drawable.width)
+ || (h != pWin->drawable.height);
+ if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+ {
+ xEvent eventT;
+ memset(&eventT, 0, sizeof(xEvent));
+ eventT.u.u.type = ResizeRequest;
+ eventT.u.resizeRequest.window = pWin->drawable.id;
+ eventT.u.resizeRequest.width = w;
+ eventT.u.resizeRequest.height = h;
+ if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+ ResizeRedirectMask, client) == 1)
+ {
+ /* if event is delivered, leave the actual size alone. */
+ w = pWin->drawable.width;
+ h = pWin->drawable.height;
+ size_change = FALSE;
+ }
+ }
+ if (!size_change)
+ {
+ if (mask & (CWX | CWY))
+ action = MOVE_WIN;
+ else if (mask & (CWStackMode | CWBorderWidth))
+ action = RESTACK_WIN;
+ else /* really nothing to do */
+ return(Success) ;
+ }
+ }
+
+ if (action == RESIZE_WIN)
+ /* we've already checked whether there's really a size change */
+ goto ActuallyDoSomething;
+ if ((mask & CWX) && (x != beforeX))
+ goto ActuallyDoSomething;
+ if ((mask & CWY) && (y != beforeY))
+ goto ActuallyDoSomething;
+ if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+ goto ActuallyDoSomething;
+ if (mask & CWStackMode)
+ {
+#ifndef ROOTLESS
+ /* See above for why we always reorder in rootless mode. */
+ if (pWin->nextSib != pSib)
+#endif
+ goto ActuallyDoSomething;
+ }
+ return(Success);
+
+ActuallyDoSomething:
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ConfigureNotify;
+ event.u.configureNotify.window = pWin->drawable.id;
+ if (pSib)
+ event.u.configureNotify.aboveSibling = pSib->drawable.id;
+ else
+ event.u.configureNotify.aboveSibling = None;
+ event.u.configureNotify.x = x;
+ event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+ event.u.configureNotify.x += panoramiXdataPtr[0].x;
+ event.u.configureNotify.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.configureNotify.width = w;
+ event.u.configureNotify.height = h;
+ event.u.configureNotify.borderWidth = bw;
+ event.u.configureNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (mask & CWBorderWidth)
+ {
+ if (action == RESTACK_WIN)
+ {
+ action = MOVE_WIN;
+ pWin->borderWidth = bw;
+ }
+ else if ((action == MOVE_WIN) &&
+ (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+ (beforeY + wBorderWidth (pWin) == y + (int)bw))
+ {
+ action = REBORDER_WIN;
+ (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+ }
+ else
+ pWin->borderWidth = bw;
+ }
+ if (action == MOVE_WIN)
+ (*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+ (mask & CWBorderWidth) ? VTOther : VTMove);
+ else if (action == RESIZE_WIN)
+ (*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ else if (mask & CWStackMode)
+ ReflectStackChange(pWin, pSib, VTOther);
+
+ if (action != RESTACK_WIN)
+ CheckCursorConfinement(pWin);
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+/*****
+ * ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+ int x, int y, ClientPtr client)
+{
+ WindowPtr pPrev, pPriorParent;
+ Bool WasMapped = (Bool)(pWin->mapped);
+ xEvent event;
+ int bw = wBorderWidth (pWin);
+ register ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ if (TraverseTree(pWin, CompareWIDs, (void *)&pParent->drawable.id) == WT_STOPWALKING)
+ return(BadMatch);
+ if (!MakeWindowOptional(pWin))
+ return(BadAlloc);
+
+ if (WasMapped)
+ UnmapWindow(pWin, FALSE);
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = ReparentNotify;
+ event.u.reparent.window = pWin->drawable.id;
+ event.u.reparent.parent = pParent->drawable.id;
+ event.u.reparent.x = x;
+ event.u.reparent.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && !pParent->parent) {
+ event.u.reparent.x += panoramiXdataPtr[0].x;
+ event.u.reparent.y += panoramiXdataPtr[0].y;
+ }
+#endif
+ event.u.reparent.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, pParent);
+
+ /* take out of sibling chain */
+
+ pPriorParent = pPrev = pWin->parent;
+ if (pPrev->firstChild == pWin)
+ pPrev->firstChild = pWin->nextSib;
+ if (pPrev->lastChild == pWin)
+ pPrev->lastChild = pWin->prevSib;
+
+ if (pWin->nextSib)
+ pWin->nextSib->prevSib = pWin->prevSib;
+ if (pWin->prevSib)
+ pWin->prevSib->nextSib = pWin->nextSib;
+
+ /* insert at begining of pParent */
+ pWin->parent = pParent;
+ pPrev = RealChildHead(pParent);
+
+ if (pWin->parent == screenInfo.screens[0]->root)
+ {
+ nxagentSetTopLevelEventMask(pWin);
+ }
+
+ if (pPrev)
+ {
+ pWin->nextSib = pPrev->nextSib;
+ if (pPrev->nextSib)
+ pPrev->nextSib->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pPrev->nextSib = pWin;
+ pWin->prevSib = pPrev;
+ }
+ else
+ {
+ pWin->nextSib = pParent->firstChild;
+ pWin->prevSib = NullWindow;
+ if (pParent->firstChild)
+ pParent->firstChild->prevSib = pWin;
+ else
+ pParent->lastChild = pWin;
+ pParent->firstChild = pWin;
+ }
+
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.x = x + bw + pParent->drawable.x;
+ pWin->drawable.y = y + bw + pParent->drawable.y;
+
+ /* clip to parent */
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+ (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ CheckWindowOptionalNeed(pWin);
+
+ if (WasMapped)
+ MapWindow(pWin, client);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+}
+
+/*****
+ * MapWindow
+ * If some other client has selected SubStructureReDirect on the parent
+ * and override-redirect is xFalse, then a MapRequest event is generated,
+ * but the window remains unmapped. Otherwise, the window is mapped and a
+ * MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+ register ScreenPtr pScreen;
+
+ register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+ }
+ #endif
+
+ if (pWin->mapped)
+ return(Success);
+
+#ifdef XCSECURITY
+ /* don't let an untrusted client map a child-of-trusted-window, InputOnly
+ * window; too easy to steal device input
+ */
+ if ( (client->trustLevel != XSecurityClientTrusted) &&
+ (pWin->drawable.class == InputOnly) &&
+ (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+ return Success;
+#endif
+
+ pScreen = pWin->drawable.pScreen;
+ if ( (pParent = pWin->parent) )
+ {
+ xEvent event;
+ Bool anyMarked;
+
+ if ((!pWin->overrideRedirect) &&
+ (RedirectSend(pParent)
+ ))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapRequest;
+ event.u.mapRequest.window = pWin->drawable.id;
+ event.u.mapRequest.parent = pParent->drawable.id;
+
+ if (MaybeDeliverEventsToClient(pParent, &event, 1,
+ SubstructureRedirectMask, client) == 1)
+ return(Success);
+ }
+
+ pWin->mapped = TRUE;
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = MapNotify;
+ event.u.mapNotify.window = pWin->drawable.id;
+ event.u.mapNotify.override = pWin->overrideRedirect;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+
+ if (!pParent->realized)
+ return(Success);
+ RealizeTree(pWin);
+ if (pWin->viewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+ }
+ WindowsRestructured ();
+ }
+ else
+ {
+ RegionRec temp;
+
+ pWin->mapped = TRUE;
+ pWin->realized = TRUE; /* for roots */
+ pWin->viewable = pWin->drawable.class == InputOutput;
+ /* We SHOULD check for an error value here XXX */
+ (*pScreen->RealizeWindow)(pWin);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pWin, 0, 0);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+ RegionNull(&temp);
+ RegionCopy(&temp, &pWin->clipList);
+ (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+ RegionUninit(&temp);
+ }
+
+ nxagentFlushConfigureWindow();
+
+ return(Success);
+}
+
+/*****
+ * UnmapWindow
+ * If the window is already unmapped, this request has no effect.
+ * Otherwise, the window is unmapped and an UnMapNotify event is
+ * generated. Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+ register WindowPtr pParent;
+ xEvent event;
+ Bool wasRealized = (Bool)pWin->realized;
+ Bool wasViewable = (Bool)pWin->viewable;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ #ifdef TEST
+ if (nxagentWindowTopLevel(pWin))
+ {
+ fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+ fromConfigure);
+ }
+ #endif
+
+ if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ return(Success);
+ if (SubStrSend(pWin, pParent))
+ {
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = UnmapNotify;
+ event.u.unmapNotify.window = pWin->drawable.id;
+ event.u.unmapNotify.fromConfigure = fromConfigure;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+ }
+ if (wasViewable && !fromConfigure)
+ {
+ pWin->valdata = UnmapValData;
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+ (*pScreen->MarkWindow)(pLayerWin->parent);
+ }
+ pWin->mapped = FALSE;
+ if (wasRealized)
+ UnrealizeTree(pWin, fromConfigure);
+ if (wasViewable)
+ {
+ if (!fromConfigure)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+ }
+ pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+ if (!fromConfigure && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+ }
+ if (wasRealized && !fromConfigure)
+ WindowsRestructured ();
+ return(Success);
+}
+
+void
+SaveScreens(int on, int mode)
+{
+ int i;
+ int what;
+ int type;
+
+ if (on == SCREEN_SAVER_FORCER)
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ if (mode == ScreenSaverReset)
+ what = SCREEN_SAVER_OFF;
+ else
+ what = SCREEN_SAVER_ON;
+ type = what;
+ }
+ else
+ {
+ what = on;
+ type = what;
+ if (what == screenIsSaved)
+ type = SCREEN_SAVER_CYCLE;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (on == SCREEN_SAVER_FORCER)
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ if (savedScreenInfo[i].ExternalScreenSaver)
+ {
+ if (nxagentOption(Timeout) != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+ "Ignoring it to let the auto-disconnect feature work.\n");
+ #endif
+ }
+ else
+ {
+ if ((*savedScreenInfo[i].ExternalScreenSaver)
+ (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+ continue;
+ }
+ }
+ if (type == screenIsSaved)
+ continue;
+ switch (type) {
+ case SCREEN_SAVER_OFF:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ what);
+ }
+ else if (HasSaverWindow (i))
+ {
+ savedScreenInfo[i].pWindow = NullWindow;
+ FreeResource(savedScreenInfo[i].wid, RT_NONE);
+ }
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+ {
+ WindowPtr pWin = savedScreenInfo[i].pWindow;
+ /* make it look like screen saver is off, so that
+ * NotClippedByChildren will compute a clip list
+ * for the root window, so miPaintWindow works
+ */
+ screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+ (*pWin->drawable.pScreen->MoveWindow)(pWin,
+ (short)(-(rand() % RANDOM_WIDTH)),
+ (short)(-(rand() % RANDOM_WIDTH)),
+ pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+ if (logoScreenSaver)
+ DrawLogo(pWin);
+#endif
+ screenIsSaved = SCREEN_SAVER_ON;
+ }
+ /*
+ * Call the DDX saver in case it wants to do something
+ * at cycle time
+ */
+ else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+ {
+ (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+ type);
+ }
+ break;
+ case SCREEN_SAVER_ON:
+ if (ScreenSaverBlanking != DontPreferBlanking)
+ {
+ if ((* screenInfo.screens[i]->SaveScreen)
+ (screenInfo.screens[i], what))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+ continue;
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_BLACK))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+ continue;
+ }
+ }
+ if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+ TileScreenSaver(i, SCREEN_IS_TILED))
+ {
+ savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+ }
+ else
+ savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+ break;
+ }
+ }
+ screenIsSaved = what;
+ if (mode == ScreenSaverReset)
+ SetScreenSaverTimer();
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
new file mode 100644
index 000000000..ee19c28d0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
@@ -0,0 +1,245 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/***********************************************************
+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.
+
+******************************************************************/
+
+#if !defined(__sun) && !defined(__CYGWIN__)
+
+#include "Trap.h"
+
+#include "../../Xext/xvdisp.c"
+
+#undef TEST
+#undef DEBUG
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+ case xv_PutVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutVideo(client));
+ else
+#endif
+ result = (ProcXvPutVideo(client));
+ break;
+ case xv_PutStill:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutStill(client));
+ else
+#endif
+ result = (ProcXvPutStill(client));
+ break;
+ case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (ProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvStopVideo(client));
+ else
+#endif
+ result = (ProcXvStopVideo(client));
+ break;
+ case xv_SetPortAttribute:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvSetPortAttribute(client));
+ else
+#endif
+ result = (ProcXvSetPortAttribute(client));
+ break;
+ case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvPutImage(client));
+ else
+#endif
+ result = (ProcXvPutImage(client));
+ break;
+#ifdef MITSHM
+ case xv_ShmPutImage:
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ result = (XineramaXvShmPutImage(client));
+ else
+#endif
+ result = (ProcXvShmPutImage(client));
+ break;
+#endif
+ case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+ int result;
+
+ REQUEST(xReq);
+
+ UpdateCurrentTime();
+
+ /*
+ * Report upstream that we are
+ * dispatching a XVideo operation.
+ */
+
+ nxagentXvTrap = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ switch (stuff->data)
+ {
+ case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+ case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+ case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+ case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+ case xv_PutStill: result = (SProcXvPutStill(client)); break;
+ case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+ case xv_GetStill: result = (SProcXvGetStill(client)); break;
+ case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+ case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+ case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+ case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+ case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+ case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+ case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+ case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+ case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+ case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+ case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+ case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+ case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+ default:
+ if (stuff->data < xvNumRequests)
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0,
+ BadImplementation);
+ result = (BadImplementation); break;
+ }
+ else
+ {
+ SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+ result = (BadRequest); break;
+ }
+ }
+
+ nxagentXvTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n",
+ stuff->data, client -> index);
+ #endif
+
+ return result;
+}
+#endif /* !defined(__sun) && !defined(__CYGWIN__) */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
new file mode 100644
index 000000000..978f3ab95
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -0,0 +1,210 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "X.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Options.h"
+#include "Utils.h"
+
+/*
+ * Instead of having a single options repository
+ * data could be attached to the display or the
+ * screen. The macro nxagentOption() should make
+ * the transition simple.
+ */
+
+AgentOptionsRec nxagentOptions;
+
+AgentOptionsRec nxagentOptionsBackup;
+
+AgentOptionsPtr nxagentOptionsPtr = &nxagentOptions;
+
+/*
+ * If this is set, print the geometry in the block handler.
+ */
+
+unsigned int nxagentPrintGeometryFlags = 0;
+/*
+ * This must be called at startup to initialize
+ * the options repository to the default values.
+ */
+
+void nxagentInitOptions()
+{
+ nxagentOptions.LinkType = UNDEFINED;
+
+ nxagentOptions.Desktop = UNDEFINED;
+ nxagentOptions.Persistent = 1;
+ nxagentOptions.Rootless = UNDEFINED;
+ nxagentOptions.Fullscreen = UNDEFINED;
+ nxagentOptions.NoRootlessExit = False;
+
+ nxagentOptions.X = 0;
+ nxagentOptions.Y = 0;
+ nxagentOptions.Width = 0;
+ nxagentOptions.Height = 0;
+ nxagentOptions.BorderWidth = 0;
+
+ nxagentOptions.WMBorderWidth = -1;
+ nxagentOptions.WMTitleHeight = -1;
+
+ nxagentOptions.SavedX = 0;
+ nxagentOptions.SavedY = 0;
+ nxagentOptions.SavedWidth = 0;
+ nxagentOptions.SavedHeight = 0;
+
+ nxagentOptions.Timeout = 0;
+
+ nxagentOptions.Nested = 0;
+
+ nxagentOptions.BackingStore = BackingStoreUndefined;
+
+ nxagentOptions.Clipboard = ClipboardBoth;
+
+ nxagentOptions.SharedMemory = 1;
+
+ nxagentOptions.SharedPixmaps = 1;
+
+ nxagentOptions.DeviceControl = 0;
+
+ nxagentOptions.DeviceControlUserDefined = 0;
+
+ nxagentOptions.ResetKeyboardAtResume = 1;
+
+ nxagentOptions.Reset = 0;
+
+ nxagentOptions.RootX = 0;
+ nxagentOptions.RootY = 0;
+ nxagentOptions.RootWidth = 0;
+ nxagentOptions.RootHeight = 0;
+
+ nxagentOptions.ViewportXSpan = 0;
+ nxagentOptions.ViewportYSpan = 0;
+
+ #ifndef __CYGWIN32__
+
+ nxagentOptions.DesktopResize = 1;
+
+ #else
+
+ nxagentOptions.DesktopResize = 0;
+
+ #endif
+
+ nxagentOptions.Ratio = DONT_SCALE;
+ nxagentOptions.XRatio = DONT_SCALE;
+ nxagentOptions.YRatio = DONT_SCALE;
+
+ nxagentOptions.FloatRatio = 1.0;
+ nxagentOptions.FloatXRatio = 1.0;
+ nxagentOptions.FloatYRatio = 1.0;
+
+ nxagentOptions.UseDamage = 1;
+
+ nxagentOptions.Binder = UNDEFINED;
+ nxagentOptions.BinderOptions = NULL;
+
+ nxagentOptions.Xdmcp = 0;
+
+ nxagentOptions.DisplayLatency = 0;
+ nxagentOptions.DisplayBuffer = UNDEFINED;
+ nxagentOptions.DisplayCoalescence = 0;
+
+ nxagentOptions.Composite = 1;
+
+ nxagentOptions.IgnoreVisibility = 0;
+
+ nxagentOptions.ViewOnly = 0;
+
+ nxagentOptions.Adaptive = 0;
+
+ nxagentOptions.Streaming = 0;
+
+ nxagentOptions.DeferLevel = UNDEFINED;
+ nxagentOptions.DeferTimeout = 200;
+
+ nxagentOptions.TileWidth = UNDEFINED;
+ nxagentOptions.TileHeight = UNDEFINED;
+
+ nxagentOptions.Menu = 1;
+
+ nxagentOptions.ClientOs = UNDEFINED;
+
+ nxagentOptions.InhibitXkb = 1;
+
+ nxagentOptions.CopyBufferSize = COPY_UNLIMITED;
+
+ nxagentOptions.ImageRateLimit = 0;
+
+ nxagentOptions.Xinerama = 1;
+
+ nxagentOptions.SleepTime = DEFAULT_SLEEP_TIME;
+
+ nxagentOptions.ReconnectTolerance = DEFAULT_TOLERANCE;
+}
+
+/*
+ * This is called at session reconnection
+ * to reset some options to their default
+ * values. The reason to avoid calling the
+ * nxagentInitOptions() is that not all the
+ * options can change value when reconnec-
+ * ting.
+ */
+
+void nxagentResetOptions()
+{
+ if (nxagentLockDeferLevel == 0)
+ {
+ nxagentOptions.DeferLevel = UNDEFINED;
+ }
+
+ nxagentOptions.DeferTimeout = 200;
+
+ nxagentOptions.TileWidth = UNDEFINED;
+ nxagentOptions.TileHeight = UNDEFINED;
+
+ nxagentOptions.WMBorderWidth = -1;
+ nxagentOptions.WMTitleHeight = -1;
+}
+
+void nxagentSaveOptions()
+{
+ memcpy(&nxagentOptionsBackup, &nxagentOptions, sizeof(AgentOptionsRec));
+}
+
+void nxagentRestoreOptions()
+{
+ nxagentOptions.DeferLevel = nxagentOptionsBackup.DeferLevel;
+ nxagentOptions.DeferTimeout = nxagentOptionsBackup.DeferTimeout;
+
+ nxagentOptions.TileWidth = nxagentOptionsBackup.TileWidth;
+ nxagentOptions.TileHeight = nxagentOptionsBackup.TileHeight;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
new file mode 100644
index 000000000..20616a90b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -0,0 +1,479 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Options_H__
+#define __Options_H__
+
+#ifndef True
+#define True 1
+#endif
+
+#ifndef False
+#define False 0
+#endif
+
+#define UNDEFINED -1
+#define COPY_UNLIMITED -1
+#define DEFAULT_SLEEP_TIME 50
+
+extern unsigned int nxagentPrintGeometryFlags;
+
+typedef enum _BackingStoreMode
+{
+ BackingStoreUndefined = -1,
+ BackingStoreNever,
+ BackingStoreWhenRequested,
+ BackingStoreForce
+
+} BackingStoreMode;
+
+typedef enum _ClipboardMode
+{
+ ClipboardBoth,
+ ClipboardClient,
+ ClipboardServer,
+ ClipboardNone
+
+} ClipboardMode;
+
+typedef enum _ClientOsType
+{
+ ClientOsWinnt = 0,
+ ClientOsLinux,
+ ClientOsSolaris,
+ ClientOsMac
+
+} ClientOsType;
+
+typedef enum _ToleranceChecksMode
+{
+ ToleranceChecksStrict = 0,
+ ToleranceChecksSafe = 1,
+ ToleranceChecksRisky = 2,
+ ToleranceChecksBypass = 3
+} ToleranceChecksMode;
+
+
+#define DEFAULT_TOLERANCE ToleranceChecksStrict
+
+/*
+ * Set of options affecting agent operations.
+ */
+
+typedef struct _AgentOptions
+{
+ /*
+ * Link type of the NX connection or none,
+ * if this is a direct X11 connection.
+ */
+
+ int LinkType;
+
+ /*
+ * Is agent running in desktop mode? This
+ * is presently the default.
+ */
+
+ int Desktop;
+
+ /*
+ * True if user activated rootless mode.
+ */
+
+ int Rootless;
+
+ /*
+ * True for shadow mode.
+ */
+
+ int Shadow;
+
+ /*
+ * True if user activated persistent mode.
+ */
+
+ int Persistent;
+
+ /*
+ * True if user activated fullscreen mode.
+ */
+
+ int Fullscreen;
+
+ /*
+ * True if the fullscreen NX session will
+ * extend on all available screens.
+ */
+
+ int AllScreens;
+
+ /*
+ * Set to the auto-disconnect timeout, if
+ * the user activated this feature.
+ */
+
+ int Timeout;
+
+ /*
+ * Geometry of the agent's window.
+ */
+
+ int X;
+ int Y;
+ int Width;
+ int Height;
+ int BorderWidth;
+
+ /*
+ * Geometry of the agent's window in window
+ * mode. Used to restore window size when
+ * switching back to window mode from full-
+ * screen.
+ */
+
+ int WMBorderWidth;
+ int WMTitleHeight;
+
+ int SavedX;
+ int SavedY;
+ int SavedWidth;
+ int SavedHeight;
+
+ int SavedRootWidth;
+ int SavedRootHeight;
+
+ /*
+ * Set if agent is running nested in another
+ * agent X server.
+ */
+
+ int Nested;
+
+ /*
+ * Selected backing-store mode.
+ */
+
+ BackingStoreMode BackingStore;
+
+ /*
+ * Selected clipboard mode.
+ */
+
+ ClipboardMode Clipboard;
+
+ /*
+ * Enable agent to use the MITSHM extension in
+ * path from remote proxy to the real X server.
+ */
+
+ int SharedMemory;
+
+ /*
+ * Enable agent to use shared Pixmaps
+ */
+
+ int SharedPixmaps;
+
+ /*
+ * Enable agent to propagate keyboard and pointer
+ * device configuration to the remote X server.
+ */
+
+ int DeviceControl;
+
+ /*
+ * Explicitly asked config propagation.
+ */
+
+ int DeviceControlUserDefined;
+
+ /*
+ * Resuming keyboard device corrects keymap if session
+ * migrates across platforms with different keycode
+ * layout.
+ */
+
+ int ResetKeyboardAtResume;
+
+ /*
+ * Reset server when the last client disconnects.
+ */
+
+ int Reset;
+
+ /*
+ * Geometry of the agent root window, relative to
+ * the agent default window.
+ */
+
+ int RootX;
+ int RootY;
+ int RootWidth;
+ int RootHeight;
+
+ /*
+ * Horizontal and vertical span of the
+ * agent viewport.
+ */
+
+ int ViewportXSpan;
+ int ViewportYSpan;
+
+ /*
+ * True if the user can resize the desktop
+ * by dragging the window border.
+ */
+
+ int DesktopResize;
+
+ /*
+ * The scaling ratio of the shadow agent.
+ */
+
+ int Ratio;
+
+ int XRatio;
+
+ int YRatio;
+
+ float FloatRatio;
+
+ float FloatXRatio;
+
+ float FloatYRatio;
+
+ /*
+ * The shadow agent uses the Damage extension.
+ */
+
+ int UseDamage;
+
+ /*
+ * Was the agent run with the -B option?
+ */
+
+ int Binder;
+
+ char *BinderOptions;
+
+ /*
+ * Set if the agent has to connect to a
+ * desktop manager to start the session.
+ */
+
+ int Xdmcp;
+
+ /*
+ * Latency of the link. It is simply set
+ * to a reference value, calculated based
+ * on the time required to complete the
+ * query of the agent's atoms at session
+ * startup.
+ */
+
+ int DisplayLatency;
+
+ /*
+ * Size of the Xlib display buffer. The
+ * default is set according to the link
+ * type.
+ */
+
+ int DisplayBuffer;
+
+ /*
+ * Buffer coalescence timeout.
+ */
+
+ int DisplayCoalescence;
+
+ /*
+ * Use the composite extension when
+ * available on the remote display.
+ */
+
+ int Composite;
+
+ /*
+ * If set, don't skip internal operations
+ * when the agent window is not fully visible.
+ */
+
+ int IgnoreVisibility;
+
+ /*
+ * If set, prevent the shadow session to
+ * interact with master diplay.
+ */
+
+ int ViewOnly;
+
+ /*
+ * If true select a lossy or lossless comp-
+ * ression method based on the characterist-
+ * ics of the image.
+ */
+
+ int Adaptive;
+
+ /*
+ * Stream the images and update the display
+ * when the image has been completely trans-
+ * ferred.
+ */
+
+ int Streaming;
+
+ /*
+ * Use a lazy approach in updating the remote
+ * display. This means delaying the bandwidth
+ * consuming graphic operations and synchroniz-
+ * ing the screen at idle time.
+ */
+
+ int DeferLevel;
+
+ /*
+ * Maxuimum elapsed time before a new full
+ * synchronization.
+ */
+
+ unsigned long DeferTimeout;
+
+ /*
+ * Maximum size of the tile used when sending
+ * an image to the remote display.
+ */
+
+ int TileWidth;
+ int TileHeight;
+
+ /*
+ * Enabling/disabling the pulldown menu.
+ */
+
+ int Menu;
+
+ /*
+ * Specify the Operative System of the client.
+ */
+
+ int ClientOs;
+
+ /*
+ * Inhibit some XKEYBOARD requests.
+ */
+
+ int InhibitXkb;
+
+ /*
+ * Maximum number of bytes that can be pasted from
+ * an NX session into an external application.
+ */
+
+ int CopyBufferSize;
+
+ /*
+ * Max image data rate to the encoder input.
+ */
+
+ int ImageRateLimit;
+
+ /*
+ * True if agent should not exit if there are no
+ * clients in rootless mode
+ */
+
+ int NoRootlessExit;
+
+ /*
+ * Store if the user wants Xinerama. There are variables called
+ * noPanoramiXExtension and noRRXineramaExtensison in os/utils.c but
+ * we cannot rely on them because RandR and PanoramiX change their
+ * values when trying to initialize. So we use this variable to
+ * save the user preference provided by the -/+(rr)xinerama parameter(s)
+ * before initalizing those extensions.
+ */
+
+ int Xinerama;
+
+ /*
+ * Sleep delay in microseconds.
+ */
+
+ unsigned int SleepTime;
+
+ /*
+ * Tolerance - tightens or loosens reconnect checks.
+ */
+
+ ToleranceChecksMode ReconnectTolerance;
+
+} AgentOptionsRec;
+
+typedef AgentOptionsRec *AgentOptionsPtr;
+
+extern AgentOptionsPtr nxagentOptionsPtr;
+
+/*
+ * Macros and functions giving access to options.
+ */
+
+#define nxagentOption(option) \
+ (nxagentOptionsPtr -> option)
+
+#define nxagentChangeOption(option, value) \
+ (nxagentOptionsPtr -> option = (value))
+
+#define nxagentOptions() \
+ (nxagentOptionsPtr)
+
+/*
+ * Initialize the options to the default values.
+ */
+
+extern void nxagentInitOptions(void);
+
+/*
+ * Initialize some options to the default values
+ * at reconnection.
+ */
+
+extern void nxagentResetOptions(void);
+
+/*
+ * Save a copy of the current option repository.
+ */
+
+extern void nxagentSaveOptions(void);
+
+/*
+ * Restore the options reset by nxagentResetOptions
+ * to their backup value.
+ */
+
+extern void nxagentRestoreOptions(void);
+
+#endif /* __Options_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
new file mode 100644
index 000000000..e59ef97ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -0,0 +1,392 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Xmd.h"
+#include "Xlib.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define PIXEL_ELEMENTS 256
+#define PIXEL_THRESHOLD 8
+#define PIXEL_STEP 7
+
+unsigned int Get16(const char *buffer, int order);
+unsigned int Get24(const char *buffer, int order);
+unsigned int Get32(const char *buffer, int order);
+
+void Put16(unsigned int value, char *buffer, int order);
+void Put24(unsigned int value, char *buffer, int order);
+void Put32(unsigned int value, char *buffer, int order);
+
+static int nxagentComparePixels(const void *p1, const void *p2)
+{
+ int pixel1 = *((int *) p1);
+ int pixel2 = *((int *) p2);
+
+ return (pixel1 < pixel2 ? -1 : (pixel1 == pixel2 ? 0 : 1));
+}
+
+int nxagentUniquePixels(XImage *image)
+{
+ int i = 0;
+
+ int pixels[PIXEL_ELEMENTS];
+
+ int elements = PIXEL_ELEMENTS;
+ int unique = 0;
+
+ int total;
+ int ratio;
+ int step;
+
+ int last = -1;
+
+ const char *next = image -> data;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Image geometry [%d,%d] depth [%d] bits per pixel [%d].\n",
+ image -> width, image -> height, image -> depth, image -> bits_per_pixel);
+ #endif
+
+ /*
+ * Take at most 256 pixels from the image.
+ */
+
+ total = image -> width * image -> height;
+
+ step = total / elements;
+
+ if (step < PIXEL_STEP)
+ {
+ step = PIXEL_STEP;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Step is [%d] with [%d] pixels and [%d] elements.\n",
+ step, total, elements);
+ #endif
+
+ /*
+ * Shift at the left after each scanline.
+ */
+
+ if (image -> bytes_per_line % step == 0)
+ {
+ step++;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Increasing step to [%d] with [%d] bytes per line.\n",
+ step, image -> bytes_per_line);
+ #endif
+ }
+
+ elements = total / step;
+
+ if (elements > PIXEL_ELEMENTS)
+ {
+ elements = PIXEL_ELEMENTS;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Step is now [%d] with [%d] elements.\n",
+ step, elements);
+ #endif
+
+ if (elements < PIXEL_THRESHOLD)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Assuming ratio [100] with only [%d] elements.\n",
+ elements);
+ #endif
+
+ return 100;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Scanning [%d] pixels out of [%d] with step [%d].\n",
+ elements, total, step);
+ #endif
+
+ /*
+ * Take one pixel every n from the image and
+ * add it to the array.
+ */
+
+ switch (image -> bits_per_pixel)
+ {
+ case 32:
+ {
+ for (i = 0; i < elements; i++)
+ {
+ pixels[i] = Get32(next, image -> byte_order);
+
+ next += (4 * step);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+ i, pixels[i]);
+ #endif
+ }
+
+ break;
+ }
+ case 24:
+ {
+ for (i = 0; i < elements; i++)
+ {
+ pixels[i] = Get24(next, image -> byte_order);
+
+ next += (3 * step);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+ i, pixels[i]);
+ #endif
+ }
+
+ break;
+ }
+ case 16:
+ case 15:
+ {
+ /*
+ * Note that the padding bytes at the end
+ * of the scanline are included in the set.
+ * This is not a big problem. What we want
+ * to find out is just how compressible is
+ * the image data.
+ */
+
+ for (i = 0; i < elements; i++)
+ {
+ pixels[i] = Get16(next, image -> byte_order);
+
+ next += (2 * step);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+ i, pixels[i]);
+ #endif
+ }
+
+ break;
+ }
+ default:
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentUniquePixels: PANIC! Assuming ratio [100] with [%d] bits per pixel.\n",
+ image -> bits_per_pixel);
+ #endif
+
+ return 100;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Sorting [%d] elements in the list.\n", i);
+ #endif
+
+ qsort(pixels, elements, sizeof(int), nxagentComparePixels);
+
+ for (i = 0; i < elements; i++)
+ {
+ if (last != pixels[i])
+ {
+ unique++;
+
+ last = pixels[i];
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+ i, pixels[i]);
+ #endif
+ }
+
+ ratio = unique * 100 / elements;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentUniquePixels: Found [%d] unique pixels out of [%d] with ratio [%d%%].\n",
+ unique, elements, ratio);
+ #endif
+
+ return ratio;
+}
+
+unsigned int Get16(const char *buffer, int order)
+{
+ unsigned int result;
+
+ if (order == MSBFirst)
+ {
+ result = *buffer;
+
+ result <<= 8;
+
+ result += buffer[1];
+ }
+ else
+ {
+ result = buffer[1];
+
+ result <<= 8;
+
+ result += *buffer;
+ }
+
+ return result;
+}
+
+unsigned int Get24(const char *buffer, int order)
+{
+ int i;
+
+ const char *next = (order == MSBFirst ? buffer : buffer + 2);
+
+ unsigned int result = 0;
+
+ for (i = 0; i < 3; i++)
+ {
+ result <<= 8;
+
+ result += *next;
+
+ if (order == MSBFirst)
+ {
+ next++;
+ }
+ else
+ {
+ next--;
+ }
+ }
+
+ return result;
+}
+
+unsigned int Get32(const char *buffer, int order)
+{
+ int i;
+
+ const char *next = (order == MSBFirst ? buffer : buffer + 3);
+
+ unsigned int result = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ result <<= 8;
+
+ result += *next;
+
+ if (order == MSBFirst)
+ {
+ next++;
+ }
+ else
+ {
+ next--;
+ }
+ }
+
+ return result;
+}
+
+void Put16(unsigned int value, char *buffer, int order)
+{
+ if (order == MSBFirst)
+ {
+ buffer[1] = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+
+ *buffer = (unsigned char) value;
+ }
+ else
+ {
+ *buffer = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+
+ buffer[1] = (unsigned char) value;
+ }
+}
+
+void Put24(unsigned int value, char *buffer, int order)
+{
+ int i;
+
+ if (order == MSBFirst)
+ {
+ buffer += 2;
+
+ for (i = 3; i > 0; i--)
+ {
+ *buffer-- = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+ }
+ }
+ else
+ {
+ for (i = 3; i > 0; i--)
+ {
+ *buffer++ = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+ }
+ }
+}
+
+void Put32(unsigned int value, char *buffer, int order)
+{
+ int i;
+
+ if (order == MSBFirst)
+ {
+ buffer += 3;
+
+ for (i = 4; i > 0; i--)
+ {
+ *buffer-- = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+ }
+ }
+ else
+ {
+ for (i = 4; i > 0; i--)
+ {
+ *buffer++ = (unsigned char) (value & 0xff);
+
+ value >>= 8;
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
new file mode 100644
index 000000000..fa25a46c7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -0,0 +1,188 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Pixels_H__
+#define __Pixels_H__
+
+#include "Visual.h"
+#include "Drawable.h"
+#include "Composite.h"
+
+/*
+ * Count how many pixels are different
+ * in the image.
+ */
+
+int nxagentUniquePixels(XImage *image);
+
+/*
+ * Convert a 32 bit pixel to 16 bit.
+ */
+
+#define Color32to16(color) \
+do \
+{ \
+ Visual *pVisual; \
+\
+ pVisual = nxagentDefaultVisual(nxagentDefaultScreen); \
+\
+ if (pVisual -> green_mask == 0x7e0) \
+ { \
+ /* \
+ * bit mask 5-6-5 \
+ */ \
+\
+ color = (((color & (pVisual -> blue_mask << 3)) >> 3) | \
+ ((color & (pVisual -> green_mask << 5)) >> 5) | \
+ ((color & (pVisual -> red_mask << 8)) >> 8)); \
+ } \
+ else \
+ { \
+ /* \
+ * bit mask 5-5-5 \
+ */ \
+\
+ color = (((color & (pVisual -> blue_mask << 3)) >> 3) | \
+ ((color & (pVisual -> green_mask << 6)) >> 6) | \
+ ((color & (pVisual -> red_mask << 9)) >> 9)); \
+ } \
+} \
+while (0)
+
+/*
+ * Rules to break the synchronization loop.
+ */
+
+#define breakOnBlocking(mask) \
+ (((mask) != NEVER_BREAK) && ((mask) & BLOCKING_BREAK) && \
+ nxagentBlocking == 1)
+
+#define breakOnCongestion(mask) \
+ (((mask) != NEVER_BREAK) && ((mask) & CONGESTION_BREAK) && \
+ nxagentCongestion > 4)
+
+#define breakOnBlockingOrCongestion(mask) \
+ (breakOnBlocking(mask) != 0 || breakOnCongestion(mask) != 0)
+
+#define breakOnCongestionDrawable(mask, pDrawable) \
+ (((mask) != NEVER_BREAK) && ((mask) & CONGESTION_BREAK) && \
+ (nxagentCongestion > 4 || \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP && \
+ nxagentCongestion > 1)))
+
+#define breakOnEvent(mask) \
+ (((mask) != NEVER_BREAK) && ((mask) & EVENT_BREAK) && \
+ nxagentUserInput(NULL) == 1)
+
+#define canBreakOnTimeout(mask) \
+ (((mask) != NEVER_BREAK) && nxagentOption(Shadow) == 0)
+
+/*
+ * Macros defining the conditions to
+ * defer X requests.
+ */
+
+#define NXAGENT_SHOULD_DEFER_TRAPEZOIDS(pDrawable) \
+ (nxagentOption(DeferLevel) >= 2 && \
+ nxagentDrawableContainGlyphs(pDrawable) == 0 && \
+ nxagentOption(LinkType) < LINK_TYPE_ADSL && \
+ nxagentCongestion > 4)
+
+/*
+FIXME: The condition checking for the render
+ version is a workaround implemented to
+ avoid problems with the render composi-
+ te on XFree86 remote server.
+*/
+/*
+FIXME: Changed macro: NXAGENT_SHOULD_DEFER_COMPOSITE
+ to handle situation, when pSrc -> pDrawable
+ is NULL. This case happens with gradients
+ and solid fill.
+
+#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst) \
+ ((nxagentRenderVersionMajor == 0 && \
+ nxagentRenderVersionMinor == 8 && \
+ (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) || \
+ ((pDst) -> pDrawable -> type == DRAWABLE_PIXMAP && \
+ (nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized || \
+ ((pMask) && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized)) && \
+ nxagentOption(DeferLevel) == 1) || \
+ (nxagentOption(DeferLevel) >= 2 && \
+ nxagentOption(LinkType) < LINK_TYPE_ADSL))
+*/
+#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst) \
+ ((nxagentRenderVersionMajor == 0 && \
+ nxagentRenderVersionMinor == 8 && \
+ (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) || \
+ (nxagentOption(DeferLevel) >= 2 && \
+ nxagentOption(LinkType) < LINK_TYPE_ADSL) || \
+ (nxagentOption(DeferLevel) == 1 && \
+ (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP && \
+ (((pSrc) -> pDrawable && nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized) || \
+ ((pMask) && (pMask) -> pDrawable && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized))))
+
+
+#define NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable) \
+ (nxagentSplitTrap == 0 && \
+ nxagentOption(DeferLevel) > 0)
+
+/*
+ * Macros defining the conditions to
+ * start the synchronization loops of
+ * resources.
+ */
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_WINDOWS(mask) \
+ ((nxagentCorruptedWindows > 0 && breakOnBlockingOrCongestion(mask) == 0) || \
+ mask == NEVER_BREAK)
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_BACKGROUNDS(mask) \
+ ((nxagentCorruptedWindows == 0 && nxagentCorruptedBackgrounds > 0 && \
+ breakOnBlockingOrCongestion(mask) == 0) || mask == NEVER_BREAK)
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_PIXMAPS(mask) \
+ ((nxagentCorruptedWindows == 0 && nxagentCorruptedPixmaps > 0 && \
+ nxagentCongestion == 0 && nxagentBlocking == 0) || \
+ mask == NEVER_BREAK)
+
+/*
+ * Macros defining the conditions to
+ * synchronize a single resource.
+ */
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_WINDOW(pDrawable) \
+ (nxagentWindowIsVisible((WindowPtr) pDrawable) == 1 && \
+ (nxagentDefaultWindowIsVisible() == 1 || nxagentCompositeEnable == 1))
+
+#define MINIMUM_PIXMAP_USAGE_COUNTER 2
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_PIXMAP(pDrawable) \
+ (nxagentPixmapUsageCounter((PixmapPtr) pDrawable) >= \
+ MINIMUM_PIXMAP_USAGE_COUNTER || \
+ nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+
+#endif /* __Pixels_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
new file mode 100644
index 000000000..be5408d13
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -0,0 +1,1660 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "miscstruct.h"
+#include "pixmapstr.h"
+#include "dixstruct.h"
+#include "regionstr.h"
+#include "../../include/gc.h"
+#include "servermd.h"
+#include "mi.h"
+
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Trap.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Split.h"
+#include "Drawable.h"
+#include "Visual.h"
+#include "Client.h"
+#include "Events.h"
+#include "Holder.h"
+#include "Args.h"
+
+#include "compext/Compext.h"
+#include <nx/NXpack.h>
+
+RESTYPE RT_NX_PIXMAP;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+#ifdef TEST
+#include "Font.h"
+#endif
+
+int nxagentPixmapPrivateIndex;
+
+int nxagentCorruptedPixmaps;
+int nxagentCorruptedBackgrounds;
+
+/*
+ * Force deallocation of the virtual pixmap.
+ */
+
+static Bool nxagentDestroyVirtualPixmap(PixmapPtr pPixmap);
+
+/*
+ * This serves as a tool to check the synchronization
+ * between pixmaps in framebuffer and the correspondent
+ * pixmaps in the real X server.
+ */
+
+#ifdef TEST
+Bool nxagentCheckPixmapIntegrity(PixmapPtr pPixmap);
+#endif
+
+struct nxagentPixmapPair
+{
+ Pixmap pixmap;
+ PixmapPtr pMap;
+};
+
+PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width, int height,
+ int depth, unsigned usage_hint)
+{
+ nxagentPrivPixmapPtr pPixmapPriv, pVirtualPriv;
+
+ PixmapPtr pPixmap;
+ PixmapPtr pVirtual;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCreatePixmap: Creating pixmap with width [%d] "
+ "height [%d] depth [%d] and allocation hint [%d].\n",
+ width, height, depth, usage_hint);
+ #endif
+
+ /*
+ * Create the pixmap structure but do
+ * not allocate memory for the data.
+ */
+
+ pPixmap = AllocatePixmap(pScreen, 0);
+
+ if (!pPixmap)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCreatePixmap: WARNING! Failed to create pixmap with "
+ "width [%d] height [%d] depth [%d] and allocation hint [%d].\n",
+ width, height, depth, usage_hint);
+ #endif
+
+ return NullPixmap;
+ }
+
+ /*
+ * Initialize the core members.
+ */
+
+ pPixmap -> drawable.type = DRAWABLE_PIXMAP;
+ pPixmap -> drawable.class = 0;
+ pPixmap -> drawable.pScreen = pScreen;
+ pPixmap -> drawable.depth = depth;
+ pPixmap -> drawable.bitsPerPixel = BitsPerPixel(depth);
+ pPixmap -> drawable.id = 0;
+ pPixmap -> drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap -> drawable.x = 0;
+ pPixmap -> drawable.y = 0;
+ pPixmap -> drawable.width = width;
+ pPixmap -> drawable.height = height;
+ pPixmap -> devKind = 0;
+ pPixmap -> refcnt = 1;
+ pPixmap -> devPrivate.ptr = NULL;
+ pPixmap -> usage_hint = usage_hint;
+
+ /*
+ * Initialize the privates of the real picture.
+ */
+
+ pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+ pPixmapPriv -> isVirtual = False;
+ pPixmapPriv -> isShared = nxagentShmPixmapTrap;
+
+ /*
+ * The shared memory pixmaps are never
+ * synchronized with the remote X Server.
+ */
+
+ if (pPixmapPriv -> isShared == 1)
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+
+ pPixmapPriv -> corruptedRegion = RegionCreate(&box, 1);
+ }
+ else
+ {
+ pPixmapPriv -> corruptedRegion = RegionCreate((BoxRec *) NULL, 1);
+ }
+
+ pPixmapPriv -> corruptedBackground = 0;
+
+ pPixmapPriv -> containGlyphs = 0;
+ pPixmapPriv -> containTrapezoids = 0;
+
+ /*
+ * The lazy encoding policy generally does
+ * not send on remote X server the off-screen
+ * images, by preferring to synchronize the
+ * windows content. Anyway this behaviour may
+ * be inadvisable if a pixmap is used, for
+ * example, for multiple copy areas on screen.
+ * This counter serves the purpose, taking in-
+ * to account the number of times the pixmap
+ * has been used as source for a deferred
+ * operation.
+ */
+
+ pPixmapPriv -> usageCounter = 0;
+
+ pPixmapPriv -> corruptedBackgroundId = 0;
+ pPixmapPriv -> corruptedId = 0;
+
+ pPixmapPriv -> synchronizationBitmap = NullPixmap;
+
+ pPixmapPriv -> corruptedTimestamp = 0;
+
+ pPixmapPriv -> splitResource = NULL;
+
+ pPixmapPriv -> isBackingPixmap = 0;
+
+ /*
+ * Create the pixmap based on the default
+ * windows. The proxy knows this and uses
+ * this information to optimize encode the
+ * create pixmap message by including the
+ * id of the drawable in the checksum.
+ */
+
+ if (width != 0 && height != 0 && nxagentGCTrap == 0)
+ {
+ pPixmapPriv -> id = XCreatePixmap(nxagentDisplay,
+ nxagentDefaultWindows[pScreen -> myNum],
+ width, height, depth);
+ }
+ else
+ {
+ pPixmapPriv -> id = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreatePixmap: Skipping the creation of pixmap at [%p] on real "
+ "X server with nxagentGCTrap [%d].\n", (void *) pPixmap, nxagentGCTrap);
+ #endif
+ }
+
+ pPixmapPriv -> mid = FakeClientID(serverClient -> index);
+
+ AddResource(pPixmapPriv -> mid, RT_NX_PIXMAP, pPixmap);
+
+ pPixmapPriv -> pRealPixmap = pPixmap;
+ pPixmapPriv -> pVirtualPixmap = NULL;
+ pPixmapPriv -> pPicture = NULL;
+
+ /*
+ * Create the pixmap in the virtual framebuffer.
+ */
+
+ pVirtual = fbCreatePixmap(pScreen, width, height, depth, usage_hint);
+
+ if (pVirtual == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCreatePixmap: PANIC! Failed to create virtual pixmap with "
+ "width [%d] height [%d] depth [%d] and allocation hint [%d].\n",
+ width, height, depth, usage_hint);
+ #endif
+
+ nxagentDestroyPixmap(pPixmap);
+
+ return NullPixmap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr,"nxagentCreatePixmap: Allocated memory for the Virtual %sPixmap %p of real Pixmap %p (%dx%d),",
+ "allocation hint [%d].\n",
+ nxagentShmPixmapTrap ? "Shm " : "", (void *) pVirtual, (void *) pPixmap, width, height, usage_hint);
+ #endif
+
+ pPixmapPriv -> pVirtualPixmap = pVirtual;
+
+ /*
+ * Initialize the privates of the virtual picture. We
+ * could avoid to use a flag and just check the pointer
+ * to the virtual pixmap that, if the pixmap is actually
+ * virtual, will be NULL. Unfortunately the flag can be
+ * changed in nxagentValidateGC(). That code should be
+ * removed in future.
+ */
+
+ pVirtualPriv = nxagentPixmapPriv(pVirtual);
+
+ pVirtualPriv -> isVirtual = True;
+ pVirtualPriv -> isShared = nxagentShmPixmapTrap;
+
+ pVirtualPriv -> corruptedRegion = RegionCreate((BoxRec *) NULL, 1);
+
+ pVirtualPriv -> corruptedBackground = 0;
+
+ pVirtualPriv -> containGlyphs = 0;
+ pVirtualPriv -> containTrapezoids = 0;
+
+ pVirtualPriv -> usageCounter = 0;
+
+ pVirtualPriv -> corruptedBackgroundId = 0;
+ pVirtualPriv -> corruptedId = 0;
+
+ pVirtualPriv -> synchronizationBitmap = NullPixmap;
+
+ pVirtualPriv -> corruptedTimestamp = 0;
+
+ pVirtualPriv -> splitResource = NULL;
+
+ /*
+ * We might distinguish real and virtual pixmaps by
+ * checking the pointers to pVirtualPixmap. We should
+ * also remove the copy of id and use the one of the
+ * real pixmap.
+ */
+
+ pVirtualPriv -> id = pPixmapPriv -> id;
+ pVirtualPriv -> mid = 0;
+
+ /*
+ * Storing a pointer back to the real pixmap is
+ * silly. Unfortunately this is the way it has
+ * been originally implemented. See also the
+ * comment in destroy of the pixmap.
+ */
+
+ pVirtualPriv -> pRealPixmap = pPixmap;
+ pVirtualPriv -> pVirtualPixmap = NULL;
+ pVirtualPriv -> pPicture = NULL;
+
+ /*
+ * Check that the virtual pixmap is created with
+ * the appropriate bits-per-plane, otherwise free
+ * everything and return.
+ */
+
+ if (pVirtual -> drawable.bitsPerPixel == 0)
+ {
+ #ifdef WARNING
+
+ fprintf(stderr, "nxagentCreatePixmap: WARNING! Virtual pixmap at [%p] has invalid "
+ "bits per pixel.\n", (void *) pVirtual);
+
+ fprintf(stderr, "nxagentCreatePixmap: WARNING! Real pixmap created with width [%d] "
+ "height [%d] depth [%d] bits per pixel [%d] and allocation hint [%d].\n",
+ pPixmap -> drawable.width,
+ pPixmap -> drawable.height = height, pPixmap -> drawable.depth,
+ pPixmap -> drawable.bitsPerPixel,
+ usage_hint);
+ #endif
+
+ if (!nxagentRenderTrap)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "Warning: Disabling render extension due to missing pixmap format.\n");
+ #endif
+
+ nxagentRenderTrap = 1;
+ }
+
+ nxagentDestroyPixmap(pPixmap);
+
+ return NullPixmap;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreatePixmap: Created pixmap at [%p] virtual at [%p] with width [%d] "
+ "height [%d] depth [%d] and allocation hint [%d].\n",
+ (void *) pPixmap, (void *) pVirtual, width, height, depth, usage_hint);
+ #endif
+
+ return pPixmap;
+}
+
+Bool nxagentDestroyPixmap(PixmapPtr pPixmap)
+{
+ PixmapPtr pVirtual;
+
+ nxagentPrivPixmapPtr pPixmapPriv;
+
+ if (!pPixmap)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentDestroyPixmap: PANIC! Invalid attempt to destroy "
+ "a null pixmap pointer.\n");
+ #endif
+
+ return False;
+ }
+
+ pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+ pVirtual = pPixmapPriv -> pVirtualPixmap;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyPixmap: Destroying pixmap at [%p] with virtual at [%p].\n",
+ (void *) pPixmap, (void *) pVirtual);
+ #endif
+
+ if (pPixmapPriv -> isVirtual)
+ {
+ int refcnt;
+
+ /*
+ * For some pixmaps we receive the destroy only for the
+ * virtual. Infact to draw in the framebuffer we can use
+ * the virtual pixmap instead of the pointer to the real
+ * one. As the virtual pixmap can collect references, we
+ * must transfer those references to the real pixmap so
+ * we can continue as the destroy had been requested for
+ * it.
+ */
+
+ pVirtual = pPixmap;
+ pPixmap = pPixmapPriv -> pRealPixmap;
+
+ pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+ /*
+ * Move the references accumulated by the virtual
+ * pixmap into the references of the real one.
+ */
+
+ refcnt = pVirtual -> refcnt - 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyPixmap: Adding [%d] references to pixmap at [%p].\n",
+ refcnt, (void *) pPixmap);
+ #endif
+
+ pPixmap -> refcnt += refcnt;
+
+ pVirtual -> refcnt -= refcnt;
+ }
+
+ --pPixmap -> refcnt;
+
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentDestroyPixmap: Pixmap has now [%d] references with virtual pixmap [%d].\n",
+ pPixmap -> refcnt, pVirtual -> refcnt);
+
+ if (pVirtual != NULL && pVirtual -> refcnt != 1)
+ {
+ fprintf(stderr, "nxagentDestroyPixmap: PANIC! Virtual pixmap has [%d] references.\n",
+ pVirtual -> refcnt);
+ }
+
+ #endif
+
+ if (pPixmap -> refcnt > 0)
+ {
+ return True;
+ }
+
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentDestroyPixmap: Managing to destroy the pixmap at [%p]\n",
+ (void *) pPixmap);
+ #endif
+
+ nxagentRemoveItemBSPixmapList(nxagentPixmap(pPixmap));
+
+ nxagentDestroyVirtualPixmap(pPixmap);
+
+ if (pPixmapPriv -> corruptedRegion != NullRegion)
+ {
+ RegionDestroy(pPixmapPriv -> corruptedRegion);
+
+ pPixmapPriv -> corruptedRegion = NullRegion;
+ }
+
+ if (nxagentSynchronization.pDrawable == (DrawablePtr) pPixmap)
+ {
+ nxagentSynchronization.pDrawable = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyPixmap: Synchronization drawable [%p] removed from resources.\n",
+ (void *) pPixmap);
+ #endif
+ }
+
+ nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+ nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+
+ nxagentDestroyDrawableBitmap((DrawablePtr) pPixmap);
+
+ if (pPixmapPriv -> splitResource != NULL)
+ {
+ nxagentReleaseSplit((DrawablePtr) pPixmap);
+ }
+
+ /*
+ * A pixmap with width and height set to 0 is
+ * created at the beginning. To this pixmap is
+ * not assigned an id. This is likely a scratch
+ * pixmap used by the X server.
+ */
+
+ if (pPixmapPriv -> id)
+ {
+ XFreePixmap(nxagentDisplay, pPixmapPriv -> id);
+ }
+
+ if (pPixmapPriv -> mid)
+ {
+ FreeResource(pPixmapPriv -> mid, RT_NONE);
+ }
+
+ free(pPixmap);
+
+ return True;
+}
+
+Bool nxagentDestroyVirtualPixmap(PixmapPtr pPixmap)
+{
+ PixmapPtr pVirtual;
+ nxagentPrivPixmapPtr pVirtualPriv;
+
+ pVirtual = nxagentPixmapPriv(pPixmap) -> pVirtualPixmap;
+
+ /*
+ * Force the routine to get rid of the virtual
+ * pixmap.
+ */
+
+ if (pVirtual != NULL)
+ {
+ pVirtual -> refcnt = 1;
+
+ pVirtualPriv = nxagentPixmapPriv(pVirtual);
+
+ if (pVirtualPriv -> corruptedRegion != NullRegion)
+ {
+ RegionDestroy(pVirtualPriv -> corruptedRegion);
+
+ pVirtualPriv -> corruptedRegion = NullRegion;
+ }
+
+ fbDestroyPixmap(pVirtual);
+ }
+
+ return True;
+}
+
+RegionPtr nxagentPixmapToRegion(PixmapPtr pPixmap)
+{
+ #ifdef TEST
+ fprintf(stderr, "PixmapToRegion: Pixmap = [%p] nxagentVirtualPixmap = [%p]\n",
+ (void *) pPixmap, (void *) nxagentVirtualPixmap(pPixmap));
+ #endif
+
+ return fbPixmapToRegion(nxagentVirtualPixmap(pPixmap));
+}
+
+Bool nxagentModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, void * pPixData)
+{
+ PixmapPtr pVirtualPixmap;
+
+ /*
+ * See miModifyPixmapHeader() in miscrinit.c. This
+ * function is used to recycle the scratch pixmap
+ * for this screen. We let it refer to the virtual
+ * pixmap.
+ */
+
+ if (!pPixmap)
+ {
+ return False;
+ }
+
+ if (nxagentPixmapIsVirtual(pPixmap))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentModifyPixmapHeader: PANIC! Pixmap at [%p] is virtual.\n",
+ (void *) pPixmap);
+ #endif
+
+ FatalError("nxagentModifyPixmapHeader: PANIC! Pixmap is virtual.");
+ }
+
+ pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentModifyPixmapHeader: Pixmap at [%p] Virtual at [%p].\n",
+ (void *) pPixmap, (void *) pVirtualPixmap);
+
+ fprintf(stderr, "nxagentModifyPixmapHeader: Pixmap has width [%d] height [%d] depth [%d] "
+ "bits-per-pixel [%d] devKind [%d] pPixData [%p].\n", pPixmap->drawable.width,
+ pPixmap->drawable.height, pPixmap->drawable.depth, pPixmap->drawable.bitsPerPixel,
+ pPixmap->devKind, (void *) pPixmap->devPrivate.ptr);
+
+ fprintf(stderr, "nxagentModifyPixmapHeader: New parameters are width [%d] height [%d] depth [%d] "
+ "bits-per-pixel [%d] devKind [%d] pPixData [%p].\n", width, height, depth,
+ bitsPerPixel, devKind, (void *) pPixData);
+ #endif
+
+ if ((width > 0) && (height > 0) && (depth > 0) &&
+ (bitsPerPixel > 0) && (devKind > 0) && pPixData)
+ {
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = devKind;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = pPixData;
+
+ pVirtualPixmap->drawable.depth = depth;
+ pVirtualPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ pVirtualPixmap->drawable.id = 0;
+ pVirtualPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pVirtualPixmap->drawable.x = 0;
+ pVirtualPixmap->drawable.y = 0;
+ pVirtualPixmap->drawable.width = width;
+ pVirtualPixmap->drawable.height = height;
+ pVirtualPixmap->devKind = devKind;
+ pVirtualPixmap->refcnt = 1;
+ pVirtualPixmap->devPrivate.ptr = pPixData;
+ }
+ else
+ {
+ if (width > 0)
+ pPixmap->drawable.width = width;
+
+ if (height > 0)
+ pPixmap->drawable.height = height;
+
+ if (depth > 0)
+ pPixmap->drawable.depth = depth;
+
+ if (bitsPerPixel > 0)
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ else if ((bitsPerPixel < 0) && (depth > 0))
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+
+ if (devKind > 0)
+ pPixmap->devKind = devKind;
+ else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+ pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
+ pPixmap->drawable.depth);
+
+ if (pPixData)
+ pPixmap->devPrivate.ptr = pPixData;
+
+ /*
+ * XXX This was the previous assignment:
+ *
+ * pVirtualPixmap->devPrivate.ptr = pPixData;
+ */
+
+ if (width > 0)
+ pVirtualPixmap->drawable.width = width;
+
+ if (height > 0)
+ pVirtualPixmap->drawable.height = height;
+
+ if (depth > 0)
+ pVirtualPixmap->drawable.depth = depth;
+
+ if (bitsPerPixel > 0)
+ pVirtualPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ else if ((bitsPerPixel < 0) && (depth > 0))
+ pVirtualPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+
+ if (devKind > 0)
+ pVirtualPixmap->devKind = devKind;
+ else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+ pVirtualPixmap->devKind = PixmapBytePad(pVirtualPixmap->drawable.width,
+ pVirtualPixmap->drawable.depth);
+
+ if (pPixData)
+ pVirtualPixmap->devPrivate.ptr = pPixData;
+
+ #ifdef PANIC
+
+ if (pPixmap->drawable.x != 0 || pPixmap->drawable.y != 0)
+ {
+ fprintf(stderr, "nxagentModifyPixmapHeader: PANIC! Pixmap at [%p] has x [%d] and y [%d].\n",
+ (void *) pPixmap, pPixmap->drawable.x, pPixmap->drawable.y);
+
+ FatalError("nxagentModifyPixmapHeader: PANIC! Pixmap has x or y greater than zero.");
+ }
+
+ #endif
+ }
+
+ return True;
+}
+
+static void nxagentPixmapMatchID(void *p0, XID x1, void *p2)
+{
+ PixmapPtr pPixmap = (PixmapPtr)p0;
+ struct nxagentPixmapPair *pPair = p2;
+
+ if ((pPair -> pMap == NULL) && (nxagentPixmap(pPixmap) == pPair -> pixmap))
+ {
+ pPair -> pMap = pPixmap;
+ }
+}
+
+PixmapPtr nxagentPixmapPtr(Pixmap pixmap)
+{
+ int i;
+ struct nxagentPixmapPair pair;
+
+ if (pixmap == None)
+ {
+ return NULL;
+ }
+
+ pair.pixmap = pixmap;
+ pair.pMap = NULL;
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP,
+ nxagentPixmapMatchID, &pair);
+
+ for (i = 0; (pair.pMap == NULL) && (i < MAXCLIENTS); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], RT_PIXMAP,
+ nxagentPixmapMatchID, &pair);
+ }
+ }
+
+ #ifdef WARNING
+
+ if (pair.pMap == NULL)
+ {
+ fprintf(stderr, "nxagentFindPixmap: WARNING! Failed to find "
+ "remote pixmap [%ld].\n", (long int) pair.pixmap);
+ }
+ else if (nxagentDrawableStatus((DrawablePtr) pair.pMap) == NotSynchronized)
+ {
+ fprintf(stderr, "WARNING! Rootless icon at [%p] [%d,%d] is not synchronized.\n",
+ (void *) pair.pMap, pair.pMap -> drawable.width,
+ pair.pMap -> drawable.height);
+ }
+
+ #endif
+
+ return pair.pMap;
+}
+
+/*
+ * Reconnection stuff.
+ */
+
+int nxagentDestroyNewPixmapResourceType(void * p, XID id)
+{
+ /*
+ * Address of the destructor is set in Init.c.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyNewPixmapResourceType: Destroying mirror id [%ld] for pixmap at [%p].\n",
+ nxagentPixmapPriv((PixmapPtr) p) -> mid, (void *) p);
+ #endif
+
+ nxagentPixmapPriv((PixmapPtr) p) -> mid = None;
+
+ return True;
+}
+
+void nxagentDisconnectPixmap(void *p0, XID x1, void *p2)
+{
+ PixmapPtr pPixmap = (PixmapPtr) p0;
+
+ #ifdef TEST
+ Bool *pBool;
+
+ pBool = (Bool*) p2;
+
+ fprintf(stderr, "nxagentDisconnectPixmap: Called with bool [%d] and pixmap at [%p].\n",
+ *pBool, (void *) pPixmap);
+
+ fprintf(stderr, "nxagentDisconnectPixmap: Virtual pixmap is [%ld].\n",
+ nxagentPixmap(pPixmap));
+ #endif
+
+ nxagentPixmap(pPixmap) = None;
+
+ if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+ {
+ nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+ nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+ }
+}
+
+Bool nxagentDisconnectAllPixmaps()
+{
+ int r = 1;
+ int i;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: Going to iterate through pixmap resources.\n");
+ #endif
+
+ /*
+ * The RT_NX_PIXMAP resource type is allocated
+ * only on the server client, so we don't need
+ * to find it through the other clients too.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP, nxagentDisconnectPixmap, &r);
+
+ #ifdef WARNING
+
+ if (r == 0)
+ {
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+ "pixmap for client [%d].\n", serverClient -> index);
+ }
+
+ #endif
+
+ for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+ {
+ if (clients[i])
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: Going to disconnect pixmaps of client [%d].\n", i);
+ #endif
+
+ FindClientResourcesByType(clients[i], RT_PIXMAP, nxagentDisconnectPixmap, &r);
+
+ #ifdef WARNING
+
+ if (r == 0)
+ {
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+ "pixmap for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ #ifdef WARNING
+
+ if (r == 0)
+ {
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+ "pixmap for client [%d].\n", i);
+ }
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectAllPixmaps: Pixmaps disconnection completed.\n");
+ #endif
+
+ return r;
+}
+
+void nxagentReconnectPixmap(void *p0, XID x1, void *p2)
+{
+ PixmapPtr pPixmap = (PixmapPtr) p0;
+ Bool *pBool = (Bool*) p2;
+ nxagentPrivPixmapPtr pPixmapPriv;
+
+ if (*pBool == 0 || pPixmap == NULL ||
+ NXDisplayError(nxagentDisplay) == 1)
+ {
+ *pBool = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPixmap: Ignoring pixmap at [%p] while "
+ "recovering from the error.\n", (void *) pPixmap);
+ #endif
+
+ return;
+ }
+ else if (pPixmap == nxagentDefaultScreen -> pScratchPixmap)
+ {
+ /*
+ * Every time the scratch pixmap is used its
+ * data is changed, so we don't need to recon-
+ * nect it.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPixmap: Ignoring scratch pixmap at [%p].\n",
+ (void *) pPixmap);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPixmap: Called with result [%d] and pixmap at [%p].\n",
+ *pBool, (void *) pPixmap);
+
+ fprintf(stderr, "nxagentReconnectPixmap: Virtual pixmap is at [%p] picture is at [%p].\n",
+ (void *) nxagentPixmapPriv(pPixmap) -> pVirtualPixmap,
+ (void *) nxagentPixmapPriv(pPixmap) -> pPicture);
+ #endif
+
+ pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+ if (pPixmap -> drawable.width && pPixmap -> drawable.height)
+ {
+ pPixmapPriv -> id = XCreatePixmap(nxagentDisplay,
+ nxagentDefaultWindows[pPixmap -> drawable.pScreen -> myNum],
+ pPixmap -> drawable.width,
+ pPixmap -> drawable.height,
+ pPixmap -> drawable.depth);
+
+ nxagentPixmap(pPixmapPriv -> pVirtualPixmap) = pPixmapPriv -> id;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPixmap: Created virtual pixmap with id [%ld] for pixmap at [%p].\n",
+ nxagentPixmap(pPixmap), (void *) pPixmap);
+ #endif
+
+ if (pPixmap == (PixmapPtr) nxagentDefaultScreen -> devPrivate)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectPixmap: WARNING! Pixmap is root screen. Returning.\n");
+ #endif
+
+ return;
+ }
+
+ nxagentSplitTrap = 1;
+
+ *pBool = nxagentSynchronizeDrawableData((DrawablePtr) pPixmap, NEVER_BREAK, NULL);
+
+ nxagentSplitTrap = 0;
+
+ if (*pBool == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentReconnectPixmap: PANIC! Failed to synchronize the pixmap.\n");
+ #endif
+ }
+
+
+ if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+ {
+ if (nxagentIsCorruptedBackground(pPixmap) == 1)
+ {
+ nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+ nxagentFillRemoteRegion((DrawablePtr) pPixmap,
+ nxagentCorruptedRegion((DrawablePtr) pPixmap));
+ }
+ else
+ {
+ nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+ }
+ }
+ }
+}
+
+Bool nxagentReconnectAllPixmaps(void *p0)
+{
+ Bool result = 1;
+
+ int i;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllPixmaps: Going to recreate all pixmaps.\n");
+ #endif
+
+ /*
+ * Reset the geometry and alpha information
+ * used by proxy to unpack the packed images.
+ */
+
+ nxagentResetVisualCache();
+
+ nxagentResetAlphaCache();
+
+ /*
+ * The RT_NX_PIXMAP resource type is allocated
+ * only on the server client, so we don't need
+ * to find it through the other clients too.
+ */
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP, nxagentReconnectPixmap, &result);
+
+ #ifdef WARNING
+
+ if (result == 0)
+ {
+ fprintf(stderr, "nxagentReconnectAllPixmaps: WARNING! Failed to reconnect "
+ "pixmap for client [%d].\n", serverClient -> index);
+ }
+
+ #endif
+
+ for (i = 0, result = 1; i < MAXCLIENTS; result = 1, i++)
+ {
+ if (clients[i] != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllPixmaps: Going to reconnect pixmaps of client [%d].\n", i);
+ #endif
+
+ /*
+ * Let the pixmap be reconnected as it was an
+ * image request issued by the client owning
+ * the resource. The client index is used as
+ * a subscript by the image routines to cache
+ * the data per-client.
+ */
+
+ FindClientResourcesByType(clients[i], RT_PIXMAP, nxagentReconnectPixmap, &result);
+
+ #ifdef WARNING
+
+ if (result == 0)
+ {
+ fprintf(stderr, "nxagentReconnectAllPixmaps: WARNING! Failed to reconnect "
+ "pixmap for client [%d].\n", serverClient -> index);
+ }
+
+ #endif
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllPixmaps: Pixmaps reconnection completed.\n");
+ #endif
+
+ return result;
+}
+
+#ifdef TEST
+
+static void nxagentCheckOnePixmapIntegrity(void *p0, XID x1, void *p2)
+{
+ PixmapPtr pPixmap = (PixmapPtr) p0;
+ Bool *pBool = (Bool*) p2;
+
+ if (*pBool == False)
+ {
+ return;
+ }
+
+ if (pPixmap == nxagentDefaultScreen -> devPrivate)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckOnePixmapIntegrity: pixmap %p is screen.\n",
+ (void *) pPixmap);
+ #endif
+
+ return;
+ }
+
+ if (pPixmap == nxagentDefaultScreen -> PixmapPerDepth[0])
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckOnePixmapIntegrity: pixmap %p is default stipple of screen.\n",
+ (void *) pPixmap);
+ #endif
+
+ return;
+ }
+
+ *pBool = nxagentCheckPixmapIntegrity(pPixmap);
+}
+
+Bool nxagentCheckPixmapIntegrity(PixmapPtr pPixmap)
+{
+ Bool integrity = 1;
+ XImage *image;
+ char *data;
+ int format;
+ unsigned long plane_mask = AllPlanes;
+ unsigned int width, height, length, depth;
+ PixmapPtr pVirtual = nxagentVirtualPixmap(pPixmap);
+
+ width = pPixmap -> drawable.width;
+ height = pPixmap -> drawable.height;
+ depth = pPixmap -> drawable.depth;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ if (width && height)
+ {
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ data = malloc(length);
+
+ if (data == NULL)
+ {
+ FatalError("nxagentCheckPixmapIntegrity: Failed to allocate a buffer of size %d.\n", length);
+ }
+
+ image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), 0, 0,
+ width, height, plane_mask, format);
+ if (image == NULL)
+ {
+ FatalError("XGetImage: Failed.\n");
+
+ free(data);
+
+ return False;
+ }
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Image from X has length [%d] and checksum [0x%s].\n",
+ length, nxagentChecksum(image->data, length));
+ #endif
+
+ NXCleanImage(image);
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Image after clean has checksum [0x%s].\n",
+ nxagentChecksum(image->data, length));
+ #endif
+
+ fbGetImage((DrawablePtr) pVirtual, 0, 0, width, height, format, plane_mask, data);
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Image from FB has length [%d] and checksum [0x%s].\n",
+ length, nxagentChecksum(data, length));
+ #endif
+
+ if (image != NULL && memcmp(image -> data, data, length) != 0)
+ {
+ integrity = 0;
+ }
+ else
+ {
+ integrity = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Pixmap at [%p] has been realized. "
+ "Now remote and frambuffer data are synchronized.\n", (void *) pPixmap);
+ #endif
+ }
+
+ #ifdef WARNING
+
+ if (integrity == 0)
+ {
+
+ int i;
+ char *p, *q;
+
+ for (i = 0, p = image -> data, q = data; i < length; i++)
+ {
+ if (p[i] != q[i])
+ {
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Byte [%d] image -> data [%d] data [%d]. "
+ "Buffers differ!\n", i, p[i], q[i]);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Byte [%d] image -> data [%d] data [%d].\n",
+ i, p[i], q[i]);
+ }
+ }
+
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Pixmap at [%p] width [%d], height [%d], has been realized "
+ "but the data buffer still differs.\n", (void *) pPixmap, width, height);
+
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: bytes_per_line [%d] byte pad [%d] format [%d].\n",
+ image -> bytes_per_line, nxagentImagePad(width, height, 0, depth), image -> format);
+
+ FatalError("nxagentCheckPixmapIntegrity: Image is corrupted!!\n");
+
+ }
+
+ #endif
+
+ if (image != NULL)
+ {
+ XDestroyImage(image);
+ }
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckPixmapIntegrity: Ignored pixmap at [%p] with geometry [%d] [%d].\n",
+ (void *) pPixmap, width, height);
+ #endif
+ }
+
+ return integrity;
+}
+
+Bool nxagentCheckAllPixmapIntegrity()
+{
+ int i;
+ Bool imageIsGood = True;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckAllPixmapIntegrity\n");
+ #endif
+
+ FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP,
+ nxagentCheckOnePixmapIntegrity, &imageIsGood);
+
+ for (i = 0; (i < MAXCLIENTS) && (imageIsGood); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], RT_PIXMAP,
+ nxagentCheckOnePixmapIntegrity, &imageIsGood);
+
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCheckAllPixmapIntegrity: pixmaps integrity = %d.\n", imageIsGood);
+ #endif
+
+ return imageIsGood;
+}
+
+#endif
+
+void nxagentSynchronizeShmPixmap(DrawablePtr pDrawable, int xPict, int yPict,
+ int wPict, int hPict)
+{
+ GCPtr pGC;
+ char *data;
+ int width, height;
+ int depth, length, format;
+ CARD32 attributes[3];
+
+ int saveTrap;
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pDrawable) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSynchronizeShmPixmap: WARNING! Synchronizing shared pixmap at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ pGC = nxagentGetScratchGC(pDrawable -> depth, pDrawable -> pScreen);
+
+ attributes[0] = 0x228b22;
+ attributes[1] = 0xffffff;
+ attributes[2] = FillSolid;
+
+ ChangeGC(pGC, GCForeground | GCBackground | GCFillStyle, attributes);
+
+ ValidateGC(pDrawable, pGC);
+
+ width = (wPict != 0 && wPict <= pDrawable -> width) ? wPict : pDrawable -> width;
+ height = (hPict != 0 && hPict <= pDrawable -> height) ? hPict : pDrawable -> height;
+
+ depth = pDrawable -> depth;
+
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ saveTrap = nxagentGCTrap;
+
+ nxagentGCTrap = 0;
+
+ nxagentSplitTrap = 1;
+
+ nxagentFBTrap = 1;
+
+ if ((data = malloc(length)) != NULL)
+ {
+ fbGetImage(nxagentVirtualDrawable(pDrawable), xPict, yPict,
+ width, height, format, 0xffffffff, data);
+
+ nxagentPutImage(pDrawable, pGC, depth, xPict, yPict,
+ width, height, 0, format, data);
+
+ free(data);
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "nxagentSynchronizeShmPixmap: WARNING! Failed to allocate memory for the operation.\n");
+ }
+ #endif
+
+ nxagentGCTrap = saveTrap;
+
+ nxagentSplitTrap = 0;
+
+ nxagentFBTrap = 0;
+
+ nxagentFreeScratchGC(pGC);
+ }
+}
+
+#ifdef DUMP
+
+/*
+ * This function is useful to visualize a pixmap and check
+ * its data consistency. To avoid the creation of many
+ * windows, one pixmap only can be monitored at a time.
+ */
+
+Bool nxagentPixmapOnShadowDisplay(PixmapPtr pMap)
+{
+ static Display *shadow;
+ static Window win;
+ static int init = True;
+ static int showTime;
+ static PixmapPtr pPixmap;
+ static int depth;
+ static int width;
+ static int height;
+ static int length;
+ static unsigned int format;
+
+ XlibGC gc;
+ XGCValues value;
+ XImage *image;
+ Visual *pVisual;
+ char *data = NULL;
+
+
+ if (init)
+ {
+ if (pMap == NULL)
+ {
+ return False;
+ }
+ else
+ {
+ pPixmap = pMap;
+ }
+
+ depth = pPixmap -> drawable.depth;
+ width = pPixmap -> drawable.width;
+ height = pPixmap -> drawable.height;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ shadow = XOpenDisplay("localhost:0");
+
+ if (shadow == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Shadow display not opened.\n");
+ #endif
+
+ return False;
+ }
+
+ init = False;
+
+ win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+ width, height, 0, 0xFFCC33, 0xFF);
+
+ XMapWindow(shadow, win);
+ XClearWindow(shadow, win);
+ }
+
+/*
+FIXME: If the pixmap has a different depth from the window, the
+ XPutImage returns a BadMatch. For example this may happens if
+ the Render extension is enabled.
+ Can we fix this creating a new pixmap?
+*/
+
+ if (DisplayPlanes(shadow, DefaultScreen(shadow)) != depth)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPixmapOnShadowDisplay: Pixmap and Window depths [%d - %d] are not equals!\n",
+ depth, DisplayPlanes(shadow, DefaultScreen(shadow)));
+ #endif
+
+ return False;
+ }
+
+ /*
+ * If the framebuffer is updated continuously, the nxagent
+ * visualization become too much slow.
+ */
+
+ if ((GetTimeInMillis() - showTime) < 500)
+ {
+ return False;
+ }
+
+ showTime = GetTimeInMillis();
+
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ return False;
+ }
+
+ fbGetImage((DrawablePtr) nxagentVirtualPixmap(pPixmap), 0, 0,
+ width, height, format, AllPlanes, data);
+
+ pVisual = nxagentImageVisual((DrawablePtr) pPixmap, depth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ image = XCreateImage(nxagentDisplay, pVisual,
+ depth, format, 0, (char *) data,
+ width, height, BitmapPad(nxagentDisplay),
+ nxagentImagePad(width, format, 0, depth));
+
+ if (image == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentPixmapOnShadowDisplay: XCreateImage failed.\n");
+ #endif
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+
+ return False;
+ }
+
+ value.foreground = 0xff0000;
+ value.background = 0x000000;
+ value.plane_mask = 0xffffff;
+ value.fill_style = FillSolid;
+
+ gc = XCreateGC(shadow, win, GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+ NXCleanImage(image);
+
+ XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+ XFreeGC(shadow, gc);
+
+ if (image != NULL)
+ {
+ XDestroyImage(image);
+ }
+
+ return True;
+}
+
+Bool nxagentFbOnShadowDisplay()
+{
+ static Display *shadow;
+ static Window win;
+ static int init = True;
+ static int showTime;
+ static int prevWidth, prevHeight;
+
+ XlibGC gc;
+ XGCValues value;
+ XImage *image;
+ Visual *pVisual;
+ WindowPtr pWin = screenInfo.screens[0]->root;
+ unsigned int format;
+ int depth, width, height, length;
+ char *data = NULL;
+
+
+ if (pWin == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: The parent window is NULL.\n");
+ #endif
+
+ return False;
+ }
+
+ depth = pWin -> drawable.depth;
+ width = pWin -> drawable.width;
+ height = pWin -> drawable.height;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ if (init)
+ {
+ shadow = XOpenDisplay("localhost:0");
+
+ if (shadow == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Shadow display not opened.\n");
+ #endif
+
+ return False;
+ }
+
+ init = False;
+
+ prevWidth = width;
+ prevHeight = height;
+
+ win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+ width, height, 0, 0xFFCC33, 0xFF);
+
+ XMapWindow(shadow, win);
+ XClearWindow(shadow, win);
+ }
+
+ if (DisplayPlanes(shadow, DefaultScreen(shadow)) != depth)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: Depths [%d - %d] are not equals!\n",
+ depth, DisplayPlanes(shadow, DefaultScreen(shadow)));
+ #endif
+
+ return False;
+ }
+
+ /*
+ * If the framebuffer is updated continuously, the nxagent
+ * visualization becomes too much slow.
+ */
+
+ if ((GetTimeInMillis() - showTime) < 500)
+ {
+ return False;
+ }
+
+ showTime = GetTimeInMillis();
+
+ /*
+ * If the root window is resized, also the window on shadow
+ * display must be resized.
+ */
+
+ if (prevWidth != width || prevHeight != height)
+ {
+ XWindowChanges values;
+
+ prevWidth = width;
+ prevHeight = height;
+
+ values.width = width;
+ values.height = height;
+ XConfigureWindow(shadow, win, CWWidth | CWHeight, &values);
+ }
+
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Failed to allocate memory for the operation.\n");
+ #endif
+
+ return False;
+ }
+
+ fbGetImage((DrawablePtr)pWin, 0, 0,
+ width, height, format, AllPlanes, data);
+
+ pVisual = nxagentImageVisual((DrawablePtr) pWin, depth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ image = XCreateImage(nxagentDisplay, pVisual,
+ depth, format, 0, (char *) data,
+ width, height, BitmapPad(nxagentDisplay),
+ nxagentImagePad(width, format, 0, depth));
+
+ if (image == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbOnShadowDisplay: XCreateImage failed.\n");
+ #endif
+
+ if (data)
+ {
+ free(data);
+ }
+
+ return False;
+ }
+
+ value.foreground = 0xff0000;
+ value.background = 0x000000;
+ value.plane_mask = 0xffffff;
+ value.fill_style = FillSolid;
+
+ gc = XCreateGC(shadow, win, GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+ NXCleanImage(image);
+
+ XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+ XFreeGC(shadow, gc);
+
+ if (image != NULL)
+ {
+ XDestroyImage(image);
+ }
+
+ return True;
+}
+
+#endif
+
+#ifdef DEBUG
+
+void nxagentPrintResourceTypes()
+{
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_PIXMAP [%lu].\n", (unsigned long) RT_PIXMAP);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_PIXMAP [%lu].\n", (unsigned long) RT_NX_PIXMAP);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_GC [%lu].\n", (unsigned long) RT_GC);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_GC [%lu].\n", (unsigned long) RT_NX_GC);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_FONT [%lu].\n", (unsigned long) RT_FONT);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_FONT [%lu].\n", (unsigned long) RT_NX_FONT);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_CURSOR [%lu].\n", (unsigned long) RT_CURSOR);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_WINDOW [%lu].\n", (unsigned long) RT_WINDOW);
+ fprintf(stderr, "nxagentPrintResourceTypes: RT_COLORMAP [%lu].\n", (unsigned long) RT_COLORMAP);
+}
+
+void nxagentPrintResourcePredicate(void *value, XID id, XID type, void *cdata)
+{
+ fprintf(stderr, "nxagentPrintResourcePredicate: Resource [%p] id [%lu] type [%lu].\n",
+ (void *) value, (unsigned long) id, (unsigned long) type);
+}
+
+void nxagentPrintResources()
+{
+ Bool result;
+ int i;
+
+ nxagentPrintResourceTypes();
+
+ for (i = 0; i < MAXCLIENTS; i++)
+ {
+ if (clients[i])
+ {
+ fprintf(stderr, "nxagentPrintResources: Printing resources for client [%d]:\n",
+ i);
+
+ FindAllClientResources(clients[i], nxagentPrintResourcePredicate, &result);
+ }
+ }
+}
+
+#endif
+
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
new file mode 100644
index 000000000..00cc39c5f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -0,0 +1,145 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Pixmap_H__
+#define __Pixmap_H__
+
+#include "resource.h"
+#include "Split.h"
+
+extern RESTYPE RT_NX_PIXMAP;
+
+/*
+ * Pixmap privates structure.
+ */
+
+typedef struct
+{
+ Pixmap id;
+ XID mid;
+
+ Bool isVirtual;
+ Bool isShared;
+
+ PixmapPtr pVirtualPixmap;
+ PixmapPtr pRealPixmap;
+
+ void *pPicture;
+
+ RegionPtr corruptedRegion;
+
+ int corruptedBackground;
+
+ int containGlyphs;
+ int containTrapezoids;
+
+ int usageCounter;
+
+ XID corruptedBackgroundId;
+ XID corruptedId;
+
+ PixmapPtr synchronizationBitmap;
+
+ Time corruptedTimestamp;
+
+ SplitResourcePtr splitResource;
+
+ int isBackingPixmap;
+
+} nxagentPrivPixmapRec;
+
+typedef nxagentPrivPixmapRec *nxagentPrivPixmapPtr;
+
+extern int nxagentPixmapPrivateIndex;
+
+/*
+ * Pixmap privates macro.
+ */
+
+#define nxagentPixmapPriv(pPixmap) \
+ ((nxagentPrivPixmapPtr)((pPixmap) -> devPrivates[nxagentPixmapPrivateIndex].ptr))
+
+#define nxagentPixmap(pPixmap) (nxagentPixmapPriv(pPixmap) -> id)
+
+#define nxagentPixmapIsVirtual(pPixmap) \
+ (nxagentPixmapPriv(pPixmap) -> isVirtual)
+
+#define nxagentIsShmPixmap(pPixmap) \
+ (nxagentPixmapPriv(pPixmap) -> isShared)
+
+#define nxagentRealPixmap(pPixmap) \
+ (nxagentPixmapPriv(pPixmap) -> pRealPixmap)
+
+#define nxagentVirtualPixmap(pPixmap) \
+ (nxagentPixmapPriv(pPixmap) -> isVirtual ? pPixmap : \
+ nxagentPixmapPriv(pPixmap) -> pVirtualPixmap)
+
+#define nxagentPixmapCorruptedRegion(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedRegion)
+
+#define nxagentPixmapContainGlyphs(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> containGlyphs)
+
+#define nxagentPixmapContainTrapezoids(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> containTrapezoids)
+
+#define nxagentIsCorruptedBackground(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedBackground)
+
+#define nxagentPixmapUsageCounter(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> usageCounter)
+
+#define nxagentPixmapTimestamp(pPixmap) \
+ (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedTimestamp)
+
+PixmapPtr nxagentPixmapPtr(Pixmap pixmap);
+
+PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width,
+ int height, int depth, unsigned usage_hint);
+
+Bool nxagentDestroyPixmap(PixmapPtr pPixmap);
+
+RegionPtr nxagentPixmapToRegion(PixmapPtr pPixmap);
+
+Bool nxagentModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, void * pPixData);
+
+RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int width, int height);
+
+void nxagentReconnectPixmap(void *p0, XID x1, void *p2);
+Bool nxagentReconnectAllPixmaps(void *p0);
+void nxagentDisconnectPixmap(void *p0, XID x1, void* p2);
+Bool nxagentDisconnectAllPixmaps(void);
+
+int nxagentDestroyNewPixmapResourceType(void * p, XID id);
+
+void nxagentSynchronizeShmPixmap(DrawablePtr pDrawable, int xPict, int yPict,
+ int wPict, int hPict);
+
+Bool nxagentPixmapOnShadowDisplay(PixmapPtr pMap);
+Bool nxagentFbOnShadowDisplay();
+
+#endif /* __Pixmap_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
new file mode 100644
index 000000000..c59230724
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -0,0 +1,199 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointer.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Events.h"
+#include "Options.h"
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
+void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl)
+{
+ /*
+ * The original behaviour was to reset the pointer settings
+ * (acceleration and alas) to the default values. What the
+ * average user expects, on the contrary, is to have agent
+ * inheriting whatever value is set on the real X display.
+ * Having to reflect changes made inside the agent session,
+ * the correct behavior would be saving the original values
+ * and restoring them as soon as focus leaves the agent's
+ * window.
+ */
+
+ if (nxagentOption(DeviceControl) == True)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangePointerControl: WARNING! Propagating changes to pointer settings.\n");
+ #endif
+
+ XChangePointerControl(nxagentDisplay, True, True,
+ ctrl->num, ctrl->den, ctrl->threshold);
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangePointerControl: WARNING! Not propagating changes to pointer settings.\n");
+ #endif
+}
+
+int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
+{
+ CARD8 map[MAXBUTTONS];
+ int nmap;
+ int i;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_INIT].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ nmap = XGetPointerMapping(nxagentDisplay, map, MAXBUTTONS);
+ for (i = 0; i <= nmap; i++)
+ map[i] = i; /* buttons are already mapped */
+ InitPointerDeviceStruct((DevicePtr) pDev, map, nmap,
+ miPointerGetMotionEvents,
+ nxagentChangePointerControl,
+ miPointerGetMotionBufferSize());
+ break;
+ case DEVICE_ON:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_ON].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ nxagentInitPointerMap();
+
+ nxagentEnablePointerEvents();
+
+ break;
+
+ case DEVICE_OFF:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_OFF].\n");
+ #endif
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return Success;
+ }
+
+ nxagentDisablePointerEvents();
+
+ break;
+
+ case DEVICE_CLOSE:
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_CLOSE].\n");
+ #endif
+
+ break;
+ }
+
+ return Success;
+}
+
+void nxagentInitPointerMap(void)
+{
+ int numButtons;
+
+ int i;
+
+ unsigned char pointerMap[MAXBUTTONS];
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentInitPointerMap: Going to retrieve the "
+ "pointer map from remote display.\n");
+ #endif
+
+ numButtons = XGetPointerMapping(nxagentDisplay, pointerMap, MAXBUTTONS);
+
+ /*
+ * Computing revers pointer map.
+ */
+
+ for (i = 1; i <= numButtons; i++)
+ {
+ nxagentReversePointerMap[pointerMap[i - 1]] = i;
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
new file mode 100644
index 000000000..85162d4a5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -0,0 +1,62 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Pointer_H__
+#define __Pointer_H__
+
+#define MAXBUTTONS 256
+
+#define NXAGENT_POINTER_EVENT_MASK \
+ (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
+ EnterWindowMask | LeaveWindowMask)
+
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+extern unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
+void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl);
+
+int nxagentPointerProc(DeviceIntPtr pDev, int onoff);
+
+void nxagentInitPointerMap(void);
+
+#endif /* __Pointer_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
new file mode 100644
index 000000000..fb2303549
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -0,0 +1,849 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <signal.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "Xpoll.h"
+#include "mi.h"
+#include "fb.h"
+#include "inputstr.h"
+
+#include "Agent.h"
+#include "Atoms.h"
+#include "Drawable.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Display.h"
+#include "Dialog.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Events.h"
+#include "Dialog.h"
+#include "Args.h"
+#include "Font.h"
+#include "GCs.h"
+#include "Trap.h"
+#include "Keyboard.h"
+#include "Composite.h"
+#include "Millis.h"
+#include "Splash.h"
+#include "Error.h"
+#include "Keystroke.h"
+
+#ifdef XKB
+#include "XKBsrv.h"
+#endif
+
+#include <nx/NX.h>
+#include "compext/Compext.h"
+#include <nx/NXalert.h>
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define NXAGENT_RECONNECT_DEFAULT_MESSAGE_SIZE 32
+
+extern Bool nxagentReconnectAllCursor(void*);
+extern Bool nxagentReconnectAllColormap(void*);
+extern Bool nxagentReconnectAllWindows(void*);
+extern Bool nxagentReconnectAllGlyphSet(void*);
+extern Bool nxagentReconnectAllPictFormat(void*);
+extern Bool nxagentReconnectAllPicture(void*);
+
+extern Bool nxagentDisconnectAllPicture(void);
+extern Bool nxagentDisconnectAllWindows(void);
+extern Bool nxagentDisconnectAllCursor(void);
+
+extern Bool nxagentReconnectFailedFonts(void*);
+extern Bool nxagentInstallFontServerPath(void);
+extern Bool nxagentUninstallFontServerPath(void);
+
+extern void nxagentRemoveXConnection(void);
+
+extern void nxagentInitPointerMap(void);
+
+static char *nxagentGetReconnectError(void);
+
+void nxagentInitializeRecLossyLevel(void);
+
+static char *nxagentReconnectErrorMessage = NULL;
+static int nxagentReconnectErrorId;
+
+extern Bool nxagentRenderEnable;
+
+extern char *nxagentKeyboard;
+
+enum SESSION_STATE nxagentSessionState = SESSION_STARTING;
+
+struct nxagentExceptionStruct nxagentException = {0, 0};
+
+enum RECONNECTION_STEP
+{
+ DISPLAY_STEP = 0,
+ SCREEN_STEP,
+ FONT_STEP,
+ PIXMAP_STEP,
+ GC_STEP,
+ CURSOR_STEP,
+ COLORMAP_STEP,
+ WINDOW_STEP,
+ GLYPHSET_STEP,
+ PICTFORMAT_STEP,
+ PICTURE_STEP,
+ STEP_NONE
+};
+
+void *reconnectLossyLevel[STEP_NONE];
+
+static enum RECONNECTION_STEP failedStep;
+
+#include <limits.h>
+
+/*
+ * Path of state File
+ */
+char stateFile[PATH_MAX];
+
+
+void setStatePath(char* path)
+{
+ strncpy(stateFile, path, PATH_MAX-1);
+}
+
+void saveAgentState(char* state)
+{
+ FILE* fptr;
+ if(strlen(stateFile))
+ {
+ fptr=fopen(stateFile, "w");
+ if(!fptr)
+ return;
+ fprintf(fptr,"%s", state);
+ fclose(fptr);
+ }
+}
+
+
+int nxagentHandleConnectionStates(void)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Handling Exception with "
+ "state [%s] and transport [%d] and generation [%ld].\n",
+ DECODE_SESSION_STATE(nxagentSessionState), NXTransRunning(NX_FD_ANY), serverGeneration);
+ fprintf(stderr, "nxagentHandleConnectionStates: Entering with nxagentException.sigHup = [%d], "
+ "nxagentException.ioError = [%d]\n",
+ nxagentException.sigHup, nxagentException.ioError);
+ #endif
+
+ if (nxagentException.sigHup > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got SIGHUP in the exception flags.\n");
+ #endif
+
+ nxagentException.sigHup = 0;
+
+ if (nxagentSessionState == SESSION_UP)
+ {
+ if (nxagentOption(Persistent))
+ {
+ nxagentSessionState = SESSION_GOING_DOWN;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Handling "
+ "signal [SIGHUP] by disconnecting the agent.\n");
+
+ #endif
+
+ }
+ else
+ {
+ nxagentTerminateSession();
+ }
+ }
+ else if (nxagentSessionState == SESSION_STARTING)
+ {
+ nxagentTerminateSession();
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentHandleConnectionStates: Handling signal [SIGHUP] by terminating the agent.\n");
+ #endif
+ }
+ else if (nxagentSessionState == SESSION_DOWN &&
+ NXTransRunning(NX_FD_ANY) == 0)
+ {
+ nxagentSessionState = SESSION_GOING_UP;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Handling signal [SIGHUP] by reconnecting the agent.\n");
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Handling signal with state [%s] and exception [%d].\n",
+ DECODE_SESSION_STATE(nxagentSessionState), dispatchException);
+ #endif
+ }
+ }
+
+ if (nxagentNeedConnectionChange() == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Calling nxagentHandleConnectionChanges "
+ "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+ #endif
+
+ nxagentHandleConnectionChanges();
+ }
+
+ if (nxagentException.ioError > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error in the exception flags.\n");
+ #endif
+/*
+TODO: This should be reset only when
+ the state became SESSION_DOWN.
+*/
+ nxagentException.ioError = 0;
+
+ if (nxagentOption(Persistent) == 1 && nxagentSessionState != SESSION_STARTING)
+ {
+ if (nxagentSessionState == SESSION_UP)
+ {
+ if ((dispatchException & DE_TERMINATE) == 0)
+ {
+ fprintf(stderr, "Session: Display failure detected at '%s'.\n", GetTimeAsString());
+
+ fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+ saveAgentState("SUSPENDING");
+ }
+
+ nxagentDisconnectSession();
+ }
+ else if (nxagentSessionState == SESSION_GOING_DOWN)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+ "[SESSION_GOING_DOWN].\n");
+ #endif
+ }
+ else if (nxagentSessionState == SESSION_GOING_UP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+ "[SESSION_GOING_UP].\n");
+ #endif
+
+ nxagentSessionState = SESSION_GOING_DOWN;
+
+ nxagentSetReconnectError(FAILED_RESUME_DISPLAY_BROKEN_ALERT,
+ "Got I/O error during reconnect.");
+
+ nxagentChangeOption(Fullscreen, False);
+
+ return 1;
+ }
+ else if (nxagentSessionState == SESSION_DOWN)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+ "[SESSION_DOWN]. Ignoring.\n");
+ #endif
+
+ return 1;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+ "[%d].\n", nxagentSessionState);
+ #endif
+ }
+
+ nxagentSessionState = SESSION_DOWN;
+
+ if ((dispatchException & DE_TERMINATE) == 0)
+ {
+ #ifdef NX_DEBUG_INPUT
+ fprintf(stderr, "Session: Session suspended at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+ #else
+ fprintf(stderr, "Session: Session suspended at '%s'.\n", GetTimeAsString());
+ #endif
+ }
+ saveAgentState("SUSPENDED");
+
+ nxagentResetDisplayHandlers();
+
+ return 1;
+ }
+
+ fprintf(stderr, "Info: Disconnected from display '%s'.\n", nxagentDisplayName);
+
+ nxagentTerminateSession();
+
+ return -1;
+ }
+
+ return 0;
+}
+
+void nxagentInitializeRecLossyLevel()
+{
+ *(int *)reconnectLossyLevel[DISPLAY_STEP] = 0;
+ *(int *)reconnectLossyLevel[SCREEN_STEP] = 0;
+ *(int *)reconnectLossyLevel[FONT_STEP] = 0;
+ *(int *)reconnectLossyLevel[PIXMAP_STEP] = 0;
+ *(int *)reconnectLossyLevel[GC_STEP] = 0;
+ *(int *)reconnectLossyLevel[CURSOR_STEP] = 0;
+ *(int *)reconnectLossyLevel[COLORMAP_STEP] = 0;
+ *(int *)reconnectLossyLevel[WINDOW_STEP] = 0;
+ *(int *)reconnectLossyLevel[GLYPHSET_STEP] = 0;
+ *(int *)reconnectLossyLevel[PICTFORMAT_STEP] = 0;
+ *(int *)reconnectLossyLevel[PICTURE_STEP] = 0;
+}
+
+void nxagentInitReconnector(void)
+{
+ nxagentReconnectTrap = 0;
+
+ reconnectLossyLevel[DISPLAY_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[SCREEN_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[FONT_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[PIXMAP_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[GC_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[CURSOR_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[COLORMAP_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[WINDOW_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[GLYPHSET_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[PICTFORMAT_STEP] = malloc(sizeof(int));
+ reconnectLossyLevel[PICTURE_STEP] = malloc(sizeof(int));
+}
+
+void nxagentDisconnectSession(void)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectSession: Disconnecting session with state [%s].\n",
+ DECODE_SESSION_STATE(nxagentSessionState));
+ #endif
+
+ /*
+ * Force an I/O error on the display
+ * and wait until the NX transport
+ * is gone.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectSession: Disconnecting the X display.\n");
+ #endif
+
+ nxagentWaitDisplay();
+
+ /*
+ * Prepare for the next reconnection.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectSession: Disconnecting all X resources.\n");
+ #endif
+
+ nxagentInitializeRecLossyLevel();
+
+ nxagentBackupDisplayInfo();
+
+ if (nxagentOption(Rootless))
+ {
+ nxagentFreePropertyList();
+ }
+
+ if (nxagentRenderEnable)
+ {
+ nxagentDisconnectAllPicture();
+ }
+
+ nxagentEmptyAllBackingStoreRegions();
+
+ nxagentDisconnectAllWindows();
+ nxagentDisconnectAllCursor();
+ nxagentDisconnectAllPixmaps();
+ nxagentDisconnectAllGCs();
+ nxagentDisconnectDisplay();
+
+ nxagentWMIsRunning = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectSession: Disconnection completed. SigHup is [%d]. IoError is [%d].\n",
+ nxagentException.sigHup, nxagentException.ioError);
+ #endif
+}
+
+Bool nxagentReconnectSession(void)
+{
+ char *nxagentOldKeyboard = NULL;
+
+ nxagentResizeDesktopAtStartup = False;
+
+ /*
+ * Propagate device settings if explicitly asked for.
+ */
+
+ nxagentChangeOption(DeviceControl, nxagentOption(DeviceControlUserDefined));
+
+ /*
+ * We need to zero out every new XID
+ * created by the disconnected display.
+ */
+
+ nxagentDisconnectSession();
+
+ /*
+ * Set this in order to let the screen
+ * function to behave differently at
+ * reconnection time.
+ */
+
+ nxagentReconnectTrap = True;
+
+ nxagentSetReconnectError(0, NULL);
+
+ if (nxagentKeyboard != NULL)
+ {
+ nxagentOldKeyboard = strndup(nxagentKeyboard, strlen(nxagentKeyboard));
+ if (nxagentOldKeyboard == NULL)
+ {
+ /* 0 means reconnection failed */
+ return 0;
+ }
+
+ free(nxagentKeyboard);
+ nxagentKeyboard = NULL;
+ }
+
+ nxagentSaveOptions();
+
+ nxagentResetOptions();
+
+ nxagentProcessOptionsFile();
+
+ if (nxagentReconnectDisplay(reconnectLossyLevel[DISPLAY_STEP]) == 0)
+ {
+ failedStep = DISPLAY_STEP;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnect: WARNING! Failed display reconnection.\n");
+ #endif
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectScreen(reconnectLossyLevel[SCREEN_STEP]) == 0)
+ {
+ failedStep = SCREEN_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ nxagentDisconnectAllFonts();
+
+ nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+ if (nxagentReconnectAllFonts(reconnectLossyLevel[FONT_STEP]) == 0)
+ {
+ if (nxagentReconnectFailedFonts(reconnectLossyLevel[FONT_STEP]) == 0)
+ {
+ failedStep = FONT_STEP;
+
+ goto nxagentReconnectError;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnect: WARNING! Unable to retrieve all the fonts currently in use. "
+ "Missing fonts have been replaced.\n");
+ #endif
+
+ nxagentLaunchDialog(DIALOG_FONT_REPLACEMENT);
+ }
+ }
+
+ /*
+ * Map the main window and send a
+ * SetSelectionOwner request to
+ * notify of the agent start.
+ */
+
+ nxagentMapDefaultWindows();
+
+ /*
+ * Ensure that the SetSelectionOwner
+ * request is sent through the link.
+ */
+
+ XFlush(nxagentDisplay);
+
+ NXTransContinue(NULL);
+
+ nxagentEmptyBSPixmapList();
+
+ if (nxagentReconnectAllPixmaps(reconnectLossyLevel[PIXMAP_STEP]) == 0)
+ {
+ failedStep = PIXMAP_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectAllGCs(reconnectLossyLevel[GC_STEP]) == 0)
+ {
+ failedStep = GC_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectAllColormap(reconnectLossyLevel[COLORMAP_STEP]) == 0)
+ {
+ failedStep = COLORMAP_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectAllWindows(reconnectLossyLevel[WINDOW_STEP]) == 0)
+ {
+ failedStep = WINDOW_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentRenderEnable)
+ {
+ if (nxagentReconnectAllGlyphSet(reconnectLossyLevel[GLYPHSET_STEP]) == 0)
+ {
+ failedStep = GLYPHSET_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectAllPictFormat(reconnectLossyLevel[PICTFORMAT_STEP]) == 0)
+ {
+ failedStep = PICTFORMAT_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentReconnectAllPicture(reconnectLossyLevel[PICTURE_STEP]) == 0)
+ {
+ failedStep = PICTURE_STEP;
+
+ goto nxagentReconnectError;
+ }
+ }
+
+ if (nxagentReconnectAllCursor(reconnectLossyLevel[CURSOR_STEP]) == 0)
+ {
+ failedStep = CURSOR_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentSetWindowCursors(reconnectLossyLevel[WINDOW_STEP]) == 0)
+ {
+ failedStep = WINDOW_STEP;
+
+ goto nxagentReconnectError;
+ }
+
+ if (nxagentOption(ResetKeyboardAtResume) == 1 &&
+ (nxagentKeyboard == NULL || nxagentOldKeyboard == NULL ||
+ strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
+ strcmp(nxagentKeyboard, "query") == 0))
+ {
+ if (nxagentResetKeyboard() == 0)
+ {
+ #ifdef WARNING
+ if (nxagentVerbose == 1)
+ {
+ fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
+ }
+ #endif
+
+ failedStep = WINDOW_STEP;
+
+ goto nxagentReconnectError;
+ }
+ }
+ else
+ {
+ nxagentResetKeycodeConversion();
+ }
+
+ nxagentXkbState.Initialized = 0;
+
+ if (nxagentOldKeyboard != NULL)
+ {
+ free(nxagentOldKeyboard);
+
+ nxagentOldKeyboard = NULL;
+ }
+
+ nxagentInitPointerMap();
+
+ nxagentDeactivatePointerGrab();
+
+ nxagentWakeupByReconnect();
+
+ nxagentFreeGCList();
+
+ nxagentRedirectDefaultWindows();
+
+ if (nxagentResizeDesktopAtStartup || nxagentOption(Rootless) == True || nxagentOption(Xinerama) == True)
+ {
+ nxagentChangeScreenConfig(0, nxagentOption(RootWidth),
+ nxagentOption(RootHeight), 0, 0);
+
+ nxagentResizeDesktopAtStartup = False;
+ }
+
+ nxagentReconnectTrap = False;
+
+ nxagentExposeArrayIsInitialized = False;
+
+ if (nxagentSessionState != SESSION_GOING_UP)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnect: WARNING! Unexpected session state [%s] while reconnecting.\n",
+ DECODE_SESSION_STATE(nxagentSessionState));
+ #endif
+
+ goto nxagentReconnectError;
+ }
+
+ /* Re-read keystrokes definitions in case the keystrokes file has
+ changed while being supended */
+ nxagentInitKeystrokes(True);
+
+ #ifdef NX_DEBUG_INPUT
+ fprintf(stderr, "Session: Session resumed at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+ #else
+ fprintf(stderr, "Session: Session resumed at '%s'.\n", GetTimeAsString());
+ #endif
+ saveAgentState("RUNNING");
+
+ nxagentRemoveSplashWindow(NULL);
+
+ /*
+ * We let the proxy flush the link on our behalf
+ * after having opened the display. We are now
+ * entering again the dispatcher so can flush
+ * the link explicitly.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnect: Setting the NX flush policy to deferred.\n");
+ #endif
+
+ NXSetDisplayPolicy(nxagentDisplay, NXPolicyDeferred);
+
+ nxagentCleanupBackupDisplayInfo();
+
+ return 1;
+
+nxagentReconnectError:
+
+ if (failedStep == DISPLAY_STEP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnect: Reconnection failed in display step. Restoring options.\n");
+ #endif
+
+ nxagentRestoreOptions();
+ }
+ else
+ {
+ nxagentCleanupBackupDisplayInfo();
+ }
+
+ if (*nxagentGetReconnectError() == '\0')
+ {
+ #ifdef WARNING
+ if (nxagentVerbose == 1)
+ {
+ fprintf(stderr, "nxagentReconnect: WARNING! The reconnect error message is not set. Failed step is [%d].\n",
+ failedStep);
+ }
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnect: Reconnection failed due to a display error.\n");
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnect: Reconnection failed with reason '%s'\n",
+ nxagentGetReconnectError());
+ #endif
+ }
+
+ if (NXDisplayError(nxagentDisplay) == 0)
+ {
+ nxagentUnmapWindows();
+
+ nxagentFailedReconnectionDialog(nxagentReconnectErrorId, nxagentGetReconnectError());
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentReconnect: Cannot launch the dialog without a valid display.\n");
+ }
+ #endif
+
+ if (failedStep == FONT_STEP)
+ {
+ *((int *) reconnectLossyLevel[FONT_STEP]) = 1;
+ }
+
+ if (nxagentDisplay == NULL)
+ {
+ nxagentDisconnectDisplay();
+ }
+
+ if (nxagentOldKeyboard != NULL)
+ {
+ free(nxagentOldKeyboard);
+
+ nxagentOldKeyboard = NULL;
+ }
+
+ return 0;
+}
+
+void nxagentSetReconnectError(int id, char *format, ...)
+{
+ static int size = 0;
+
+ va_list ap;
+ int n;
+
+ if (format == NULL)
+ {
+ nxagentSetReconnectError(id, "");
+
+ return;
+ }
+
+ nxagentReconnectErrorId = id;
+
+ while (1)
+ {
+ va_start (ap, format);
+
+ n = vsnprintf(nxagentReconnectErrorMessage, size, format, ap);
+
+ va_end(ap);
+
+ if (n > -1 && n < size)
+ {
+ break;
+ }
+ if (n > -1)
+ {
+ size = n + 1;
+ }
+ else
+ {
+ /*
+ * The vsnprintf() in glibc 2.0.6 would return
+ * -1 when the output was truncated. See section
+ * NOTES on printf(3).
+ */
+
+ size = (size ? size * 2 : NXAGENT_RECONNECT_DEFAULT_MESSAGE_SIZE);
+ }
+
+ nxagentReconnectErrorMessage = realloc(nxagentReconnectErrorMessage, size);
+
+ if (nxagentReconnectErrorMessage == NULL)
+ {
+ FatalError("realloc failed");
+ }
+ }
+
+ return;
+}
+
+static char* nxagentGetReconnectError()
+{
+ if (nxagentReconnectErrorMessage == NULL)
+ {
+ nxagentSetReconnectError(nxagentReconnectErrorId, "");
+ }
+
+ return nxagentReconnectErrorMessage;
+}
+
+void nxagentHandleConnectionChanges()
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleConnectionChanges: Called.\n");
+ #endif
+
+ if (nxagentSessionState == SESSION_GOING_DOWN)
+ {
+ fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+ saveAgentState("SUSPENDING");
+
+ nxagentDisconnectSession();
+ }
+ else if (nxagentSessionState == SESSION_GOING_UP)
+ {
+ fprintf(stderr, "Session: Resuming session at '%s'.\n", GetTimeAsString());
+ saveAgentState("RESUMING");
+
+ if (nxagentReconnectSession())
+ {
+ nxagentSessionState = SESSION_UP;
+ }
+ else
+ {
+ nxagentSessionState = SESSION_GOING_DOWN;
+
+ fprintf(stderr, "Session: Display failure detected at '%s'.\n", GetTimeAsString());
+
+ fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+ saveAgentState("SUSPENDING");
+
+ nxagentDisconnectSession();
+ }
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
new file mode 100644
index 000000000..d1c62166b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -0,0 +1,78 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Reconnect_H__
+#define __Reconnect_H__
+
+extern Display *nxagentDisplayState;
+
+struct nxagentExceptionStruct
+{
+ int sigHup;
+ int ioError;
+};
+
+extern struct nxagentExceptionStruct nxagentException;
+
+void nxagentSetReconnectError(int id, char *format, ...);
+
+void nxagentInitReconnector(void);
+Bool nxagentReconnectSession(void);
+int nxagentHandleConnectionStates(void);
+void nxagentHandleConnectionChanges(void);
+void setStatePath(char*);
+void saveAgentState(char*);
+
+enum SESSION_STATE
+{
+ SESSION_STARTING,
+ SESSION_UP,
+ SESSION_DOWN,
+ SESSION_GOING_DOWN,
+ SESSION_GOING_UP
+};
+
+extern enum SESSION_STATE nxagentSessionState;
+
+#define DECODE_SESSION_STATE(state) \
+ ((state) == SESSION_STARTING ? "SESSION_STARTING" : \
+ (state) == SESSION_UP ? "SESSION_UP" : \
+ (state) == SESSION_GOING_UP? "SESSION_GOING_UP" : \
+ (state) == SESSION_DOWN ? "SESSION_DOWN" : \
+ (state) == SESSION_GOING_DOWN? "SESSION_GOING_DOWN" : \
+ "UNKNOWN")
+
+/*
+ * Use this macro in the block and wakeup
+ * handlers to save a function call.
+ */
+
+#define nxagentNeedConnectionChange() \
+ (nxagentSessionState == SESSION_GOING_DOWN || \
+ nxagentSessionState == SESSION_GOING_UP)
+
+void nxagentDisconnectSession(void);
+
+#endif /* __Reconnect_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
new file mode 100644
index 000000000..753134eb3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -0,0 +1,3047 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "picturestr.h"
+#include "glyphstr.h"
+
+#include "Render.h"
+
+#include "X.h"
+#include "Xproto.h"
+
+#include "render.h"
+#include "renderproto.h"
+
+#include "mi.h"
+#include "fb.h"
+#include "mipict.h"
+#include "fbpict.h"
+#include "dixstruct.h"
+#include "protocol-versions.h"
+
+#include "Agent.h"
+#include "Drawable.h"
+#include "Trap.h"
+#include "Args.h"
+
+#define Atom XlibAtom
+#define Pixmap XlibPixmap
+#include "X11/include/Xrenderint_nxagent.h"
+#undef Atom
+#undef Pixmap
+
+#include "region.h"
+#include <X11/extensions/extutil.h>
+
+#include "Display.h"
+#include "Pixmaps.h"
+#include "Cursor.h"
+#include "Client.h"
+#include "Image.h"
+#include "Pixels.h"
+#include "Handlers.h"
+
+#include <nx/NXproto.h>
+
+#define MAX_FORMATS 255
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+/*
+ * Define if you want split multiple glyph lists
+ * into multiple RenderCompositeGlyphs requests.
+ */
+
+#undef SPLIT_GLYPH_LISTS
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+FIXME: Most operations don't seem to produce any visible result
+ but still generate tons of traffic.
+*/
+#undef SKIP_LOUSY_RENDER_OPERATIONS
+#undef SKIP_REALLY_ALL_LOUSY_RENDER_OPERATIONS
+
+/*
+ * Do we split the big trapezoid requests?
+ */
+
+#define TRAPEZOIDS_PER_REQUEST 256
+
+/*
+ * Margin added around the glyphs extent (in pixels).
+ */
+
+#define GLYPH_BOX_MARGIN 2
+
+int nxagentRenderEnable = UNDEFINED;
+int nxagentRenderVersionMajor;
+int nxagentRenderVersionMinor;
+
+int nxagentPicturePrivateIndex = 0;
+
+static int nxagentNumFormats = 0;
+
+static XRenderPictFormat nxagentArrayFormats[MAX_FORMATS];
+
+XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pForm);
+
+BoxPtr nxagentGlyphsExtents;
+BoxPtr nxagentTrapezoidExtents;
+
+#ifdef DEBUG
+
+static void nxagentPrintFormat(XRenderPictFormat *pFormat);
+
+#endif
+
+/*
+ * From NXglyph.c.
+ */
+
+extern const CARD8 glyphDepths[];
+
+/*
+ * From BitmapUtils.c.
+ */
+
+extern void nxagentBitOrderInvert(unsigned char *data, int nbytes);
+
+/*
+ * Other functions defined here.
+ */
+
+void nxagentQueryFormats(void);
+
+void nxagentCreateGlyphSet(GlyphSetPtr pGly);
+
+int nxagentCursorSaveRenderInfo(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
+ PicturePtr pPicture, int x, int y);
+
+int nxagentCreatePicture(PicturePtr pPicture, Mask mask);
+
+int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
+ xRectangle *rects, int xOrigin, int yOrigin);
+
+void nxagentDestroyPictureClip(PicturePtr pPicture);
+
+void nxagentValidatePicture(PicturePtr pPicture, Mask mask);
+
+void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height);
+
+void nxagentGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists,
+ XGlyphElt8 *elts, int sizeID, GlyphPtr *glyphsBase);
+
+void nxagentCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color,
+ int nRect, xRectangle *rects);
+
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps);
+
+void nxagentRasterizeTrapezoid(PicturePtr pMask, xTrapezoid *trap,
+ int x_off, int y_off);
+
+void nxagentTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris);
+
+void nxagentTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int npoint, xPointFixed *points);
+
+void nxagentChangePicture(PicturePtr pPicture, Mask mask);
+
+void nxagentTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int npoint, xPointFixed *points);
+
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+
+void nxagentSetPictureTransform(PicturePtr pPicture, void * transform);
+
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+ void * params, int nparams);
+
+Bool nxagentReconnectAllGlyphSet(void *p);
+
+Bool nxagentReconnectAllPicture(void *);
+
+Bool nxagentDisconnectAllPicture(void);
+
+void nxagentRenderExtensionInit()
+{
+ int first_event, first_error;
+ int major_version, minor_version;
+
+ if (XRenderQueryExtension(nxagentDisplay, &first_event, &first_error))
+ {
+ XRenderQueryVersion(nxagentDisplay, &major_version, &minor_version);
+
+ /*
+ * As the RENDER requests are passed directly to
+ * the remote X server this can cause problems if
+ * our RENDER version is different from the version
+ * supported by the remote. For this reasos let's
+ * advertise to our clients the lowest between the
+ + two versions.
+ */
+
+ if (major_version > SERVER_RENDER_MAJOR_VERSION ||
+ (major_version == SERVER_RENDER_MAJOR_VERSION &&
+ minor_version > SERVER_RENDER_MINOR_VERSION))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderExtensionInit: Using render version [%d.%d] with "
+ "remote version [%d.%d].\n", SERVER_RENDER_MAJOR_VERSION, SERVER_RENDER_MINOR_VERSION,
+ major_version, minor_version);
+ #endif
+
+ nxagentRenderVersionMajor = SERVER_RENDER_MAJOR_VERSION;
+ nxagentRenderVersionMinor = SERVER_RENDER_MINOR_VERSION;
+ }
+ else if (major_version < SERVER_RENDER_MAJOR_VERSION ||
+ (major_version == SERVER_RENDER_MAJOR_VERSION &&
+ minor_version < SERVER_RENDER_MINOR_VERSION))
+ {
+ #ifdef TEST
+ fprintf(stderr, "Info: Local render version %d.%d is higher "
+ "than remote version %d.%d.\n", SERVER_RENDER_MAJOR_VERSION, SERVER_RENDER_MINOR_VERSION,
+ major_version, minor_version);
+
+ fprintf(stderr, "Info: Lowering the render version reported to clients.\n");
+ #endif
+
+ nxagentRenderVersionMajor = major_version;
+ nxagentRenderVersionMinor = minor_version;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderExtensionInit: Local render version %d.%d "
+ "matches remote version %d.%d.\n", SERVER_RENDER_MAJOR_VERSION, SERVER_RENDER_MINOR_VERSION,
+ major_version, minor_version);
+ #endif
+
+ nxagentRenderVersionMajor = major_version;
+ nxagentRenderVersionMinor = minor_version;
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "Warning: Render not available on the remote display.\n");
+ #endif
+
+ nxagentRenderEnable = False;
+ }
+}
+
+int nxagentCursorSaveRenderInfo(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ pCursor -> devPriv[pScreen -> myNum] = malloc(sizeof(nxagentPrivCursor));
+
+ if (nxagentCursorPriv(pCursor, pScreen) == NULL)
+ {
+ FatalError("malloc failed");
+ }
+
+ nxagentCursorUsesRender(pCursor, pScreen) = 1;
+ nxagentCursorPicture(pCursor, pScreen) = NULL;
+
+ return 1;
+}
+
+void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
+ PicturePtr pPicture, int x, int y)
+{
+ nxagentCursorPicture(pCursor, pScreen) = pPicture;
+ nxagentCursorXOffset(pCursor, pScreen) = x;
+ nxagentCursorYOffset(pCursor, pScreen) = y;
+}
+
+int nxagentRenderRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ int cid;
+ int x, y;
+
+ PicturePtr pPicture;
+
+ pPicture = nxagentCursorPicture(pCursor, pScreen);
+
+ pPicture -> refcnt++;
+
+ x = nxagentCursorXOffset(pCursor, pScreen);
+ y = nxagentCursorYOffset(pCursor, pScreen);
+
+ /*
+ * Set the lossless trap so that the image functions
+ * will not try to encode the image using a lossy
+ * compression. Drawables should have a quality flag,
+ * telling if they were originally encoded with a
+ * lossy algorithm. This would allow us to skip the
+ * synchronization if the cursor was already encoded
+ * with the best quality.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderRealizeCursor: Forcing the synchronization "
+ "of the cursor.\n");
+ #endif
+
+ nxagentMarkCorruptedRegion(pPicture -> pDrawable, NULL);
+
+ nxagentLosslessTrap = 1;
+
+ nxagentSynchronizeDrawable(pPicture -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+
+ nxagentLosslessTrap = 0;
+
+ cid = XRenderCreateCursor(nxagentDisplay, nxagentPicture(pPicture), x, y);
+
+ nxagentCursor(pCursor, pScreen) = cid;
+
+ return 1;
+}
+
+int nxagentCreatePicture(PicturePtr pPicture, Mask mask)
+{
+ XRenderPictureAttributes attributes;
+ unsigned long valuemask=0;
+ XRenderPictFormat *pForm;
+
+ Picture id;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCreatePicture: Function called with picture at [%p] and mask [%ld].\n",
+ (void *) pPicture, mask);
+ #endif
+
+ if (pPicture == NULL)
+ {
+ return 0;
+ }
+
+ #ifdef DEBUG
+
+ if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ if (nxagentIsShmPixmap((PixmapPtr)pPicture -> pDrawable))
+ {
+ fprintf (stderr, "nxagentCreatePicture: Picture uses a shared pixmap.\n");
+ }
+ else
+ {
+ fprintf (stderr, "nxagentCreatePicture: Picture uses a plain pixmap.\n");
+ }
+ }
+ else
+ {
+ fprintf (stderr, "nxagentCreatePicture: Picture uses a window.\n");
+ }
+
+ #endif
+
+ /*
+ * All the picture default values are 0.
+ */
+
+ memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0, sizeof(XRenderPictureAttributes));
+
+ if (mask & CPRepeat)
+ {
+ attributes.repeat = (Bool)pPicture -> repeat;
+
+ valuemask |= CPRepeat;
+
+ nxagentSetPictureRemoteValue(pPicture, repeat, attributes.repeat);
+ }
+
+ if (mask & CPAlphaMap)
+ {
+ attributes.alpha_map = nxagentPicturePriv(pPicture -> alphaMap) -> picture;
+
+ valuemask |= CPAlphaMap;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map);
+ }
+
+ if (mask & CPAlphaXOrigin)
+ {
+ attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+
+ valuemask |= CPAlphaXOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin);
+ }
+
+ if (mask & CPAlphaYOrigin)
+ {
+ attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+ valuemask |= CPAlphaYOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin);
+ }
+
+ if (mask & CPClipXOrigin)
+ {
+ attributes.clip_x_origin = pPicture -> clipOrigin.x;
+
+ valuemask |= CPClipXOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin);
+ }
+
+ if (mask & CPClipYOrigin)
+ {
+ attributes.clip_y_origin = pPicture -> clipOrigin.y;
+
+ valuemask |= CPClipYOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin);
+ }
+
+ if (mask & CPGraphicsExposure)
+ {
+ attributes.graphics_exposures = (Bool)pPicture -> graphicsExposures;
+
+ valuemask |= CPGraphicsExposure;
+
+ nxagentSetPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures);
+ }
+
+ if (mask & CPSubwindowMode)
+ {
+ attributes.subwindow_mode = pPicture -> subWindowMode;
+
+ valuemask |= CPSubwindowMode;
+
+ nxagentSetPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode);
+ }
+
+ if (mask & CPClipMask)
+ {
+ attributes.clip_mask = None;
+
+ valuemask |= CPClipMask;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_mask, attributes.clip_mask);
+ }
+
+ if (mask & CPPolyEdge)
+ {
+ attributes.poly_edge = pPicture -> polyEdge;
+
+ valuemask |= CPPolyEdge;
+
+ nxagentSetPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge);
+ }
+
+ if (mask & CPPolyMode)
+ {
+ attributes.poly_mode = pPicture -> polyMode;
+
+ valuemask |= CPPolyMode;
+
+ nxagentSetPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode);
+ }
+
+ if (mask & CPDither)
+ {
+ attributes.dither = pPicture -> dither;
+
+ valuemask |= CPDither;
+
+ nxagentSetPictureRemoteValue(pPicture, dither, attributes.dither);
+ }
+
+ if (mask & CPComponentAlpha)
+ {
+ attributes.component_alpha = pPicture -> componentAlpha;
+
+ valuemask |= CPComponentAlpha;
+
+ nxagentSetPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha);
+ }
+
+ pForm = NULL;
+
+ if (pPicture -> pFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(pPicture -> pFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+ }
+
+ if (pForm == NULL)
+ {
+ fprintf(stderr, "nxagentCreatePicture: WARNING! The requested format was not found.\n");
+
+ return 0;
+ }
+
+ id = XRenderCreatePicture(nxagentDisplay,
+ nxagentDrawable(pPicture -> pDrawable),
+ pForm,
+ valuemask,
+ &attributes);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreatePicture: Created picture at [%p] with drawable at [%p].\n",
+ (void *) pPicture, (void *) pPicture -> pDrawable);
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ nxagentPicturePriv(pPicture) -> picture = id;
+
+ if (nxagentAlphaEnabled == 1 && pPicture -> pDrawable->depth == 32 &&
+ pPicture -> pFormat -> direct.alpha != 0)
+ {
+ if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pPicture -> pDrawable)) -> pPicture = pPicture;
+ }
+ else if (pPicture -> pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ nxagentWindowPriv((WindowPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+ }
+ }
+
+ return 1;
+}
+
+XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pFormat)
+{
+ int i;
+
+ for (i = 0; i < nxagentNumFormats; i++)
+ {
+ if (pFormat -> type == nxagentArrayFormats[i].type &&
+ pFormat -> depth == nxagentArrayFormats[i].depth &&
+ pFormat -> direct.red == nxagentArrayFormats[i].direct.red &&
+ pFormat -> direct.green == nxagentArrayFormats[i].direct.green &&
+ pFormat -> direct.blue == nxagentArrayFormats[i].direct.blue &&
+ pFormat -> direct.redMask == nxagentArrayFormats[i].direct.redMask &&
+ pFormat -> direct.greenMask == nxagentArrayFormats[i].direct.greenMask &&
+ pFormat -> direct.blueMask == nxagentArrayFormats[i].direct.blueMask &&
+ pFormat -> direct.alpha == nxagentArrayFormats[i].direct.alpha &&
+ pFormat -> direct.alphaMask == nxagentArrayFormats[i].direct.alphaMask)
+ {
+ return &nxagentArrayFormats[i];
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentMatchingFormats: The requested format was not found.\n");
+ #endif
+
+ return NULL;
+}
+
+void nxagentDestroyPicture(PicturePtr pPicture)
+{
+ if (pPicture == NULL || nxagentPicturePriv(pPicture) -> picture == 0)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyPicture: Going to destroy picture at [%p].\n",
+ (void *) pPicture);
+ #endif
+
+ XRenderFreePicture(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
+ xRectangle *rects, int xOrigin, int yOrigin)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangePictureClip: Going to change clip of picture at [%p].\n",
+ (void *) pPicture);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePictureClip: clipType [%d] nRects [%d] xRectangle [%p] "
+ "xOrigin [%d] yOrigin [%d].\n", clipType, nRects, (void *) rects, xOrigin, yOrigin);
+ #endif
+
+ if (pPicture == NULL)
+ {
+ return 0;
+ }
+
+ switch (clipType)
+ {
+ case CT_PIXMAP:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_PIXMAP].\n");
+ #endif
+
+ /*
+ * if(!nRects)
+ * {
+ * return 0;
+ * }
+ */
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ XRenderSetPictureClipRectangles(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ xOrigin,
+ yOrigin,
+ (XRectangle*)rects,
+ nRects);
+
+ nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ break;
+ }
+ case CT_NONE:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_NONE].\n");
+ #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ XRenderSetPictureClipRectangles(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ xOrigin,
+ yOrigin,
+ (XRectangle*)rects,
+ nRects);
+
+ nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ break;
+ }
+ case CT_REGION:
+ {
+ Region reg;
+ XRectangle rectangle;
+ int index;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_REGION].\n");
+ #endif
+
+ reg = XCreateRegion();
+
+ for (index = 0; index <= nRects; index++, rects++)
+ {
+ rectangle.x = rects -> x;
+ rectangle.y = rects -> y;
+ rectangle.width = rects -> width;
+ rectangle.height = rects -> height;
+
+ XUnionRectWithRegion(&rectangle, reg, reg);
+ }
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ XRenderSetPictureClipRegion(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ reg);
+
+ nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+ nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ XDestroyRegion(reg);
+
+ break;
+ }
+ default:
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePictureClip: clipType not found\n");
+ #endif
+
+ break;
+ }
+ }
+
+ return 1;
+}
+
+void nxagentDestroyPictureClip(PicturePtr pPicture)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDestroyPictureClip: Nothing to do.\n");
+ #endif
+}
+
+void nxagentChangePicture(PicturePtr pPicture, Mask mask)
+{
+ XRenderPictureAttributes attributes;
+ unsigned long valuemask = 0;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangePicture: Going to change picture at [%p] with mask [%ld].\n",
+ (void *) pPicture, mask);
+ #endif
+
+ if (pPicture == NULL)
+ {
+ return;
+ }
+
+ if (mask & CPRepeat)
+ {
+ attributes.repeat = (Bool)pPicture -> repeat;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, repeat, attributes.repeat) == 0)
+ {
+ valuemask |= CPRepeat;
+
+ nxagentSetPictureRemoteValue(pPicture, repeat, attributes.repeat);
+ }
+ }
+
+ if (mask & CPAlphaMap)
+ {
+ attributes.alpha_map = nxagentPicturePriv(pPicture -> alphaMap) -> picture;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map) == 0)
+ {
+ valuemask |= CPAlphaMap;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map);
+ }
+ }
+
+ if (mask & CPAlphaXOrigin)
+ {
+ attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin) == 0)
+ {
+ valuemask |= CPAlphaXOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin);
+ }
+ }
+
+ if (mask & CPAlphaYOrigin)
+ {
+ attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin) == 0)
+ {
+ valuemask |= CPAlphaYOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin);
+ }
+ }
+
+ if (mask & CPClipXOrigin)
+ {
+ attributes.clip_x_origin = pPicture -> clipOrigin.x;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin) == 0)
+ {
+ valuemask |= CPClipXOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin);
+ }
+ }
+
+ if (mask & CPClipYOrigin)
+ {
+ attributes.clip_y_origin = pPicture -> clipOrigin.y;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin) == 0)
+ {
+ valuemask |= CPClipYOrigin;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin);
+ }
+ }
+
+ if (mask & CPGraphicsExposure)
+ {
+ attributes.graphics_exposures = (Bool)pPicture -> graphicsExposures;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures) == 0)
+ {
+ valuemask |= CPGraphicsExposure;
+
+ nxagentSetPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures);
+ }
+ }
+
+ if (mask & CPSubwindowMode)
+ {
+ attributes.subwindow_mode = pPicture -> subWindowMode;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode) == 0)
+ {
+ valuemask |= CPSubwindowMode;
+
+ nxagentSetPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode);
+ }
+ }
+
+ if (mask & CPClipMask)
+ {
+ attributes.clip_mask = None;
+
+ /*
+ * The nxagent doesn't know the remote id of
+ * the picture's clip mask, so the clip_mask
+ * value is used as a boolean: it is set to 0
+ * when the clip_mask is None, otherwise it is
+ * 1.
+ */
+
+ if (nxagentPicturePriv(pPicture) -> lastServerValues.clip_mask != 0)
+ {
+ valuemask |= CPClipMask;
+
+ nxagentSetPictureRemoteValue(pPicture, clip_mask, 0);
+ }
+ }
+
+ if (mask & CPPolyEdge)
+ {
+ attributes.poly_edge = pPicture -> polyEdge;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge) == 0)
+ {
+ valuemask |= CPPolyEdge;
+
+ nxagentSetPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge);
+ }
+ }
+
+ if (mask & CPPolyMode)
+ {
+ attributes.poly_mode = pPicture -> polyMode;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode) == 0)
+ {
+ valuemask |= CPPolyMode;
+
+ nxagentSetPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode);
+ }
+ }
+
+ if (mask & CPDither)
+ {
+ attributes.dither = pPicture -> dither;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, dither, attributes.dither) == 0)
+ {
+ valuemask |= CPDither;
+
+ nxagentSetPictureRemoteValue(pPicture, dither, attributes.dither);
+ }
+ }
+
+ if (mask & CPComponentAlpha)
+ {
+ attributes.component_alpha = pPicture -> componentAlpha;
+
+ if (nxagentCheckPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha) == 0)
+ {
+ valuemask |= CPComponentAlpha;
+
+ nxagentSetPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha);
+ }
+ }
+
+ #ifdef TEST
+
+ if (pPicture && pPicture->pDrawable && pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ fprintf(stderr, "nxagentChangePicture: %sPixmap [%p] Picture [%p][%p].\n",
+ nxagentIsShmPixmap((PixmapPtr)pPicture -> pDrawable) ? "Shared " : "",
+ (void *) pPicture -> pDrawable, (void *) nxagentPicturePriv(pPicture) -> picture,
+ (void *) pPicture);
+ }
+
+ #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+
+ Without this the text is not rendered on GTK/Cairo.
+*/
+ #ifndef SKIP_REALLY_ALL_LOUSY_RENDER_OPERATIONS
+
+ if (valuemask != 0)
+ {
+ XRenderChangePicture(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ valuemask,
+ &attributes);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentChangePicture: Skipping change of picture [%p] on remote X server.\n",
+ (void *) pPicture);
+ }
+ #endif
+
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentValidatePicture(PicturePtr pPicture, Mask mask)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentValidatePicture: Nothing to do.\n");
+ #endif
+}
+
+void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height)
+{
+ RegionPtr pDstRegion;
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+
+ if (pSrc && pSrc -> pDrawable != NULL)
+ {
+ fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
+ nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
+ (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
+ pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+ (void *) pSrc -> pDrawable);
+ }
+
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentComposite: Destination Picture [%lu][%p] with drawable [%s%s][%p].\n",
+ nxagentPicturePriv(pDst) -> picture, (void *) pDst,
+ (pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pDst -> pDrawable)) ? "Shared " : "",
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+ (void *) pDst -> pDrawable);
+ }
+
+ if (pMask && pMask->pDrawable)
+ {
+ fprintf(stderr, "nxagentComposite: Mask Picture [%lu][%p] with drawable [%s%s][%p].\n",
+ nxagentPicturePriv(pMask) -> picture, (void *) pMask,
+ (pMask -> pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentIsShmPixmap((PixmapPtr) pMask -> pDrawable)) ? "Shared " : "",
+ pMask -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+ (void *) pMask -> pDrawable);
+ }
+
+ #endif
+
+ if (NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst))
+ {
+ pDstRegion = nxagentCreateRegion(pDst -> pDrawable, NULL, xDst, yDst, width, height);
+
+ #ifdef TEST
+ if ((pDstRegion) && (pDst && pDst->pDrawable)) {
+ fprintf(stderr, "nxagentComposite: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+ "for drawable at [%p] with type [%s].\n", pDstRegion -> extents.x1,
+ pDstRegion -> extents.y1, pDstRegion -> extents.x2, pDstRegion -> extents.y2,
+ (void *) pDst -> pDrawable,
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window");
+ }
+ #endif
+
+ nxagentMarkCorruptedRegion(pDst -> pDrawable, pDstRegion);
+
+ nxagentFreeRegion(pDst -> pDrawable, pDstRegion);
+
+ return;
+ }
+
+ /*
+ * Synchronize the content of the shared memory pixmap
+ * but pay attention at not doing this more than once.
+ * We need to wait until the image data has been recom-
+ * posed at the X server side or the operation will use
+ * the wrong data.
+ */
+
+ if (pSrc -> pDrawable != NULL)
+ {
+ nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
+
+ if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
+ (void *) pSrc -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+ }
+
+ if (pDst -> pDrawable != pSrc -> pDrawable)
+ {
+ nxagentSynchronizeShmPixmap(pDst -> pDrawable, xDst, yDst, width, height);
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentComposite: Synchronizing the destination drawable [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+ }
+
+ if (pMask != NULL && pMask -> pDrawable != NULL &&
+ pMask -> pDrawable != pSrc -> pDrawable &&
+ pMask -> pDrawable != pDst -> pDrawable)
+ {
+ nxagentSynchronizeShmPixmap(pMask -> pDrawable, xMask, yMask, width, height);
+
+ if (nxagentDrawableStatus(pMask -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentComposite: Synchronizing the mask drawable [%p].\n",
+ (void *) pMask -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pMask -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+ }
+
+ /*
+ * The glyphs flag have to be propagated between
+ * drawables, in order to avoid to encode the
+ * text with lossy algorithms (like JPEG). Unlu-
+ * ckily we have verified that if the render com-
+ * posite propagates the flag, the deferring of
+ * render trapezoids doesn't work well. Moreover,
+ * by commenting out this code we have not noticed
+ * any visual problems.
+ *
+ * if (nxagentDrawableContainGlyphs(pSrc -> pDrawable) == 1)
+ * {
+ * nxagentSetDrawableContainGlyphs(pDst -> pDrawable, 1);
+ * }
+ */
+
+ XRenderComposite(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ pMask ? nxagentPicturePriv(pMask) -> picture : 0,
+ nxagentPicturePriv(pDst) -> picture,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists,
+ XGlyphElt8 *elts, int sizeID, GlyphPtr *glyphsBase)
+{
+ XRenderPictFormat *pForm;
+
+ BoxRec glyphBox;
+
+ XGlyphElt8 *elements;
+
+ #ifdef SPLIT_GLYPH_LISTS
+
+ GlyphPtr glyph;
+
+ int x;
+ int y;
+ int i;
+ int j;
+
+ #endif /* #ifdef SPLIT_GLYPH_LISTS */
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ if ((pSrc && pSrc->pDrawable) && (pDst && pDst->pDrawable)) {
+ fprintf(stderr, "nxagentGlyphs: Called with source [%s][%p] destination [%s][%p] and size id [%d].\n",
+ (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pSrc,
+ (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pDst,
+ sizeID);
+ }
+ #endif
+
+ pForm = NULL;
+
+ if (maskFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(maskFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+
+ if (nxagentGlyphsExtents != NullBox)
+ {
+ glyphBox.x1 = nxagentGlyphsExtents -> x1;
+ glyphBox.y1 = nxagentGlyphsExtents -> y1;
+ glyphBox.x2 = nxagentGlyphsExtents -> x2;
+ glyphBox.y2 = nxagentGlyphsExtents -> y2;
+
+ /*
+ * By extending the glyph extents the
+ * visual aspect looks nicer because
+ * the synchronized region is not glued
+ * to the fonts.
+ */
+
+ if (glyphBox.x2 != glyphBox.x1)
+ {
+ glyphBox.x1 -= GLYPH_BOX_MARGIN;
+ glyphBox.x2 += GLYPH_BOX_MARGIN;
+ }
+
+ if (glyphBox.y2 != glyphBox.y1)
+ {
+ glyphBox.y1 -= GLYPH_BOX_MARGIN;
+ glyphBox.y2 += GLYPH_BOX_MARGIN;
+ }
+ }
+
+ /*
+ * If the destination window is hidden, the
+ * operation can be prevented.
+ */
+
+ if (pDst -> pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ RegionPtr pRegion;
+
+ pRegion = nxagentCreateRegion(pDst -> pDrawable, NULL, glyphBox.x1, glyphBox.y1,
+ glyphBox.x2 - glyphBox.x1, glyphBox.y2 - glyphBox.y1);
+
+ if (RegionNil(pRegion) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentGlyphs: WARNING! Glyphs prevented on hidden window at [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentFreeRegion(pDst -> pDrawable, pRegion);
+
+ return;
+ }
+
+ nxagentFreeRegion(pDst -> pDrawable, pRegion);
+ }
+
+ /*
+ * Need to synchronize the pixmaps involved in
+ * the operation before rendering the glyphs
+ * on the real X server.
+ */
+
+ if (pSrc -> pDrawable != NULL &&
+ nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ if (pSrc && pSrc->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing source [%s] at [%p].\n",
+ pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+ (void *) pSrc -> pDrawable);
+ }
+ #endif
+
+ /*
+ * If the source drawable is going to be
+ * repeated over the destination drawable
+ * during the composite operation, we need
+ * to synchronize the whole drawable to
+ * avoid graphical problems.
+ */
+
+ if (pSrc -> repeat == 1 || nxagentGlyphsExtents == NullBox)
+ {
+ #ifdef DEBUG
+ if (pSrc && pSrc->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing source [%s] at [%p] "
+ "with geometry [%d,%d,%d,%d].\n",
+ (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ (void *) pSrc -> pDrawable, pSrc -> pDrawable -> x, pSrc -> pDrawable -> y,
+ pSrc -> pDrawable -> x + pSrc -> pDrawable -> width,
+ pSrc -> pDrawable -> y + pSrc -> pDrawable -> height);
+ }
+ #endif
+
+ nxagentSynchronizeBox(pSrc -> pDrawable, NullBox, NEVER_BREAK);
+ }
+ else
+ {
+ #ifdef DEBUG
+ if (pSrc && pSrc->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing region [%d,%d,%d,%d] of source [%s] at [%p] "
+ "with geometry [%d,%d,%d,%d].\n", glyphBox.x1, glyphBox.y1, glyphBox.x2, glyphBox.y2,
+ (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ (void *) pSrc -> pDrawable, pSrc -> pDrawable -> x, pSrc -> pDrawable -> y,
+ pSrc -> pDrawable -> x + pSrc -> pDrawable -> width,
+ pSrc -> pDrawable -> y + pSrc -> pDrawable -> height);
+ }
+ #endif
+
+ nxagentSynchronizeBox(pSrc -> pDrawable, &glyphBox, NEVER_BREAK);
+ }
+
+ if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentIncreasePixmapUsageCounter((PixmapPtr) pSrc -> pDrawable);
+ }
+ }
+
+ if (pSrc -> pDrawable != pDst -> pDrawable &&
+ nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing destination [%s] at [%p].\n",
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+ (void *) pDst -> pDrawable);
+ }
+ #endif
+
+ if (nxagentGlyphsExtents == NullBox)
+ {
+ #ifdef DEBUG
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing destination [%s] at [%p] "
+ "with geometry [%d,%d,%d,%d].\n",
+ (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ (void *) pDst -> pDrawable, pDst -> pDrawable -> x, pDst -> pDrawable -> y,
+ pDst -> pDrawable -> x + pDst -> pDrawable -> width,
+ pDst -> pDrawable -> y + pDst -> pDrawable -> height);
+ }
+ #endif
+
+ nxagentSynchronizeBox(pDst -> pDrawable, NullBox, NEVER_BREAK);
+ }
+ else
+ {
+ #ifdef DEBUG
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Synchronizing region [%d,%d,%d,%d] of destination [%s] at [%p] "
+ "with geometry [%d,%d,%d,%d].\n", glyphBox.x1, glyphBox.y1, glyphBox.x2, glyphBox.y2,
+ (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ (void *) pDst -> pDrawable, pDst -> pDrawable -> x, pDst -> pDrawable -> y,
+ pDst -> pDrawable -> x + pDst -> pDrawable -> width,
+ pDst -> pDrawable -> y + pDst -> pDrawable -> height);
+ }
+ #endif
+
+ nxagentSynchronizeBox(pDst -> pDrawable, &glyphBox, NEVER_BREAK);
+ }
+
+ if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentIncreasePixmapUsageCounter((PixmapPtr) pDst -> pDrawable);
+ }
+ }
+
+ nxagentSetDrawableContainGlyphs(pDst -> pDrawable, 1);
+
+ #ifdef TEST
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentGlyphs: Glyph flag set on drawable [%s][%p].\n",
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+ (void *) pDst -> pDrawable);
+ }
+ #endif
+
+ #ifdef SPLIT_GLYPH_LISTS
+
+ /*
+ * We split glyphs lists here and recalculate
+ * the offsets of each list to make them ab-
+ * solute and not relatives to the prior list.
+ * This way each time we call XRenderComposi-
+ * teText it has to deal only with a list of
+ * glyphs. This is done to further improve
+ * caching.
+ */
+
+ elements = elts;
+
+ if (nlists > 1)
+ {
+ for (j = 1; j < nlists; j++)
+ {
+ x = elements -> xOff;
+ y = elements -> yOff;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGlyphs: Element [%d] of [%d] has offset [%d,%d].\n",
+ j, nlists, elements -> xOff, elements -> yOff);
+ #endif
+
+ for (i = 0; i < elements -> nchars; i++)
+ {
+ glyph = *glyphsBase++;
+
+ x += glyph -> info.xOff;
+ y += glyph -> info.yOff;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGlyphs: Glyph at index [%d] has offset [%d,%d] and "
+ "position [%d,%d].\n", i, elements -> nchars, glyph -> info.xOff,
+ glyph -> info.yOff, x, y);
+ #endif
+ }
+
+ elements++;
+
+ elements -> xOff += x;
+ elements -> yOff += y;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentGlyphs: New offset for list at [%p] is [%d,%d].\n",
+ elements, elements -> xOff, elements -> yOff);
+ #endif
+ }
+
+ elements = elts;
+ }
+
+ switch (sizeID)
+ {
+ case 1:
+ {
+ for (j = 0; j < nlists; j++)
+ {
+ XRenderCompositeText8(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc)->picture,
+ nxagentPicturePriv(pDst)->picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt8*) elements,
+ 1);
+
+ elements++;
+ }
+
+ break;
+ }
+ case 2:
+ {
+ for (j = 0; j < nlists; j++)
+ {
+ XRenderCompositeText16(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt16*) elements,
+ 1);
+
+ elements++;
+ }
+
+ break;
+ }
+ case 4:
+ {
+ for (j = 0; j < nlists; j++)
+ {
+ XRenderCompositeText32(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt32*) elements,
+ 1);
+
+ elements++;
+ }
+
+ break;
+ }
+ default:
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGlyphs: WARNING! Invalid size id [%d].\n",
+ sizeID);
+ #endif
+
+ break;
+ }
+ }
+
+ #else /* #ifdef SPLIT_GLYPH_LISTS */
+
+ elements = elts;
+
+ switch (sizeID)
+ {
+ case 1:
+ {
+ XRenderCompositeText8(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc)->picture,
+ nxagentPicturePriv(pDst)->picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt8*) elements,
+ nlists);
+
+ break;
+ }
+ case 2:
+ {
+ XRenderCompositeText16(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt16*) elements,
+ nlists);
+
+ break;
+ }
+ case 4:
+ {
+ XRenderCompositeText32(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ elements -> xOff,
+ elements -> yOff,
+ (XGlyphElt32*) elements,
+ nlists);
+
+ break;
+ }
+ default:
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentGlyphs: WARNING! Invalid size id [%d].\n",
+ sizeID);
+ #endif
+
+ break;
+ }
+ }
+
+ #endif /* #ifdef SPLIT_GLYPH_LISTS */
+}
+
+void nxagentCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color,
+ int nRect, xRectangle *rects)
+{
+ RegionPtr rectRegion;
+
+ if (pDst == NULL)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentCompositeRects: Called for picture at [%p] with [%s] at [%p].\n",
+ (void *) pDst, (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ (void *) pDst -> pDrawable);
+ }
+ #endif
+
+ /*
+ * The CompositeRects() clears the destination's
+ * corrupted region like the PolyFillRects() does.
+ * As this case is harder to handle, at the moment
+ * we only check for two ops.
+ */
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized &&
+ (op == PictOpSrc ||
+ (op == PictOpOver && color -> alpha == 0xffff)))
+ {
+ rectRegion = RegionFromRects(nRect, rects, CT_REGION);
+
+ if (pDst -> clientClipType != CT_NONE)
+ {
+ RegionRec tmpRegion;
+
+ RegionInit(&tmpRegion, NullBox, 1);
+
+ RegionCopy(&tmpRegion, (RegionPtr) pDst -> clientClip);
+
+ if (pDst -> clipOrigin.x != 0 || pDst -> clipOrigin.y != 0)
+ {
+ RegionTranslate(&tmpRegion, pDst -> clipOrigin.x, pDst -> clipOrigin.y);
+ }
+
+ RegionIntersect(rectRegion, rectRegion, &tmpRegion);
+
+ RegionUninit(&tmpRegion);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCompositeRects: Going to clean the drawable with extents [%d,%d,%d,%d].\n",
+ rectRegion -> extents.x1, rectRegion -> extents.y1, rectRegion -> extents.x2, rectRegion -> extents.y2);
+ #endif
+
+ nxagentUnmarkCorruptedRegion(pDst -> pDrawable, rectRegion);
+
+ RegionDestroy(rectRegion);
+ }
+
+ XRenderFillRectangles(nxagentDisplay,
+ op,
+ (Picture)nxagentPicturePriv(pDst) -> picture,
+ (XRenderColor *) color,
+ (XRectangle *) rects,
+ nRect);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps)
+{
+ XRenderPictFormat *pForm;
+
+ XTrapezoid *current = (XTrapezoid *) traps;
+
+ RegionPtr pDstRegion;
+
+ int remaining = ntrap;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentTrapezoids: Source [%p] destination [%p] coordinates "
+ "[%d,%d] elements [%d].\n", (void *) pSrc, (void *) pDst,
+ xSrc, ySrc, ntrap);
+ #endif
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ pForm = NULL;
+
+ if (maskFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(maskFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ #ifdef TEST
+
+ if (pSrc->pDrawable) {
+ fprintf(stderr, "nxagentTrapezoids: Source is a [%s] of geometry [%d,%d].\n",
+ (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ pSrc -> pDrawable -> width, pSrc -> pDrawable -> height);
+ }
+ if (pSrc ->pDrawable != pDst -> pDrawable)
+ {
+ fprintf(stderr, "nxagentTrapezoids: Destination is a [%s] of geometry [%d,%d].\n",
+ (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+ pDst -> pDrawable -> width, pDst -> pDrawable -> height);
+ }
+
+ #endif
+
+ /*
+ * If the destination drawable is not synchronized
+ * but the trapezoids extents are included in the
+ * dirty region, we can defer the operation.
+ */
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized &&
+ RegionContainsRect(nxagentCorruptedRegion(pDst -> pDrawable),
+ nxagentTrapezoidExtents) == rgnIN)
+ {
+ #ifdef TEST
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentTrapezoids: WARNING! Prevented operation on region [%d,%d,%d,%d] already dirty "
+ "for drawable [%s][%p].\n", nxagentTrapezoidExtents -> x1, nxagentTrapezoidExtents -> y1,
+ nxagentTrapezoidExtents -> x2, nxagentTrapezoidExtents -> y2,
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+ (void *) pDst -> pDrawable);
+ }
+ #endif
+
+ if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapContainTrapezoids((PixmapPtr) pDst -> pDrawable) = 1;
+ }
+
+ return;
+ }
+
+ /*
+ * If the destination doesn't contain any glyphs,
+ * we can defer the trapezoids drawing by marking
+ * the destination as dirty.
+ */
+
+ if (NXAGENT_SHOULD_DEFER_TRAPEZOIDS(pDst -> pDrawable))
+ {
+ pDstRegion = nxagentCreateRegion(pDst -> pDrawable, NULL,
+ nxagentTrapezoidExtents -> x1,
+ nxagentTrapezoidExtents -> y1,
+ nxagentTrapezoidExtents -> x2 - nxagentTrapezoidExtents -> x1,
+ nxagentTrapezoidExtents -> y2 - nxagentTrapezoidExtents -> y1);
+
+ #ifdef TEST
+ if (pDst && pDst->pDrawable) {
+ fprintf(stderr, "nxagentTrapezoids: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+ "for drawable [%s][%p].\n", pDstRegion -> extents.x1, pDstRegion -> extents.y1,
+ pDstRegion -> extents.x2, pDstRegion -> extents.y2,
+ pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+ (void *) pDst -> pDrawable);
+ }
+ #endif
+
+ nxagentMarkCorruptedRegion(pDst -> pDrawable, pDstRegion);
+
+ nxagentFreeRegion(pDst -> pDrawable, pDstRegion);
+
+ if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapContainTrapezoids((PixmapPtr) pDst -> pDrawable) = 1;
+ }
+
+ return;
+ }
+
+ if (pSrc -> pDrawable != NULL &&
+ nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTrapezoids: Going to synchronize the source drawable at [%p].\n",
+ (void *) pSrc -> pDrawable);
+ #endif
+
+ nxagentSynchronizeBox(pSrc -> pDrawable, NullBox, NEVER_BREAK);
+ }
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTrapezoids: Going to synchronize the destination drawable at [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentSynchronizeBox(pDst -> pDrawable, nxagentTrapezoidExtents, NEVER_BREAK);
+ }
+
+ while (remaining > 0)
+ {
+ XRenderCompositeTrapezoids(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ (XTrapezoid *) current,
+ (remaining > TRAPEZOIDS_PER_REQUEST ?
+ TRAPEZOIDS_PER_REQUEST : remaining));
+
+ remaining -= TRAPEZOIDS_PER_REQUEST;
+ current += TRAPEZOIDS_PER_REQUEST;
+ }
+
+ #endif
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentRasterizeTrapezoid(PicturePtr pMask, xTrapezoid *trap,
+ int x_off, int y_off)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentRasterizeTrapezoids: Nothing to do.\n");
+ #endif
+}
+
+void nxagentTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris)
+{
+ XRenderPictFormat *pForm;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentTriangles: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+ (void *) pSrc, (void *) pDst, xSrc, ySrc, ntri);
+ #endif
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ pForm = NULL;
+
+ if (maskFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(maskFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+
+ /*
+ * If the X_RenderCompositeTriangles requests
+ * increment the traffic, we can defer the
+ * operation like nxagentTrapezoids() does.
+ */
+
+ if (pSrc -> pDrawable != NULL &&
+ nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriangles: Going to synchronize the source drawable at [%p].\n",
+ (void *) pSrc -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriangles: Going to synchronize the destination drawable at [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ XRenderCompositeTriangles(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ (XTriangle*)tris,
+ ntri);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int npoint, xPointFixed *points)
+{
+ XRenderPictFormat *pForm;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentTriStrip: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+ (void *) pSrc, (void *) pDst, xSrc, ySrc, npoint);
+ #endif
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ pForm = NULL;
+
+ if (maskFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(maskFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+
+ /*
+ * If the X_RenderCompositeTriStrip requests
+ * increment the traffic, we can defer the
+ * operation like nxagentTrapezoids() does.
+ */
+
+ if (pSrc -> pDrawable != NULL &&
+ nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriStrip: Going to synchronize the source drawable at [%p].\n",
+ (void *) pSrc -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriStrip: Going to synchronize the destination drawable at [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ XRenderCompositeTriStrip(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ (XPointFixed*)points,
+ npoint);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int npoint, xPointFixed *points)
+{
+ XRenderPictFormat *pForm;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentTriFan: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+ (void *) pSrc, (void *) pDst, xSrc, ySrc, npoint);
+ #endif
+
+ if (pSrc == NULL || pDst == NULL)
+ {
+ return;
+ }
+
+ pForm = NULL;
+
+ if (maskFormat != NULL)
+ {
+ pForm = nxagentMatchingFormats(maskFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+
+ /*
+ * If the X_RenderCompositeTriFan requests
+ * increment the traffic, we can defer the
+ * operation like nxagentTrapezoids() does.
+ */
+
+ if (pSrc -> pDrawable != NULL &&
+ nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriFan: Going to synchronize the source drawable at [%p].\n",
+ (void *) pSrc -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentTriFan: Going to synchronize the destination drawable at [%p].\n",
+ (void *) pDst -> pDrawable);
+ #endif
+
+ nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+ }
+
+ XRenderCompositeTriFan(nxagentDisplay,
+ op,
+ nxagentPicturePriv(pSrc) -> picture,
+ nxagentPicturePriv(pDst) -> picture,
+ pForm,
+ xSrc,
+ ySrc,
+ (XPointFixed*)points,
+ npoint);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentQueryFormats()
+{
+ XRenderInfo *xri;
+ XExtDisplayInfo *info = NULL;
+ XRenderPictFormat *pformat=NULL;
+
+ int i;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentQueryFormats.\n");
+ #endif
+
+ if (XRenderQueryFormats(nxagentDisplay))
+ {
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ info = (XExtDisplayInfo *) XRenderFindDisplay(nxagentDisplay);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ xri = (XRenderInfo *) info -> data;
+
+ pformat = xri -> format;
+
+ for (i = 0; i < xri -> nformat; i++)
+ {
+ nxagentArrayFormats[i] = *pformat;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentQueryFormats: Added format type [%d] depth [%d] rgb [%d,%d,%d] "
+ "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d].\n",
+ nxagentArrayFormats[i].type, nxagentArrayFormats[i].depth, nxagentArrayFormats[i].direct.red,
+ nxagentArrayFormats[i].direct.green, nxagentArrayFormats[i].direct.blue,
+ nxagentArrayFormats[i].direct.redMask, nxagentArrayFormats[i].direct.greenMask,
+ nxagentArrayFormats[i].direct.blueMask, nxagentArrayFormats[i].direct.alpha,
+ nxagentArrayFormats[i].direct.alphaMask);
+ #endif
+
+ pformat++;
+ }
+
+ #ifdef DEBUG
+
+ if (nxagentNumFormats == 0)
+ {
+ fprintf(stderr, "nxagentQueryFormats: Number of formats is [%d].\n",
+ i);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentQueryFormats: Old number of formats is [%d]. New number of formats is [%d].\n",
+ nxagentNumFormats, i);
+ }
+
+ #endif
+
+ nxagentNumFormats = i;
+ }
+}
+
+void nxagentCreateGlyphSet(GlyphSetPtr pGly)
+{
+ XRenderPictFormat *pForm;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCreateGlyphSet: Glyphset at [%p].\n", (void *) pGly);
+ #endif
+
+ pForm = NULL;
+
+ if (pGly -> format != NULL)
+ {
+ pForm = nxagentMatchingFormats(pGly -> format);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+
+ if (pForm == NULL)
+ {
+ return;
+ }
+ }
+
+ pGly -> remoteID = XRenderCreateGlyphSet(nxagentDisplay, pForm);
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet)
+{
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReferenceGlyphSet: Operation deferred because glyphset at [%p] is corrupted.\n",
+ (void *) glyphSet);
+ #endif
+
+ return;
+ }
+
+ XRenderReferenceGlyphSet (nxagentDisplay, glyphSet -> remoteID);
+}
+
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet)
+{
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeGlyphs: Operation ignored because glyphset at [%p] is corrupted.\n",
+ (void *) glyphSet);
+ #endif
+
+ return;
+ }
+
+ XRenderFreeGlyphSet(nxagentDisplay, glyphSet -> remoteID);
+}
+
+void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
+ int nglyphs, CARD8 *images, int sizeImages)
+{
+ GlyphRefPtr gr;
+ Glyph *tempGids;
+
+ int i;
+
+ CARD8 *normalizedImages;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAddGlyphs: Glyphset at [%p]. Number of glyphs [%d].\n",
+ (void *) glyphSet, nglyphs);
+ #endif
+
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddGlyphs: Going to reconnect the glyhpset at [%p] before adding glyphs.\n",
+ (void *) glyphSet);
+ #endif
+
+ nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+ }
+
+ /*
+ * By adding a glyph to a glyphset on
+ * remote X server we mark its reference
+ * as synchronized.
+ */
+
+ tempGids = gids;
+
+ for (i = 0; i < nglyphs; i++)
+ {
+ if ((gr = FindGlyphRef(&glyphSet -> hash, *tempGids, 0, 0)) &&
+ gr -> glyph != DeletedGlyph)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAddGlyphs: Added Glyph [%p][%ld] to glyphset [%p].\n",
+ (void *) gr -> glyph, *tempGids, (void *) glyphSet);
+ #endif
+
+ gr -> corruptedGlyph = 0;
+ }
+
+ tempGids++;
+ }
+
+ normalizedImages = NULL;
+
+ if (sizeImages > 0)
+ {
+ normalizedImages = malloc(sizeImages);
+
+ if (normalizedImages != NULL)
+ {
+ memcpy(normalizedImages, images, sizeImages);
+
+ if (glyphDepths[glyphSet -> fdepth] == 1 &&
+ nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+ {
+ nxagentBitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+ }
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentAddGlyphs: PANIC! Allocation of normalized glyph images failed.\n");
+ #endif
+ }
+ }
+
+ if (normalizedImages == NULL)
+ {
+ normalizedImages = images;
+ }
+
+ XRenderAddGlyphs(nxagentDisplay,
+ glyphSet -> remoteID,
+ gids,
+ (XGlyphInfo*)(gi),
+ nglyphs,
+ (char*) normalizedImages,
+ sizeImages);
+
+ if (normalizedImages != images)
+ {
+ free(normalizedImages);
+ }
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+}
+
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph)
+{
+ GlyphRefPtr gr;
+ CARD32 *tempGids;
+ Glyph gid;
+
+ int i;
+
+ if (glyphSet -> remoteID == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeGlyphs: Operation ignored because glyphset at [%p] is corrupted.\n",
+ (void *) glyphSet);
+ #endif
+
+ return;
+ }
+
+ /*
+ * We loop across the list of glyphs id
+ * to establish if they have been added
+ * to glyphset on remote X server, so
+ * they can be freed.
+ */
+
+ tempGids = gids;
+
+ for (i = 0; i < nglyph; i++)
+ {
+ gid = (Glyph)*tempGids;
+
+ if ((gr = FindGlyphRef(&glyphSet -> hash, *tempGids, 0, 0)) &&
+ gr -> glyph != DeletedGlyph &&
+ gr -> corruptedGlyph == 0)
+ {
+ XRenderFreeGlyphs(nxagentDisplay, glyphSet -> remoteID, &gid, 1);
+ }
+
+ tempGids++;
+ }
+}
+
+void nxagentSetPictureTransform(PicturePtr pPicture, void * transform)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPictureTransform: Going to set transform [%p] to picture at [%p].\n",
+ (void *) transform, (void *) pPicture);
+ #endif
+
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ XRenderSetPictureTransform(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ (XTransform *) transform);
+ #endif
+}
+
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+ void * params, int nparams)
+{
+ char *szFilter = Xmalloc(name_size + 1);
+
+ if (szFilter == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSetPictureFilter: error allocating memory for filter name.\n");
+ #endif
+
+ return;
+ }
+
+ strncpy(szFilter, filter, name_size);
+
+ szFilter[name_size] = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPictureFilter: Going to set filter [%s] to picture at [%p].\n",
+ szFilter, (void *) pPicture);
+ #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+ Apparently useless with QT.
+*/
+ #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+ XRenderSetPictureFilter(nxagentDisplay,
+ nxagentPicturePriv(pPicture) -> picture,
+ szFilter,
+ (XFixed *) params,
+ nparams);
+ #endif
+
+ free(szFilter);
+}
+
+
+Bool nxagentPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ #ifdef RENDER
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentPictureInit: Screen [%p].\n", (void *) pScreen);
+ #endif
+
+ nxagentQueryFormats();
+
+ if (fbPictureInit(pScreen, formats, nformats) == 0)
+ {
+ return FALSE;
+ }
+
+ nxagentPicturePrivateIndex = AllocatePicturePrivateIndex();
+
+ AllocatePicturePrivate(pScreen, nxagentPicturePrivateIndex, sizeof(nxagentPrivPictureRec));
+
+ #endif
+
+ return TRUE;
+}
+
+#ifdef DEBUG
+
+static void nxagentPrintFormat(XRenderPictFormat *pFormat)
+{
+ if (pFormat == NULL)
+ {
+ fprintf(stderr, "nxagentPrintFormat: WARNING! null pointer passed to function.\n");
+
+ return;
+ }
+
+ fprintf(stderr, "nxagentPrintFormat: Dumping information for format at [%p]:\n\
+ type=%d\n\
+ depth=%d\n\
+ red=%d\n\
+ redMask=%d\n\
+ green=%d\n\
+ greenMask=%d\n\
+ blue=%d\n\
+ blueMask=%d\n\
+ alpha=%d\n\
+ alphaMask=%d\n",
+ (void *) pFormat,
+ pFormat -> type,
+ pFormat -> depth,
+ pFormat -> direct.red,
+ pFormat -> direct.redMask,
+ pFormat -> direct.green,
+ pFormat -> direct.greenMask,
+ pFormat -> direct.blue,
+ pFormat -> direct.blueMask,
+ pFormat -> direct.alpha,
+ pFormat -> direct.alphaMask);
+}
+
+#endif
+
+Bool nxagentFillGlyphSet(GlyphSetPtr pGly)
+{
+ GlyphPtr glyph;
+
+ int i;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentFillGlyphSet: GlyphSet at [%p] Refcount [%ld] Glyphs [%ld] "
+ "Format [%p] FDepth [%d] RemoteID [%ld].\n", (void *) pGly, pGly -> refcnt,
+ pGly -> hash.hashSet -> size, (void *) pGly -> format, pGly -> fdepth, pGly -> remoteID);
+ #endif
+
+ /*
+ * The glyphs are synchronized when they
+ * are used in a composite text. During
+ * the reconnection we have only to mark
+ * corrupted the glyphs for each glyphset.
+ */
+
+ for (i = 0; i < pGly -> hash.hashSet -> size; i++)
+ {
+ glyph = pGly -> hash.table[i].glyph;
+
+ if (glyph && (glyph != DeletedGlyph))
+ {
+ pGly -> hash.table[i].corruptedGlyph = 1;
+ }
+ }
+
+ return TRUE;
+}
+
+void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2)
+{
+ GlyphSetPtr pGly = (GlyphSetPtr) p0;
+
+ XRenderPictFormat *pForm = NULL;
+
+ int i;
+
+ if (nxagentReconnectTrap == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconnectGlyphSet: GlyphSet at [%p].\n", (void *) pGly);
+ #endif
+
+ if (pGly -> format)
+ {
+ pForm = nxagentMatchingFormats(pGly -> format);
+ }
+
+ pGly -> remoteID = XRenderCreateGlyphSet(nxagentDisplay, pForm);
+
+ /*
+ * If we have deferred the operation, we
+ * have to check the number of references
+ * to the glyphset to update the X server.
+ */
+
+ if ((i = pGly -> refcnt) > 1)
+ {
+ while (i-- > 1)
+ {
+ nxagentReferenceGlyphSet(pGly);
+ }
+ }
+
+ #ifdef DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ nxagentFillGlyphSet(pGly);
+ }
+ else
+ {
+ pGly -> remoteID = 0;
+ }
+}
+
+Bool nxagentReconnectAllGlyphSet(void *p)
+{
+ Bool success = TRUE;
+ int i;
+
+ nxagentQueryFormats();
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconnectAllGlyphSet\n");
+ #endif
+
+ for (i = 0; (i < MAXCLIENTS) && (success); i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], GlyphSetType, nxagentReconnectGlyphSet, &success);
+ }
+ }
+
+ return success;
+}
+
+void nxagentReconnectPicture(void * p0, XID x1, void *p2)
+{
+ PicturePtr pPicture = (PicturePtr) p0;
+ Bool *pBool = (Bool *) p2;
+ unsigned long mask = 0;
+
+ XRenderPictureAttributes attributes;
+ XRenderPictFormat *pForm;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPicture: Called with bool [%d] and picture at [%p].\n",
+ *pBool, (void *) pPicture);
+
+ fprintf(stderr, "nxagentReconnectPicture: Virtual picture is [%ld].\n",
+ nxagentPicture(pPicture));
+ #endif
+
+ /*
+ * Check if a previous operation has failed
+ * and that the involved objects are valid.
+ */
+
+ if (*pBool == 0 || pPicture == NULL ||
+ nxagentPicture(pPicture) != 0)
+ {
+ return;
+ }
+
+ if (pPicture -> repeat)
+ {
+ mask |= CPRepeat;
+
+ attributes.repeat = (Bool) pPicture -> repeat;
+ }
+
+ if (pPicture -> alphaMap)
+ {
+ if (!nxagentPicture(pPicture -> alphaMap))
+ {
+ nxagentReconnectPicture(pPicture -> alphaMap, 0, pBool);
+
+ if (!*pBool || !nxagentPicture(pPicture -> alphaMap))
+ {
+ return;
+ }
+ }
+
+ attributes.alpha_map = nxagentPicture(pPicture -> alphaMap);
+ attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+ attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+ mask |= (CPAlphaMap | CPAlphaXOrigin | CPAlphaYOrigin);
+ }
+
+ if (pPicture -> graphicsExposures)
+ {
+ attributes.graphics_exposures = pPicture -> graphicsExposures;
+
+ mask |= CPGraphicsExposure;
+ }
+
+ attributes.subwindow_mode = pPicture -> subWindowMode;
+
+ mask |= CPSubwindowMode;
+
+ attributes.poly_edge = pPicture -> polyEdge;
+
+ mask |= CPPolyEdge;
+
+ attributes.poly_mode = pPicture -> polyMode;
+
+ mask |= CPPolyMode;
+
+ attributes.dither = pPicture -> dither;
+
+ mask |= CPDither;
+
+ attributes.component_alpha = pPicture -> componentAlpha;
+
+ mask |= CPComponentAlpha;
+
+ pForm = NULL;
+
+ if (pPicture -> pFormat)
+ {
+ pForm = nxagentMatchingFormats(pPicture -> pFormat);
+
+ #ifdef DEBUG
+
+ nxagentPrintFormat(pForm);
+
+ #endif
+ }
+
+ if (!pForm && pPicture->pSourcePict)
+ {
+ /*possible we need to add support for other picture types, for example gradients...*/
+ switch(pPicture->pSourcePict->type)
+ {
+ case SourcePictTypeSolidFill:
+ nxagentPicturePriv(pPicture) -> picture = XRenderCreateSolidFill(nxagentDisplay,
+ (const XRenderColor*) &pPicture->pSourcePict->solidFill.fullColor);
+ break;
+ }
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPicture: Creating picture at [%p] with drawable [%ld] at [%p].\n",
+ (void *) pPicture, nxagentDrawable(pPicture -> pDrawable), (void *) pPicture -> pDrawable);
+
+ fprintf(stderr, "nxagentReconnectPicture: Format is at [%p] mask is [%ld] attributes are at [%p].\n",
+ (void *) pForm, mask, (void *) &attributes);
+ #endif
+
+ nxagentPicture(pPicture) = XRenderCreatePicture(nxagentDisplay,
+ nxagentDrawable(pPicture -> pDrawable),
+ pForm,
+ mask,
+ &attributes);
+
+ #ifdef TEST
+
+ XSync(nxagentDisplay, 0);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectPicture: Reconnected picture at [%p] with value [%ld].\n",
+ (void *) pPicture, nxagentPicture(pPicture));
+ #endif
+
+ if (nxagentAlphaEnabled == 1 && pPicture -> pDrawable -> depth == 32 &&
+ pPicture -> pFormat -> direct.alpha != 0)
+ {
+ if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv((PixmapPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+ }
+ else if (pPicture -> pDrawable -> type == DRAWABLE_WINDOW)
+ {
+ nxagentWindowPriv((WindowPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+ }
+ }
+}
+
+Bool nxagentReconnectAllPicture(void *p)
+{
+ int i;
+ Bool r;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectAllPicture: Going to recreate all pictures.\n");
+ #endif
+
+ for (i = 0, r = 1; i < MAXCLIENTS; i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], PictureType, nxagentReconnectPicture, &r);
+
+ #ifdef WARNING
+
+ if (r == False)
+ {
+ fprintf(stderr, "nxagentReconnectAllPicture: WARNING! Failed to recreate "
+ "picture for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ return True;
+}
+
+void nxagentDisconnectPicture(void * p0, XID x1, void* p2)
+{
+ PicturePtr pPicture = (PicturePtr) p0;
+ Bool *pBool = (Bool *) p2;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDisconnectPicture: Called with bool [%d] and picture at [%p].\n",
+ *pBool, (void *) pPicture);
+
+ fprintf(stderr, "nxagentDisconnectPicture: Virtual picture is [%ld].\n",
+ nxagentPicture(pPicture));
+ #endif
+
+ if (!*pBool || !pPicture)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisconnectPicture: %p - XID %lx\n",
+ (void *) pPicture, nxagentPicture(pPicture));
+ #endif
+
+ nxagentPicture(pPicture) = None;
+}
+
+Bool nxagentDisconnectAllPicture()
+{
+ int i;
+ Bool r;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDisconnectAllPicture.\n");
+ #endif
+
+ for (i = 0, r = 1; i < MAXCLIENTS; i++)
+ {
+ if (clients[i])
+ {
+ FindClientResourcesByType(clients[i], PictureType, nxagentDisconnectPicture, &r);
+
+ #ifdef WARNING
+
+ if (r == False)
+ {
+ fprintf(stderr, "nxagentDisconnectAllPicture: WARNING! Failed to disconnect "
+ "picture for client [%d].\n", i);
+ }
+
+ #endif
+ }
+ }
+
+ return True;
+}
+
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color)
+{
+ Picture id;
+
+ if (nxagentRenderEnable == False)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRenderCreateSolidFill: Got called.\n");
+
+ if (pPicture == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! pPicture pointer is NULL.\n");
+ }
+
+ if (color == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! color pointer is NULL.\n");
+ }
+
+ #endif /* #ifdef DEBUG */
+
+ memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+ sizeof(XRenderPictureAttributes_));
+
+ id = XRenderCreateSolidFill(nxagentDisplay, (XRenderColor *) color);
+
+ #ifdef DEBUG
+ XSync(nxagentDisplay, 0);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderCreateSolidFill: Created solid fill xid [%lu].\n", id);
+ #endif
+
+ nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+ xPointFixed *p2, int nStops,
+ xFixed *stops,
+ xRenderColor *colors)
+{
+ Picture id;
+
+ XLinearGradient linearGradient;
+
+ if (nxagentRenderEnable == False)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: Got called.\n");
+
+ if (pPicture == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! pPicture pointer is NULL.\n");
+ }
+
+ if (p1 == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p1 pointer is NULL.\n");
+ }
+
+ if (p2 == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p2 pointer is NULL.\n");
+ }
+
+ if (stops == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! stops pointer is NULL.\n");
+ }
+
+ if (colors == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! colors pointer is NULL.\n");
+ }
+
+ #endif /* #ifdef DEBUG */
+
+ memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+ sizeof(XRenderPictureAttributes_));
+
+ linearGradient.p1.x = (XFixed) p1 -> x;
+ linearGradient.p1.y = (XFixed) p1 -> y;
+ linearGradient.p2.x = (XFixed) p2 -> x;
+ linearGradient.p2.y = (XFixed) p2 -> y;
+
+ id = XRenderCreateLinearGradient(nxagentDisplay, &linearGradient,
+ (XFixed *) stops,
+ (XRenderColor *) colors, nStops);
+
+ #ifdef DEBUG
+ XSync(nxagentDisplay, 0);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderCreateLinearGradient: Created linear gradient xid [%lu].\n", id);
+ #endif
+
+ nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors)
+{
+ Picture id;
+
+ XRadialGradient radialGradient;
+
+ if (nxagentRenderEnable == False)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: Got called.\n");
+
+ if (pPicture == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! pPicture pointer is NULL.\n");
+ }
+
+ if (inner == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! inner pointer is NULL.\n");
+ }
+
+ if (outer == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! outer pointer is NULL.\n");
+ }
+
+ if (stops == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! stops pointer is NULL.\n");
+ }
+
+ if (colors == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! colors pointer is NULL.\n");
+ }
+
+ #endif /* #ifdef DEBUG */
+
+ memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+ sizeof(XRenderPictureAttributes_));
+
+ radialGradient.inner.x = (XFixed) inner -> x;
+ radialGradient.inner.y = (XFixed) inner -> y;
+ radialGradient.inner.radius = (XFixed) innerRadius;
+ radialGradient.outer.x = (XFixed) outer -> x;
+ radialGradient.outer.y = (XFixed) outer -> y;
+ radialGradient.outer.radius = (XFixed) outerRadius;
+
+ id = XRenderCreateRadialGradient(nxagentDisplay, &radialGradient,
+ (XFixed *) stops,
+ (XRenderColor *) colors, nStops);
+
+ #ifdef DEBUG
+ XSync(nxagentDisplay, 0);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderCreateRadialGradient: Created radial gradient xid [%lu].\n", id);
+ #endif
+
+ nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+ xPointFixed *center,
+ xFixed angle, int nStops,
+ xFixed *stops,
+ xRenderColor *colors)
+{
+ Picture id;
+
+ XConicalGradient conicalGradient;
+
+ if (nxagentRenderEnable == False)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: Got called.\n");
+
+ if (pPicture == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! pPicture pointer is NULL.\n");
+ }
+
+ if (center == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! center pointer is NULL.\n");
+ }
+
+ if (stops == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! stops pointer is NULL.\n");
+ }
+
+ if (colors == NULL)
+ {
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! colors pointer is NULL.\n");
+ }
+
+ #endif /* #ifdef DEBUG */
+
+ memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+ sizeof(XRenderPictureAttributes_));
+
+ conicalGradient.center.x = (XFixed) center -> x;
+ conicalGradient.center.y = (XFixed) center -> y;
+ conicalGradient.angle = (XFixed) angle;
+
+ id = XRenderCreateConicalGradient(nxagentDisplay, &conicalGradient,
+ (XFixed *) stops,
+ (XRenderColor *) colors, nStops);
+
+ #ifdef DEBUG
+ XSync(nxagentDisplay, 0);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRenderCreateConicalGradient: Created conical gradient xid [%lu].\n", id);
+ #endif
+
+ nxagentPicturePriv(pPicture) -> picture = id;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
new file mode 100644
index 000000000..1c56ec16b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Render_H__
+#define __Render_H__
+
+#include "screenint.h"
+#include "cursor.h"
+#include "picture.h"
+#include "renderproto.h"
+
+#include "glyphstr.h"
+
+#include "Agent.h"
+
+extern int nxagentRenderEnable;
+extern int nxagentRenderVersionMajor;
+extern int nxagentRenderVersionMinor;
+
+extern int nxagentPicturePrivateIndex;
+
+extern BoxPtr nxagentGlyphsExtents;
+extern BoxPtr nxagentTrapezoidExtents;
+
+/*
+ * Structure imported from Xrender.h. We don't
+ * include Xrender.h at this point because of
+ * clashes of definition.
+ */
+
+/*
+ * Xlib Pixmap and Atom types are 8 bytes long
+ * on 64-bit archs, whilst they are 4 bytes long
+ * on 32-bit ones. At this point, Pixmap and Atom
+ * are not Xlib types but Xserver ones: here they
+ * are always 4 bytes long. So that we use XlibID
+ * symbols defined below to fill the structure with
+ * fields having the right size.
+ */
+
+typedef struct {
+ int repeat;
+ Picture alpha_map;
+ int alpha_x_origin;
+ int alpha_y_origin;
+ int clip_x_origin;
+ int clip_y_origin;
+ XlibPixmap clip_mask;
+ Bool graphics_exposures;
+ int subwindow_mode;
+ int poly_edge;
+ int poly_mode;
+ XlibAtom dither;
+ Bool component_alpha;
+} XRenderPictureAttributes_;
+
+typedef struct
+{
+ Picture picture;
+
+ XRenderPictureAttributes_ lastServerValues;
+
+} nxagentPrivPictureRec;
+
+typedef nxagentPrivPictureRec *nxagentPrivPicturePtr;
+
+#define nxagentPicturePriv(pPicture) \
+ ((nxagentPrivPicturePtr) ((pPicture) -> devPrivates[nxagentPicturePrivateIndex].ptr))
+
+#define nxagentPicture(pPicture) (nxagentPicturePriv(pPicture) -> picture)
+
+#define nxagentSetPictureRemoteValue(pPicture, pvalue, value) \
+do \
+{ \
+ nxagentPicturePriv(pPicture) -> lastServerValues.pvalue = value; \
+} \
+while (0)
+
+#define nxagentCheckPictureRemoteValue(pPicture, pvalue, value) \
+ (nxagentPicturePriv(pPicture) -> lastServerValues.pvalue == value)
+
+void nxagentRenderExtensionInit(void);
+Bool nxagentPictureInit(ScreenPtr, PictFormatPtr, int);
+
+int nxagentRenderRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
+ int nglyphs, CARD8 *images, int sizeImages);
+
+void nxagentReconnectPicture(void * p0, XID x1, void *p2);
+void nxagentDisconnectPicture(void * p0, XID x1, void* p2);
+
+void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2);
+
+void nxagentDestroyPicture(PicturePtr pPicture);
+
+#endif /* __Render_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
new file mode 100644
index 000000000..f42f9d99d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -0,0 +1,1291 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "X.h"
+
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "propertyst.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Drawable.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+#include "Atoms.h"
+#include "Trap.h"
+#include "Utils.h"
+
+#include "compext/Compext.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Assigned at the time the root window is
+ * initialized.
+ */
+
+typedef struct
+{
+ CARD32 flags;
+ CARD32 input;
+ CARD32 initial_state;
+ CARD32 icon_pixmap;
+ CARD32 icon_window;
+ INT32 icon_x;
+ INT32 icon_y;
+ CARD32 icon_mask;
+ CARD32 window_group;
+}
+nxagentWMHints;
+
+/*
+ * This structure is compatible with 32
+ * and 64 bit library interface. It has
+ * been copied from Xatomtype.h and it's
+ * a parameter of XChangeProperty().
+ */
+
+typedef struct
+{
+ unsigned long flags;
+ long input;
+ long initialState;
+ unsigned long iconPixmap;
+ unsigned long iconWindow;
+ long iconX;
+ long iconY;
+ unsigned long iconMask;
+ unsigned long windowGroup;
+}
+nxagentPropWMHints;
+
+WindowPtr nxagentRootlessWindow = NULL;
+
+#define TOP_LEVEL_TABLE_UNIT 100
+
+typedef struct {
+ Window xid;
+ WindowPtr pWin;
+} TopLevelParentRec;
+
+typedef struct {
+ TopLevelParentRec *elt;
+ int next;
+ int size;
+} TopLevelParentMap;
+
+static TopLevelParentMap topLevelParentMap = { NULL, 0, 0 };
+
+static void nxagentRemovePropertyFromList(void);
+
+/*
+ * This is currently unused.
+ */
+
+#ifdef TEST
+
+static void nxagentPrintRootlessTopLevelWindowMap(void);
+
+void nxagentPrintRootlessTopLevelWindowMap()
+{
+ int i;
+
+ fprintf(stderr, "nxagentPrintRootlessTopLevelWindowMap: Map size is [%d] num of entry [%d].\n",
+ topLevelParentMap.size, topLevelParentMap.next);
+
+ for (i = 0; i < topLevelParentMap.next; i++)
+ {
+ fprintf(stderr, "nxagentPrintRootlessTopLevelWindowMap: [%d] pWin at [%p] XID at [%ld].\n",
+ i, (void *) topLevelParentMap.elt[i].pWin, (long int) topLevelParentMap.elt[i].xid);
+ }
+}
+
+#endif
+
+void nxagentRootlessAddTopLevelWindow(WindowPtr pWin, Window w)
+{
+ int i;
+
+ for (i = 0; i < topLevelParentMap.next; i++)
+ {
+ if (topLevelParentMap.elt[i].pWin == pWin)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentRootlessAddTopLevelWindow: WARNING! "
+ "Trying to add duplicated entry window at [%p] xid [%ld].\n",
+ (void *) pWin, w);
+ #endif
+
+ topLevelParentMap.elt[i].xid = w;
+
+ return;
+ }
+ }
+
+ if (topLevelParentMap.next == topLevelParentMap.size)
+ {
+ TopLevelParentRec *ptr = topLevelParentMap.elt;
+ size_t size = (topLevelParentMap.size += TOP_LEVEL_TABLE_UNIT);
+
+ ptr = realloc(ptr, size * sizeof(TopLevelParentRec));
+
+ if (ptr == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRootlessAddTopLevelWindow: Warning failed to allocate memory.\n");
+ #endif
+
+ return;
+ }
+
+ topLevelParentMap.elt = ptr;
+ topLevelParentMap.size = size;
+ }
+
+ topLevelParentMap.elt[topLevelParentMap.next].xid = w;
+ topLevelParentMap.elt[topLevelParentMap.next].pWin = pWin;
+ topLevelParentMap.next++;
+}
+
+WindowPtr nxagentRootlessTopLevelWindow(Window w)
+{
+ int i;
+
+ for (i = 0; i < topLevelParentMap.next; i++)
+ {
+ if (w == topLevelParentMap.elt[i].xid)
+ {
+ return topLevelParentMap.elt[i].pWin;
+ }
+ }
+
+ return NULL;
+}
+
+void nxagentRootlessDelTopLevelWindow(WindowPtr pWin)
+{
+ int i;
+
+ for (i = 0; i < topLevelParentMap.next; i++)
+ {
+ if (pWin == topLevelParentMap.elt[i].pWin)
+ {
+ topLevelParentMap.elt[i] = topLevelParentMap.elt[topLevelParentMap.next - 1];
+ topLevelParentMap.next--;
+
+ return;
+ }
+ }
+}
+
+Window nxagentRootlessWMTopLevelWindow(WindowPtr pWin);
+
+void nxagentConfigureRootlessWindow(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib, int stack_mode, Mask mask)
+{
+ XWindowChanges changes;
+ Window sibw = 0;
+
+ changes.x = x;
+ changes.y = y;
+ changes.width = w;
+ changes.height = h;
+ changes.border_width = bw;
+ changes.stack_mode = stack_mode;
+
+ if (pSib)
+ {
+ sibw = nxagentWindow(pSib);
+ }
+
+ if (sibw)
+ {
+ changes.sibling = sibw;
+ }
+
+ XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), mask, &changes);
+}
+
+void nxagentCirculateRootlessWindows(int direction)
+{
+ XCirculateSubwindows(nxagentDisplay, DefaultRootWindow(nxagentDisplay), direction);
+}
+
+#ifdef DEBUG
+
+Bool nxagentRootlessTreesMatch()
+{
+ Window root_return;
+ Window parent_return;
+ Window *children_return;
+ unsigned int nChildrenReturn;
+ WindowPtr pW;
+ WindowPtr pTestWin = screenInfo.screens[0]->root -> firstChild;
+ Bool treesMatch = True;
+ Status result;
+
+ result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ &root_return, &parent_return, &children_return, &nChildrenReturn);
+
+ if (!result)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentRootlessTreesMatch: WARNING! Failed QueryTree request.\n");
+ #endif
+
+ return False;
+ }
+
+ while (nChildrenReturn > 0)
+ {
+ pW = nxagentWindowPtr(children_return[--nChildrenReturn]);
+
+ if (!pW)
+ {
+ pW = nxagentRootlessTopLevelWindow(children_return[nChildrenReturn]);
+ }
+
+ if (pW && pW != screenInfo.screens[0]->root)
+ {
+ if (treesMatch && pTestWin && pTestWin == pW)
+ {
+ pTestWin = pTestWin -> nextSib;
+ }
+ else
+ {
+ treesMatch = False;
+ }
+ }
+ }
+
+ if (children_return)
+ {
+ XFree(children_return);
+ }
+
+ return treesMatch;
+}
+
+#endif
+
+#ifndef _XSERVER64
+void nxagentRootlessRestack(Window children[], unsigned int nchildren)
+#else
+void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren)
+#endif
+{
+ WindowPtr *toplevel;
+ unsigned int ntoplevel;
+ int i;
+ WindowPtr pWin;
+ ClientPtr pClient;
+ XID values[2];
+ Mask mask;
+
+ toplevel = malloc(sizeof(WindowPtr) * nchildren);
+
+ if (!toplevel)
+ {
+ /* FIXME: Is this too much and we and simply return here? */
+ FatalError("nxagentRootlessRestack: malloc() failed.");
+ }
+
+ ntoplevel = 0;
+
+ for(i = 0; i < nchildren; i++)
+ {
+ pWin = nxagentWindowPtr(children[i]);
+
+ if (!pWin)
+ {
+ pWin = nxagentRootlessTopLevelWindow(children[i]);
+ }
+
+ if (pWin && pWin != screenInfo.screens[0]->root)
+ {
+ toplevel[ntoplevel++] = pWin;
+ }
+ }
+
+ if (!ntoplevel)
+ {
+ free(toplevel);
+ return;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRootlessRestack: External top level windows before restack:");
+
+ for (i = 0; i < ntoplevel; i++)
+ {
+ fprintf(stderr, "nxagentRootlessRestack: [%p]\n", toplevel[i]);
+ }
+
+ fprintf(stderr, "nxagentRootlessRestack: Internal top level windows before restack:");
+
+ for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
+ {
+ fprintf(stderr, "nxagentRootlessRestack: [%p]\n", pWin);
+ }
+
+ #endif
+
+ pWin = screenInfo.screens[0]->root -> firstChild;
+
+ values[1] = (XID) Above;
+
+ while(ntoplevel-- > 0 && pWin != NULL)
+ {
+ if (toplevel[ntoplevel] != pWin)
+ {
+ mask = CWSibling | CWStackMode;
+ values[0] = pWin -> drawable.id;
+ pClient = wClient(toplevel[ntoplevel]);
+ nxagentScreenTrap = 1;
+ ConfigureWindow(toplevel[ntoplevel], mask, (XID *) values, pClient);
+ nxagentScreenTrap = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRootlessRestack: Restacked window [%p].\n", (void*) toplevel[ntoplevel]);
+ #endif
+ }
+
+ pWin = toplevel[ntoplevel] -> nextSib;
+ }
+
+ #ifdef DEBUG
+
+ fprintf(stderr, "nxagentRootlessRestack: External top level windows after restack:");
+
+ ntoplevel = i;
+
+ for (i = 0; i < ntoplevel; i++)
+ {
+ fprintf(stderr, "nxagentRootlessRestack: [%p]\n", toplevel[i]);
+ }
+
+ fprintf(stderr, "nxagentRootlessRestack: Internal top level windows after restack:");
+
+ for (pWin = screenInfo.screens[0]->root -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
+ {
+ fprintf(stderr, "nxagentRootlessRestack: [%p]\n", pWin);
+ }
+
+ #endif
+
+ free(toplevel);
+
+ return;
+}
+
+/*
+ * Determine if window is a top-level window.
+ */
+
+Window nxagentRootlessWindowParent(WindowPtr pWin)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentRootlessWindowParent: Called for window at [%p][%ld] with parent [%p][%ld].\n",
+ (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin->parent,
+ (pWin->parent ? nxagentWindowPriv(pWin->parent)->window : 0));
+ #endif
+
+ if (pWin -> parent == NULL)
+ {
+ return DefaultRootWindow(nxagentDisplay);
+ }
+ else if (pWin -> parent == nxagentRootlessWindow)
+ {
+ return DefaultRootWindow(nxagentDisplay);
+ }
+ else
+ {
+ return nxagentWindow(pWin -> parent);
+ }
+}
+
+int nxagentExportAllProperty(pWin)
+ WindowPtr pWin;
+{
+ PropertyPtr pProp;
+ int total = 0;
+
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
+ {
+ total += nxagentExportProperty(pWin,
+ pProp->propertyName,
+ pProp->type,
+ pProp->format,
+ PropModeReplace,
+ pProp->size,
+ pProp->data);
+ }
+
+ return total;
+}
+
+int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
+ WindowPtr pWin;
+ Atom property, type;
+ int format, mode;
+ unsigned long nUnits;
+ void *value;
+{
+ const char *propertyS, *typeS;
+ Atom propertyX, typeX;
+ char *output = NULL;
+ nxagentWMHints wmHints;
+ nxagentPropWMHints propHints;
+ Bool export = False;
+ Bool freeMem = False;
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return 0;
+ }
+
+ propertyS = NameForAtom(property);
+ typeS = NameForAtom(type);
+
+ if (strncmp(propertyS, "WM_", 3) != 0 &&
+ strncmp(propertyS, "_NET_", 5) != 0 &&
+ strcmp(propertyS, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR") != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExportProperty: WARNING! Ignored ChangeProperty "
+ "on %swindow %lx property %s type %s nUnits %ld format %d\n",
+ nxagentWindowTopLevel(pWin) ? "toplevel " : "", nxagentWindow(pWin),
+ validateString(propertyS), validateString(typeS), nUnits, format);
+ #endif
+ }
+ else if (strcmp(typeS, "STRING") == 0 ||
+ #ifndef _XSERVER64
+ strcmp(typeS, "CARDINAL") == 0 ||
+ strcmp(typeS, "WM_SIZE_HINTS") == 0 ||
+ #endif
+ strcmp(typeS, "UTF8_STRING") == 0)
+ {
+ output = value;
+ export = True;
+ }
+ #ifdef _XSERVER64
+ else if (strcmp(typeS, "CARDINAL") == 0 || strcmp(typeS, "WM_SIZE_HINTS") == 0)
+ {
+ /* FIXME: is it okay here to ignore malloc fails? */
+ unsigned long *buffer = malloc(nUnits * sizeof(*buffer));
+ int *input = value;
+ int i;
+
+ if (buffer)
+ {
+ freeMem = True;
+ export = True;
+ output = (char*) buffer;
+
+ for (i = 0; i < nUnits; i++)
+ {
+ buffer[i] = input[i];
+ }
+ }
+ }
+ #endif
+ else if (strcmp(typeS, "WM_HINTS") == 0)
+ {
+ ClientPtr pClient = wClient(pWin);
+ wmHints = *(nxagentWMHints*)value;
+
+ wmHints.flags |= InputHint;
+ wmHints.input = True;
+
+ /*
+ * Initialize the structure used in XChangeProperty().
+ */
+
+ propHints.flags = wmHints.flags;
+ propHints.input = (wmHints.input == True ? 1 : 0);
+ propHints.initialState = wmHints.initial_state;
+ propHints.iconPixmap = wmHints.icon_pixmap;
+ propHints.iconWindow = wmHints.icon_window;
+ propHints.iconX = wmHints.icon_x;
+ propHints.iconY = wmHints.icon_y;
+ propHints.iconMask = wmHints.icon_mask;
+ propHints.windowGroup = wmHints.window_group;
+
+ output = (char*) &propHints;
+ export = True;
+
+ if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
+ {
+ PixmapPtr icon = (PixmapPtr)SecurityLookupIDByType(pClient, wmHints.icon_pixmap,
+ RT_PIXMAP, DixDestroyAccess);
+
+ if (icon)
+ {
+ if (nxagentDrawableStatus((DrawablePtr) icon) == NotSynchronized)
+ {
+ nxagentSynchronizeRegion((DrawablePtr) icon, NullRegion, NEVER_BREAK, NULL);
+ }
+
+ propHints.iconPixmap = nxagentPixmap(icon);
+ }
+ else
+ {
+ propHints.flags &= ~IconPixmapHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %x from hint "
+ "exporting property %s type %s on window %p.\n",
+ (unsigned int) wmHints.icon_pixmap, propertyS, typeS,
+ (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & IconWindowHint) && (wmHints.icon_window != None))
+ {
+ WindowPtr icon = (WindowPtr)SecurityLookupWindow(wmHints.icon_window, pClient,
+ DixDestroyAccess);
+
+ if (icon)
+ {
+ propHints.iconWindow = nxagentWindow(icon);
+ }
+ else
+ {
+ propHints.flags &= ~IconWindowHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %x from hint "
+ "exporting property %s type %s on window %p.\n",
+ (unsigned int) wmHints.icon_window, propertyS, typeS,
+ (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & IconMaskHint) && (wmHints.icon_mask != None))
+ {
+ PixmapPtr icon = (PixmapPtr)SecurityLookupIDByType(pClient, wmHints.icon_mask,
+ RT_PIXMAP, DixDestroyAccess);
+
+ if (icon)
+ {
+ propHints.iconMask = nxagentPixmap(icon);
+ }
+ else
+ {
+ propHints.flags &= ~IconMaskHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %x from hint "
+ "exporting property %s type %s on window %p.\n",
+ (unsigned int) wmHints.icon_mask, propertyS, typeS,
+ (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & WindowGroupHint) && (wmHints.window_group != None))
+ {
+ WindowPtr window = (WindowPtr)SecurityLookupWindow(wmHints.window_group, pClient,
+ DixDestroyAccess);
+
+ if (window)
+ {
+ propHints.windowGroup = nxagentWindow(window);
+ }
+ else
+ {
+ propHints.flags &= ~WindowGroupHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %x from hint "
+ "exporting property %s type %s on window %p.\n",
+ (unsigned int) wmHints.window_group, propertyS, typeS,
+ (void *) pWin);
+ #endif
+ }
+ }
+ }
+ else if (strcmp(typeS, "ATOM") == 0)
+ {
+ XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
+ Atom *input = value;
+ const char *atomName = NULL;
+ int i;
+ int j = 0;
+
+ if (!atoms)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! malloc() failed for '%s'- bailing out.\n", typeS);
+ #endif
+ return False;
+ }
+
+ freeMem = True;
+ export = True;
+ output = (char *) atoms;
+
+ for (i = 0; i < nUnits; i++)
+ {
+ /*
+ * Exporting the _NET_WM_PING property could
+ * result in rootless windows being grayed out
+ * when the compiz window manager is running.
+ *
+ * Better solution would probably be to handle
+ * the communication with the window manager
+ * instead of just getting rid of the property.
+ */
+
+ if ((atomName = NameForAtom(input[i])) != NULL &&
+ strcmp(atomName, "_NET_WM_PING") != 0)
+ {
+ atoms[j] = nxagentLocalToRemoteAtom(input[i]);
+
+ if (atoms[j] == None)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
+ (long int) input[i], validateString(atomName));
+ #endif
+ }
+
+ j++;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentExportProperty: WARNING! "
+ "Not exporting the _NET_WM_PING property.\n");
+ }
+ #endif
+ }
+
+ nUnits = j;
+ }
+ else if (strcmp(typeS, "WINDOW") == 0)
+ {
+ Window *input = value;
+ XlibWindow *wind = malloc(nUnits * sizeof(*wind));
+ ClientPtr pClient = wClient(pWin);
+ WindowPtr pWindow;
+ int i;
+
+ if (!wind)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! malloc() failed for '%s' - bailing out.\n", typeS);
+ #endif
+ return False;
+ }
+
+ freeMem = True;
+ export = True;
+ output = (char*) wind;
+
+ for (i = 0; i < nUnits; i++)
+ {
+ pWindow = (WindowPtr)SecurityLookupWindow(input[i], pClient,
+ DixDestroyAccess);
+ if ((input[i] != None) && pWindow)
+ {
+ wind[i] = nxagentWindow(pWindow);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window %ld "
+ "exporting property %s type %s on window %p.\n",
+ (long int) input[i], propertyS, typeS, (void *) pWin);
+ #endif
+
+ /*
+ * It seems that clients specifie
+ * strange windows, perhaps are
+ * not real windows so we can try
+ * to let them pass anyway.
+ *
+ * wind[i] = None;
+ *
+ */
+ }
+ }
+ }
+
+ if (export)
+ {
+ propertyX = nxagentLocalToRemoteAtom(property);
+ typeX = nxagentLocalToRemoteAtom(type);
+
+ if (propertyX == None || typeX == None)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom.\n");
+ #endif
+
+ export = 0;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExportProperty: Property [%lu] format [%i] "
+ "units [%lu].\n", propertyX, format, nUnits);
+ #endif
+
+ if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+ (MAX_REQUEST_SIZE << 2))
+ {
+ XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX,
+ format, mode, (void*)output, nUnits);
+ }
+ else if (mode == PropModeReplace)
+ {
+ int n;
+ char *data;
+
+ XDeleteProperty(nxagentDisplay, nxagentWindow(pWin), propertyX);
+
+ data = (char *) output;
+
+ while (nUnits > 0)
+ {
+ if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+ (MAX_REQUEST_SIZE << 2))
+ {
+ n = nUnits;
+ }
+ else
+ {
+ n = ((MAX_REQUEST_SIZE << 2) - sizeof(xChangePropertyReq)) /
+ (format >> 3);
+ }
+
+ XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX,
+ typeX, format, PropModeAppend, (void*) data, n);
+
+ nUnits -= n;
+
+ data = (char *) data + n * (format >> 3);
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentExportProperty: WARNING! "
+ "Property [%lu] too long.\n", (long unsigned int)propertyX);
+ #endif
+
+ goto nxagentExportPropertyError;
+ }
+
+ nxagentAddPropertyToList(propertyX, pWin);
+ }
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentExportProperty: WARNING! Ignored ChangeProperty "
+ "on %swindow %x property %s type %s nUnits %ld format %d\n",
+ nxagentWindowTopLevel(pWin) ? "toplevel " : "",
+ nxagentWindow(pWin), validateString(propertyS), validateString(typeS),
+ nUnits, format);
+ #endif
+ }
+
+ nxagentExportPropertyError:
+
+ if (freeMem)
+ {
+ free(output);
+ }
+
+ return export;
+}
+
+void nxagentImportProperty(Window window,
+ Atom property,
+ Atom type,
+ int format,
+ unsigned long nitems,
+ unsigned long bytes_after,
+ unsigned char *buffer)
+{
+ Atom propertyL;
+ Atom typeL;
+
+ WindowPtr pWin;
+ Bool import = False;
+ Bool freeMem = False;
+ nxagentWMHints wmHints;
+
+ typedef struct {
+ CARD32 state;
+ Window icon;
+ } WMState;
+ WMState wmState;
+
+ char *output = NULL;
+ const char *typeS;
+
+ pWin = nxagentWindowPtr(window);
+
+ if (pWin == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: Failed to look up remote window %lx property [%ld] exiting.\n",
+ window, property);
+ #endif
+
+ return;
+ }
+
+ propertyL = nxagentRemoteToLocalAtom(property);
+
+ if (!ValidAtom(propertyL))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: Failed to convert remote property atom.\n");
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: Window %lx property [%ld]: %s\n",
+ window, property, validateString(NameForAtom(propertyL)));
+ #endif
+
+ /*
+ * We settle a property size limit of
+ * 256K beyond which we simply ignore them.
+ */
+
+ typeL = nxagentRemoteToLocalAtom(type);
+ typeS = NameForAtom(typeL);
+
+ if (buffer == NULL && (nitems > 0))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: Failed to retrieve remote property [%ld] %s on Window %ld\n",
+ (long int) property, validateString(NameForAtom(propertyL)), (long int) window);
+ #endif
+ }
+ else if (bytes_after != 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: Remote property bigger than maximum limits.\n");
+ #endif
+ }
+ else if (!ValidAtom(typeL))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: Failed to convert remote atoms [%ld].\n",
+ (long int) type);
+ #endif
+ }
+ else if (nitems == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: Importing void property.\n");
+ #endif
+
+ import = True;
+ }
+ else if (strcmp(typeS, "STRING") == 0 ||
+ strcmp(typeS, "UTF8_STRING") == 0 ||
+ strcmp(typeS, "CARDINAL") == 0 ||
+ strcmp(typeS, "WM_SIZE_HINTS") == 0)
+ {
+ output = (char*)buffer;
+ import = True;
+ }
+ else if (strcmp(typeS, "WM_STATE") == 0)
+ {
+ /*
+ * Contents of property of type WM_STATE
+ * are {CARD32 state, WINDOW icon}. Only
+ * the icon field has to be modified before
+ * importing the property.
+ */
+
+ WindowPtr pIcon;
+
+ wmState = *(WMState*)buffer;
+ pIcon = nxagentWindowPtr(wmState.icon);
+
+ if (pIcon || wmState.icon == None)
+ {
+ import = True;
+ output = (char*) &wmState;
+ wmState.icon = pIcon ? nxagentWindow(pIcon) : None;
+ }
+ else if (wmState.icon)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to convert remote window %ld"
+ " importing property %ld of type WM_STATE", (long int) wmState.icon,
+ (long int) property);
+ #endif
+ }
+ }
+ else if (strcmp(typeS, "WM_HINTS") == 0)
+ {
+ wmHints = *(nxagentWMHints*)buffer;
+ output = (char*) &wmHints;
+ import = True;
+
+ if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
+ {
+ PixmapPtr icon = nxagentPixmapPtr(wmHints.icon_pixmap);
+
+ if (icon)
+ {
+ wmHints.icon_pixmap = icon -> drawable.id;
+ }
+ else
+ {
+ wmHints.flags &= ~IconPixmapHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
+ "pixmap %d from hint importing property [%ld] type %s on window %p.\n",
+ (unsigned int) wmHints.icon_pixmap, (long int) property,
+ typeS, (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & IconWindowHint) && (wmHints.icon_window != None))
+ {
+ WindowPtr icon = nxagentWindowPtr(wmHints.icon_window);
+
+ if (icon)
+ {
+ wmHints.icon_window = icon -> drawable.id;
+ }
+ else
+ {
+ wmHints.flags &= ~IconWindowHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagenImportProperty: WARNING! Failed to look up remote icon "
+ "window %x from hint importing property [%ld] type %s on window %p.\n",
+ (unsigned int) wmHints.icon_window,
+ (long int) property, typeS, (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & IconMaskHint) && (wmHints.icon_mask != None))
+ {
+ PixmapPtr icon = nxagentPixmapPtr(wmHints.icon_mask);
+
+ if (icon)
+ {
+ wmHints.icon_mask = icon -> drawable.id;
+ }
+ else
+ {
+ wmHints.flags &= ~IconMaskHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
+ "mask %x from hint importing property [%ld] type %s on window %p.\n",
+ (unsigned int) wmHints.icon_mask, (long int) property, typeS, (void *) pWin);
+ #endif
+ }
+ }
+
+ if ((wmHints.flags & WindowGroupHint) && (wmHints.window_group != None))
+ {
+ WindowPtr group = nxagentWindowPtr(wmHints.window_group);
+
+ if (group)
+ {
+ wmHints.window_group = group -> drawable.id;
+ }
+ else
+ {
+ wmHints.flags &= ~WindowGroupHint;
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote window "
+ "group %x from hint importing property [%ld] type %s on window %p.\n",
+ (unsigned int) wmHints.window_group,
+ (long int) property, typeS, (void *) pWin);
+ #endif
+ }
+ }
+ }
+ else if (strcmp(typeS, "ATOM") == 0)
+ {
+ Atom *atoms = malloc(nitems * sizeof(Atom));
+ Atom *input = (Atom*) buffer;
+ int i;
+
+ if (atoms == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! malloc() failed for '%s' - bailing out.\n", typeS);
+ #endif
+
+ return;
+ }
+
+ freeMem = True;
+ import = True;
+ output = (char *) atoms;
+
+ for (i = 0; i < nitems; i++)
+ {
+ atoms[i] = nxagentRemoteToLocalAtom(input[i]);
+
+ if (atoms[i] == None)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to convert remote atom %ld.\n",
+ (long int) input[i]);
+ #endif
+ }
+ }
+ }
+ else if (strcmp(typeS, "WINDOW") == 0)
+ {
+ Window *input = (Window*) buffer;
+ Window *wind = malloc(nitems * sizeof(Window));
+ WindowPtr pWindow;
+ int i;
+
+ if (!wind)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! malloc() failed for '%s' - bailing out.\n", typeS);
+ #endif
+
+ return;
+ }
+ freeMem = True;
+ import = True;
+ output = (char*) wind;
+
+ for (i = 0; i < nitems; i++)
+ {
+ pWindow = nxagentWindowPtr(input[i]);
+
+ if (pWindow)
+ {
+ wind[i] = pWindow -> drawable.id;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote window %lx "
+ "importing property [%ld] type %s on window %p.\n",
+ (long int) input[i], (long int) property, typeS, (void*)pWin);
+ #endif
+
+ wind[i] = None;
+ }
+ }
+ }
+
+ if (import)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: ChangeProperty "
+ "on window %lx property [%ld] type %s nitems %ld format %d\n",
+ window, property, typeS, nitems, format);
+ #endif
+
+ ChangeWindowProperty(pWin, propertyL, typeL, format,
+ PropModeReplace, nitems, output, 1);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentImportProperty: WARNING! Ignored ChangeProperty "
+ "on window %lx property [%ld] type %s ntems %ld format %d\n",
+ window, property, validateString(typeS), nitems, format);
+ #endif
+ }
+
+ if (freeMem)
+ {
+ free(output);
+ }
+
+ return;
+}
+
+/*
+ * We want to import all properties changed by external clients to
+ * reflect properties of our internal windows but we must ignore
+ * all the property notify events generated by our own requests.
+ * For this purpose we implement a FIFO to record every change pro-
+ * perty request that we dispatch. In this way, when processing a
+ * property notify, we can distinguish between the notifications
+ * generated by our requests from those generated by other clients
+ * connected to the real X server.
+ */
+
+struct nxagentPropertyRec{
+ Window window;
+ Atom property;
+ struct nxagentPropertyRec *next;
+};
+
+static struct{
+ struct nxagentPropertyRec *first;
+ struct nxagentPropertyRec *last;
+ int size;
+} nxagentPropertyList = {NULL, NULL, 0};
+
+/*
+ * Removing first element from list.
+ */
+
+void nxagentRemovePropertyFromList()
+{
+ struct nxagentPropertyRec *tmp = nxagentPropertyList.first;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemovePropertyFromList: Property %ld on Window %lx to list, list size is %d.\n\n",
+ nxagentPropertyList.first -> property, nxagentPropertyList.first -> window,
+ nxagentPropertyList.size);
+ #endif
+
+ if (nxagentPropertyList.first)
+ {
+ nxagentPropertyList.first = nxagentPropertyList.first -> next;
+
+ if (--nxagentPropertyList.size == 0)
+ {
+ nxagentPropertyList.last = NULL;
+ }
+
+ free(tmp);
+ }
+}
+
+/*
+ * Add the record to the list.
+ */
+
+void nxagentAddPropertyToList(Atom property, WindowPtr pWin)
+{
+ struct nxagentPropertyRec *tmp;
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return;
+ }
+
+ if ((tmp = malloc(sizeof(struct nxagentPropertyRec))) == NULL)
+ {
+ FatalError("nxagentAddPropertyToList: malloc() failed.");
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddPropertyToList: Adding record Property %ld - Window %lx[%p]"
+ "to list, list size is %d.\n", property, nxagentWindow(pWin), (void*) pWin,
+ nxagentPropertyList.size);
+ #endif
+
+ tmp -> property = property;
+ tmp -> window = nxagentWindow(pWin);
+ tmp -> next = NULL;
+
+ if (nxagentPropertyList.size == 0)
+ {
+ nxagentPropertyList.first = tmp;
+ }
+ else
+ {
+ nxagentPropertyList.last -> next = tmp;
+ }
+
+ nxagentPropertyList.last = tmp;
+ nxagentPropertyList.size++;
+}
+
+void nxagentFreePropertyList()
+{
+ while (nxagentPropertyList.size != 0)
+ {
+ nxagentRemovePropertyFromList();
+ }
+}
+
+/*
+ * We are trying to distinguish notify generated by
+ * an external client from those genarated by our
+ * own requests.
+ */
+
+Bool nxagentNotifyMatchChangeProperty(void *p)
+{
+ struct nxagentPropertyRec *first = nxagentPropertyList.first;
+ XPropertyEvent *X = p;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentNotifyMatchChangeProperty: Property notify on window %lx property %ld.\n",
+ X -> window, X -> atom);
+
+ if (first)
+ {
+ fprintf(stderr, "nxagentNotifyMatchChangeProperty: First element on list is window %lx property %ld list size is %d.\n",
+ first -> window, first -> property, nxagentPropertyList.size);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentNotifyMatchChangeProperty: List is empty.\n");
+ }
+ #endif
+
+ if (first == NULL ||
+ X -> window != first -> window ||
+ X -> atom != first -> property)
+ {
+ return False;
+ }
+
+ nxagentRemovePropertyFromList();
+
+ return True;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
new file mode 100644
index 000000000..062e164f4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -0,0 +1,101 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Rootless_H__
+#define __Rootless_H__
+
+#include "window.h"
+
+/*
+ * The real X server's root window if we
+ * are in rootless mode.
+ */
+
+extern WindowPtr nxagentRootlessWindow;
+
+/*
+ * We want to import all properties changed by external clients to
+ * reflect properties of our internal windows but we must ignore
+ * all the property notify events generated by our own requests.
+ * For this purpose we implement a FIFO to record every change pro-
+ * perty request that we dispatch. In this way, when processing a
+ * property notify, we can distinguish between the notifications
+ * generated by our requests from those generated by other clients
+ * connected to the real X server.
+ */
+
+typedef struct
+{
+ Window window;
+ Atom property;
+} PropertyRequestRec;
+
+extern PropertyRequestRec nxagentPropertyRequests[256];
+
+Window nxagentRootlessWindowParent(WindowPtr pWin);
+
+void nxagentRootlessAddTopLevelWindow(WindowPtr pWin, Window w);
+void nxagentRootlessDelTopLevelWindow(WindowPtr pWin);
+
+WindowPtr nxagentRootlessTopLevelWindow(Window w);
+
+#ifndef _XSERVER64
+void nxagentRootlessRestack(Window *toplevel, unsigned int ntoplevel);
+#else
+void nxagentRootlessRestack(unsigned long *toplevel, unsigned int ntoplevel);
+#endif
+
+
+int nxagentExportAllProperty(WindowPtr pWin);
+
+int nxagentExportProperty(WindowPtr pWin, Atom property, Atom type, int format,
+ int mode, unsigned long nUnits, void * value);
+
+#define MAX_RETRIEVED_PROPERTY_SIZE 256 * 1024
+
+void nxagentImportProperty(Window window, Atom property, Atom type, int format,
+ unsigned long nitems, unsigned long bytes_after, unsigned char *buffer);
+
+/*
+ * Push last ChangeProperty to the list.
+ */
+
+void nxagentAddPropertyToList(Atom property, WindowPtr pWin);
+
+/*
+ * Check if a PropertyNotify match the top
+ * of the list.
+ */
+
+Bool nxagentNotifyMatchChangeProperty(void *X);
+
+void nxagentConfigureRootlessWindow(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib, int stack_mode, Mask mask);
+
+void nxagentCirculateRootlessWindows(int direction);
+
+void nxagentFreePropertyList(void);
+
+#endif /* __Rootless_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
new file mode 100644
index 000000000..1c3e76580
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -0,0 +1,4741 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+/*
+ * Used by the auto-disconnect feature.
+ */
+
+#include <signal.h>
+
+#include "scrnintstr.h"
+#include "dix.h"
+#include "dixstruct.h"
+#include "mi.h"
+#include "micmap.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "mipointer.h"
+#include "../../fb/fb.h"
+#include "../../randr/randrstr.h"
+#include "inputstr.h"
+#include "mivalidate.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Extensions.h"
+#include "Atoms.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Font.h"
+#include "Colormap.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Init.h"
+#include "Args.h"
+#include "Client.h"
+#include "Options.h"
+#include "Splash.h"
+#include "Holder.h"
+#include "Render.h"
+#include "Trap.h"
+#include "Keyboard.h"
+#include "Pointer.h"
+#include "Reconnect.h"
+#include "Composite.h"
+#include <nx/Shadow.h>
+#include "Utils.h"
+
+#include <nx-X11/Xlib.h>
+#include "X11/include/Xinerama_nxagent.h"
+
+
+#define GC XlibGC
+#define Font XlibFont
+#define KeySym XlibKeySym
+#define XID XlibXID
+#include <nx-X11/Xlibint.h>
+#undef GC
+#undef Font
+#undef KeySym
+#undef XID
+
+#include "Xatom.h"
+#include "Xproto.h"
+
+#include "compext/Compext.h"
+
+#include "mibstorest.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#undef PANIC
+#undef WARNING
+#undef TEST
+#undef DEBUG
+#undef WATCH
+#undef DUMP
+
+/*
+ * Display a pixmap on an shadow
+ * display used for debug.
+ */
+
+#ifdef DUMP
+
+void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height);
+
+void nxagentFbRestoreArea(PixmapPtr pPixmap, WindowPtr pWin, int xSrc, int ySrc, int width,
+ int height, int xDst, int yDst)
+#endif
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+extern Bool nxagentIpaq;
+extern Pixmap nxagentIconPixmap;
+extern Pixmap nxagentIconShape;
+extern Bool useXpmIcon;
+
+Window nxagentDefaultWindows[MAXSCREENS];
+Window nxagentInputWindows[MAXSCREENS];
+Window nxagentScreenSaverWindows[MAXSCREENS];
+
+#ifdef NXAGENT_ONSTART
+Atom nxagentWMStart;
+Window nxagentSplashWindow = None;
+Pixmap nxagentPixmapLogo;
+#endif
+
+ScreenPtr nxagentDefaultScreen = NULL;
+int nxagentArgc = 0;
+char **nxagentArgv = NULL;
+
+#ifdef NXAGENT_ARTSD
+
+char mcop_atom[] = "MCOPGLOBALS";
+Atom mcop_local_atom = None;
+unsigned char fromHexNibble(char c);
+void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+
+#endif
+
+Window nxagentIconWindow = None;
+Window nxagentFullscreenWindow = None;
+
+#ifdef VIEWPORT_FRAME
+
+WindowPtr nxagentViewportFrameLeft;
+WindowPtr nxagentViewportFrameRight;
+WindowPtr nxagentViewportFrameAbove;
+WindowPtr nxagentViewportFrameBelow;
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+Bool nxagentCreateScreenResources(ScreenPtr pScreen);
+void nxagentPrintAgentGeometry(char *hdrMessage, char *prefix);
+
+
+/*
+ * These variables are for shadowing feature.
+ */
+
+int nxagentShadowResize = 0;
+
+WindowPtr nxagentShadowWindowPtr = NULL;
+
+static XID accessPixmapID;
+static Window accessWindowID;
+static int imageByteOrder;
+static unsigned char nxagentMasterDepth;
+static unsigned char nxagentCheckDepth = 0;
+static unsigned int nxagentBppShadow;
+static unsigned int nxagentBppMaster;
+int nxagentShadowXConnectionNumber;
+GCPtr nxagentShadowGCPtr = NULL;
+PixmapPtr nxagentShadowPixmapPtr = NULL;
+char * nxagentShadowBuffer;
+unsigned char nxagentShadowDepth;
+int nxagentShadowWidth;
+int nxagentShadowHeight;
+Display * nxagentShadowDisplay;
+short nxagentShadowUid = -1;
+
+void nxagentShadowAdaptDepth(unsigned int, unsigned int, unsigned int, char **);
+
+RegionRec nxagentShadowUpdateRegion;
+
+#define NXAGENT_DEFAULT_DPI 75
+
+/*
+ * From randr/randr.c. This was originally static
+ * but we need it here.
+ */
+
+int TellChanged(WindowPtr pWin, void * value);
+
+int nxagentBitsPerPixel(int depth)
+{
+ if (depth == 1) return 1;
+ else if (depth <= 8) return 8;
+ else if (depth <= 16) return 16;
+ else return 32;
+}
+
+void nxagentSetScreenInfo(ScreenInfo *screenInfo)
+{
+ /*
+ * Setup global screen info parameters. In the Xnest
+ * server this stuff is done after having opened the
+ * real display as Xnest lets the screen reflect the
+ * order of the remote end. Agent will instead set
+ * the order according to local endianess and swap
+ * data whenever it is appropriate.
+ *
+ * From a standard implementation:
+ *
+ * screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ * screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ * screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ * screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+ *
+ * From Xnest implementation:
+ *
+ * screenInfo -> imageByteOrder = ImageByteOrder(nxagentDisplay);
+ * screenInfo -> bitmapScanlineUnit = BitmapUnit(nxagentDisplay);
+ * screenInfo -> bitmapScanlinePad = BitmapPad(nxagentDisplay);
+ * screenInfo -> bitmapBitOrder = BitmapBitOrder(nxagentDisplay);
+ */
+
+ screenInfo -> imageByteOrder = IMAGE_BYTE_ORDER;
+ screenInfo -> bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ screenInfo -> bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ screenInfo -> bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetScreenInfo: Server image order is [%d] bitmap order is [%d].\n",
+ screenInfo -> imageByteOrder, screenInfo -> bitmapBitOrder);
+
+ fprintf(stderr, "nxagentSetScreenInfo: Server scanline unit is [%d] scanline pad is [%d].\n",
+ screenInfo -> bitmapScanlineUnit, screenInfo -> bitmapScanlinePad);
+ #endif
+}
+
+void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
+{
+ int i;
+
+ /*
+ * Formats are created with no care of which are supported
+ * on the real display. Creating only formats supported
+ * by the remote end makes troublesome handling migration
+ * of session from a display to another.
+ */
+
+ screenInfo -> numPixmapFormats = nxagentNumPixmapFormats;
+
+ for (i = 0; i < nxagentNumPixmapFormats; i++)
+ {
+ screenInfo -> formats[i].depth = nxagentPixmapFormats[i].depth;
+ screenInfo -> formats[i].bitsPerPixel = nxagentPixmapFormats[i].bits_per_pixel;
+ screenInfo -> formats[i].scanlinePad = nxagentPixmapFormats[i].scanline_pad;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetPixmapFormats: Set format at index [%d] to depth [%d] "
+ "bits per pixel [%d] scanline pad [%d].\n", i,
+ screenInfo -> formats[i].depth, screenInfo -> formats[i].bitsPerPixel,
+ screenInfo -> formats[i].scanlinePad);
+ #endif
+ }
+}
+
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
+{
+ XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
+
+ if (nxagentIpaq)
+ {
+ XMapWindow(nxagentDisplay, nxagentIconWindow);
+ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+ DefaultScreen(nxagentDisplay));
+ }
+ else
+ {
+ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+ DefaultScreen(nxagentDisplay));
+ }
+}
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
+{
+ if (nxagentIpaq)
+ {
+ XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+
+ XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
+ }
+ else
+ {
+/*
+ XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+/*
+FIXME: We'll check for ReparentNotify and LeaveNotify events after XReparentWindow()
+ in order to avoid the session window is iconified.
+ We could avoid the sesssion window is iconified when a LeaveNotify event is received,
+ so this check would be unnecessary.
+*/
+ struct timeval timeout;
+ int i;
+ XEvent e;
+
+ XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
+ RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
+
+ for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+ #endif
+
+ if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
+ {
+ break;
+ }
+
+ XSync(nxagentDisplay, 0);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 50 * 1000;
+
+ nxagentWaitEvents(nxagentDisplay, &timeout);
+ }
+
+ XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+ DefaultScreen(nxagentDisplay));
+
+ while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
+/*
+ XMapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+ }
+}
+
+Window nxagentCreateIconWindow()
+{
+ XSetWindowAttributes attributes;
+ unsigned long valuemask;
+ char* window_name;
+ XTextProperty windowName;
+ XSizeHints sizeHints;
+ XWMHints wmHints;
+ Window w;
+ Mask mask;
+
+ /*
+ * Create icon window.
+ */
+
+ attributes.override_redirect = False;
+ attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+ attributes.background_pixmap = nxagentScreenSaverPixmap;
+ valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
+ #endif
+
+ w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ 0, 0, 1, 1, 0,
+ DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+ InputOutput,
+ DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+ valuemask, &attributes);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%lu].\n",
+ (long unsigned int)nxagentIconWindow);
+ #endif
+
+ /*
+ * Set hints to the window manager for the icon window.
+ */
+
+ window_name = nxagentWindowName;
+ XStringListToTextProperty(&window_name, 1, &windowName);
+ sizeHints.flags = PMinSize | PMaxSize;
+ sizeHints.min_width = sizeHints.max_width = 1;
+ sizeHints.min_height = sizeHints.max_height = 1;
+ wmHints.flags = IconPixmapHint | IconMaskHint;
+ wmHints.initial_state = IconicState;
+ wmHints.icon_pixmap = nxagentIconPixmap;
+
+ if (useXpmIcon)
+ {
+ wmHints.icon_mask = nxagentIconShape;
+ wmHints.flags = IconPixmapHint | IconMaskHint;
+ }
+ else
+ {
+ wmHints.flags = StateHint | IconPixmapHint;
+ }
+
+ XSetWMProperties(nxagentDisplay, w,
+ &windowName, &windowName,
+ NULL , 0 , &sizeHints, &wmHints, NULL);
+
+ /*
+ * Enable events from the icon window.
+ */
+
+ nxagentGetDefaultEventMask(&mask);
+
+ XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
+ KeyReleaseMask)) | StructureNotifyMask);
+
+ /*
+ * Notify to client if user closes icon window.
+ */
+
+ if (nxagentWMIsRunning && !nxagentOption(Rootless))
+ {
+ XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+ XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
+ }
+
+ return w;
+}
+
+Bool nxagentMagicPixelZone(int x, int y)
+{
+ return (x >= nxagentOption(Width) - 1 && y < 1);
+}
+
+void nxagentSetScreenSaverTime(void)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetScreenSaverTime: ScreenSaverTime was [%lu], ScreenSaverInterval was [%lu].\n",
+ (long unsigned int)ScreenSaverTime, (long unsigned int)ScreenSaverInterval);
+ #endif
+
+ /*
+ * More than one timeout could be used here,
+ * to make use of screen-saver handler not
+ * only for the timeout feature. In a case
+ * like this, the lower timeout have to be
+ * used as ScreenSaverTime.
+ */
+
+ if (nxagentAutoDisconnectTimeout > 0)
+ {
+ ScreenSaverTime = nxagentAutoDisconnectTimeout;
+ }
+
+ ScreenSaverInterval = ScreenSaverTime;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetScreenSaverTime: ScreenSaverTime now is [%lu], ScreenSaverInterval now is [%lu].\n",
+ (long unsigned int)ScreenSaverTime, (long unsigned int)ScreenSaverInterval);
+ #endif
+}
+
+static Bool nxagentSaveScreen(ScreenPtr pScreen, int what)
+{
+ #ifdef TEST
+ fprintf(stderr, "nxagentSaveScreen: Called for screen at [%p] with parameter [%d].\n",
+ (void *) pScreen, what);
+
+ fprintf(stderr, "nxagentSaveScreen: SCREEN_SAVER_ON is [%d] SCREEN_SAVER_OFF is [%d] "
+ "SCREEN_SAVER_FORCER is [%d] SCREEN_SAVER_CYCLE is [%d].\n",
+ SCREEN_SAVER_ON, SCREEN_SAVER_OFF, SCREEN_SAVER_FORCER,
+ SCREEN_SAVER_CYCLE);
+ #endif
+
+ /*
+ * We need only to reset the timeouts
+ * in this case.
+ */
+
+ if (what == SCREEN_SAVER_OFF)
+ {
+ nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+
+ return 1;
+ }
+
+ /*
+ * The lastDeviceEventTime is updated every time
+ * a device event is received, and it is used by
+ * WaitForSomething() to know when the SaveScreens()
+ * function should be called. This solution doesn't
+ * take care of a pointer button not released, so
+ * we have to handle this case by ourselves.
+ */
+
+/*
+FIXME: Do we need to check the key grab if the
+ autorepeat feature is disabled?
+*/
+ if (inputInfo.pointer -> button -> buttonsDown > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSaveScreen: Ignoring timeout, there is a pointer button down.\n");
+ #endif
+
+ /*
+ * Returning 0 the SaveScreens() function
+ * (which calls this one) tries to build
+ * a screen-saver creating a new window.
+ * We don't want this, so we return 1 in
+ * any case.
+ */
+
+ return 1;
+ }
+
+ /*
+ * Handling the auto-disconnect feature.
+ * If there is any client attached and the persisten-
+ * ce is allowed then leave the session running, else
+ * terminate it. It should use something less brutal,
+ * though raising a signal should ensure that the code
+ * follows the usual execution path.
+ */
+
+ if (nxagentOption(Timeout) > 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout was [%d].\n",
+ nxagentAutoDisconnectTimeout);
+ #endif
+
+ nxagentAutoDisconnectTimeout -= ScreenSaverTime;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout is [%d].\n",
+ nxagentAutoDisconnectTimeout);
+ #endif
+
+ if (nxagentSessionState == SESSION_UP &&
+ nxagentAutoDisconnectTimeout <= 0)
+ {
+ nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+
+ if (nxagentClients == 0)
+ {
+ fprintf(stderr, "Info: Terminating session with no client running.\n");
+
+ raise(SIGTERM);
+ }
+ else if (nxagentOption(Persistent) == 0)
+ {
+ fprintf(stderr, "Info: Terminating session with persistence not allowed.\n");
+
+ raise(SIGTERM);
+ }
+ else
+ {
+ fprintf(stderr, "Info: Suspending session with %d clients running.\n",
+ nxagentClients);
+
+ raise(SIGHUP);
+ }
+ }
+ }
+
+ return 1;
+}
+
+Bool nxagentCreateScreenResources(ScreenPtr pScreen)
+{
+ Bool ret;
+
+ CreatePixmapProcPtr savedCreatePixmap = pScreen->CreatePixmap;
+ ModifyPixmapHeaderProcPtr savedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
+
+ pScreen->CreatePixmap = fbCreatePixmap;
+ pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
+ ret = miCreateScreenResources(pScreen);
+
+ pScreen->CreatePixmap = savedCreatePixmap;
+ pScreen->ModifyPixmapHeader = savedModifyPixmapHeader;
+
+ return ret;
+}
+
+static Bool nxagentCursorOffScreen(ScreenPtr *pPtrScreen, int *x, int *y)
+{
+ return False;
+}
+
+static void nxagentCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static miPointerScreenFuncRec nxagentPointerCursorFuncs =
+{
+ nxagentCursorOffScreen,
+ nxagentCrossScreen,
+ miPointerWarpCursor
+};
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentInitViewportFrame(ScreenPtr pScreen, WindowPtr pRootWin)
+{
+ int error = Success;
+ VisualID visual = 0;
+ int i;
+ XID xid;
+
+ if (nxagentOption(Rootless))
+ {
+ return;
+ }
+
+ for (i = 0; i < pScreen -> numDepths; i++)
+ {
+ if (pScreen -> allowedDepths[i].depth == pRootWin -> drawable.depth)
+ {
+ visual = pScreen -> allowedDepths[i].vids[0];
+ break;
+ }
+ }
+
+ /*
+ * It is not necessary create the windows on the real X server. But this
+ * windows are not visible. Create them it is not a great effort, and avoids
+ * many errors.
+ *
+ * nxagentScreenTrap = True;
+ */
+
+ xid = FakeClientID(serverClient -> index);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+ #endif
+
+ nxagentViewportFrameLeft = CreateWindow(xid, pRootWin, -NXAGENT_FRAME_WIDTH, 0, NXAGENT_FRAME_WIDTH,
+ pRootWin -> drawable.height,
+ 0, InputOutput, 0, NULL,
+ pRootWin -> drawable.depth,
+ serverClient, visual, &error);
+
+ AddResource(xid, RT_WINDOW, (void *) nxagentViewportFrameLeft);
+
+ if (error != Success)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameLeft.\n");
+ #endif
+
+ error = Success;
+ }
+
+ xid = FakeClientID(serverClient -> index);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+ #endif
+
+ nxagentViewportFrameRight = CreateWindow(xid, pRootWin, pRootWin -> drawable.width, 0,
+ NXAGENT_FRAME_WIDTH,
+ pRootWin -> drawable.height,
+ 0, InputOutput, 0, NULL,
+ pRootWin -> drawable.depth,
+ serverClient, visual,
+ &error);
+
+ AddResource(xid, RT_WINDOW, (void *) nxagentViewportFrameRight);
+
+ if (error != Success)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameRight.\n");
+ #endif
+
+ error = Success;
+ }
+
+ xid = FakeClientID(serverClient -> index);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+ #endif
+
+ nxagentViewportFrameAbove = CreateWindow(xid, pRootWin, 0, -NXAGENT_FRAME_WIDTH,
+ pRootWin -> drawable.width,
+ NXAGENT_FRAME_WIDTH, 0,
+ InputOutput, 0, NULL,
+ pRootWin -> drawable.depth,
+ serverClient, visual,
+ &error);
+
+ AddResource(xid, RT_WINDOW, (void *) nxagentViewportFrameAbove);
+
+ if (error != Success)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameAbove.\n");
+ #endif
+
+ error = Success;
+ }
+
+ xid = FakeClientID(serverClient -> index);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+ #endif
+
+ nxagentViewportFrameBelow = CreateWindow(xid, pRootWin, 0,
+ pRootWin -> drawable.height,
+ pRootWin -> drawable.width,
+ NXAGENT_FRAME_WIDTH, 0,
+ InputOutput, 0, NULL,
+ pRootWin -> drawable.depth,
+ serverClient, visual, &error);
+
+ AddResource(xid, RT_WINDOW, (void *) nxagentViewportFrameBelow);
+
+ if (error != Success)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameBelow.\n");
+ #endif
+ }
+
+ nxagentViewportFrameLeft -> overrideRedirect = 1;
+ nxagentViewportFrameRight -> overrideRedirect = 1;
+ nxagentViewportFrameAbove -> overrideRedirect = 1;
+ nxagentViewportFrameBelow -> overrideRedirect = 1;
+
+ MapWindow(nxagentViewportFrameLeft, serverClient);
+ MapWindow(nxagentViewportFrameRight, serverClient);
+ MapWindow(nxagentViewportFrameAbove, serverClient);
+ MapWindow(nxagentViewportFrameBelow, serverClient);
+
+ /*
+ * nxagentScreenTrap = False;
+ */
+}
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentPrintAgentGeometry(char *hdrMessage, char *prefix)
+{
+ #ifdef WARNING
+
+ if (prefix == NULL)
+ {
+ prefix = "";
+ }
+
+ if (hdrMessage)
+ {
+ fprintf(stderr, "--------------- %s -----------------.\n", hdrMessage);
+ }
+
+ fprintf(stderr, "%s Root window at offset (%d,%d) size (%d,%d).\n", prefix,
+ nxagentOption(RootX), nxagentOption(RootY),
+ nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+ fprintf(stderr, "%s Default window at offset (%d,%d) size (%d,%d) border size %d.\n", prefix,
+ nxagentOption(X), nxagentOption(Y), nxagentOption(Width), nxagentOption(Height),
+ nxagentOption(BorderWidth));
+
+ fprintf(stderr, "%s Span between root window and default window is (%d,%d).\n", prefix,
+ nxagentOption(ViewportXSpan), nxagentOption(ViewportYSpan));
+
+ fprintf(stderr, "%s Default window in window mode has offset (%d,%d) and size (%d,%d).\n", prefix,
+ nxagentOption(SavedX), nxagentOption(SavedY), nxagentOption(SavedWidth), nxagentOption(SavedHeight));
+
+ fprintf(stderr, "%s Fullscreen is %s.\n", prefix,
+ nxagentOption(Fullscreen) ? "ON" : "OFF");
+
+ fprintf(stderr, "%s Desktop resize mode is %s.\n", prefix,
+ nxagentOption(DesktopResize) ? "ON" : "OFF");
+
+ fprintf(stderr, "%s Resize desktop at startup is %s.\n", prefix,
+ nxagentResizeDesktopAtStartup ? "ON" : "OFF");
+
+ #endif
+}
+
+static int nxagentColorOffset(unsigned long mask)
+{
+ int count;
+
+ for (count = 0; !(mask & 1) && count < 32; count++)
+ {
+ mask >>= 1;
+ }
+
+ return count;
+}
+
+Bool nxagentOpenScreen(ScreenPtr pScreen,
+ int argc, char *argv[])
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int numVisuals, numDepths;
+ int i, j, depthIndex;
+ unsigned long valuemask;
+ XSetWindowAttributes attributes;
+ XWindowAttributes gattributes;
+ XSizeHints sizeHints;
+ XWMHints wmHints;
+ Mask mask;
+ Bool resetAgentPosition = False;
+
+ VisualID defaultVisual;
+ int rootDepth;
+
+ void * pFrameBufferBits;
+ int bitsPerPixel;
+ int sizeInBytes;
+
+ int defaultVisualIndex = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Called for screen index [%d].\n",
+ pScreen->myNum);
+ #endif
+
+ if (nxagentRenderEnable && nxagentReconnectTrap == False)
+ {
+ PictureScreenPrivateIndex = -1;
+ }
+
+ nxagentDefaultScreen = pScreen;
+
+ nxagentQueryAtoms(pScreen);
+
+ #ifdef NXAGENT_ONSTART
+ nxagentWMStart = nxagentAtoms[3]; /* WM_NX_READY */
+ #endif
+
+ /*
+ * Forced geometry parameter
+ * to user geometry.
+ */
+
+ if (nxagentResizeDesktopAtStartup)
+ {
+ if (nxagentUserGeometry.flag & XValue)
+ {
+ nxagentChangeOption(X, nxagentUserGeometry.X);
+ }
+
+ if (nxagentUserGeometry.flag & YValue)
+ {
+ nxagentChangeOption(Y, nxagentUserGeometry.Y);
+ }
+
+ if (nxagentUserGeometry.flag & WidthValue)
+ {
+ nxagentChangeOption(Width, nxagentUserGeometry.Width);
+ nxagentChangeOption(RootWidth, nxagentUserGeometry.Width);
+
+ if (nxagentOption(SavedWidth) > nxagentUserGeometry.Width)
+ {
+ nxagentChangeOption(SavedWidth, nxagentUserGeometry.Width);
+ }
+ }
+
+ if (nxagentUserGeometry.flag & HeightValue)
+ {
+ nxagentChangeOption(Height, nxagentUserGeometry.Height);
+ nxagentChangeOption(RootHeight, nxagentUserGeometry.Height);
+
+ if (nxagentOption(SavedHeight) > nxagentUserGeometry.Height)
+ {
+ nxagentChangeOption(SavedHeight, nxagentUserGeometry.Height);
+ }
+ }
+ }
+
+ /*
+ * This is first time the
+ * screen is initialized.
+ * Filling the geometry parameter
+ * from user geometry.
+ */
+
+ if (nxagentReconnectTrap == False)
+ {
+ if (nxagentUserGeometry.flag & XValue)
+ {
+ nxagentChangeOption(X, nxagentUserGeometry.X);
+ }
+
+ if (nxagentUserGeometry.flag & YValue)
+ {
+ nxagentChangeOption(Y, nxagentUserGeometry.Y);
+ }
+
+ if (nxagentUserGeometry.flag & WidthValue)
+ {
+ nxagentChangeOption(RootWidth, nxagentUserGeometry.Width);
+ }
+
+ if (nxagentUserGeometry.flag & HeightValue)
+ {
+ nxagentChangeOption(RootHeight, nxagentUserGeometry.Height);
+ }
+ }
+ else if (nxagentWMIsRunning && !nxagentOption(Rootless) && !nxagentOption(Fullscreen))
+ {
+ /*
+ * At reconnection, try to estimate the shift due to WM reparenting.
+ */
+
+ if (nxagentOption(X) >= 6)
+ {
+ nxagentChangeOption(X, nxagentOption(X) - 6);
+ }
+
+ if (nxagentOption(Y) >= 25)
+ {
+ nxagentChangeOption(Y, nxagentOption(Y) - 25);
+ }
+ }
+
+ /*
+ * Determine the size of the root window.
+ * It is the maximum size of the screen
+ * if we are either in rootless or in
+ * fullscreen mode.
+ */
+
+ if (nxagentOption(Rootless) == False && nxagentWMIsRunning == False)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Forcing fullscreen mode with no window manager running.\n");
+ #endif
+
+ nxagentChangeOption(Fullscreen, True);
+
+ if (nxagentOption(ClientOs) == ClientOsWinnt &&
+ (nxagentReconnectTrap == False || nxagentResizeDesktopAtStartup))
+ {
+ NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
+ }
+ }
+
+ if (nxagentOption(Fullscreen) &&
+ nxagentWMIsRunning &&
+ nxagentReconnectTrap &&
+ nxagentResizeDesktopAtStartup == False &&
+ nxagentXServerGeometryChanged())
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Forcing window mode with server geometry changed.\n");
+ #endif
+
+ nxagentChangeOption(Fullscreen, False);
+
+ nxagentChangeOption(AllScreens, False);
+
+ nxagentFullscreenWindow = 0;
+
+ resetAgentPosition = True;
+ }
+
+ if (nxagentOption(Fullscreen))
+ {
+ nxagentChangeOption(X, 0);
+ nxagentChangeOption(Y, 0);
+
+ nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+ nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+ nxagentChangeOption(BorderWidth, 0);
+
+ if (nxagentReconnectTrap == False || nxagentResizeDesktopAtStartup)
+ {
+ nxagentChangeOption(RootWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+ nxagentChangeOption(RootHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+ if (nxagentOption(RootWidth) > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+ {
+ nxagentChangeOption(SavedWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+ }
+ else
+ {
+ nxagentChangeOption(SavedWidth, nxagentOption(RootWidth));
+ }
+
+ if (nxagentOption(RootHeight) > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+ {
+ nxagentChangeOption(SavedHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+ }
+ else
+ {
+ nxagentChangeOption(SavedHeight, nxagentOption(RootHeight));
+ }
+ }
+
+ nxagentChangeOption(RootX, ((WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+ nxagentOption(RootWidth)) / 2));
+ nxagentChangeOption(RootY, ((HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+ nxagentOption(RootHeight)) / 2));
+ }
+ else
+ {
+ nxagentChangeOption(BorderWidth, 0);
+
+ if (nxagentReconnectTrap == False)
+ {
+ nxagentChangeOption(RootX, 0);
+ nxagentChangeOption(RootY, 0);
+
+ nxagentChangeOption(Width, nxagentOption(RootWidth));
+ nxagentChangeOption(Height, nxagentOption(RootHeight));
+ }
+
+ /*
+ * Be sure that the agent window won't be bigger
+ * than the root window.
+ */
+
+ if (nxagentOption(Width) > nxagentOption(RootWidth))
+ {
+ nxagentChangeOption(Width, nxagentOption(RootWidth));
+ }
+
+ if (nxagentOption(Height) > nxagentOption(RootHeight))
+ {
+ nxagentChangeOption(Height, nxagentOption(RootHeight));
+ }
+
+ /*
+ * Be sure that the agent window won't be bigger
+ * than the X server root window.
+ */
+
+ if (nxagentOption(Width) > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+ {
+ nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+ }
+
+ if (nxagentOption(Height) > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+ {
+ nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+ }
+
+ /*
+ * Forcing the agent window geometry to be equal to
+ * the root window geometry the first time the
+ * screen is initialized if the geometry hasn't been
+ * esplicitly set in the option file and if
+ * the root window isn't bigger than the X server
+ * root window..
+ */
+
+ if (nxagentReconnectTrap == False)
+ {
+ if ((nxagentOption(RootWidth) < WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))) &&
+ !(nxagentUserGeometry.flag & WidthValue))
+ {
+ nxagentChangeOption(Width, nxagentOption(RootWidth));
+ }
+
+ if ((nxagentOption(RootHeight) < HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))) &&
+ !(nxagentUserGeometry.flag & HeightValue))
+ {
+ nxagentChangeOption(Height, nxagentOption(RootHeight));
+ }
+ }
+
+ if (resetAgentPosition)
+ {
+ nxagentChangeOption(X, ((WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+ nxagentOption(Width)) / 2));
+
+ nxagentChangeOption(Y, ((HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+ nxagentOption(Height)) / 2));
+ }
+
+ nxagentChangeOption(SavedWidth, nxagentOption(RootWidth));
+ nxagentChangeOption(SavedHeight, nxagentOption(RootHeight));
+ }
+
+ if (nxagentOption(Rootless))
+ {
+ nxagentChangeOption(RootWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+ nxagentChangeOption(RootHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+ }
+
+ nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+ nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+ nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+ nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+ if (nxagentReconnectTrap == 0)
+ {
+ if (nxagentOption(Persistent))
+ {
+ nxagentArgc = argc;
+ nxagentArgv = argv;
+ }
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ {
+ extern unsigned long startTime;
+
+ fprintf(stderr, "Screen: going to open screen, time is [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+
+ #endif
+
+ /*
+ * Initialize all our privates.
+ */
+
+ if (AllocateWindowPrivate(pScreen, nxagentWindowPrivateIndex, sizeof(nxagentPrivWindowRec)) == 0 ||
+ AllocateGCPrivate(pScreen, nxagentGCPrivateIndex, sizeof(nxagentPrivGC)) == 0 ||
+ AllocateClientPrivate(nxagentClientPrivateIndex, sizeof(PrivClientRec)) == 0 ||
+ AllocatePixmapPrivate(pScreen, nxagentPixmapPrivateIndex, sizeof(nxagentPrivPixmapRec)) == 0)
+ {
+ return False;
+ }
+
+ /*
+ * Initialize the depths.
+ */
+
+ depths = (DepthPtr) malloc(nxagentNumDepths * sizeof(DepthRec));
+
+ for (i = 0; i < nxagentNumDepths; i++)
+ {
+ depths[i].depth = nxagentDepths[i];
+ depths[i].numVids = 0;
+ depths[i].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+ }
+
+ /*
+ * Initialize the visuals.
+ */
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Setting up visuals. Original array has size "
+ "[%d].\n", nxagentNumVisuals);
+ #endif
+
+ numVisuals = 0;
+ numDepths = nxagentNumDepths;
+
+ visuals = (VisualPtr) malloc(nxagentNumVisuals * sizeof(VisualRec));
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ visuals[numVisuals].vid = FakeClientID(0);
+ visuals[numVisuals].class = nxagentVisuals[i].class;
+ visuals[numVisuals].bitsPerRGBValue = nxagentVisuals[i].bits_per_rgb;
+ visuals[numVisuals].ColormapEntries = nxagentVisuals[i].colormap_size;
+ visuals[numVisuals].nplanes = nxagentVisuals[i].depth;
+ visuals[numVisuals].redMask = nxagentVisuals[i].red_mask;
+ visuals[numVisuals].greenMask = nxagentVisuals[i].green_mask;
+ visuals[numVisuals].blueMask = nxagentVisuals[i].blue_mask;
+ visuals[numVisuals].offsetRed = nxagentColorOffset(nxagentVisuals[i].red_mask);
+ visuals[numVisuals].offsetGreen = nxagentColorOffset(nxagentVisuals[i].green_mask);
+ visuals[numVisuals].offsetBlue = nxagentColorOffset(nxagentVisuals[i].blue_mask);
+
+ /*
+ * Check for and remove the duplicates.
+ */
+
+ if (i == nxagentDefaultVisualIndex)
+ {
+ defaultVisualIndex = numVisuals;
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Set default visual index [%d].\n" ,
+ defaultVisualIndex);
+ #endif
+ }
+ else
+ {
+ for (j = 0; j < numVisuals; j++)
+ {
+ if (visuals[numVisuals].class == visuals[j].class &&
+ visuals[numVisuals].bitsPerRGBValue ==
+ visuals[j].bitsPerRGBValue &&
+ visuals[numVisuals].ColormapEntries ==
+ visuals[j].ColormapEntries &&
+ visuals[numVisuals].nplanes == visuals[j].nplanes &&
+ visuals[numVisuals].redMask == visuals[j].redMask &&
+ visuals[numVisuals].greenMask == visuals[j].greenMask &&
+ visuals[numVisuals].blueMask == visuals[j].blueMask &&
+ visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
+ visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
+ visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
+ break;
+ }
+
+ if (j < numVisuals)
+ continue;
+
+ }
+
+ depthIndex = UNDEFINED;
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Added visual [%lu].\n" ,
+ (long unsigned int)visuals[numVisuals].vid);
+ #endif
+
+ for (j = 0; j < numDepths; j++)
+ {
+ if (depths[j].depth == nxagentVisuals[i].depth)
+ {
+ depthIndex = j;
+ break;
+ }
+ }
+
+ if (depthIndex == UNDEFINED)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentOpenScreen: WARNING! Can't find a matching depth for visual depth [%d].\n",
+ nxagentVisuals[i].depth);
+ #endif
+
+ depthIndex = numDepths;
+
+ depths[depthIndex].depth = nxagentVisuals[i].depth;
+ depths[depthIndex].numVids = 0;
+ depths[depthIndex].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+
+ numDepths++;
+ }
+
+ if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH)
+ {
+ FatalError("Visual table overflow");
+ }
+
+ depths[depthIndex].vids[depths[depthIndex].numVids] = visuals[numVisuals].vid;
+
+ depths[depthIndex].numVids++;
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Registered visual [%lu] for depth [%d (%d)].\n" ,
+ (long unsigned int)visuals[numVisuals].vid, depthIndex,
+ depths[depthIndex].depth);
+ #endif
+
+ numVisuals++;
+ }
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "Debug: Setting default visual [%d (%lu)].\n",
+ defaultVisualIndex, (long unsigned int)visuals[defaultVisualIndex].vid);
+
+ fprintf(stderr, "Debug: Setting root depth [%d].\n",
+ visuals[defaultVisualIndex].nplanes);
+ #endif
+
+ defaultVisual = visuals[defaultVisualIndex].vid;
+ rootDepth = visuals[defaultVisualIndex].nplanes;
+
+ nxagentInitAlphaVisual();
+
+ bitsPerPixel = nxagentBitsPerPixel(rootDepth);
+
+ if (bitsPerPixel == 1)
+ {
+ sizeInBytes = PixmapBytePad(nxagentOption(RootWidth), rootDepth) * nxagentOption(RootHeight);
+ }
+ else
+ {
+ sizeInBytes = PixmapBytePad(nxagentOption(RootWidth), rootDepth) * nxagentOption(RootHeight) * bitsPerPixel/8;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Frame buffer allocated. rootDepth "
+ "[%d] bitsPerPixel [%d] sizeInBytes [%d]\n", rootDepth, bitsPerPixel, sizeInBytes);
+ #endif
+
+ pFrameBufferBits = (char *) malloc(sizeInBytes);
+
+ if (!pFrameBufferBits)
+ {
+ return FALSE;
+ }
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "nxagentOpenScreen: Before fbScreenInit numVisuals [%d] numDepths [%d] "
+ "rootDepth [%d] defaultVisual [%lu].\n", numVisuals, numDepths,
+ rootDepth, (long unsigned int)defaultVisual);
+ #endif
+
+ if (monitorResolution < 1)
+ {
+ monitorResolution = NXAGENT_DEFAULT_DPI;
+ }
+
+ if (!fbScreenInit(pScreen, pFrameBufferBits, nxagentOption(RootWidth), nxagentOption(RootHeight),
+ monitorResolution, monitorResolution, PixmapBytePad(nxagentOption(RootWidth), rootDepth), bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "nxagentOpenScreen: After fbScreenInit numVisuals [%d] numDepths [%d] "
+ "rootDepth [%d] defaultVisual [%lu].\n", numVisuals, numDepths,
+ rootDepth, (long unsigned int)defaultVisual);
+ #endif
+
+ /*
+ * Complete the initialization of the GLX
+ * extension. This will add the GLX visuals
+ * and will modify numVisuals and numDepths.
+ */
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "nxagentOpenScreen: Before GLX numVisuals [%d] numDepths [%d] "
+ "rootDepth [%d] defaultVisual [%lu].\n", numVisuals, numDepths,
+ rootDepth, (long unsigned int)defaultVisual);
+ #endif
+
+ nxagentInitGlxExtension(&visuals, &depths, &numVisuals, &numDepths,
+ &rootDepth, &defaultVisual);
+
+ #if defined(DEBUG) || defined(DEBUG_COLORMAP)
+ fprintf(stderr, "nxagentOpenScreen: After GLX numVisuals [%d] numDepths [%d] "
+ "rootDepth [%d] defaultVisual [%lu].\n", numVisuals, numDepths,
+ rootDepth, (long unsigned int)defaultVisual);
+ #endif
+
+ /*
+ * Replace the visuals and depths initialized
+ * by fbScreenInit with our own.
+ */
+
+ free(pScreen -> visuals);
+ free(pScreen -> allowedDepths);
+
+ pScreen -> visuals = visuals;
+ pScreen -> allowedDepths = depths;
+ pScreen -> numVisuals = numVisuals;
+ pScreen -> numDepths = numDepths;
+ pScreen -> rootVisual = defaultVisual;
+ pScreen -> rootDepth = rootDepth;
+
+ /*
+ * Complete the initialization of the RANDR
+ * extension.
+ */
+
+ nxagentInitRandRExtension(pScreen);
+
+ /*
+ * Set up the internal structures used for
+ * tracking the proxy resources associated
+ * to the unpack and split operations.
+ */
+
+ nxagentInitSplitResources();
+ nxagentInitUnpackResources();
+
+ /*
+ * Initializing the pixmaps that will serve as
+ * "placeholders" in lazy encoding. We need one
+ * pixmap for each depth.
+ */
+
+ for (i = 0; i < numDepths; i++)
+ {
+ nxagentMarkPlaceholderNotLoaded(i);
+ }
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenScreen: Watchpoint 7.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+N/A
+*/
+
+ sleep(30);
+
+ #endif
+
+ if (nxagentParentWindow != 0)
+ {
+ /*
+ * This would cause a GetWindowAttributes
+ * and a GetGeometry (asynchronous) reply.
+ */
+
+ XGetWindowAttributes(nxagentDisplay, nxagentParentWindow, &gattributes);
+
+ nxagentChangeOption(Width, gattributes.width);
+ nxagentChangeOption(Height, gattributes.height);
+ }
+
+ if (nxagentOption(AllScreens))
+ {
+ attributes.override_redirect = True;
+ }
+
+ if (nxagentOption(Fullscreen))
+ {
+ /*
+ * We need to disable the host's screensaver or
+ * it will otherwise grab the screen even if it
+ * is under agent's control.
+ */
+
+ XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+ }
+
+ if (nxagentTrue24)
+ {
+ fbGetScreenPrivate(pScreen) -> win32bpp = visuals[nxagentDefaultVisualIndex].nplanes;
+ fbGetScreenPrivate(pScreen) -> pix32bpp = visuals[nxagentDefaultVisualIndex].nplanes;
+ }
+ else
+ {
+ fbGetScreenPrivate(pScreen) -> win32bpp = 32;
+ fbGetScreenPrivate(pScreen) -> pix32bpp = 32;
+ }
+
+ /*
+ * We call miScreenInit with NULL in place of the screen area if we
+ * don't want to initialize the frame buffer.
+ *
+ * if (!miScreenInit(pScreen, NULL, nxagentOption(RootWidth),
+ * nxagentOption(RootHeight), 1, 1, nxagentOption(RootWidth),
+ * visuals[nxagentDefaultVisualIndex].nplanes, / * Root depth. * /
+ * numDepths, depths,
+ * visuals[nxagentDefaultVisualIndex].vid,* Root visual. * /
+ * numVisuals, visuals))
+ * return FALSE;
+ */
+
+ pScreen->defColormap = (Colormap) FakeClientID(0);
+ pScreen->minInstalledCmaps = MINCMAPS;
+ pScreen->maxInstalledCmaps = MAXCMAPS;
+
+ pScreen->whitePixel = nxagentWhitePixel;
+ pScreen->blackPixel = nxagentBlackPixel;
+ /* rgf */
+ /* GCperDepth */
+ /* PixmapPerDepth */
+ /* WindowPrivateLen */
+ /* WindowPrivateSizes */
+ /* totalWindowSize */
+ /* GCPrivateLen */
+ /* GCPrivateSizes */
+ /* totalGCSize */
+
+ /*
+ * Random screen procedures.
+ */
+
+ pScreen->CloseScreen = nxagentCloseScreen;
+ pScreen->QueryBestSize = nxagentQueryBestSize;
+ pScreen->SaveScreen = nxagentSaveScreen;
+ pScreen->GetImage = nxagentGetImage;
+ pScreen->GetSpans = nxagentGetSpans;
+ pScreen->PointerNonInterestBox = (void (*)()) 0;
+ pScreen->SourceValidate = (void (*)()) 0;
+
+ pScreen->CreateScreenResources = nxagentCreateScreenResources;
+
+ /*
+ * Window Procedures.
+ *
+ * Note that the following functions are not
+ * replaced with nxagent counterparts:
+ *
+ * ValidateTreeProcPtr ValidateTree;
+ * ClearToBackgroundProcPtr ClearToBackground;
+ *
+ * Note also that the ConfigureWindow procedure
+ * has not a pointer in the screen structure.
+ */
+
+ pScreen->CreateWindow = nxagentCreateWindow;
+ pScreen->DestroyWindow = nxagentDestroyWindow;
+ pScreen->PositionWindow = nxagentPositionWindow;
+ pScreen->ChangeWindowAttributes = nxagentChangeWindowAttributes;
+ pScreen->RealizeWindow = nxagentRealizeWindow;
+ pScreen->UnrealizeWindow = nxagentUnrealizeWindow;
+ pScreen->PostValidateTree = nxagentPostValidateTree;
+ pScreen->WindowExposures = nxagentWindowExposures;
+ pScreen->PaintWindowBackground = nxagentPaintWindowBackground;
+ pScreen->PaintWindowBorder = nxagentPaintWindowBorder;
+ pScreen->CopyWindow = nxagentCopyWindow;
+ pScreen->ClipNotify = nxagentClipNotify;
+ pScreen->RestackWindow = nxagentRestackWindow;
+ pScreen->ReparentWindow = nxagentReparentWindow;
+
+ /*
+ * Pixmap procedures.
+ */
+
+ pScreen->CreatePixmap = nxagentCreatePixmap;
+ pScreen->DestroyPixmap = nxagentDestroyPixmap;
+
+ /*
+ * This is originally miModifyPixmapHeader()
+ * from miscrinit.c. It is used to recycle
+ * the scratch pixmap for this screen.
+ */
+
+ pScreen->ModifyPixmapHeader = nxagentModifyPixmapHeader;
+
+ /*
+ * Font procedures.
+ */
+
+ pScreen->RealizeFont = nxagentRealizeFont;
+ pScreen->UnrealizeFont = nxagentUnrealizeFont;
+
+ /*
+ * GC procedures.
+ */
+
+ pScreen->CreateGC = nxagentCreateGC;
+ pScreen->BitmapToRegion = nxagentPixmapToRegion;
+
+ /*
+ * Colormap procedures.
+ */
+
+ pScreen->CreateColormap = nxagentCreateColormap;
+ pScreen->DestroyColormap = nxagentDestroyColormap;
+ pScreen->InstallColormap = nxagentInstallColormap;
+ pScreen->UninstallColormap = nxagentUninstallColormap;
+ pScreen->ListInstalledColormaps = nxagentListInstalledColormaps;
+ pScreen->StoreColors = nxagentStoreColors;
+ pScreen->ResolveColor = nxagentResolveColor;
+
+ /*
+ * Backing store procedures.
+ */
+
+ pScreen->SaveDoomedAreas = (void (*)()) 0;
+ pScreen->RestoreAreas = (RegionPtr (*)()) 0;
+ pScreen->ExposeCopy = (void (*)()) 0;
+ pScreen->TranslateBackingStore = (RegionPtr (*)()) 0;
+ pScreen->ClearBackingStore = (RegionPtr (*)()) 0;
+ pScreen->DrawGuarantee = (void (*)()) 0;
+
+ if (enableBackingStore == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Going to initialize backing store.\n");
+ #endif
+
+ pScreen -> BackingStoreFuncs.SaveAreas = nxagentSaveAreas;
+ pScreen -> BackingStoreFuncs.RestoreAreas = nxagentRestoreAreas;
+ pScreen -> BackingStoreFuncs.SetClipmaskRgn = 0;
+ pScreen -> BackingStoreFuncs.GetImagePixmap = 0;
+ pScreen -> BackingStoreFuncs.GetSpansPixmap = 0;
+
+ miInitializeBackingStore(pScreen);
+ }
+
+ /*
+ * OS layer procedures.
+ */
+
+ pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
+ pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
+ pScreen->blockData = NULL;
+ pScreen->wakeupData = NULL;
+
+ #ifdef RENDER
+
+ /*
+ * Initialize picture support. This have to be
+ * placed here because miDCInitialize calls
+ * DamageSetup, that should wrap the picture
+ * screen functions. So PictureInit has to be
+ * called before.
+ */
+
+ if (nxagentRenderEnable && !nxagentReconnectTrap)
+ {
+ if (!nxagentPictureInit(pScreen, 0, 0))
+ {
+ nxagentRenderEnable = False;
+
+ return FALSE;
+ }
+
+ if (nxagentAlphaEnabled)
+ {
+ fprintf(stderr, "Info: Using alpha channel in render extension.\n");
+ }
+ }
+
+ #endif /* RENDER */
+
+ /*
+ * From misprite.c: called from device-dependent screen
+ * initialization proc after all of the function pointers
+ * have been stored in the screen structure.
+ */
+
+ miDCInitialize(pScreen, &nxagentPointerCursorFuncs);
+
+ /*
+ * Cursor Procedures.
+ */
+
+ pScreen->ConstrainCursor = nxagentConstrainCursor;
+ pScreen->CursorLimits = nxagentCursorLimits;
+ pScreen->DisplayCursor = nxagentDisplayCursor;
+ pScreen->RealizeCursor = nxagentRealizeCursor;
+ pScreen->UnrealizeCursor = nxagentUnrealizeCursor;
+ pScreen->RecolorCursor = nxagentRecolorCursor;
+
+ nxagentSetCursorPositionW = pScreen->SetCursorPosition;
+
+ pScreen->SetCursorPosition = nxagentSetCursorPosition;
+
+ #define POSITION_OFFSET (pScreen->myNum * (nxagentOption(Width) + \
+ nxagentOption(Height)) / 32)
+ }
+
+ #ifdef TEST
+ nxagentPrintAgentGeometry(NULL, "nxagentOpenScreen:");
+ #endif
+
+ if (nxagentDoFullGeneration == 1 ||
+ nxagentReconnectTrap == 1)
+ {
+ valuemask = CWBackPixel | CWEventMask | CWColormap |
+ (nxagentOption(AllScreens) == 1 ? CWOverrideRedirect : 0);
+
+ attributes.background_pixel = nxagentBlackPixel;
+
+ /* Assume that the mask fits in int... broken on Big Endian 64bit systems. */
+ Mask tmp_mask = attributes.event_mask;
+ nxagentGetDefaultEventMask(&tmp_mask);
+ attributes.event_mask = (int)tmp_mask;
+
+ attributes.colormap = nxagentDefaultVisualColormap(nxagentDefaultVisual(pScreen));
+
+ if (nxagentOption(AllScreens) == 1)
+ {
+ attributes.override_redirect = True;
+ }
+
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ if (nxagentReconnectTrap)
+ {
+ /*
+ * We need to disable the host's screensaver or
+ * it will otherwise grab the screen even if it
+ * is under agent's control.
+ */
+
+ XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+ }
+ }
+
+ /*
+ * This would be used when running agent
+ * embedded into another X window.
+ */
+
+ if (nxagentParentWindow != 0)
+ {
+ nxagentDefaultWindows[pScreen->myNum] = nxagentParentWindow;
+
+ nxagentGetDefaultEventMask(&mask);
+
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], mask);
+ }
+ else
+ {
+ /*
+ * Create any top-level window as a child of the
+ * real root of the remote display. See also the
+ * InitRootWindow() procedure and the function
+ * handling the splash screen.
+ */
+
+ if (nxagentOption(Rootless) == True)
+ {
+ nxagentDefaultWindows[pScreen->myNum] = DefaultRootWindow(nxagentDisplay);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Using root window id [%ld].\n",
+ (long int)nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Going to create new default window.\n");
+ #endif
+
+ nxagentDefaultWindows[pScreen->myNum] =
+ XCreateWindow(nxagentDisplay,
+ DefaultRootWindow(nxagentDisplay),
+ nxagentOption(X) + POSITION_OFFSET,
+ nxagentOption(Y) + POSITION_OFFSET,
+ nxagentOption(Width),
+ nxagentOption(Height),
+ nxagentOption(BorderWidth),
+ pScreen->rootDepth,
+ InputOutput,
+ nxagentDefaultVisual(pScreen),
+ valuemask, &attributes);
+
+ if (nxagentOption(Rootless) == 0)
+ {
+ valuemask = CWEventMask;
+ mask = PointerMotionMask;
+ attributes.event_mask = mask;
+
+ nxagentInputWindows[pScreen -> myNum] =
+ XCreateWindow(nxagentDisplay,
+ nxagentDefaultWindows[pScreen -> myNum],
+ 0, 0,
+ nxagentOption(Width),
+ nxagentOption(Height),
+ 0, 0, InputOnly,
+ nxagentDefaultVisual(pScreen),
+ valuemask , &attributes);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Created new default window with id [%ld].\n",
+ (long int)nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+
+ /*
+ * Setting WM_CLASS to "X2GoAgent" when running in X2Go Agent mode
+ * we need it to properly display all window parameters by some WMs
+ * (for example on Maemo)
+ */
+ if(nxagentX2go)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Setting WM_CLASS and WM_NAME for window withid [%ld].\n",
+ (long int)nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+ XClassHint hint;
+ hint.res_name=malloc(strlen("X2GoAgent")+1);
+ hint.res_class=malloc(strlen("X2GoAgent")+1);
+ strcpy(hint.res_name,"X2GoAgent");
+ strcpy(hint.res_class,"X2GoAgent");
+ XSetClassHint(nxagentDisplay,nxagentDefaultWindows[pScreen->myNum],&hint);
+ free(hint.res_name);
+ free(hint.res_class);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Setting WM_CLASS and WM_NAME for window withid [%ld].\n",
+ (long int)nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+
+ XClassHint hint;
+ hint.res_name=malloc(strlen("NXAgent")+1);
+ hint.res_class=malloc(strlen("NXAgent")+1);
+ strcpy(hint.res_name,"NXAgent");
+ strcpy(hint.res_class,"NXAgent");
+ XSetClassHint(nxagentDisplay,nxagentDefaultWindows[pScreen->myNum],&hint);
+ free(hint.res_name);
+ free(hint.res_class);
+ }
+
+
+ if (nxagentOption(Fullscreen))
+ {
+ nxagentFullscreenWindow = nxagentDefaultWindows[pScreen->myNum];
+ }
+
+ if (nxagentIpaq)
+ {
+ XWindowChanges ch;
+ unsigned int ch_mask;
+
+ ch.stack_mode = Below;
+ ch_mask = CWStackMode;
+
+ XConfigureWindow(nxagentDisplay, nxagentFullscreenWindow, ch_mask, &ch);
+ }
+ }
+
+ if (nxagentOption(Fullscreen))
+ {
+ /*
+ * FIXME: Do we still need to set this property?
+ */
+
+ if (nxagentAtoms[8] != 0)
+ {
+ XChangeProperty(nxagentDisplay,
+ nxagentDefaultWindows[pScreen->myNum],
+ nxagentAtoms[8], /* NX_AGENT_SIGNATURE */
+ XA_STRING,
+ 8,
+ PropModeReplace,
+ (unsigned char*) "X-AGENT",
+ strlen("X-AGENT"));
+ }
+
+ nxagentGetDefaultEventMask(&mask);
+
+ XSelectInput(nxagentDisplay, nxagentFullscreenWindow, mask);
+ }
+
+ sizeHints.flags = PPosition | PMinSize | PMaxSize;
+ sizeHints.x = nxagentOption(X) + POSITION_OFFSET;
+ sizeHints.y = nxagentOption(Y) + POSITION_OFFSET;
+ sizeHints.min_width = MIN_NXAGENT_WIDTH;
+ sizeHints.min_height = MIN_NXAGENT_HEIGHT;
+
+ sizeHints.width = nxagentOption(RootWidth);
+ sizeHints.height = nxagentOption(RootHeight);
+
+ if (nxagentOption(DesktopResize) == 1 || nxagentOption(Fullscreen) == 1)
+ {
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ }
+ else
+ {
+ sizeHints.max_width = nxagentOption(RootWidth);
+ sizeHints.max_height = nxagentOption(RootHeight);
+ }
+
+ if (nxagentUserGeometry.flag & XValue || nxagentUserGeometry.flag & YValue)
+ sizeHints.flags |= USPosition;
+ if (nxagentUserGeometry.flag & WidthValue || nxagentUserGeometry.flag & HeightValue)
+ sizeHints.flags |= USSize;
+
+ XSetStandardProperties(nxagentDisplay,
+ nxagentDefaultWindows[pScreen->myNum],
+ nxagentWindowName,
+ nxagentWindowName,
+ nxagentIconPixmap,
+ argv, argc, &sizeHints);
+
+ wmHints.icon_pixmap = nxagentIconPixmap;
+
+ if (useXpmIcon)
+ {
+ wmHints.icon_mask = nxagentIconShape;
+ wmHints.flags = IconPixmapHint | IconMaskHint;
+ }
+ else
+ {
+ wmHints.flags = IconPixmapHint;
+ }
+
+ XSetWMHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &wmHints);
+
+ /*
+ * Clear the window but let it unmapped. We'll map it
+ * at the time the we'll initialize our screen root
+ * and only if we are not running in rootless mode.
+ */
+
+ XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+
+ if (nxagentOption(AllScreens))
+ {
+ if (nxagentReconnectTrap)
+ {
+ XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
+ GrabModeAsync, CurrentTime);
+ }
+
+ nxagentIconWindow = nxagentCreateIconWindow();
+ }
+ else
+ {
+ nxagentIconWindow = 0;
+ }
+
+ /*
+ * When we don't have window manager we grab keyboard
+ * to let nxagent get keyboard events.
+ */
+
+ if (!nxagentWMIsRunning && !nxagentOption(Fullscreen))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: No window manager, we call XGrabKeyboard.\n");
+ #endif
+
+ XGrabKeyboard(nxagentDisplay, RootWindow (nxagentDisplay, 0), True, GrabModeAsync,
+ GrabModeAsync, CurrentTime);
+ }
+ }
+
+ if (!nxagentCreateDefaultColormap(pScreen))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentOpenScreen: Failed to create default colormap for screen.\n");
+ #endif
+
+ return False;
+ }
+
+ /*
+ * The purpose of this check is to verify if there
+ * is a window manager running. Unfortunately due
+ * to the way we manage the intern atoms call, the
+ * atom will always exist.
+ */
+
+ if (nxagentWMIsRunning)
+ {
+ XlibAtom deleteWMatom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: Found WM, delete window atom [%ld].\n",
+ deleteWMatom);
+ #endif
+
+ if (nxagentOption(Rootless) == False)
+ {
+ /*
+ * Set the WM_DELETE_WINDOW protocol for the main agent
+ * window and, if we are in fullscreen mode, include the
+ * icon window.
+ */
+
+ XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
+ }
+ else
+ {
+ /*
+ * We need to register the ICCCM WM_DELETE_WINDOW
+ * protocol for any top-level window or the agent
+ * will be killed if any window is closed.
+ */
+
+ XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
+
+ #ifdef TEST
+ fprintf(stderr, "Warning: Not setting the WM_DELETE_WINDOW protocol.\n");
+ #endif
+ }
+ }
+ else
+ {
+ /*
+ * We should always enable the configuration of the
+ * remote X server's devices if we are running full-
+ * screen and there is no WM running.
+ */
+
+ if (nxagentOption(Fullscreen))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentOpenScreen: WARNING! Forcing propagation of device control changes.\n");
+ #endif
+
+ nxagentChangeOption(DeviceControl, True);
+ }
+ }
+
+ /*
+ * Inform the user whether the agent's clients will
+ * be able to change the real X server's keyboard
+ * and pointer settings.
+ */
+
+ if (nxagentOption(DeviceControl) == False)
+ {
+ fprintf(stderr, "Info: Not using local device configuration changes.\n");
+ }
+ else
+ {
+ fprintf(stderr, "Info: Using local device configuration changes.\n");
+ }
+
+ #ifdef RENDER
+
+ /*
+ * if (nxagentRenderEnable && !nxagentReconnectTrap)
+ * {
+ * if (!nxagentPictureInit(pScreen, 0, 0))
+ * {
+ * nxagentRenderEnable = False;
+ *
+ * return FALSE;
+ * }
+ *
+ * if (nxagentAlphaEnabled)
+ * {
+ * fprintf(stderr, "Info: Using alpha channel in render extension.\n");
+ * }
+ * }
+ */
+
+ #endif /* RENDER */
+
+ /*
+ * Check if the composite extension is
+ * supported on the remote display and
+ * prepare the agent for its use.
+ */
+
+ nxagentCompositeExtensionInit();
+
+ /* We use this to get informed about RandR changes on the real display.
+ FIXME: It would probably be better to use an RRScreenChangeNotifyEvent here. */
+ XSelectInput(nxagentDisplay, DefaultRootWindow(nxagentDisplay), StructureNotifyMask);
+
+ #ifdef NXAGENT_TIMESTAMP
+
+ {
+ extern unsigned long startTime;
+
+ fprintf(stderr, "Screen: open screen finished, time is [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+
+ #endif
+
+ #ifdef WATCH
+
+ fprintf(stderr, "nxagentOpenScreen: Watchpoint 8.\n");
+
+/*
+Reply Total Cached Bits In Bits Out Bits/Reply Ratio
+------- ----- ------ ------- -------- ---------- -----
+#1 U 2 1 5344 bits (1 KB) -> 2344 bits (0 KB) -> 2672/1 -> 1172/1 = 2.280:1
+#16 11 2816 bits (0 KB) -> 197 bits (0 KB) -> 256/1 -> 18/1 = 14.294:1
+#91 1 16640 bits (2 KB) -> 12314 bits (2 KB) -> 16640/1 -> 12314/1 = 1.351:1
+#98 2 512 bits (0 KB) -> 57 bits (0 KB) -> 256/1 -> 28/1 = 8.982:1
+*/
+
+ sleep(30);
+
+ #endif
+
+ return True;
+}
+
+Bool nxagentCloseScreen(ScreenPtr pScreen)
+{
+ int i;
+
+ #ifdef DEBUG
+ fprintf(stderr, "running nxagentCloseScreen()\n");
+ #endif
+
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ free(pScreen->allowedDepths[i].vids);
+ }
+
+ /*
+ * Free the frame buffer.
+ */
+
+ free(((PixmapPtr)pScreen -> devPrivate) -> devPrivate.ptr);
+
+ free(pScreen->allowedDepths);
+ free(pScreen->visuals);
+ free(pScreen->devPrivate);
+
+ /*
+ * Reset the geometry and alpha information
+ * used by proxy to unpack the packed images.
+ */
+
+ nxagentResetVisualCache();
+ nxagentResetAlphaCache();
+ nxagentReleaseAllSplits();
+
+ /*
+ * The assumption is that all X resources will be
+ * destroyed upon closing the display connection.
+ * There is no need to generate extra protocol.
+ */
+
+ return True;
+}
+
+/*
+ * This function comes from the xfree86 Xserver.
+ */
+
+static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable)
+{
+ WindowPtr pWin = pScreen->root;
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = RegionCreate(NullBox, 1);
+ RegionSubtract(borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ /*
+ * Use REGION_BREAK to avoid optimizations in ValidateTree
+ * that assume the root borderClip can't change well, normally
+ * it doesn't...)
+ */
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ RegionInit(&pWin->winSize, &box, 1);
+ RegionInit(&pWin->borderSize, &box, 1);
+ if (WasViewable)
+ RegionReset(&pWin->borderClip, &box);
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.height = pScreen->height;
+ RegionBreak(&pWin->clipList);
+ }
+ else
+ {
+ RegionEmpty(&pWin->borderClip);
+ RegionBreak(&pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = RegionCreate(NullBox, 1);
+ RegionCopy(pOldClip, &pWin->clipList);
+ }
+
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage && pOldClip &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ RegionDestroy(pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ RegionEmpty(valExposed);
+ RegionDestroy(bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ FlushAllOutput ();
+}
+
+Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
+ int mmWidth, int mmHeight)
+{
+ BoxRec box;
+ XSizeHints sizeHints;
+ PixmapPtr pPixmap;
+ char *fbBits;
+
+ int oldWidth;
+ int oldHeight;
+ int oldMmWidth;
+ int oldMmHeight;
+
+ #ifdef TEST
+ nxagentPrintAgentGeometry("Before Resize Screen", "nxagentResizeScreen:");
+ #endif
+
+ /*
+ * Change screen properties.
+ */
+
+ oldWidth = pScreen -> width;
+ oldHeight = pScreen -> height;
+ oldMmWidth = pScreen -> mmWidth;
+ oldMmHeight = pScreen -> mmHeight;
+
+ pScreen -> width = width;
+ pScreen -> height = height;
+
+ /*
+ * Compute screen dimensions if they aren't given.
+ */
+
+ if (mmWidth == 0)
+ {
+ mmWidth = (width * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+ if (mmWidth < 1)
+ {
+ mmWidth = 1;
+ }
+ }
+
+ if (mmHeight == 0)
+ {
+ mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+ if (mmHeight < 1)
+ {
+ mmHeight = 1;
+ }
+ }
+
+ pScreen -> mmWidth = mmWidth;
+ pScreen -> mmHeight = mmHeight;
+
+ pPixmap = fbGetScreenPixmap(pScreen);
+
+ if ((fbBits = realloc(pPixmap -> devPrivate.ptr, PixmapBytePad(width, pScreen->rootDepth) *
+ height * BitsPerPixel(pScreen->rootDepth) / 8)) == NULL)
+ {
+ pScreen -> width = oldWidth;
+ pScreen -> height = oldHeight;
+ pScreen -> mmWidth = oldMmWidth;
+ pScreen -> mmHeight = oldMmHeight;
+
+ goto nxagentResizeScreenError;
+ }
+
+ if (!miModifyPixmapHeader(pPixmap, width, height,
+ pScreen->rootDepth, BitsPerPixel(pScreen->rootDepth),
+ PixmapBytePad(width,
+ pScreen->rootDepth), fbBits))
+ {
+/*
+FIXME: We should try to restore the previously
+ reallocated frame buffer pixmap.
+*/
+
+ pScreen -> width = oldWidth;
+ pScreen -> height = oldHeight;
+ pScreen -> mmWidth = oldMmWidth;
+ pScreen -> mmHeight = oldMmHeight;
+
+ goto nxagentResizeScreenError;
+ }
+
+ nxagentChangeOption(RootWidth, width);
+ nxagentChangeOption(RootHeight, height);
+
+ if (nxagentOption(Fullscreen))
+ {
+ nxagentChangeOption(RootX, (nxagentOption(Width) -
+ nxagentOption(RootWidth)) / 2);
+ nxagentChangeOption(RootY, (nxagentOption(Height) -
+ nxagentOption(RootHeight)) / 2);
+ }
+ else
+ {
+ nxagentChangeOption(RootX, 0);
+ nxagentChangeOption(RootY, 0);
+ }
+
+ nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+ nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+ /*
+ * Change agent window size and size hints.
+ */
+
+ if ((nxagentOption(Fullscreen) == 0 && nxagentOption(AllScreens) == 0))
+ {
+ sizeHints.flags = PPosition | PMinSize | PMaxSize;
+ sizeHints.x = nxagentOption(X);
+ sizeHints.y = nxagentOption(Y);
+
+ sizeHints.min_width = MIN_NXAGENT_WIDTH;
+ sizeHints.min_height = MIN_NXAGENT_HEIGHT;
+ sizeHints.width = width;
+ sizeHints.height = height;
+
+ if (nxagentOption(DesktopResize) == 1)
+ {
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ }
+ else
+ {
+ sizeHints.max_width = nxagentOption(RootWidth);
+ sizeHints.max_height = nxagentOption(RootHeight);
+ }
+
+ if (nxagentUserGeometry.flag & XValue || nxagentUserGeometry.flag & YValue)
+ {
+ sizeHints.flags |= USPosition;
+ }
+
+ if (nxagentUserGeometry.flag & WidthValue || nxagentUserGeometry.flag & HeightValue)
+ {
+ sizeHints.flags |= USSize;
+ }
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &sizeHints);
+
+ XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], width, height);
+
+ if (nxagentOption(Rootless) == 0)
+ {
+ XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum], width, height);
+ }
+ }
+
+ /*
+ * Set properties for the agent root window.
+ */
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+
+ pScreen->root -> drawable.width = width;
+ pScreen->root -> drawable.height = height;
+ pScreen->root -> drawable.x = 0;
+ pScreen->root -> drawable.y = 0;
+
+ RegionInit(&pScreen->root -> borderSize, &box, 1);
+ RegionInit(&pScreen->root -> winSize, &box, 1);
+ RegionInit(&pScreen->root -> clipList, &box, 1);
+ RegionInit(&pScreen->root -> borderClip, &box, 1);
+
+ (*pScreen -> PositionWindow)(pScreen->root, 0, 0);
+
+ nxagentSetRootClip(pScreen, 1);
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root),
+ nxagentOption(RootX), nxagentOption(RootY));
+
+ nxagentMoveViewport(pScreen, 0, 0);
+
+ /*
+ * Update void * bounds.
+ */
+
+ ScreenRestructured(pScreen);
+
+ #ifdef TEST
+ nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
+ #endif
+
+ nxagentSetPrintGeometry(pScreen -> myNum);
+
+ return 1;
+
+nxagentResizeScreenError:
+
+ return 0;
+}
+
+void nxagentShadowSetRatio(float floatXRatio, float floatYRatio)
+{
+ int intXRatio;
+ int intYRatio;
+
+ if (floatXRatio == 0)
+ {
+ floatXRatio = 1.0;
+ }
+
+ if (floatYRatio == 0)
+ {
+ floatYRatio = 1.0;
+ }
+
+ intXRatio = floatXRatio * (1 << PRECISION);
+ intYRatio = floatYRatio * (1 << PRECISION);
+
+ nxagentChangeOption(FloatXRatio, floatXRatio);
+ nxagentChangeOption(FloatYRatio, floatYRatio);
+
+ nxagentChangeOption(XRatio, intXRatio);
+ nxagentChangeOption(YRatio, intYRatio);
+
+ #ifdef TEST
+ fprintf(stderr, "Info: Using X ratio [%f] Y ratio [%f].\n",
+ nxagentOption(FloatXRatio), nxagentOption(FloatYRatio));
+ #endif
+}
+
+void nxagentShadowSetWindowsSize(void)
+{
+ XResizeWindow(nxagentDisplay, nxagentDefaultWindows[0],
+ nxagentOption(Width), nxagentOption(Height));
+
+ XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+ nxagentOption(Width), nxagentOption(Height));
+}
+
+void nxagentShadowSetWindowOptions(void)
+{
+ nxagentChangeOption(RootWidth, nxagentScale(nxagentShadowWidth, nxagentOption(XRatio)));
+ nxagentChangeOption(RootHeight, nxagentScale(nxagentShadowHeight, nxagentOption(YRatio)));
+
+ nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+ nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+ nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) >> 1);
+ nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) >> 1);
+}
+
+int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
+{
+ int i;
+ char *layout = NULL;
+ extern char *nxagentKeyboard;
+ XlibGC gc;
+ XGCValues value;
+
+ #ifndef __CYGWIN32__
+
+ Atom nxagentShadowAtom;
+
+ int fd;
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "Info: Init shadow session. nxagentDisplayName [%s] "
+ "nxagentDisplay [%p] nxagentShadowDisplayName [%s].\n",
+ nxagentDisplayName, (void *) nxagentDisplay,
+ nxagentShadowDisplayName);
+ #endif
+
+ if (nxagentKeyboard != NULL)
+ {
+ for (i = 0; nxagentKeyboard[i] != '/' && nxagentKeyboard[i] != 0; i++);
+
+ if(nxagentKeyboard[i] == 0 || nxagentKeyboard[i + 1] == 0 || i == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr,"WARNING! Wrong keyboard type: %s.\n", nxagentKeyboard);
+ #endif
+ }
+ else
+ {
+ layout = malloc(strlen(&nxagentKeyboard[i + 1]) + 1);
+
+ strcpy(layout, &nxagentKeyboard[i + 1]);
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShadowInit: Setting the master uid [%d].\n",
+ nxagentShadowUid);
+ #endif
+
+#if !defined (__CYGWIN32__) && !defined (WIN32)
+
+ if (nxagentShadowUid != -1)
+ {
+ NXShadowSetDisplayUid(nxagentShadowUid);
+ }
+
+ if (nxagentOption(UseDamage) == 0)
+ {
+ NXShadowDisableDamage();
+ }
+
+#endif
+
+ if (NXShadowCreate(nxagentDisplay, layout, nxagentShadowDisplayName,
+ (void *) &nxagentShadowDisplay) != 1)
+ {
+ #ifdef PANIIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! Failed to initialize shadow "
+ "display [%s].\n", nxagentShadowDisplayName);
+ #endif
+
+ return -1;
+ }
+
+ /*
+ * The shadow nxagent sets the _NX_SHADOW
+ * property on the master X server root
+ * window in order to notify its presence.
+ */
+
+ #ifndef __CYGWIN__
+
+ nxagentShadowAtom = XInternAtom(nxagentShadowDisplay, "_NX_SHADOW", False);
+
+ XChangeProperty(nxagentShadowDisplay, DefaultRootWindow(nxagentShadowDisplay),
+ nxagentShadowAtom, XA_STRING, 8, PropModeReplace, NULL, 0);
+ #endif
+
+ if (NXShadowAddUpdaterDisplay(nxagentDisplay, &nxagentShadowWidth,
+ &nxagentShadowHeight, &nxagentMasterDepth) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! Failed to add display [%s].\n",
+ nxagentDisplayName);
+ #endif
+
+ return -1;
+ }
+
+ #ifndef __CYGWIN32__
+
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ nxagentShadowSetRatio(WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 1.0 / nxagentShadowWidth,
+ HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 1.0 / nxagentShadowHeight);
+ }
+ else if (nxagentUserGeometry.flag != 0)
+ {
+ nxagentShadowSetRatio(nxagentOption(RootWidth) * 1.0 / nxagentShadowWidth,
+ nxagentOption(RootHeight) * 1.0 / nxagentShadowHeight);
+ }
+
+ if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) ->
+ class != TrueColor)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! The visual class of the remote "
+ "X server is not TrueColor.\n");
+ #endif
+
+ return -1;
+ }
+
+ if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) ->
+ class != TrueColor)
+ {
+ #ifdef PANIC
+
+ const char *className;
+
+ switch (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) -> class)
+ {
+ case StaticGray:
+ {
+ className = "StaticGray";
+
+ break;
+ }
+ case StaticColor:
+ {
+ className = "StaticColor";
+
+ break;
+ }
+ case PseudoColor:
+ {
+ className = "PseudoColor";
+
+ break;
+ }
+ case DirectColor:
+ {
+ className = "DirectColor";
+
+ break;
+ }
+ case GrayScale:
+ {
+ className = "GrayScale";
+
+ break;
+ }
+ default:
+ {
+ className = "";
+
+ break;
+ }
+ }
+
+ fprintf(stderr, "nxagentShadowInit: PANIC! Cannot shadow the display. "
+ "%s visual class is not supported. Only TrueColor visuals "
+ "are supported.\n", className);
+
+ #endif /* #endif PANIC */
+
+ return -1;
+ }
+
+ #endif
+
+ nxagentShadowDepth = pScreen -> rootDepth;
+
+ switch (nxagentMasterDepth)
+ {
+ case 32:
+ case 24:
+ {
+ if (nxagentShadowDepth == 16)
+ {
+ nxagentCheckDepth = 1;
+ }
+ else if (nxagentShadowDepth == 8)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a %d bit "
+ "display with a 8 bit screen depth.\n", nxagentMasterDepth);
+ #endif
+
+ return -1;
+ }
+
+ nxagentBppMaster = 4;
+
+ break;
+ }
+ case 16:
+ {
+ if (nxagentShadowDepth > 16)
+ {
+ nxagentCheckDepth = 1;
+ }
+ else if (nxagentShadowDepth == 8)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a 16 bit "
+ "display with a 8 bit screen depth.\n");
+ #endif
+
+ return -1;
+ }
+
+ nxagentBppMaster = 2;
+
+ break;
+ }
+ case 8:
+ {
+ if (nxagentShadowDepth != 8)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a 8 bit "
+ "display with a %d bit screen depth.\n", nxagentShadowDepth);
+ #endif
+
+ return -1;
+ }
+
+ nxagentBppMaster = 1;
+
+ break;
+ }
+ default:
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowInit: PANIC! The depth is not 32, 24, 16 or 8 bit.\n");
+ #endif
+
+ return -1;
+ }
+ }
+
+ if (nxagentShadowDepth >= 24)
+ {
+ nxagentBppShadow = 4;
+ }
+ else if (nxagentShadowDepth == 16)
+ {
+ nxagentBppShadow = 2;
+ }
+ else if (nxagentShadowDepth == 8)
+ {
+ nxagentBppShadow = 1;
+ }
+
+#if !defined(__CYGWIN__)
+
+ imageByteOrder = nxagentShadowDisplay -> byte_order;
+
+ fd = XConnectionNumber(nxagentShadowDisplay);
+
+ nxagentShadowXConnectionNumber = fd;
+
+#endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddXConnection: Adding the X connection [%d] "
+ "to the device set.\n", fd);
+ #endif
+
+ SetNotifyFd(nxagentShadowXConnectionNumber, nxagentNotifyConnection, X_NOTIFY_READ, NULL);
+
+ accessPixmapID = FakeClientID(serverClient -> index);
+
+ AddResource(accessPixmapID, RT_PIXMAP, (void *)nxagentShadowPixmapPtr);
+
+ accessWindowID = FakeClientID(serverClient -> index);
+
+ AddResource(accessWindowID, RT_WINDOW, (void *)nxagentShadowWindowPtr);
+
+ nxagentResizeScreen(pScreen, nxagentShadowWidth, nxagentShadowHeight, pScreen -> mmWidth, pScreen -> mmHeight);
+
+ nxagentShadowCreateMainWindow(pScreen, pWin, nxagentShadowWidth, nxagentShadowHeight);
+
+ if (nxagentRemoteMajor <= 3)
+ {
+ nxagentShadowSetWindowsSize();
+
+ nxagentSetWMNormalHints(0);
+ }
+
+ XMapWindow(nxagentDisplay, nxagentDefaultWindows[0]);
+
+ /*
+ * Clean up the main window.
+ */
+
+ value.foreground = 0x00000000;
+ value.background = 0x00000000;
+ value.plane_mask = 0xffffffff;
+ value.fill_style = FillSolid;
+
+ gc = XCreateGC(nxagentDisplay, nxagentPixmap(nxagentShadowPixmapPtr), GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+ XFillRectangle(nxagentDisplay, nxagentPixmap(nxagentShadowPixmapPtr), gc, 0, 0,
+ nxagentShadowWidth, nxagentShadowHeight);
+
+ XFreeGC(nxagentDisplay, gc);
+
+ RegionInit(&nxagentShadowUpdateRegion, (BoxRec*)NULL, 1);
+
+ return 0;
+}
+
+int nxagentShadowCreateMainWindow(ScreenPtr pScreen, WindowPtr pWin, int width, int height)
+{
+ XWindowChanges changes;
+ Mask mask,maskb;
+ XID values[4], *vlist;
+ int error;
+ XID xid;
+
+ nxagentShadowWidth = width;
+ nxagentShadowHeight = height;
+
+ NXShadowUpdateBuffer((void *)&nxagentShadowBuffer);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowCreateMainWindow: Update frame buffer [%p].\n", nxagentShadowBuffer);
+ #endif
+
+ nxagentShadowSetWindowOptions();
+
+ if (nxagentShadowPixmapPtr != NULL)
+ {
+ nxagentDestroyPixmap(nxagentShadowPixmapPtr);
+ }
+
+ if (nxagentShadowWindowPtr != NULL)
+ {
+ DeleteWindow(nxagentShadowWindowPtr, accessWindowID);
+ }
+
+ nxagentShadowPixmapPtr = nxagentCreatePixmap(pScreen, nxagentShadowWidth, nxagentShadowHeight, nxagentShadowDepth, 0);
+
+ if (nxagentShadowPixmapPtr)
+ {
+ ChangeResourceValue(accessPixmapID, RT_PIXMAP, (void *) nxagentShadowPixmapPtr);
+ nxagentShadowPixmapPtr -> drawable.id = accessPixmapID;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowCreateMainWindow: nxagentShadowPixmapPtr [%p] PixmapM -> drawable.id [%lu].\n",
+ (void *)nxagentShadowPixmapPtr, nxagentShadowPixmapPtr -> drawable.id);
+ fprintf(stderr, "nxagentShadowCreateMainWindow: Create pixmap with width [%d] height [%d] depth [%d].\n",
+ nxagentShadowWidth, nxagentShadowHeight, (int)nxagentShadowDepth);
+ #endif
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create pixmap with width [%d] height [%d] depth [%d].\n",
+ nxagentShadowWidth, nxagentShadowHeight, (int)nxagentShadowDepth);
+ #endif
+ }
+
+ XFreePixmap(nxagentDisplay, nxagentPixmap(nxagentVirtualPixmap(nxagentShadowPixmapPtr)));
+
+ xid = XCreatePixmap(nxagentDisplay, nxagentDefaultWindows[0],
+ nxagentScale(nxagentShadowWidth, nxagentOption(XRatio)),
+ nxagentScale(nxagentShadowHeight, nxagentOption(YRatio)), nxagentShadowDepth);
+
+ nxagentPixmap(nxagentVirtualPixmap(nxagentShadowPixmapPtr)) = xid;
+
+ nxagentPixmap(nxagentRealPixmap(nxagentShadowPixmapPtr)) = xid;
+
+ if (nxagentShadowGCPtr != NULL)
+ {
+ FreeScratchGC(nxagentShadowGCPtr);
+ }
+/*
+ * FIXME: Should use CreateGC.
+ */
+ nxagentShadowGCPtr = GetScratchGC(nxagentShadowPixmapPtr -> drawable.depth, nxagentShadowPixmapPtr -> drawable.pScreen);
+
+ if (nxagentShadowGCPtr)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowCreateMainWindow: Created GC with pGC[%p]\n", (void *) nxagentShadowGCPtr);
+ #endif
+ ValidateGC((DrawablePtr)nxagentShadowPixmapPtr, nxagentShadowGCPtr);
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create GC.");
+ #endif
+ }
+
+ mask = CWBackPixmap | CWEventMask | CWCursor;
+
+ nxagentGetDefaultEventMask(&maskb);
+ maskb |= ResizeRedirectMask | ExposureMask;
+
+ vlist = values;
+ *vlist++ = (XID)nxagentShadowPixmapPtr -> drawable.id;
+ *vlist++ = (XID)maskb;
+
+ *vlist = (XID)None;
+
+ nxagentShadowWindowPtr = CreateWindow(accessWindowID, pWin, 0, 0, nxagentShadowWidth,
+ nxagentShadowHeight, 0, InputOutput, mask, (XID *)values,
+ nxagentShadowDepth, serverClient, CopyFromParent, &error);
+
+ mask = CWWidth | CWHeight;
+ changes.width = nxagentScale(nxagentShadowWidth, nxagentOption(XRatio));
+ changes.height = nxagentScale(nxagentShadowHeight, nxagentOption(YRatio));
+
+ XConfigureWindow(nxagentDisplay, nxagentWindow(nxagentShadowWindowPtr), mask, &changes);
+
+ nxagentMoveViewport(pScreen, 0, 0);
+
+ if (nxagentShadowWindowPtr && !error)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowCreateMainWindow: Create window with nxagentShadowWindowPtr [%p]"
+ "nxagentShadowWindowPtr -> drawable.id [%lu].\n", (void *) nxagentShadowWindowPtr,
+ nxagentShadowWindowPtr -> drawable.id);
+
+ fprintf(stderr, "nxagentShadowCreateMainWindow: parent nxagentShadowWindowPtr [%p] parent -> drawable.id [%lu].\n",
+ (void *)nxagentShadowWindowPtr->parent, nxagentShadowWindowPtr -> parent -> drawable.id);
+
+ #endif
+
+ ChangeResourceValue(accessWindowID, RT_WINDOW, (void *) nxagentShadowWindowPtr);
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create window.\n");
+ #endif
+ }
+
+ XMapWindow(nxagentDisplay, nxagentWindow(nxagentShadowWindowPtr));
+ MapWindow(nxagentShadowWindowPtr, serverClient);
+
+ mask = CWX | CWY | CWWidth | CWHeight;
+ changes.x = nxagentOption(RootX);
+ changes.y = nxagentOption(RootY);
+ changes.width = nxagentScale(nxagentShadowWidth, nxagentOption(XRatio));
+ changes.height = nxagentScale(nxagentShadowHeight, nxagentOption(YRatio));
+ XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), mask, &changes);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowCreateMainWindow: Completed mapping of Access window.\n");
+ #endif
+
+ return 0;
+}
+
+int nxagentShadowSendUpdates(int *suspended)
+{
+ *suspended = 0;
+
+ if (RegionNil(&nxagentShadowUpdateRegion) == 1)
+ {
+ return 0;
+ }
+
+ nxagentMarkCorruptedRegion((DrawablePtr)nxagentShadowPixmapPtr, &nxagentShadowUpdateRegion);
+
+ RegionEmpty(&nxagentShadowUpdateRegion);
+
+ return 1;
+}
+
+int nxagentShadowPoll(PixmapPtr nxagentShadowPixmapPtr, GCPtr nxagentShadowGCPtr,
+ unsigned char nxagentShadowDepth, int nxagentShadowWidth,
+ int nxagentShadowHeight, char *nxagentShadowBuffer, int *changed, int *suspended)
+{
+ int x, y, y2, n, c, line;
+ int result;
+ long numRects;
+ unsigned int width, height, length;
+ char *tBuffer = NULL;
+ char *iBuffer, *ptBox;
+ BoxRec *pBox;
+ RegionRec updateRegion;
+ RegionRec tempRegion;
+ BoxRec box;
+ int overlap;
+
+
+ RegionNull(&updateRegion);
+
+ RegionNull(&tempRegion);
+
+#ifdef __CYGWIN32__
+
+ if (NXShadowCaptureCursor(nxagentWindow(nxagentShadowWindowPtr),
+ nxagentShadowWindowPtr -> drawable.pScreen -> visuals) == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentShadowPoll: Failed to capture cursor.\n");
+ #endif
+ }
+
+#endif
+
+ result = NXShadowHasChanged(nxagentUserInput, NULL, suspended);
+
+ *changed = result;
+
+ if (result == 1)
+ {
+ if (nxagentWMPassed == 0)
+ {
+ nxagentRemoveSplashWindow(NULL);
+ }
+
+ NXShadowExportChanges(&numRects, &ptBox);
+ pBox = (BoxRec *)ptBox;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowPoll: nRects[%ld], pBox[%p] depth[%d].\n", numRects, (void *) pBox, nxagentShadowDepth);
+ #endif
+
+ for (n = 0; n < numRects; n++)
+ {
+ /*
+ * The BoxRec struct defined in the Xserver has a different
+ * variable order in comparison with the BoxRec struct in the Xlib.
+ * the second and third field are inverted.
+ */
+
+ x = pBox[n].x1;
+ y = pBox[n].x2;
+ y2 = pBox[n].y2;
+ width = pBox[n].y1 - pBox[n].x1;/* y1 = x2 */
+ height = y2 - pBox[n].x2; /* x2 = y1 */
+
+ if((x + width) > nxagentShadowWidth || (y + height) > nxagentShadowHeight)
+ {
+ /*
+ * Out of bounds. Maybe a resize of the master session is going on.
+ */
+
+ continue;
+ }
+
+ line = PixmapBytePad(width, nxagentMasterDepth);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShadowPoll: Rectangle Number[%d] - x[%d]y[%d]W[%u]H[%u].\n", n+1, x, y, width, height);
+ #endif
+
+ length = nxagentImageLength(width, height, ZPixmap, 0, nxagentMasterDepth);
+
+ if (tBuffer)
+ {
+ free(tBuffer);
+ }
+
+ tBuffer = malloc(length);
+
+ if (tBuffer == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentShadowPoll: malloc failed.\n");
+ #endif
+
+ return -1;
+ }
+
+ iBuffer = tBuffer;
+
+ for (c = 0; c + y < y2; c++)
+ {
+ memcpy(tBuffer, nxagentShadowBuffer + x * nxagentBppMaster +
+ (y + c) * nxagentShadowWidth * nxagentBppMaster, line);
+
+ tBuffer += line;
+
+ }
+
+ tBuffer = iBuffer;
+
+#ifdef __CYGWIN32__
+ if (nxagentBppMaster == 2)
+ {
+ NXShadowCorrectColor(length, tBuffer);
+ }
+#else
+ if (nxagentCheckDepth == 1)
+ {
+ nxagentShadowAdaptDepth(width, height, line, &tBuffer);
+ }
+#endif
+
+ fbPutImage(nxagentVirtualDrawable((DrawablePtr)nxagentShadowPixmapPtr), nxagentShadowGCPtr,
+ nxagentShadowDepth, x, y, width, height, 0, ZPixmap, tBuffer);
+
+ box.x1 = x;
+ box.x2 = x + width;
+ box.y1 = y;
+ box.y2 = y + height;
+
+ RegionInit(&tempRegion, &box, 1);
+
+ RegionAppend(&updateRegion, &tempRegion);
+
+ RegionUninit(&tempRegion);
+
+ RegionValidate(&updateRegion, &overlap);
+
+ RegionUnion(&nxagentShadowUpdateRegion, &nxagentShadowUpdateRegion, &updateRegion);
+ }
+
+ if (tBuffer)
+ {
+ free(tBuffer);
+ }
+
+ RegionUninit(&updateRegion);
+ }
+ else if (result == -1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentShadowPoll: polling failed!\n");
+ #endif
+
+ usleep(50 * 1000);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+void nxagentShadowAdaptDepth(unsigned int width, unsigned int height,
+ unsigned int lineMaster, char **buffer)
+{
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned short color16 = 0;
+ unsigned char * icBuffer;
+ unsigned char * cBuffer = NULL;
+ unsigned char * tBuffer = (unsigned char *) *buffer;
+ unsigned int lineShadow;
+ unsigned int length;
+ unsigned int c;
+ unsigned int pad;
+ unsigned int color32 = 0;
+ unsigned long redMask;
+ unsigned long greenMask;
+ unsigned long blueMask;
+ Visual *pVisual;
+
+ length = nxagentImageLength(width, height, ZPixmap, 0, nxagentShadowDepth);
+
+ cBuffer = malloc(length);
+ icBuffer = cBuffer;
+
+ pVisual = nxagentImageVisual((DrawablePtr) nxagentShadowPixmapPtr, nxagentShadowDepth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCorrectDepthShadow: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorrectDepthShadow: Shadow redMask [%lu] greenMask[%lu] blueMask[%lu].\n",
+ pVisual -> red_mask, pVisual -> green_mask, pVisual -> blue_mask);
+ #endif
+
+ redMask = nxagentShadowDisplay -> screens[0].root_visual[0].red_mask;
+ greenMask = nxagentShadowDisplay -> screens[0].root_visual[0].green_mask;
+ blueMask = nxagentShadowDisplay -> screens[0].root_visual[0].blue_mask;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorrectDepthShadow: Master redMask [%lu] greenMask[%lu] blueMask[%lu].\n",
+ redMask, greenMask, blueMask);
+ #endif
+
+ switch(nxagentMasterDepth)
+ {
+ /*
+ * The Shadow agent has 24 bit depth.
+ */
+ case 16:
+ {
+ pad = lineMaster - nxagentBppMaster * width;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorrectDepthShadow: line [%d] width[%d] pad[%d].\n", lineMaster, width, pad);
+ #endif
+
+ while (height > 0)
+ {
+ for (c = 0; c < width ; c++)
+ {
+ if (imageByteOrder == LSBFirst)
+ {
+ color16 = *tBuffer++;
+ color16 |= (*tBuffer << 8);
+ }
+ else
+ {
+ color16 = (*tBuffer++) << 8;
+ color16 |= *tBuffer;
+ }
+
+ blue = ((short) blueMask & color16) << 3;
+ blue |= 0x3;
+
+ if (greenMask == 0x7e0)
+ {
+ /*
+ * bit mask 5-6-5
+ */
+
+ green = ((short) greenMask & color16) >> 3;
+ green |= 0x2;
+
+ red = ((short) redMask & color16) >> 8;
+ red |= 0x3;
+ }
+ else
+ {
+ /*
+ * bit mask 5-5-5
+ */
+
+ green = ((short) greenMask & color16) >> 2;
+ green |= 0x3;
+
+ red = ((short) redMask & color16) >> 7;
+ red |= 0x3;
+ }
+
+ tBuffer++;
+
+ if (nxagentDisplay -> byte_order == LSBFirst)
+ {
+ *cBuffer++ = blue;
+ *cBuffer++ = green;
+ *cBuffer++ = red;
+ cBuffer++;
+ }
+ else
+ {
+ cBuffer++;
+ *cBuffer++ = red;
+ *cBuffer++ = green;
+ *cBuffer++ = blue;
+ }
+ }
+ tBuffer += pad;
+ height--;
+ }
+ break;
+ }
+
+ /*
+ * The Shadow agent has 16 bit depth.
+ */
+ case 24:
+ {
+ lineShadow = PixmapBytePad(width, nxagentShadowDepth);
+
+ pad = lineShadow - nxagentBppShadow * width;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCorrectDepthShadow: line [%d] width[%d] pad[%d].\n", lineShadow, width, pad);
+ #endif
+
+ while (height > 0)
+ {
+ for (c = 0; c < width; c++)
+ {
+ if (imageByteOrder == LSBFirst)
+ {
+ color32 = *tBuffer++;
+ color32 |= (*tBuffer++ << 8);
+ color32 |= (*tBuffer++ << 16);
+ tBuffer++;
+ }
+ else
+ {
+ tBuffer++;
+ color32 = (*tBuffer++ << 16);
+ color32 |= (*tBuffer++ << 8);
+ color32 |= *tBuffer++;
+ }
+
+ color16 = (color32 & (pVisual -> blue_mask << 3)) >> 3;
+
+ if (pVisual -> green_mask == 0x7e0)
+ {
+ /*
+ * bit mask 5-6-5
+ */
+ color16 |= (color32 & (pVisual -> green_mask << 5)) >> 5;
+ color16 |= (color32 & (pVisual -> red_mask << 8)) >> 8;
+ }
+ else
+ {
+ /*
+ * bit mask 5-5-5
+ */
+ color16 |= (color32 & (pVisual -> green_mask << 6)) >> 6;
+ color16 |= (color32 & (pVisual -> red_mask << 9)) >> 9;
+ }
+
+ if (nxagentDisplay -> byte_order == LSBFirst)
+ {
+ *cBuffer++ = color16 & 0xff;
+ *cBuffer++ = (color16 & 0xff00) >> 8;
+ }
+ else
+ {
+ *cBuffer++ = (color16 & 0xff00) >> 8;
+ *cBuffer++ = color16 & 0xff;
+ }
+ }
+ cBuffer += pad;
+ height--;
+ }
+ break;
+ }
+ }
+ cBuffer = (unsigned char *) *buffer;
+ *buffer = (char *) icBuffer;
+
+ if (cBuffer != NULL)
+ {
+ free(cBuffer);
+ }
+}
+
+#ifdef NXAGENT_ARTSD
+
+unsigned char fromHexNibble(char c)
+{
+ int uc = (unsigned char)c;
+
+ if(uc >= '0' && uc <= '9') return uc - (unsigned char)'0';
+ if(uc >= 'a' && uc <= 'f') return uc + 10 - (unsigned char)'a';
+ if(uc >= 'A' && uc <= 'F') return uc + 10 - (unsigned char)'A';
+
+ return 16; /*error*/
+}
+
+void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port)
+{
+ Window rootWin;
+ XlibAtom atomReturnType;
+ XlibAtom propAtom;
+ int iReturnFormat;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ int iReturn;
+
+ int i,in;
+ char tchar[] = " ";
+/*
+FIXME: The port information is not used at the moment and produces a
+ warning on recent gcc versions. Do we need such information
+ to run the audio forawrding?
+
+ char *chport;
+ char hex[] = "0123456789abcdef";
+*/
+ rootWin = DefaultRootWindow(nxagentDisplay);
+ propAtom = nxagentAtoms[4]; /* MCOPGLOBALS */
+
+ /*
+ * Get at most 64KB of data.
+ */
+
+ iReturn = XGetWindowProperty(nxagentDisplay,
+ rootWin,
+ propAtom,
+ 0,
+ 65536 / 4,
+ False,
+ XA_STRING,
+ &atomReturnType,
+ &iReturnFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
+
+ if (iReturn == Success && atomReturnType != None &&
+ ulReturnItems > 0 && pszReturnData != NULL)
+ {
+ char *local_buf;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPropagateArtsdProperties: Got [%ld] elements of format [%d] with [%ld] bytes left.\n",
+ ulReturnItems, iReturnFormat, ulReturnBytesLeft);
+ #endif
+
+ #ifdef WARNING
+
+ if (ulReturnBytesLeft > 0)
+ {
+ fprintf(stderr, "nxagentPropagateArtsdProperties: WARNING! Could not get the whole ARTSD property data.\n");
+ }
+
+ #endif
+
+ local_buf = (char *) malloc(strlen((char*)pszReturnData) + 100);
+
+ if (local_buf)
+ {
+ memset(local_buf, 0, strlen((char *) pszReturnData));
+
+ for (i = 0, in = 0; pszReturnData[i] != '\0'; i++)
+ {
+ local_buf[in]=pszReturnData[i];
+
+ if(pszReturnData[i]==':')
+ {
+ i++;
+
+ while(pszReturnData[i]!='\n')
+ {
+ unsigned char h;
+ unsigned char l;
+
+ h = fromHexNibble(pszReturnData[i]);
+ i++;
+ if(pszReturnData[i]=='\0') continue;
+ l = fromHexNibble(pszReturnData[i]);
+ i++;
+
+ if(h >= 16 || l >= 16) continue;
+
+ /*
+ * FIXME: The array tchar[] was used uninitialized.
+ * It's not clear to me the original purpose of the
+ * piece of code using it. To be removed in future
+ * versions.
+ */
+
+ tchar[0]=tchar[1];
+ tchar[1]=tchar[2];
+ tchar[2]=tchar[3];
+ tchar[3] = (h << 4) + l;
+ tchar[4]='\0';
+
+ if (strncmp(tchar, "tcp:", 4) == 0)
+ {
+ local_buf[in-7]='1';
+ local_buf[in-6]=strlen(port)+47;
+
+ in++;
+ local_buf[in]=pszReturnData[i-2];
+ in++;
+ local_buf[in]=pszReturnData[i-1];
+
+ strcat(local_buf,"6c6f63616c686f73743a");
+ in+=20;
+
+/*
+FIXME: The port information is not used at the moment and produces a
+ warning on recent gcc versions. Do we need such information
+ to run the audio forawrding?
+
+ chport=&port[0];
+
+ while(*chport!='\0')
+ {
+ in++;
+ local_buf[in]=hex[(*chport >> 4) & 0xf];
+ in++;
+ local_buf[in]=hex[*chport & 0xf];
+ *chport++;
+ }
+*/
+ strcat(local_buf,"00");
+ in+=2;
+
+ while(pszReturnData[i]!='\n')
+ {
+ i++;
+ }
+ }
+ else
+ {
+ in++;
+ local_buf[in]=pszReturnData[i-2];
+ in++;
+ local_buf[in]=pszReturnData[i-1];
+ }
+ }
+
+ in++;
+ local_buf[in]=pszReturnData[i];
+ }
+
+ in++;
+ }
+
+ local_buf[in]=0;
+
+ if (strlen(local_buf))
+ {
+ mcop_local_atom = MakeAtom(mcop_atom, strlen(mcop_atom), 1);
+
+ ChangeWindowProperty(pScreen->root,
+ mcop_local_atom,
+ XA_STRING,
+ iReturnFormat, PropModeReplace,
+ strlen(local_buf), local_buf, 1);
+ }
+
+ free(local_buf);
+ }
+ }
+}
+
+#endif
+
+Bool nxagentReconnectScreen(void *p0)
+{
+ CARD16 w, h;
+ PixmapPtr pPixmap = (PixmapPtr)nxagentDefaultScreen->devPrivate;
+ Mask mask;
+
+#if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_SCREEN_DEBUG)
+ fprintf(stderr, "nxagentReconnectScreen\n");
+#endif
+
+ if (!nxagentOpenScreen(nxagentDefaultScreen, nxagentArgc, nxagentArgv))
+ {
+ return False;
+ }
+
+ nxagentPixmap(pPixmap) = XCreatePixmap(nxagentDisplay,
+ nxagentDefaultWindows[nxagentDefaultScreen->myNum],
+ pPixmap -> drawable.width,
+ pPixmap -> drawable.height,
+ pPixmap -> drawable.depth);
+#ifdef NXAGENT_RECONNECT_SCREEN_DEBUG
+ fprintf(stderr, "nxagentReconnectScreen: recreated %p - ID %lx\n",
+ pPixmap,
+ nxagentPixmap( pPixmap ));
+#endif
+ w = 16;
+ h = 16;
+ (*nxagentDefaultScreen->QueryBestSize)(StippleShape, &w, &h, nxagentDefaultScreen);
+ if (!(nxagentPixmap(nxagentDefaultScreen->PixmapPerDepth[0]) =
+ XCreatePixmap(nxagentDisplay,
+ nxagentDefaultDrawables[1],
+ w,
+ h,
+ 1)));
+
+ nxagentGetDefaultEventMask(&mask);
+ mask |= NXAGENT_KEYBOARD_EVENT_MASK | NXAGENT_POINTER_EVENT_MASK;
+ nxagentSetDefaultEventMask(mask);
+ XSelectInput(nxagentDisplay, nxagentDefaultWindows[0], mask);
+
+ /*
+ * Turn off the screen-saver and reset the
+ * time to the next auto-disconnection.
+ */
+
+ SaveScreens(SCREEN_SAVER_OFF, ScreenSaverActive);
+
+ lastDeviceEventTime.milliseconds = GetTimeInMillis();
+
+ return True;
+}
+
+/* intersect two rectangles */
+Bool intersect(int ax1, int ay1, unsigned int aw, unsigned int ah,
+ int bx1, int by1, unsigned int bw, unsigned int bh,
+ int *x, int *y, unsigned int *w, unsigned int *h)
+{
+ int tx1, ty1, tx2, ty2, ix, iy;
+ unsigned int iw, ih;
+
+ int ax2 = ax1 + aw;
+ int ay2 = ay1 + ah;
+ int bx2 = bx1 + bw;
+ int by2 = by1 + bh;
+
+ /* thanks to http://silentmatt.com/rectangle-intersection */
+
+ /* check if there's any intersection at all */
+ if (ax2 < bx1 || bx2 < ax1 || ay2 < by1 || by2 < ay1) {
+ return FALSE;
+ }
+
+ tx1 = MAX(ax1, bx1);
+ ty1 = MAX(ay1, by1);
+ tx2 = MIN(ax2, bx2);
+ ty2 = MIN(ay2, by2);
+
+ ix = tx1 - ax1;
+ iy = ty1 - ay1;
+ iw = tx2 - tx1;
+ ih = ty2 - ty1;
+
+ /* check if the resulting rectangle is feasible */
+ if (iw <= 0 || ih <= 0) {
+ return FALSE;
+ }
+ *x = ix;
+ *y = iy;
+ *w = iw;
+ *h = ih;
+ return TRUE;
+}
+
+#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING
+/* intersect two rectangles, return aw/ah for w/h if resulting
+ rectangle is (partly) outside of bounding box */
+Bool intersect_bb(int ax1, int ay1, unsigned int aw, unsigned int ah,
+ int bx1, int by1, unsigned int bw, unsigned int bh,
+ int bbx1, int bby1, int bbx2, int bby2,
+ int *x, int *y, unsigned int *w, unsigned int *h)
+{
+ Bool result = intersect(ax1, ay1, aw, ah, bx1, by1, bw, bh, x, y, w, h);
+ if (result == TRUE) {
+ /* check if outside of bounding box */
+ if (ax1 < bbx1 || ax1 + aw > bbx2) {
+ #ifdef DEBUG
+ fprintf(stderr, "intersect: box has parts outside bounding box - width stays unchanged [%d]\n", aw);
+ #endif
+ *w = aw;
+ }
+
+ if (ay1 < bby1 || ay1 + ah > bby2) {
+ #ifdef DEBUG
+ fprintf(stderr, "intersect: box has parts outside bounding box - height stays unchanged [%d]\n", ah);
+ #endif
+ *h = ah;
+ }
+ }
+
+ return result;
+}
+#endif
+
+int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight)
+{
+ ScreenPtr pScreen;
+ /* FIXME: when is this needed? */
+ int doNotify = TRUE;
+ int r;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangeScreenConfig: called for screen [%d], width [%d] height [%d] mmWidth [%d] mmHeight [%d]\n", screen, width, height, mmWidth, mmHeight);
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeScreenConfig: screenInfo.screens[%d]->root [%p]\n", screen, (void *) screenInfo.screens[screen]);
+ #endif
+ if (screenInfo.screens[screen]->root == NULL)
+ {
+ return 0;
+ }
+
+ UpdateCurrentTime();
+
+ #ifdef DEBUG
+ if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED)
+ fprintf(stderr, "nxagentChangeScreenConfig: grabstate [SERVER_GRABBED], client [%p]\n", (void *) nxagentGrabServerInfo.client);
+ else if (nxagentGrabServerInfo.grabstate == SERVER_UNGRABBED)
+ fprintf(stderr, "nxagentChangeScreenConfig: grabstate [SERVER_UNGRABBED], client [%p]\n", (void *) nxagentGrabServerInfo.client);
+ else if (nxagentGrabServerInfo.grabstate == CLIENT_PERVIOUS)
+ fprintf(stderr, "nxagentChangeScreenConfig: grabstate [CLIENT_PERVIOUS], client [%p]\n", (void *) nxagentGrabServerInfo.client);
+ else if (nxagentGrabServerInfo.grabstate == CLIENT_IMPERVIOUS)
+ fprintf(stderr, "nxagentChangeScreenConfig: grabstate [CLIENT_IMPERVIOUS], client [%p]\n", (void *) nxagentGrabServerInfo.client);
+ else
+ fprintf(stderr, "nxagentChangeScreenConfig: grabstate [UNKNOWN], client [%p]\n", (void *) nxagentGrabServerInfo.client);
+ #endif
+
+ if (nxagentGrabServerInfo.grabstate == SERVER_GRABBED && nxagentGrabServerInfo.client != NULL)
+ {
+ /*
+ * If any client grabbed the server it won't expect screen
+ * configuration changes until it releases the grab. That could
+ * lead to an X error because available modes are changed
+ * in the meantime.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeScreenConfig: Cancel with grabbed server (grab held by [%p]).\n", (void *) nxagentGrabServerInfo.client);
+ #endif
+
+ return 0;
+ }
+
+ pScreen = screenInfo.screens[screen] -> root -> drawable.pScreen;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeScreenConfig: Changing config to %d x %d (%dmm x %dmm).\n", width, height, mmWidth, mmHeight);
+ #endif
+
+ r = nxagentResizeScreen(pScreen, width, height, mmWidth, mmHeight);
+
+ if (r != 0)
+ {
+ nxagentAdjustRandRXinerama(pScreen);
+ }
+
+ if (doNotify)
+ {
+ RRScreenSizeNotify(pScreen);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangeScreenConfig: current geometry: %d,%d %dx%d\n", nxagentOption(X), nxagentOption(Y), nxagentOption(Width), nxagentOption(Height));
+ fprintf(stderr, "nxagentChangeScreenConfig: returning [%d]\n", r);
+ #endif
+
+ return r;
+}
+
+/*
+ Destroy an output after removing it from any crtc that might reference it
+ */
+void nxagentDropOutput(RROutputPtr o) {
+ RRCrtcPtr c = o->crtc;
+ if (c) {
+ for (int i = 0; i < c->numOutputs; i++) {
+ if (c->outputs[i] == o) {
+#ifdef DEBUG
+ fprintf(stderr, "nxagentDropOutput: output [%s] is in use by crtc [%p], removing it from there\n", o->name, c);
+#endif
+ RRCrtcSet(c, NULL, 0, 0, RR_Rotate_0, 0, NULL);
+ }
+ }
+ }
+#ifdef DEBUG
+ fprintf(stderr, "nxagentDropOutput: destroying output [%s]\n", o->name);
+#endif
+ RROutputDestroy(o);
+}
+
+int nxagentAdjustRandRXinerama(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+ RROutputPtr output;
+ xRRModeInfo modeInfo;
+ char name[100];
+ int refresh = 60;
+ int width = nxagentOption(Width);
+ int height = nxagentOption(Height);
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv)
+ {
+ int i;
+ int number = 0;
+
+ XineramaScreenInfo *screeninfo = NULL;
+
+ if (nxagentOption(Xinerama)) {
+ screeninfo = XineramaQueryScreens(nxagentDisplay, &number);
+#ifdef DEBUG
+ if (number) {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() returned [%d] screens:\n", number);
+ for (int i=0; i < number; i++) {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: screen_number [%d] x_org [%d] y_org [%d] width [%d] height [%d]\n", screeninfo[i].screen_number, screeninfo[i].x_org, screeninfo[i].y_org, screeninfo[i].width, screeninfo[i].height);
+ }
+
+ }
+ else
+ {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: XineramaQueryScreens() failed - continuing without Xinerama\n");
+ }
+ }
+ else
+ {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: Xinerama is disabled\n");
+#endif
+ }
+
+ /*
+ * if there's no xinerama on the real server or xinerama is
+ * disabled in nxagent we only report one big screen. Clients
+ * still see xinerama enabled but it will report only one (big)
+ * screen. This is consistent with the way rrxinerama always
+ * behaved. The single PanoramiX/Xinerama extension however
+ * disables xinerama if only one screen exists.
+ */
+ if (number == 0) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: faking xinerama\n");
+ #endif
+ number = 1;
+
+ if (screeninfo) {
+ free(screeninfo);
+ }
+ if (!(screeninfo = malloc(sizeof(XineramaScreenInfo)))) {
+ return FALSE;
+ }
+
+ /* fake a xinerama screeninfo that covers the whole screen */
+ screeninfo->screen_number = 0;
+ screeninfo->x_org = nxagentOption(X);
+ screeninfo->y_org = nxagentOption(Y);
+ screeninfo->width = nxagentOption(Width);
+ screeninfo->height = nxagentOption(Height);
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs);
+ {
+ Bool rrgetinfo;
+
+ /*
+ * Convert old RANDR 1.0 data (if any) to current structure. This
+ * is needed once at the first run of this function. If we don't
+ * do this here it will be done implicitely later and add mode(s) to
+ * our crtc(s)!
+ */
+ rrgetinfo = RRGetInfo(pScreen, FALSE);
+
+ fprintf(stderr, "nxagentAdjustRandRXinerama: RRGetInfo returned [%d]\n", rrgetinfo);
+ }
+#else
+ /* we are not interested in the return code */
+ RRGetInfo(pScreen, FALSE);
+#endif
+
+#ifndef NXAGENT_RANDR_XINERAMA_CLIPPING
+ /* calculate bounding box (outer edges) */
+ int bbx2, bbx1, bby1, bby2;
+ bbx2 = bby2 = 0;
+ bbx1 = bby1 = INT_MAX;
+
+ for (i = 0; i < number; i++) {
+ bbx2 = MAX(bbx2, screeninfo[i].x_org + screeninfo[i].width);
+ bby2 = MAX(bby2, screeninfo[i].y_org + screeninfo[i].height);
+ bbx1 = MIN(bbx1, screeninfo[i].x_org);
+ bby1 = MIN(bby1, screeninfo[i].y_org);
+ }
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: bounding box: left [%d] right [%d] top [%d] bottom [%d]\n", bbx1, bbx2, bby1, bby2);
+ #endif
+#endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs);
+ #endif
+
+ /* adjust the number of CRTCs to match the number of reported
+ xinerama screens on the real server */
+ while (number != pScrPriv->numCrtcs) {
+ if (number < pScrPriv->numCrtcs) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: destroying crtc\n");
+ #endif
+ /* first reset the crtc to free possible outputs, then destroy the crtc */
+ RRCrtcSet(pScrPriv->crtcs[pScrPriv->numCrtcs - 1], NULL, 0, 0, RR_Rotate_0, 0, NULL);
+ RRCrtcDestroy(pScrPriv->crtcs[pScrPriv->numCrtcs - 1]);
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: adding crtc\n");
+ #endif
+ RRCrtcCreate(pScreen, NULL);
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: numCrtcs [%d], numOutputs [%d]\n", pScrPriv->numCrtcs, pScrPriv->numOutputs);
+ #endif
+
+ /* set gamma. Currently the only reason for doing this is
+ preventing the xrandr command from complaining about missing
+ gamma. */
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ if (pScrPriv->crtcs[i]->gammaSize == 0) {
+ CARD16 gamma = 0;
+ RRCrtcGammaSetSize(pScrPriv->crtcs[i], 1);
+ RRCrtcGammaSet(pScrPriv->crtcs[i], &gamma, &gamma, &gamma);
+ RRCrtcGammaNotify(pScrPriv->crtcs[i]);
+ }
+ }
+
+ /* delete superfluous non-NX outputs */
+ for (i = pScrPriv->numOutputs - 1; i >= 0; i--)
+ if (strncmp(pScrPriv->outputs[i]->name, "NX", 2))
+ nxagentDropOutput(pScrPriv->outputs[i]);
+
+ /* at this stage only NX outputs are left - we delete the superfluous ones */
+ for (i = pScrPriv->numOutputs - 1; i >= number; i--)
+ nxagentDropOutput(pScrPriv->outputs[i]);
+
+ /* add and init outputs */
+ for (i = 0; i < number; i++) {
+ if (i >= pScrPriv->numOutputs) {
+ sprintf(name, "NX%d", i+1);
+ output = RROutputCreate(pScreen, name, strlen(name), NULL);
+ /* will be done later
+ RROutputSetConnection(output, RR_Disconnected);
+ */
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: created new output [%s]\n", name);
+ #endif
+ }
+ else
+ {
+ output = pScrPriv->outputs[i];
+ }
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: adjusting output [%s]\n", pScrPriv->outputs[i]->name);
+ #endif
+ RROutputSetCrtcs(output, &(pScrPriv->crtcs[i]), 1);
+ /* FIXME: Isn't there a function for setting this? */
+ output->crtc = pScrPriv->crtcs[i];
+ /* FIXME: get SubPixelOrder from real X server */
+ RROutputSetSubpixelOrder(output, SubPixelUnknown);
+ /* FIXME: What is the correct physical size here? */
+ RROutputSetPhysicalSize(output, 0, 0);
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ Bool disable_output = FALSE;
+ RRModePtr mymode, prevmode;
+ int new_x, new_y;
+ unsigned int new_w, new_h;
+
+ /*
+ if ((nxagentOption(X) < bbx1 || (nxagentOption(X) + width >= bbx2 )) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: window has parts outside visible area - width stays unchanged [%d]\n", i, pScrPriv->outputs[i]->name, width);
+ #endif
+ new_w = width;
+ }
+
+ if ((nxagentOption(Y) < bby1 || (nxagentOption(Y) + height >= bby2 ) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: window has parts outside visible area - height stays unchanged [%d]\n", i, pScrPriv->outputs[i]->name, height);
+ #endif
+ new_h = height;
+ }
+ */
+
+ /* if there's no intersection disconnect the output */
+#ifdef NXAGENT_RANDR_XINERAMA_CLIPPING
+ disable_output = !intersect(nxagentOption(X), nxagentOption(Y),
+ width, height,
+ screeninfo[i].x_org, screeninfo[i].y_org,
+ screeninfo[i].width, screeninfo[i].height,
+ &new_x, &new_y, &new_w, &new_h);
+#else
+ disable_output = !intersect_bb(nxagentOption(X), nxagentOption(Y),
+ width, height,
+ screeninfo[i].x_org, screeninfo[i].y_org,
+ screeninfo[i].width, screeninfo[i].height,
+ bbx1, bby1, bbx2, bby2,
+ &new_x, &new_y, &new_w, &new_h);
+#endif
+
+ /* save previous mode */
+ prevmode = pScrPriv->crtcs[i]->mode;
+ #ifdef DEBUG
+ if (prevmode) {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: prevmode [%s] ([%p]) refcnt [%d]\n", i, pScrPriv->outputs[i]->name, prevmode->name, (void *)prevmode, prevmode->refcnt);
+ } else {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: no prevmode\n", i, pScrPriv->outputs[i]->name);
+ }
+ #endif
+
+ RROutputSetCrtcs(pScrPriv->outputs[i], &(pScrPriv->crtcs[i]), 1);
+
+ if (disable_output) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: no (valid) intersection - disconnecting\n", i, pScrPriv->outputs[i]->name);
+ #endif
+ RROutputSetConnection(pScrPriv->outputs[i], RR_Disconnected);
+
+ /*
+ * Tests revealed that some window managers (e.g. LXDE) also
+ * take disconnected outputs into account when calculating
+ * stuff like wallpaper tile size and maximum window
+ * size. This is problematic when a disconnected output is
+ * smaller than any of the connected ones. Solution: unset the
+ * mode of the output's crtc. This also leads to xinerama not
+ * showing the disconnected head anymore.
+ */
+ if (prevmode) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from output [%d] name [%s]\n", i, pScrPriv->outputs[i]->name);
+ #endif
+ RROutputSetModes(pScrPriv->outputs[i], NULL, 0, 0);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: removing mode from ctrc [%d]\n", i);
+ #endif
+ RRCrtcSet(pScrPriv->crtcs[i], NULL, 0, 0, RR_Rotate_0, 1, &(pScrPriv->outputs[i]));
+ }
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: intersection is x [%d] y [%d] width [%d] height [%d]\n", i, pScrPriv->outputs[i]->name, new_x, new_y, new_w, new_h);
+ #endif
+
+ RROutputSetConnection(pScrPriv->outputs[i], RR_Connected);
+
+ memset(&modeInfo, '\0', sizeof(modeInfo));
+
+#ifdef NXAGENT_RANDR_MODE_PREFIX
+ /* avoid collisions with pre-existing default modes by using a
+ separate namespace. If we'd simply use XxY we could not
+ distinguish between pre-existing modes which should stay
+ and our own modes that should be removed after use. */
+ sprintf(name, "nx_%dx%d", new_w, new_h);
+#else
+ sprintf(name, "%dx%d", new_w, new_h);
+#endif
+
+ modeInfo.width = new_w;
+ modeInfo.height = new_h;
+ modeInfo.hTotal = new_w;
+ modeInfo.vTotal = new_h;
+ modeInfo.dotClock = ((CARD32) new_w * (CARD32) new_h * (CARD32) refresh);
+ modeInfo.nameLength = strlen(name);
+
+ mymode = RRModeGet(&modeInfo, name);
+
+#ifdef DEBUG
+ if (mymode) {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] ([%p]) created/received, refcnt [%d]\n", i, pScrPriv->outputs[i]->name, name, (void *) mymode, mymode->refcnt);
+ }
+ else
+ {
+ /* FIXME: what is the correct behaviour in this case? */
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]: mode [%s] creation failed!\n", i, pScrPriv->outputs[i]->name, name);
+ }
+#endif
+ if (prevmode && mymode == prevmode) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: mymode [%s] ([%p]) == prevmode [%s] ([%p])\n", mymode->name, (void *) mymode, prevmode->name, (void *)prevmode);
+ #endif
+
+ /* if they are the same RRModeGet() has increased the
+ refcnt by 1. We decrease it again by calling only
+ RRModeDestroy() and forget about prevmode */
+ RRModeDestroy(mymode);
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for output %d [%s]\n", mymode->name, (void *) mymode, mymode->refcnt, i, pScrPriv->outputs[i]->name);
+ #endif
+ RROutputSetModes(pScrPriv->outputs[i], &mymode, 1, 0);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: setting mode [%s] ([%p]) refcnt [%d] for crtc %d\n", mymode->name, (void *) mymode, mymode->refcnt, i);
+ #endif
+ RRCrtcSet(pScrPriv->crtcs[i], mymode, new_x, new_y, RR_Rotate_0, 1, &(pScrPriv->outputs[i]));
+
+ }
+ } /* if disable_output */
+
+ /* throw away the mode if otherwise unused. We do not need it
+ anymore. We call FreeResource() to ensure the system will not
+ try to free it again on shutdown */
+ if (prevmode && prevmode->refcnt == 1) {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: destroying prevmode [%s]\n", prevmode->name);
+ #endif
+ FreeResource(prevmode->mode.id, 0);
+ }
+
+ RROutputChanged(pScrPriv->outputs[i], TRUE);
+ RRCrtcChanged(pScrPriv->crtcs[i], TRUE);
+ }
+
+ /* release allocated memory */
+ if (screeninfo) {
+ free(screeninfo);
+ screeninfo = NULL;
+ }
+
+#ifdef DEBUG
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRModePtr mode = pScrPriv->crtcs[i]->mode;
+ if (mode) {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: crtc [%d] ([%p]) has mode [%s] ([%p]), refcnt [%d] and [%d] outputs:\n", i, (void *) pScrPriv->crtcs[i], pScrPriv->crtcs[i]->mode->name, (void *)pScrPriv->crtcs[i]->mode, pScrPriv->crtcs[i]->mode->refcnt, pScrPriv->crtcs[i]->numOutputs);
+ }
+ else
+ {
+ fprintf(stderr, "nxagentAdjustRandRXinerama: crtc [%d] ([%p]) has no mode and [%d] outputs:\n", i, (void *) pScrPriv->crtcs[i], pScrPriv->crtcs[i]->numOutputs);
+ }
+
+ if (pScrPriv->crtcs[i]->numOutputs > 0)
+ for (int j=0; j < pScrPriv->crtcs[i]->numOutputs; j++)
+ fprintf(stderr, "nxagentAdjustRandRXinerama: output [%d] name [%s]->crtc=[%p]\n", j, pScrPriv->crtcs[i]->outputs[j]->name, (void *)pScrPriv->crtcs[i]->outputs[j]->crtc);
+ }
+#endif
+
+ pScrPriv -> lastSetTime = currentTime;
+
+ pScrPriv->changed = TRUE;
+ pScrPriv->configChanged = TRUE;
+ }
+
+ /* FIXME: adjust maximum screen size according to remote randr/xinerama setup */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentAdjustRandRXinerama: Min %dx%d, Max %dx%d \n", pScrPriv->minWidth, pScrPriv->minHeight, pScrPriv->maxWidth, pScrPriv->maxHeight);
+ #endif
+
+ return TRUE;
+}
+
+void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin)
+{
+ PixmapPtr pVirtualPixmap;
+ nxagentPrivPixmapPtr pPrivPixmap;
+ XlibGC gc;
+ XGCValues values;
+ int i;
+ int xSrc, ySrc, xDst, yDst, w, h;
+ int nRects;
+ int size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+ BoxRec extents;
+ RegionRec cleanRegion;
+
+ miBSWindowPtr pBackingStore = (miBSWindowPtr) pWin -> backStorage;
+
+ pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+ pPrivPixmap = nxagentPixmapPriv(pPixmap);
+
+ pPrivPixmap -> isBackingPixmap = 1;
+
+ fbCopyWindowProc(&pWin -> drawable, &pVirtualPixmap -> drawable, 0, RegionRects(prgnSave),
+ RegionNumRects(prgnSave), xorg, yorg, FALSE, FALSE, 0, 0);
+
+ values.subwindow_mode = IncludeInferiors;
+
+ gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values);
+
+ /*
+ * Initialize to the corrupted region.
+ * Coordinates are relative to the window.
+ */
+
+ RegionInit(&cleanRegion, NullBox, 1);
+
+ RegionCopy(&cleanRegion, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+ /*
+ * Subtract the corrupted region from the saved region.
+ */
+
+ RegionSubtract(&pBackingStore -> SavedRegion, &pBackingStore -> SavedRegion, &cleanRegion);
+
+ /*
+ * Translate the corrupted region. Coordinates
+ * are relative to the backing store pixmap.
+ */
+
+ RegionTranslate(&cleanRegion, -pBackingStore -> x, -pBackingStore -> y);
+
+ /*
+ * Compute the clean region to be saved: subtract
+ * the corrupted region from the region to be saved.
+ */
+
+ RegionSubtract(&cleanRegion, prgnSave, &cleanRegion);
+
+ nRects = RegionNumRects(&cleanRegion);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) malloc(size);
+ pBox = RegionRects(&cleanRegion);
+
+ for (i = nRects; i-- > 0;)
+ {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ XSetClipRectangles(nxagentDisplay, gc, 0, 0, pRects, nRects, Unsorted);
+
+ free((char *) pRects);
+
+ extents = *RegionExtents(&cleanRegion);
+
+ RegionUninit(&cleanRegion);
+
+ xDst = extents.x1;
+ yDst = extents.y1;
+
+/*
+ * Left here the wrong solution. The window could be not
+ * configured yet on the real X, whilst the x and y in the
+ * WindowRec are the new coordinates. The right solution
+ * is the other, as it is independent from the window
+ * coordinates.
+ *
+ * xSrc = xDst + xorg - pWin -> drawable.x;
+ * ySrc = yDst + yorg - pWin -> drawable.y;
+ */
+
+ xSrc = xDst + pBackingStore -> x;
+ ySrc = yDst + pBackingStore -> y;
+
+ w = extents.x2 - extents.x1;
+ h = extents.y2 - extents.y1;
+
+ XCopyArea(nxagentDisplay, nxagentWindow(pWin), nxagentPixmap(pPixmap), gc,
+ xSrc, ySrc, w, h, xDst, yDst);
+
+ nxagentAddItemBSPixmapList(nxagentPixmap(pPixmap), pPixmap, pWin,
+ pBackingStore -> x, pBackingStore -> y);
+
+ #ifdef TEST
+ fprintf(stderr,"nxagentSaveAreas: Added pixmap [%p] with id [%d] on window [%p] to BSPixmapList.\n",
+ (void *) pPixmap, nxagentPixmap(pPixmap), (void *) pWin);
+ #endif
+
+ XFreeGC(nxagentDisplay, gc);
+
+ return;
+}
+
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
+ int yorg, WindowPtr pWin)
+{
+ PixmapPtr pVirtualPixmap;
+ RegionPtr clipRegion;
+ XlibGC gc;
+ XGCValues values;
+ int i;
+ int xSrc, ySrc, xDst, yDst, w, h;
+ int nRects;
+ int size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+ BoxRec extents;
+ miBSWindowPtr pBackingStore;
+
+ /*
+ * Limit the area to restore to the
+ * root window size.
+ */
+
+ RegionIntersect(prgnRestore, prgnRestore,
+ &pWin -> drawable.pScreen -> root -> winSize);
+
+ pBackingStore = (miBSWindowPtr) pWin -> backStorage;
+
+ pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+ fbCopyWindowProc(&pVirtualPixmap -> drawable, &pWin -> drawable, 0, RegionRects(prgnRestore),
+ RegionNumRects(prgnRestore), -xorg, -yorg, FALSE, FALSE, 0, 0);
+
+ values.subwindow_mode = ClipByChildren;
+
+ gc = XCreateGC(nxagentDisplay, nxagentWindow(screenInfo.screens[0]->root), GCSubwindowMode, &values);
+
+ /*
+ * Translate the reference point to the origin of the window.
+ */
+
+ RegionTranslate(prgnRestore,
+ -pWin -> drawable.x - pWin -> borderWidth,
+ -pWin -> drawable.y - pWin -> borderWidth);
+
+ clipRegion = prgnRestore;
+
+ if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+ {
+ clipRegion = RegionCreate(NullBox, 1);
+
+ RegionCopy(clipRegion,
+ nxagentCorruptedRegion((DrawablePtr) pPixmap));
+
+ /*
+ * Translate the reference point to the origin of the window.
+ */
+
+ RegionTranslate(clipRegion,
+ pBackingStore -> x, pBackingStore -> y);
+
+ RegionIntersect(clipRegion, prgnRestore, clipRegion);
+
+ /*
+ * Subtract the corrupted region from the saved areas.
+ * miBSRestoreAreas will return the exposure region.
+ */
+
+ RegionSubtract(&pBackingStore->SavedRegion,
+ &pBackingStore->SavedRegion, clipRegion);
+
+ /*
+ * Store the corrupted region to send expose later.
+ */
+
+ if (nxagentRemoteExposeRegion != NULL)
+ {
+ RegionTranslate(clipRegion, pWin -> drawable.x, pWin -> drawable.y);
+
+ RegionUnion(nxagentRemoteExposeRegion, nxagentRemoteExposeRegion, clipRegion);
+
+ RegionTranslate(clipRegion, -pWin -> drawable.x, -pWin -> drawable.y);
+ }
+
+ /*
+ * Compute the region to be restored.
+ */
+
+ RegionSubtract(clipRegion, prgnRestore, clipRegion);
+ }
+
+ nRects = RegionNumRects(clipRegion);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) malloc(size);
+ pBox = RegionRects(clipRegion);
+
+ for (i = nRects; i-- > 0;)
+ {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ XSetClipRectangles(nxagentDisplay, gc, 0, 0, pRects, nRects, Unsorted);
+
+ free(pRects);
+
+ extents = *RegionExtents(clipRegion);
+
+ xDst = extents.x1;
+ yDst = extents.y1;
+
+ xSrc = xDst - xorg + pWin -> drawable.x;
+ ySrc = yDst - yorg + pWin -> drawable.y;
+
+ w = extents.x2 - extents.x1;
+ h = extents.y2 - extents.y1;
+
+ nxagentFlushConfigureWindow();
+
+ XCopyArea(nxagentDisplay, nxagentPixmap(pPixmap), nxagentWindow(pWin), gc,
+ xSrc, ySrc, w, h, xDst, yDst);
+
+ XFreeGC(nxagentDisplay, gc);
+
+ if (clipRegion != NULL && clipRegion != prgnRestore)
+ {
+ RegionDestroy(clipRegion);
+ }
+
+ /*
+ * Restore the reference point to the origin of the screen.
+ */
+
+ RegionTranslate(prgnRestore,
+ pWin -> drawable.x - pWin -> borderWidth,
+ pWin -> drawable.y + pWin -> borderWidth);
+
+ return;
+}
+
+void nxagentSetWMNormalHints(int screen)
+{
+ XSizeHints sizeHints;
+
+ /*
+ * Change agent window size and size hints.
+ */
+
+ sizeHints.flags = PPosition | PMinSize | PMaxSize;
+ sizeHints.x = nxagentOption(X);
+ sizeHints.y = nxagentOption(Y);
+
+ sizeHints.min_width = MIN_NXAGENT_WIDTH;
+ sizeHints.min_height = MIN_NXAGENT_HEIGHT;
+
+ sizeHints.width = nxagentOption(Width);
+ sizeHints.height = nxagentOption(Height);
+
+ if (nxagentOption(DesktopResize) == 1)
+ {
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ }
+ else
+ {
+ sizeHints.max_width = nxagentOption(RootWidth);
+ sizeHints.max_height = nxagentOption(RootHeight);
+ }
+
+ if (nxagentUserGeometry.flag & XValue || nxagentUserGeometry.flag & YValue)
+ {
+ sizeHints.flags |= USPosition;
+ }
+
+ if (nxagentUserGeometry.flag & WidthValue || nxagentUserGeometry.flag & HeightValue)
+ {
+ sizeHints.flags |= USSize;
+ }
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[screen], &sizeHints);
+}
+
+void nxagentShadowAdaptToRatio(void)
+{
+ XSizeHints sizeHints;
+ ScreenPtr pScreen;
+ RegionRec region;
+ BoxRec box;
+
+ pScreen = screenInfo.screens[0];
+
+ nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / nxagentShadowWidth,
+ nxagentOption(Height) * 1.0 / nxagentShadowHeight);
+
+ nxagentShadowCreateMainWindow(pScreen, screenInfo.screens[0]->root, nxagentShadowWidth, nxagentShadowHeight);
+
+ sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+ sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+ sizeHints.flags = PMaxSize;
+
+ XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &sizeHints);
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = nxagentShadowPixmapPtr -> drawable.width;
+ box.y2 = nxagentShadowPixmapPtr -> drawable.height;
+
+ RegionInit(&region, &box, 1);
+
+ nxagentMarkCorruptedRegion((DrawablePtr)nxagentShadowPixmapPtr, &region);
+
+ RegionUninit(&region);
+}
+
+void nxagentPrintGeometry()
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (nxagentPrintGeometryFlags && (1 << i))
+ {
+ fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d] "
+ "fullscreen [%d].\n", i, screenInfo.screens[i] -> width,
+ screenInfo.screens[i] -> height,
+ nxagentOption(Fullscreen));
+ }
+ }
+
+ nxagentPrintGeometryFlags = 0;
+}
+
+#ifdef DUMP
+
+void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
+{
+ static int init = 1;
+ static Display *shadow;
+ static Window win;
+
+ XlibGC gc;
+ XGCValues value;
+ XImage *image;
+ WindowPtr pWin = screenInfo.screens[0]->root;
+ unsigned int format;
+ int depth, pixmapWidth, pixmapHeight, length;
+ char *data;
+
+ depth = pPixmap -> drawable.depth;
+ pixmapWidth = pPixmap -> drawable.width;
+ pixmapHeight = pPixmap -> drawable.height;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ if (init)
+ {
+ shadow = XOpenDisplay("localhost:0");
+
+ if (shadow == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentShowPixmap: WARNING! Shadow display not opened.\n");
+ #endif
+
+ return;
+ }
+
+ init = False;
+ }
+
+ if (win == 0)
+ {
+ win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+ width, height, 0, 0xFFCC33, 0xFF);
+
+ XSelectInput(shadow, win, StructureNotifyMask);
+
+ XMapWindow(shadow, win);
+
+ for(;;)
+ {
+ XEvent e;
+
+ XNextEvent(shadow, &e);
+
+ if (e.type == MapNotify)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ XResizeWindow(nxagentDisplay, win, width, height);
+ XRaiseWindow(nxagentDisplay, win);
+ }
+
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentShowPixmap: malloc failed.\n");
+ #endif
+
+ return;
+ }
+
+/*
+FIXME
+ image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), x, y,
+ width, height, AllPlanes, format);
+*/
+
+ image = XGetImage(nxagentDisplay, RootWindow(nxagentDisplay, 0), 0, 0,
+ width, height, AllPlanes, format);
+
+ if (image == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentShowPixmap: XGetImage failed.\n");
+ #endif
+
+ if (data)
+ {
+ free(data);
+ }
+
+ return;
+ }
+
+ fbGetImage((DrawablePtr)pPixmap, 0, 0,
+ width, height, format, AllPlanes, data);
+
+ memcpy(image -> data, data, length);
+
+ value.foreground = 0xffffff;
+ value.background = 0x000000;
+ value.plane_mask = 0xffffff;
+ value.fill_style = FillSolid;
+
+ gc = XCreateGC(shadow, win, GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+ XSync(shadow, 0);
+
+ NXCleanImage(image);
+
+ XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+ XFlush(shadow);
+
+ XFreeGC(shadow, gc);
+
+ if (image != NULL)
+ {
+ XDestroyImage(image);
+ }
+
+ if (data != NULL)
+ {
+ free(data);
+ }
+
+/*
+FIXME
+ if (win != NULL)
+ {
+ XDestroyWindow(shadow, win);
+ }
+*/
+}
+
+void nxagentFbRestoreArea(PixmapPtr pPixmap, WindowPtr pWin, int xSrc, int ySrc, int width,
+ int height, int xDst, int yDst)
+{
+ Display *shadow;
+
+ XlibGC gc;
+ XGCValues value;
+ XImage *image;
+ unsigned int format;
+ int depth, pixmapWidth, pixmapHeight, length;
+ char *data = NULL;
+ Visual *pVisual;
+
+ depth = pPixmap -> drawable.depth;
+ pixmapWidth = pPixmap -> drawable.width;
+ pixmapHeight = pPixmap -> drawable.height;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ shadow = nxagentDisplay;
+
+ length = nxagentImageLength(width, height, format, 0, depth);
+
+ if ((data = malloc(length)) == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbRestoreArea: malloc failed.\n");
+ #endif
+
+ return;
+ }
+/*
+ image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), xSrc, ySrc,
+ width, height, AllPlanes, format);
+*/
+
+ if (image == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbRestoreArea: XGetImage failed.\n");
+ #endif
+
+ if (data)
+ {
+ free(data);
+ }
+
+ return;
+ }
+
+ fbGetImage((DrawablePtr)pPixmap, xSrc, ySrc,
+ width, height, format, AllPlanes, data);
+
+/*
+FIXME
+*/
+ pVisual = nxagentImageVisual((DrawablePtr) pPixmap, depth);
+
+ if (pVisual == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentFbRestoreArea: WARNING! Visual not found. Using default visual.\n");
+ #endif
+
+ pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+ }
+
+ image = XCreateImage(nxagentDisplay, pVisual,
+ depth, format, 0, (char *) data,
+ width, height, BitmapPad(nxagentDisplay),
+ nxagentImagePad(width, format, 0, depth));
+/*
+FIXME
+ memcpy(image -> data, data, length);
+*/
+
+ fprintf(stderr, "nxagentFbRestoreArea: Cleaning %d bytes of image.\n", length);
+
+ value.foreground = 0xffffff;
+ value.background = 0x000000;
+ value.plane_mask = 0xffffff;
+ value.fill_style = FillSolid;
+ value.function = GXcopy;
+
+ gc = XCreateGC(shadow, nxagentWindow(screenInfo.screens[0]->root), GCBackground |
+ GCForeground | GCFillStyle | GCPlaneMask | GCFunction, &value);
+
+ NXCleanImage(image);
+
+ XPutImage(shadow, nxagentWindow(pWin), gc, image, 0, 0, xDst, yDst, width, height);
+
+/*
+FIXME
+*/
+ XFlush(shadow);
+
+ XFreeGC(shadow, gc);
+
+ if (image)
+ {
+ XDestroyImage(image);
+ }
+
+/*
+FIXME
+ if (data)
+ {
+ free(data);
+ }
+*/
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
new file mode 100644
index 000000000..3df586fa8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -0,0 +1,149 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Screen_H__
+#define __Screen_H__
+
+#include "scrnintstr.h"
+
+#define MIN_NXAGENT_WIDTH 80
+#define MIN_NXAGENT_HEIGHT 60
+#define NXAGENT_FRAME_WIDTH 2000
+
+#define nxagentSetPrintGeometry(screen) \
+ nxagentPrintGeometryFlags = (1 << (screen));
+
+extern int nxagentClients;
+
+extern int nxagentAutoDisconnectTimeout;
+
+extern ScreenPtr nxagentDefaultScreen;
+
+extern Pixmap nxagentPixmapLogo;
+
+extern Window nxagentIconWindow;
+
+extern Window nxagentFullscreenWindow;
+
+extern RegionRec nxagentShadowUpdateRegion;
+
+extern WindowPtr nxagentShadowWindowPtr;
+
+extern int nxagentShadowResize;
+
+extern short nxagentShadowUid;
+
+void nxagentSetScreenInfo(ScreenInfo *screenInfo);
+void nxagentSetPixmapFormats(ScreenInfo *screenInfo);
+
+void nxagentPrintGeometry();
+
+extern Window nxagentDefaultWindows[MAXSCREENS];
+extern Window nxagentInputWindows[MAXSCREENS];
+extern Window nxagentScreenSaverWindows[MAXSCREENS];
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentInitViewportFrame(ScreenPtr pScreen, WindowPtr pRootWin);
+
+#else /* #ifdef VIEWPORT_FRAME */
+
+#define nxagentInitViewportFrame(pScreen, pRootWin)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+Bool nxagentOpenScreen(ScreenPtr pScreen,
+ int argc, char *argv[]);
+
+Bool nxagentCloseScreen(ScreenPtr pScreen);
+
+#define nxagentScreen(window) nxagentDefaultScreen
+
+extern int nxagentBitsPerPixel(int depth);
+
+void nxagentSetScreenSaverTime(void);
+
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
+
+Window nxagentCreateIconWindow(void);
+
+Bool nxagentMagicPixelZone(int x, int y);
+
+Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
+ int mmWidth, int mmHeight);
+
+int nxagentChangeScreenConfig(int screen, int width, int height, int mmWidth, int mmHeight);
+
+int nxagentAdjustRandRXinerama(ScreenPtr pScreen);
+
+extern Bool nxagentReconnectScreen(void *p0);
+
+void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin);
+
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin);
+
+extern int monitorResolution;
+
+int nxagentShadowCreateMainWindow( ScreenPtr pScreen, WindowPtr pWin,int width, int height);
+
+int nxagentShadowSendUpdates(int *);
+
+int nxagentShadowPoll(PixmapPtr, GCPtr, unsigned char, int, int, char *, int *, int *);
+
+void nxagentShadowSetWindowsSize(void);
+
+void nxagentSetWMNormalHints(int);
+
+void nxagentShadowSetRatio(float, float);
+
+/*
+ * Change window settings to adapt to a ratio.
+ */
+
+extern void nxagentShadowAdaptToRatio(void);
+
+/*
+ * The pixmap shadowing the real frame buffer.
+ */
+
+extern PixmapPtr nxagentShadowPixmapPtr;
+
+#endif /* __Screen_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
new file mode 100644
index 000000000..0d3c2ff22
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -0,0 +1,424 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "windowstr.h"
+#include "scrnintstr.h"
+
+#ifdef _XSERVER64
+
+#include "Agent.h"
+
+#define GC XlibGC
+
+#endif /* _XSERVER64 */
+
+#include "Xlib.h"
+#include "Xutil.h"
+
+#include "Display.h"
+#include "Splash.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Atoms.h"
+#include "Trap.h"
+#include "Init.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Colors used to paint the splash screen.
+ */
+
+int nxagentLogoDepth;
+int nxagentLogoWhite;
+int nxagentLogoRed;
+int nxagentLogoBlack;
+int nxagentLogoGray;
+
+void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height);
+
+/*
+ * From Screen.c.
+ */
+
+extern Atom nxagentWMStart;
+
+/*
+ * From Clipboard.c.
+ */
+
+extern Atom serverCutProperty;
+
+int nxagentShowSplashWindow(Window parentWindow)
+{
+ XWindowAttributes getAttributes;
+ XWindowChanges values;
+ XSetWindowAttributes attributes;
+ GC gc;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShowSplash: Got called.\n");
+ #endif
+
+ #ifdef NXAGENT_TIMESTAMP
+ {
+ extern unsigned long startTime;
+
+ fprintf(stderr, "nxagentShowSplash: Initializing splash start at [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+ #endif
+
+ XSetSelectionOwner(nxagentDisplay, nxagentWMStart, None, CurrentTime);
+
+ nxagentWMPassed = False;
+
+ /*
+ * This would cause a GetWindowAttributes and a
+ * GetGeometry (asynchronous) reply. We use instead
+ * the geometry requested by the user for the agent
+ * window.
+ *
+ * XGetWindowAttributes(nxagentDisplay, parentWindow, &getAttributes);
+ */
+
+ /*
+ * During reconnection we draw the splash over
+ * the default window and not over the root
+ * window because it would be hidden by other
+ * windows.
+ */
+
+ if (nxagentReconnectTrap)
+ {
+ getAttributes.x = nxagentOption(RootX);
+ getAttributes.y = nxagentOption(RootY);
+ }
+ else
+ {
+ getAttributes.x = 0;
+ getAttributes.y = 0;
+ }
+
+ getAttributes.width = nxagentOption(RootWidth);
+ getAttributes.height = nxagentOption(RootHeight);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShowSplash: Going to create new splash window.\n");
+ #endif
+
+ nxagentSplashWindow =
+ XCreateSimpleWindow(nxagentDisplay,
+ parentWindow,
+ getAttributes.x, getAttributes.y,
+ getAttributes.width, getAttributes.height,
+ 0,
+ WhitePixel (nxagentDisplay, 0),
+ BlackPixel (nxagentDisplay, 0));
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentShowSplash: Created new splash window with id [%ld].\n",
+ nxagentSplashWindow);
+ #endif
+
+ gc = XCreateGC(nxagentDisplay, nxagentSplashWindow, 0, NULL);
+ nxagentPaintLogo(nxagentSplashWindow, gc, 1, getAttributes.width, getAttributes.height);
+ XMapRaised (nxagentDisplay, nxagentSplashWindow);
+ values.stack_mode = Above;
+ XConfigureWindow(nxagentDisplay, nxagentSplashWindow, CWStackMode, &values);
+ attributes.override_redirect = True;
+ XChangeWindowAttributes(nxagentDisplay, nxagentSplashWindow, CWOverrideRedirect, &attributes);
+ XFreeGC(nxagentDisplay, gc);
+
+ #ifdef NXAGENT_TIMESTAMP
+ {
+ extern unsigned long startTime;
+ fprintf(stderr, "nxagentShowSplash: Splash ends [%d] milliseconds.\n",
+ GetTimeInMillis() - startTime);
+ }
+ #endif
+
+ return True;
+}
+
+void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height)
+{
+ XPoint rect[4];
+ int w, h, c, w2, h2;
+
+ /*
+ * Show only X2GO Logo when running as X2Go Agent
+ */
+ if(! nxagentX2go)
+ {
+ nxagentPixmapLogo = 0L;
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagenShowtLogo: Got called.\n");
+ #endif
+
+ #ifdef NXAGENT_LOGO_DEBUG
+ fprintf(stderr, "nxagentPaintLogo: begin\n");
+ fprintf(stderr, "nxagentPaintLogo: gen params are: w=%d h=%d d=%d r=%x w=%x b=%x\n",width, height,
+ nxagentLogoDepth, nxagentLogoRed,
+ nxagentLogoWhite, nxagentLogoBlack);
+ #endif
+
+ w = width/scale;
+ h = height/scale;
+
+ w2 = w/2;
+ h2 = h/2;
+
+ if (height > width)
+ {
+ c = w/30;
+ }
+ else
+ {
+ c = w/48;
+ }
+
+ rect[0].x = 0; rect[0].y = 0;
+ rect[1].x = 0; rect[1].y = h;
+ rect[2].x = w; rect[2].y = h;
+ rect[3].x = w; rect[3].y = 0;
+
+ XSetFunction(nxagentDisplay, gc, GXcopy);
+ XSetFillStyle(nxagentDisplay, gc, FillSolid);
+ XSetForeground(nxagentDisplay, gc, nxagentLogoBlack);
+ XSetBackground(nxagentDisplay, gc, nxagentLogoRed);
+
+ nxagentPixmapLogo = XCreatePixmap(nxagentDisplay, win, width, height, nxagentLogoDepth);
+
+ if (!nxagentPixmapLogo)
+ {
+ return;
+ }
+
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ #ifdef NXAGENT_LOGO_DEBUG
+ fprintf(stderr, "filled first poly\n");
+ #endif
+
+ XSetForeground(nxagentDisplay, gc, nxagentLogoRed);
+ XSetBackground(nxagentDisplay, gc, nxagentLogoWhite);
+
+ /*
+ * Draw X2GO Logo
+ */
+
+ /*
+ * Begin 'X'.
+ */
+
+ XSetForeground(nxagentDisplay, gc, nxagentLogoGray);
+ XSetBackground(nxagentDisplay, gc, nxagentLogoWhite);
+ rect[0].x = w2-7*c; rect[0].y = h2-5*c;
+ rect[1].x = w2-8*c; rect[1].y = h2-5*c;
+ rect[2].x = w2-4*c; rect[2].y = h2+3*c;
+ rect[3].x = w2-3*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2-4*c; rect[0].y = h2-5*c;
+ rect[1].x = w2-3*c; rect[1].y = h2-5*c;
+ rect[2].x = w2-7*c; rect[2].y = h2+3*c;
+ rect[3].x = w2-8*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ /*
+ * End 'X'.
+ */
+
+ /*
+ * Start '2'.
+ */
+
+ rect[0].x = w2-2*c; rect[0].y = h2-5*c;
+ rect[1].x = w2-1*c; rect[1].y = h2-5*c;
+ rect[2].x = w2-1*c; rect[2].y = h2-3*c;
+ rect[3].x = w2-2*c; rect[3].y = h2-3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2-2*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+2*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+2*c; rect[2].y = h2-4*c;
+ rect[3].x = w2-2*c; rect[3].y = h2-4*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+1*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+2*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+2*c; rect[2].y = h2-2*c;
+ rect[3].x = w2+1*c; rect[3].y = h2-2*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+2*c; rect[0].y = h2-2*c;
+ rect[1].x = w2+1*c; rect[1].y = h2-2*c;
+ rect[2].x = w2-2*c; rect[2].y = h2+2*c;
+ rect[3].x = w2-1*c; rect[3].y = h2+2*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+
+ rect[0].x = w2-2*c; rect[0].y = h2+2*c;
+ rect[1].x = w2+2*c; rect[1].y = h2+2*c;
+ rect[2].x = w2+2*c; rect[2].y = h2+3*c;
+ rect[3].x = w2-2*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+ /*
+ * End '2'.
+ */
+
+ /*
+ * Start 'G'.
+ */
+
+ rect[0].x = w2+3*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+7*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+7*c; rect[2].y = h2-4*c;
+ rect[3].x = w2+3*c; rect[3].y = h2-4*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+3*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+4*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+4*c; rect[2].y = h2+3*c;
+ rect[3].x = w2+3*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+3*c; rect[0].y = h2+2*c;
+ rect[1].x = w2+7*c; rect[1].y = h2+2*c;
+ rect[2].x = w2+7*c; rect[2].y = h2+3*c;
+ rect[3].x = w2+3*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+6*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+7*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+7*c; rect[2].y = h2-3*c;
+ rect[3].x = w2+6*c; rect[3].y = h2-3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+6*c; rect[0].y = h2-0*c;
+ rect[1].x = w2+7*c; rect[1].y = h2-0*c;
+ rect[2].x = w2+7*c; rect[2].y = h2+3*c;
+ rect[3].x = w2+6*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+5*c; rect[0].y = h2-1*c;
+ rect[1].x = w2+7*c; rect[1].y = h2-1*c;
+ rect[2].x = w2+7*c; rect[2].y = h2+0*c;
+ rect[3].x = w2+5*c; rect[3].y = h2+0*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+ /*
+ * End 'G'.
+ */
+
+ /*
+ * Start 'O'.
+ */
+
+ rect[0].x = w2+8*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+12*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+12*c; rect[2].y = h2-4*c;
+ rect[3].x = w2+8*c; rect[3].y = h2-4*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+8*c; rect[0].y = h2+3*c;
+ rect[1].x = w2+12*c; rect[1].y = h2+3*c;
+ rect[2].x = w2+12*c; rect[2].y = h2+2*c;
+ rect[3].x = w2+8*c; rect[3].y = h2+2*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+8*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+9*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+9*c; rect[2].y = h2+3*c;
+ rect[3].x = w2+8*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ rect[0].x = w2+11*c; rect[0].y = h2-5*c;
+ rect[1].x = w2+12*c; rect[1].y = h2-5*c;
+ rect[2].x = w2+12*c; rect[2].y = h2+3*c;
+ rect[3].x = w2+11*c; rect[3].y = h2+3*c;
+ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+ /*
+ * End 'O'.
+ */
+
+
+ XSetWindowBackgroundPixmap(nxagentDisplay, win, nxagentPixmapLogo);
+
+ #ifdef NXAGENT_LOGO_DEBUG
+ fprintf(stderr, "nxagentPaintLogo: end\n");
+ #endif
+}
+
+void nxagentRemoveSplashWindow(WindowPtr pWin)
+{
+ if (nxagentReconnectTrap) return;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemoveSplashWindow: Destroying the splash window.\n");
+ #endif
+
+ if (!nxagentWMPassed)
+ {
+ XSetSelectionOwner(nxagentDisplay, nxagentWMStart,
+ nxagentDefaultWindows[0], CurrentTime);
+
+ nxagentWMPassed = True;
+ }
+
+ if (nxagentSplashWindow != None)
+ {
+ XDestroyWindow(nxagentDisplay, nxagentSplashWindow);
+
+ nxagentSplashWindow = None;
+ nxagentRefreshWindows(screenInfo.screens[0]->root);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemoveSplashWindow: setting the ownership of %s (%d) on window 0x%lx\n",
+ "NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(screenInfo.screens[0]->root));
+ #endif
+
+ XSetSelectionOwner(nxagentDisplay, serverCutProperty,
+ nxagentWindow(screenInfo.screens[0]->root), CurrentTime);
+ }
+
+ if (nxagentPixmapLogo)
+ {
+ XFreePixmap(nxagentDisplay, nxagentPixmapLogo);
+
+ nxagentPixmapLogo = (Pixmap) 0;
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
new file mode 100644
index 000000000..444f1eed0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -0,0 +1,54 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Splash_H__
+#define __Splash_H__
+
+#include "Windows.h"
+#include "X11/Xdmcp.h"
+#include <nx/NXalert.h>
+
+#define XDM_TIMEOUT 20000
+
+extern xdmcp_states XdmcpState;
+extern int XdmcpTimeOutRtx;
+extern int XdmcpStartTime;
+extern int nxagentXdmcpUp;
+
+extern int nxagentLogoDepth;
+extern int nxagentLogoWhite;
+extern int nxagentLogoRed;
+extern int nxagentLogoBlack;
+extern int nxagentLogoGray;
+
+extern Window nxagentSplashWindow;
+
+extern int nxagentWMPassed;
+
+extern int nxagentShowSplashWindow(Window);
+
+extern void nxagentRemoveSplashWindow(WindowPtr pWin);
+
+#endif /* __Splash_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
new file mode 100644
index 000000000..9b9691b02
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -0,0 +1,1256 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Drawable.h"
+#include "Events.h"
+#include "GCs.h"
+
+#include "compext/Compext.h"
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * This should be a macro but for now
+ * we make it a real function to log
+ * a warning in the logs.
+ */
+
+DrawablePtr nxagentSplitDrawable(DrawablePtr pDrawable)
+{
+ if (pDrawable -> type == DRAWABLE_PIXMAP &&
+ nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSplitDrawable: WARNING! The drawable at [%p] is "
+ "virtual. Assuming real at [%p].\n", (void *) pDrawable,
+ (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+ #endif
+
+ return (DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable);
+ }
+ else
+ {
+ return pDrawable;
+ }
+}
+
+void nxagentInitSplitResources()
+{
+ int resource;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentInitSplitResources: Initializing the split resources.\n");
+ #endif
+
+ for (resource = 0; resource < NXNumberOfResources; resource++)
+ {
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ pResource -> pending = 0;
+ pResource -> commit = 0;
+ pResource -> split = NXNoResource;
+ pResource -> unpack = NXNoResource;
+ pResource -> drawable = NULL;
+ pResource -> region = NullRegion;
+ pResource -> gc = NULL;
+ }
+}
+
+SplitResourcePtr nxagentAllocSplitResource()
+{
+ int resource;
+
+ SplitResourcePtr pResource;
+
+ for (;;)
+ {
+ resource = NXAllocSplit(nxagentDisplay, NXAnyResource);
+
+ if (resource != NXNoResource)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentAllocSplitResource: Reserving resource [%d] for the next split.\n",
+ resource);
+ #endif
+
+ break;
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentAllocSplitResource: PANIC! No more resources for the next split.\n");
+ #endif
+/*
+FIXME: Must deal with the case all resources are exausted.
+*/
+ FatalError("nxagentAllocSplitResource: PANIC! No more resources for the next split.\n");
+ }
+ }
+
+ pResource = &nxagentSplitResources[resource];
+
+ if (pResource -> pending != 0 || pResource -> split != NXNoResource ||
+ pResource -> unpack != NXNoResource || pResource -> drawable != NULL ||
+ pResource -> region != NullRegion || pResource -> commit != 0 ||
+ pResource -> gc != NULL)
+ {
+ /*
+ * This is really an unrecoverable error.
+ */
+
+ #ifdef PANIC
+ fprintf(stderr, "nxagentAllocSplitResource: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ #endif
+
+ FatalError("nxagentAllocSplitResource: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ }
+
+ pResource -> pending = 1;
+ pResource -> split = resource;
+
+ return pResource;
+}
+
+void nxagentFreeSplitResource(SplitResourcePtr pResource)
+{
+ if (pResource -> pending == 0 || pResource -> split == NXNoResource ||
+ pResource -> drawable != NULL || pResource -> region != NullRegion ||
+ pResource -> gc != NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentFreeSplitResource: PANIC! Invalid record provided with values "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ #endif
+
+ FatalError("nxagentFreeSplitResource: PANIC! Invalid record provided with values "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeSplitResource: Clearing the record for resource [%d].\n",
+ pResource -> split);
+ #endif
+
+ NXFreeSplit(nxagentDisplay, pResource -> split);
+
+ pResource -> pending = 0;
+ pResource -> commit = 0;
+ pResource -> split = NXNoResource;
+ pResource -> unpack = NXNoResource;
+ pResource -> drawable = NULL;
+ pResource -> region = NullRegion;
+ pResource -> gc = NULL;
+}
+
+void nxagentInitUnpackResources()
+{
+/*
+FIXME: This must be implemented.
+*/
+}
+
+UnpackResourcePtr nxagentAllocUnpackResource()
+{
+/*
+FIXME: This must be implemented.
+*/
+ return NULL;
+}
+
+void nxagentFreeUnpackResource(UnpackResourcePtr pResource)
+{
+/*
+FIXME: This must be implemented.
+*/
+}
+
+void nxagentReleaseAllSplits(void)
+{
+ int resource;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseAllSplits: Going to release all the split resources.\n");
+ #endif
+
+ for (resource = 0; resource < NXNumberOfResources; resource++)
+ {
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ if (pResource != NULL && pResource -> pending == 1)
+ {
+ DrawablePtr pDrawable = pResource -> drawable;
+
+ if (pDrawable != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseAllSplits: Releasing the drawable at [%p] for "
+ "resource [%d].\n", (void *) pDrawable, pResource -> split);
+ #endif
+
+ nxagentReleaseSplit(pDrawable);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseAllSplits: Freeing the resource [%d].\n",
+ resource);
+ #endif
+
+ nxagentFreeSplitResource(pResource);
+ }
+ }
+}
+
+/*
+ * Check the coherency of the split record.
+ */
+
+#ifdef TEST
+
+static void nxagentCheckSplit(DrawablePtr pDrawable, SplitResourcePtr pResource)
+{
+ if (pResource == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCheckSplit: PANIC! No record associated to drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ FatalError("nxagentCheckSplit: PANIC! No record associated to drawable at [%p].\n",
+ (void *) pDrawable);
+ }
+ else if (pResource -> drawable != pDrawable ||
+ pResource -> split == NXNoResource)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCheckSplit: PANIC! The record [%d] doesn't match the drawable at [%p].\n",
+ pResource -> split, (void *) pDrawable);
+ #endif
+
+ FatalError("nxagentCheckSplit: PANIC! The record [%d] doesn't match the drawable at [%p].\n",
+ pResource -> split, (void *) pDrawable);
+ }
+ else if (pResource -> commit == 1 &&
+ pResource -> gc == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCheckSplit: PANIC! The record [%d] doesn't have a valid GC.\n",
+ pResource -> split);
+ #endif
+
+ FatalError("nxagentCheckSplit: PANIC! The record [%d] doesn't have a valid GC.\n",
+ pResource -> split);
+ }
+}
+
+static void nxagentCheckResource(SplitResourcePtr pResource, int resource)
+{
+ if (pResource == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCheckResource: PANIC! No record associated to resource [%d].\n",
+ resource);
+ #endif
+
+ FatalError("nxagentCheckResource: PANIC! No record associated to resource [%d].\n",
+ resource);
+ }
+ else if ((pResource -> split != resource || pResource -> pending != 1) ||
+ (pResource -> commit == 1 && (pResource -> drawable == NULL ||
+ pResource -> gc == NULL)))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCheckResource: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ #endif
+
+ FatalError("nxagentCheckResource: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ }
+}
+
+#endif
+
+int nxagentCreateSplit(DrawablePtr pDrawable, GCPtr *pGC)
+{
+ SplitResourcePtr pResource;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ pResource = nxagentAllocSplitResource();
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv((PixmapPtr) pDrawable) -> splitResource = pResource;
+ }
+ else
+ {
+ nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource = pResource;
+ }
+
+ pResource -> drawable = pDrawable;
+ pResource -> commit = 1;
+
+ /*
+ * Make a copy of the GC so the client
+ * can safely remove it.
+ */
+
+ pResource -> gc = CreateScratchGC(pDrawable -> pScreen, pDrawable -> depth);
+
+/*
+FIXME: What do we do here?
+*/
+ if (pResource -> gc == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCreateSplit: PANIC! Failed to create split GC for resource [%d].\n",
+ pResource -> split);
+ #endif
+
+ FatalError("nxagentCreateSplit: PANIC! Failed to create split GC for resource [%d].\n",
+ pResource -> split);
+ }
+ else if (CopyGC(*pGC, pResource -> gc, GCFunction | GCPlaneMask |
+ GCSubwindowMode | GCClipXOrigin | GCClipYOrigin |
+ GCClipMask | GCForeground | GCBackground) != Success)
+ {
+/*
+FIXME: What do we do here?
+*/
+ #ifdef PANIC
+ fprintf(stderr, "nxagentCreateSplit: PANIC! Failed to copy split GC for resource [%d].\n",
+ pResource -> split);
+ #endif
+
+ FatalError("nxagentCreateSplit: PANIC! Failed to copy split GC for resource [%d].\n",
+ pResource -> split);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateSplit: Associated GC at [%p] to resource [%d] "
+ "with id [%lu].\n", (void *) pResource -> gc, pResource -> split,
+ (unsigned long) nxagentGC(pResource -> gc));
+ #endif
+
+ *pGC = pResource -> gc;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateSplit: Associated resource [%d] to drawable at [%p].\n",
+ pResource -> split, (void *) pResource -> drawable);
+ #endif
+
+ return pResource -> split;
+}
+
+/*
+ * Set the region to be the current
+ * streaming region.
+ */
+
+void nxagentRegionSplit(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ SplitResourcePtr pResource;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ pResource = nxagentSplitResource(pDrawable);
+
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentRegionSplit: Associating region to resource [%d] drawable at [%p].\n",
+ pResource -> split, (void *) pDrawable);
+
+ nxagentCheckSplit(pDrawable, pResource);
+
+ #endif
+
+ if (pResource == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentRegionSplit: PANIC! No valid split record for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRegionSplit: Associated region [%d,%d,%d,%d] to drawable at [%p] "
+ "with resource [%d].\n", pRegion -> extents.x1, pRegion -> extents.y1,
+ pRegion -> extents.x2, pRegion -> extents.y2, (void *) pDrawable,
+ pResource -> split);
+ #endif
+
+ pResource -> region = pRegion;
+}
+
+/*
+ * Remove the association between the drawable
+ * and the split resource. The resource is not
+ * deallocated until the end of the split.
+ */
+
+void nxagentReleaseSplit(DrawablePtr pDrawable)
+{
+ SplitResourcePtr pResource;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ pResource = nxagentSplitResource(pDrawable);
+
+ if (pResource == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseSplit: No split resources for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentReleaseSplit: Going to release resource [%d] for drawable at [%p].\n",
+ pResource -> split, (void *) pDrawable);
+
+ nxagentCheckSplit(pDrawable, pResource);
+
+ #endif
+
+ if (pResource -> region != NullRegion)
+ {
+ /*
+ * If we have a region the commits
+ * had to be still valid. In this
+ * case tell the proxy to abort the
+ * data transfer.
+ */
+
+ #ifdef TEST
+
+ if (pResource -> commit == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentReleaseSplit: PANIC! Found a region for resource [%d] but the "
+ "commits are invalid.\n", pResource -> split);
+ #endif
+
+ FatalError("nxagentCheckSplit: PANIC! Found a region for resource [%d] but the "
+ "commits are invalid.\n", pResource -> split);
+ }
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: Aborting the data transfer for resource [%d].\n",
+ pResource -> split);
+ #endif
+
+ NXAbortSplit(nxagentDisplay, pResource -> split);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseSplit: Freeing the region for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ RegionDestroy(pResource -> region);
+
+ pResource -> region = NullRegion;
+ }
+
+ if (pResource -> gc != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseSplit: Freeing the split GC for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ FreeScratchGC(pResource -> gc);
+
+ pResource -> gc = NULL;
+ }
+
+ /*
+ * Remove the association between the
+ * drawable and the resource record.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReleaseSplit: Removing association to drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ nxagentPixmapPriv((PixmapPtr) pDrawable) -> splitResource = NULL;
+ }
+ else
+ {
+ nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource = NULL;
+ }
+
+ /*
+ * Invalidate the commits and remove the
+ * association between the resource and
+ * the drawable.
+ */
+
+ pResource -> drawable = NULL;
+ pResource -> commit = 0;
+}
+
+void nxagentValidateSplit(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+ SplitResourcePtr pResource;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ pResource = nxagentSplitResource(pDrawable);
+
+ if (pResource == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: No split resource for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+ else if (pResource -> region == NullRegion)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: No split region yet for drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+ else if (pResource -> commit == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: WARNING! Split for drawable at [%p] was "
+ "already invalidated.\n", (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentValidateSplit: Going to validate resource [%d] drawable at [%p].\n",
+ pResource -> split, (void *) pDrawable);
+
+ nxagentCheckSplit(pDrawable, pResource);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: Checking the region for resource [%d] "
+ "and drawable at [%p].\n", pResource -> split, (void *) pDrawable);
+ #endif
+
+ /*
+ * If a null region is passed as parameter,
+ * we assume that all the commits have to
+ * be discarded.
+ */
+
+ if (pRegion == NullRegion)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: Forcing all commits as invalid for "
+ "drawable at [%p].\n", (void *) pDrawable);
+ #endif
+
+ nxagentReleaseSplit(pDrawable);
+ }
+ else
+ {
+ RegionRec tmpRegion;
+
+ /*
+ * Check if the provided region overlaps
+ * the area covered by the image being
+ * streamed.
+ */
+
+ RegionInit(&tmpRegion, NullBox, 1);
+
+ RegionIntersect(&tmpRegion, pResource -> region, pRegion);
+
+ if (RegionNil(&tmpRegion) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentValidateSplit: Marking the overlapping commits as invalid "
+ "for drawable at [%p].\n", (void *) pDrawable);
+ #endif
+
+ nxagentReleaseSplit(pDrawable);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentValidateSplit: Leaving the commits as valid for "
+ "drawable at [%p].\n", (void *) pDrawable);
+ }
+ #endif
+
+ RegionUninit(&tmpRegion);
+ }
+}
+
+void nxagentFreeSplit(int resource)
+{
+ DrawablePtr pDrawable;
+
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ if (pResource == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentFreeSplit: PANIC! No valid split record for resource [%d].\n",
+ resource);
+ #endif
+
+ FatalError("nxagentFreeSplit: PANIC! No valid split record for resource [%d].\n",
+ resource);
+ }
+ else if (pResource -> split != resource)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentFreeSplit: PANIC! The record [%d] doesn't match the resource [%d].\n",
+ pResource -> split, resource);
+ #endif
+
+ FatalError("nxagentFreeSplit: PANIC! The record [%d] doesn't match the resource [%d].\n",
+ pResource -> split, resource);
+ }
+
+ pDrawable = pResource -> drawable;
+
+ if (pDrawable != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeSplit: Removing association to drawable at [%p].\n",
+ (void *) pDrawable);
+ #endif
+
+ nxagentReleaseSplit(pDrawable);
+ }
+ #ifdef TEST
+ else
+ {
+ /*
+ * The end of the split has come after we have
+ * invalidated the operation and removed the
+ * association to the drawable. This happens,
+ * for example, if the drawable is destroyed.
+ */
+
+ fprintf(stderr, "nxagentFreeSplit: WARNING! Releasing invalidated resource [%d].\n",
+ pResource -> split);
+ }
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFreeSplit: Freeing the record for resource [%d].\n",
+ pResource -> split);
+ #endif
+
+ nxagentFreeSplitResource(pResource);
+}
+
+/*
+FIXME: This must be enabled when the vanilla
+ synchronization procedure is working.
+*/
+#define USE_FINISH_SPLIT
+
+void nxagentWaitDrawable(DrawablePtr pDrawable)
+{
+ SplitResourcePtr pResource;
+
+ pDrawable = nxagentSplitDrawable(pDrawable);
+
+ pResource = nxagentSplitResource(pDrawable);
+
+ if (pResource == NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWaitDrawable: WARNING! The drawable at [%p] is already awake.\n",
+ (void *) pDrawable);
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWaitDrawable: Waiting drawable at [%p] with resource [%d].\n",
+ (void *) pDrawable, pResource -> split);
+ #endif
+
+ /*
+ * Be sure we intercept an I/O error
+ * as well as an interrupt.
+ */
+
+ #ifdef USE_FINISH_SPLIT
+
+ NXFinishSplit(nxagentDisplay, pResource -> split);
+
+ #endif
+
+ NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+ for (;;)
+ {
+ /*
+ * Handling all the possible events here
+ * preempts the queue and makes a better
+ * use of the link.
+ *
+ * We should better use XIfEvent() instead
+ * of looping again and again through the
+ * event queue.
+ */
+
+ nxagentDispatchEvents(NULL);
+
+ /*
+ * Wait indefinitely until the resource
+ * is released or the display is shut
+ * down.
+ */
+
+ if (nxagentSplitResource(pDrawable) == NULL ||
+ NXDisplayError(nxagentDisplay) == 1)
+ {
+ #ifdef TEST
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ fprintf(stderr, "++++++nxagentWaitDrawable: WARNING! Display error detected while "
+ "waiting for the drawable.\n");
+ }
+ else
+ {
+ fprintf(stderr, "++++++nxagentWaitDrawable: Drawable at [%p] can now be restarted.\n",
+ (void *) pDrawable);
+ }
+
+ #endif
+
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "++++++nxagentWaitDrawable: Yielding control to the NX transport.\n");
+ #endif
+
+ nxagentWaitEvents(nxagentDisplay, NULL);
+ }
+}
+
+static Bool nxagentCommitSplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+ return (event -> type == ClientMessage &&
+ event -> xclient.data.l[0] == NXCommitSplitNotify &&
+ event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+ event -> xclient.format == 32);
+}
+
+void nxagentWaitCommitEvent(int resource)
+{
+ XEvent event;
+
+ /*
+ * Check if there is any commit pending. As
+ * we are at it, handle any commit, even those
+ * commits pertaining to other resources.
+ *
+ * We can receive some commits even if we'll
+ * later receive a no-split event. The proxy,
+ * in fact, may have missed to find the image
+ * in the memory cache and could have loaded it
+ * from disk (so requiring a commit) before we
+ * marked the end of the split sequence.
+ */
+
+ while (nxagentCheckEvents(nxagentDisplay, &event,
+ nxagentCommitSplitPredicate, NULL) == 1)
+ {
+ int client = event.xclient.data.l[1];
+ int request = event.xclient.data.l[2];
+ int position = event.xclient.data.l[3];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitCommitEvent: Commit event received with "
+ "client [%d] request [%d] and position [%d].\n",
+ client, request, position);
+ #endif
+
+ nxagentHandleCommitSplitEvent(client, request, position);
+ }
+}
+
+static Bool nxagentWaitSplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+ return (event -> type == ClientMessage &&
+ (event -> xclient.data.l[0] == NXNoSplitNotify ||
+ event -> xclient.data.l[0] == NXStartSplitNotify) &&
+ event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+ event -> xclient.format == 32);
+}
+
+int nxagentWaitSplitEvent(int resource)
+{
+ XEvent event;
+
+ int split = 0;
+
+ /*
+ * Don't flush the link. We only want to
+ * query the NX transport to check whether
+ * the operation caused a split.
+ */
+
+ NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+ for (;;)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitSplitEvent: Waiting for the split event for resource [%d].\n",
+ resource);
+ #endif
+
+ XIfEvent(nxagentDisplay, &event, nxagentWaitSplitPredicate, NULL);
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitSplitEvent: WARNING! Error detected reading the event.\n");
+ #endif
+
+ nxagentHandleNoSplitEvent(resource);
+
+ break;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWaitSplitEvent: Going to process the split event.\n");
+ #endif
+
+ if (resource != (int) event.xclient.data.l[1])
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentWaitSplitEvent: PANIC! Got event for resource [%d] while "
+ "waiting for resource [%d].\n", (int) event.xclient.data.l[1], resource);
+
+ fprintf(stderr, "nxagentWaitSplitEvent: PANIC! Restarting resource [%d] due to the "
+ "missing split event.\n", resource);
+ #endif
+
+ nxagentHandleNoSplitEvent(resource);
+
+ break;
+ }
+ else if (event.xclient.data.l[0] == NXNoSplitNotify)
+ {
+ nxagentHandleNoSplitEvent(resource);
+
+ break;
+ }
+ else
+ {
+ nxagentHandleStartSplitEvent(resource);
+
+ split = 1;
+
+ break;
+ }
+ }
+
+ return split;
+}
+
+void nxagentHandleNoSplitEvent(int resource)
+{
+ if (resource >= 0 && resource < NXNumberOfResources)
+ {
+ #ifdef TEST
+
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ fprintf(stderr, "nxagentHandleNoSplitEvent: Received event for resource [%d].\n",
+ resource);
+
+ nxagentCheckResource(pResource, resource);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleNoSplitEvent: Checking if there is any commit pending.\n");
+ #endif
+
+ nxagentWaitCommitEvent(resource);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleNoSplitEvent: No streaming was required with resource [%d] "
+ "and drawable at [%p].\n", resource, (void *) pResource -> drawable);
+ #endif
+
+ /*
+ * Release the resource.
+ */
+
+ nxagentFreeSplit(resource);
+ }
+ #ifdef PANIC
+ else
+ {
+ fprintf(stderr, "nxagentHandleNoSplitEvent: PANIC! Invalid resource identifier [%d] "
+ " received in event.\n", resource);
+ }
+ #endif
+}
+
+void nxagentHandleStartSplitEvent(int resource)
+{
+ if (resource >= 0 && resource < NXNumberOfResources)
+ {
+ #ifdef TEST
+
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ fprintf(stderr, "nxagentHandleStartSplitEvent: Received event for resource [%d].\n",
+ resource);
+
+ nxagentCheckResource(pResource, resource);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleStartSplitEvent: Checking if there is any commit pending.\n");
+ #endif
+
+ nxagentWaitCommitEvent(resource);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleStartSplitEvent: Streaming started with resource [%d] "
+ "and drawable at [%p].\n", resource, (void *) pResource -> drawable);
+ #endif
+ }
+ #ifdef PANIC
+ else
+ {
+ fprintf(stderr, "nxagentHandleStartSplitEvent: PANIC! Invalid resource identifier [%d] "
+ " received in event.\n", resource);
+ }
+ #endif
+}
+
+void nxagentHandleCommitSplitEvent(int resource, int request, int position)
+{
+ if (resource >= 0 && resource < NXNumberOfResources &&
+ request >= 0 && position >= 0)
+ {
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleCommitSplitEvent: Received event for resource [%d].\n",
+ resource);
+ #endif
+
+ if (pResource != NULL && pResource -> commit == 1)
+ {
+ #ifdef TEST
+
+ nxagentCheckResource(pResource, resource);
+
+ fprintf(stderr, "nxagentHandleCommitSplitEvent: Committing request [%d] with "
+ "position [%d] for resource [%d].\n", request, position, resource);
+
+ #endif
+
+ NXCommitSplit(nxagentDisplay, resource, 1, request, position);
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleCommitSplitEvent: Discarding request [%d] for "
+ "resource [%d] with position [%d].\n", request, resource, position);
+ #endif
+
+ NXCommitSplit(nxagentDisplay, resource, 0, request, position);
+ }
+ }
+ #ifdef PANIC
+ else
+ {
+ fprintf(stderr, "nxagentHandleCommitSplitEvent: PANIC! Invalid commit event with "
+ "request [%d] and position [%d] for resource [%d].\n", request,
+ position, resource);
+ }
+ #endif
+}
+
+void nxagentHandleEndSplitEvent(int resource)
+{
+ if (resource >= 0 && resource < NXNumberOfResources)
+ {
+ SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleEndSplitEvent: Received event for resource [%d].\n",
+ resource);
+
+ nxagentCheckResource(pResource, resource);
+
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleEndSplitEvent: Checking if there is any commit pending.\n");
+ #endif
+
+ nxagentWaitCommitEvent(resource);
+
+ if (pResource != NULL && pResource -> commit == 1)
+ {
+ #ifdef TEST
+
+ fprintf(stderr, "nxagentHandleEndSplitEvent: Checking the split region at [%p] "
+ "for drawable at [%p].\n", (void *) pResource -> drawable,
+ (void *) pResource -> region);
+
+ if (pResource -> region == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid region [%p] for drawable at [%p].\n",
+ (void *) pResource -> region, (void *) pResource -> drawable);
+ #endif
+
+ FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid region [%p] for drawable at [%p].\n",
+ (void *) pResource -> region, (void *) pResource -> drawable);
+ }
+ else if (pResource -> gc == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid GC [%p] for drawable at [%p].\n",
+ (void *) pResource -> gc, (void *) pResource -> drawable);
+ #endif
+
+ FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid GC [%p] for drawable at [%p].\n",
+ (void *) pResource -> gc, (void *) pResource -> drawable);
+ }
+
+ #endif
+
+ if (pResource -> drawable != NULL &&
+ pResource -> region != NullRegion)
+ {
+ if (RegionNil(pResource -> region) == 0)
+ {
+ RegionSubtract(
+ nxagentCorruptedRegion(pResource -> drawable),
+ nxagentCorruptedRegion(pResource -> drawable),
+ pResource -> region);
+
+/*
+FIXME: Implementing the valid region policy
+
+ nxagentExpandValidRegion(pResource -> drawable, pResource -> region);
+*/
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleEndSplitEvent: Synchronized region [%d,%d,%d,%d] "
+ "for drawable at [%p].\n", pResource -> region -> extents.x1,
+ pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+ pResource -> region -> extents.y2, (void *) pResource -> drawable);
+ #endif
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! The region [%d,%d,%d,%d] for drawable "
+ "at [%p] is empty.\n", pResource -> region -> extents.x1,
+ pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+ pResource -> region -> extents.y2, (void *) pResource -> drawable);
+ #endif
+
+ FatalError("nxagentHandleEndSplitEvent: PANIC! The region [%d,%d,%d,%d] for drawable "
+ "at [%p] is empty.\n", pResource -> region -> extents.x1,
+ pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+ pResource -> region -> extents.y2, (void *) pResource -> drawable);
+ }
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ #endif
+
+ FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid record for resource [%d] with "
+ "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+ resource, pResource -> pending, pResource -> split, pResource -> unpack,
+ (void *) pResource -> drawable, (void *) pResource -> region,
+ pResource -> commit, (void *) pResource -> gc);
+ }
+ }
+
+ /*
+ * Release the resource.
+ */
+
+ nxagentFreeSplit(resource);
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentHandleEndSplitEvent: WARNING! Ignoring split event "
+ "for resource [%d].\n", resource);
+ }
+ #endif
+}
+
+void nxagentHandleEmptySplitEvent()
+{
+/*
+FIXME: Should run a consistency check here.
+*/
+ #ifdef TEST
+ fprintf(stderr, "nxagentHandleEmptySplitEvent: No more split event to handle.\n");
+ #endif
+}
+
+/*
+ * The drawable is going to become corrupted.
+ */
+
+void nxagentSetCorruptedTimestamp(DrawablePtr pDrawable)
+{
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetCorruptedTimestamp: Corruption timestamp for pixmap at [%p] was [%lu].\n",
+ (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+
+ nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp = GetTimeInMillis();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetCorruptedTimestamp: New corruption timestamp for pixmap at [%p] is [%lu].\n",
+ (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetCorruptedTimestamp: Corruption timestamp for window at [%p] was [%lu].\n",
+ (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+
+ nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp = GetTimeInMillis();
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSetCorruptedTimestamp: New corruption timestamp for window at [%p] is [%lu].\n",
+ (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+ }
+ }
+}
+
+/*
+ * Reset the timestamp taken when the drawable
+ * became initially corrupted. The timestamp is
+ * reset only after the drawable has been fully
+ * synchronized.
+ */
+
+void nxagentResetCorruptedTimestamp(DrawablePtr pDrawable)
+{
+ if (nxagentDrawableStatus(pDrawable) == Synchronized)
+ {
+ if (pDrawable -> type == DRAWABLE_PIXMAP)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetCorruptedTimestamp: Corruption timestamp for pixmap at [%p] was [%lu].\n",
+ (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+
+ nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp = 0;
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentResetCorruptedTimestamp: Corruption timestamp for window at [%p] was [%lu].\n",
+ (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+ #endif
+
+ nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp = 0;
+ }
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
new file mode 100644
index 000000000..65db133bd
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -0,0 +1,92 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Split_H__
+#define __Split_H__
+
+typedef struct _SplitResourceRec
+{
+ int pending;
+ int split;
+ int unpack;
+ DrawablePtr drawable;
+ RegionPtr region;
+ GCPtr gc;
+ int commit;
+
+} SplitResourceRec;
+
+typedef SplitResourceRec *SplitResourcePtr;
+
+extern SplitResourceRec nxagentSplitResources[];
+
+typedef struct _UnpackResourceRec
+{
+ int pending;
+ int unpack;
+ DrawablePtr drawable;
+
+} UnpackResourceRec;
+
+typedef UnpackResourceRec *UnpackResourcePtr;
+
+extern UnpackResourceRec nxagentUnpackResources[];
+
+void nxagentInitSplitResources();
+void nxagentInitUnpackResources();
+
+SplitResourcePtr nxagentAllocSplitResource();
+void nxagentFreeSplitResource(SplitResourcePtr pResource);
+
+UnpackResourcePtr nxagentAllocUnpackResource();
+void nxagentFreeUnpackResource(UnpackResourcePtr pResource);
+
+#define nxagentSplitResource(pDrawable) \
+ ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+ (nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> splitResource) : \
+ (nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource))
+
+/*
+FIXME: Make it a real function to log a warning
+ in the logs.
+
+#define nxagentSplitDrawable(pDrawable) \
+ (((pDrawable) -> type == DRAWABLE_PIXMAP && \
+ nxagentPixmapIsVirtual((PixmapPtr) pDrawable)) ? \
+ (DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable) : pDrawable)
+*/
+DrawablePtr nxagentSplitDrawable(DrawablePtr pDrawable);
+
+int nxagentCreateSplit(DrawablePtr pDrawable, GCPtr *pGC);
+void nxagentRegionSplit(DrawablePtr pDrawable, RegionPtr pRegion);
+void nxagentValidateSplit(DrawablePtr pDrawable, RegionPtr pRegion);
+void nxagentReleaseSplit(DrawablePtr pDrawable);
+
+void nxagentReleaseAllSplits(void);
+
+void nxagentSetCorruptedTimestamp(DrawablePtr pDrawable);
+void nxagentResetCorruptedTimestamp(DrawablePtr pDrawable);
+
+#endif /* __Split_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
new file mode 100644
index 000000000..51a2ecb3d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -0,0 +1,91 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xlib.h>
+#undef Bool
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointer.h"
+#define XTestSERVER_SIDE
+#include "xtestext1.h"
+
+extern CARD32 nxagentLastEventTime;
+
+void XTestGetPointerPos(short *fmousex, short *fmousey);
+
+void XTestJumpPointer(int jx, int jy, int dev_type);
+
+void XTestGenerateEvent(int dev_type, int keycode, int keystate,
+ int mousex, int mousey);
+
+void XTestGetPointerPos(short *fmousex, short *fmousey)
+{
+ int x,y;
+
+ miPointerPosition(&x, &y);
+ *fmousex = x;
+ *fmousey = y;
+}
+
+void XTestJumpPointer(int jx, int jy, int dev_type)
+{
+ miPointerAbsoluteCursor(jx, jy, GetTimeInMillis());
+}
+
+void XTestGenerateEvent(int dev_type, int keycode, int keystate,
+ int mousex, int mousey)
+{
+/*
+ xEvent tevent;
+
+ tevent.u.u.type = (dev_type == XE_POINTER) ?
+ (keystate == XTestKEY_UP) ? ButtonRelease : ButtonPress :
+ (keystate == XTestKEY_UP) ? KeyRelease : KeyPress;
+ tevent.u.u.detail = keycode;
+ tevent.u.keyButtonPointer.rootX = mousex;
+ tevent.u.keyButtonPointer.rootY = mousey;
+ tevent.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+ mieqEnqueue(&tevent);
+*/
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
new file mode 100644
index 000000000..c582f6a16
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -0,0 +1,122 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include "Trap.h"
+
+/*
+ * Set if we are dispatching a render
+ * extension request. Used to avoid
+ * reentrancy in GC operations.
+ */
+
+int nxagentGCTrap = 0;
+
+/*
+ * Set if we are enqueing an internal
+ * operation, CreateWindow and Reparent-
+ * Window. Used to remove any screen operation.
+ */
+
+int nxagentScreenTrap = 0;
+
+/*
+ * Set if we detected that our RENDER
+ * implementation is faulty.
+ */
+
+int nxagentRenderTrap = 0;
+
+/*
+ * Set if we are executing a GC operation
+ * only on the X side. Used to avoid
+ * reentrancy in FB layer.
+ */
+
+int nxagentFBTrap = 0;
+
+/*
+ * Set if we are dispatching a shared
+ * memory extension request.
+ */
+
+int nxagentShmTrap = 0;
+
+/*
+ * Set if a shared pixmap operation is
+ * requested by the client.
+ */
+
+int nxagentShmPixmapTrap = 0;
+
+/*
+ * Set if we are dispatching a XVideo
+ * extension request.
+ */
+
+int nxagentXvTrap = 0;
+
+/*
+ * Set if we are dispatching a GLX
+ * extension request.
+ */
+
+int nxagentGlxTrap = 0;
+
+/*
+ * Set while we are resuming the session.
+ */
+
+int nxagentReconnectTrap = 0;
+
+/*
+ * Set if we need to realize a drawable
+ * by using a lossless encoding.
+ */
+
+int nxagentLosslessTrap = 0;
+
+/*
+ * Set to force the synchronization of
+ * a drawable.
+ */
+
+int nxagentSplitTrap = 0;
+
+/*
+ * Set to avoid CapsLock synchronization
+ * problems when CapsLock is the first
+ * key to be pressed in the session.
+ */
+
+int nxagentXkbCapsTrap = 0;
+
+/*
+ * Set to avoid NumLock synchronization
+ * problems when NumLock is the first
+ * key to be pressed in the session.
+ */
+
+int nxagentXkbNumTrap = 0;
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
new file mode 100644
index 000000000..f0884f657
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -0,0 +1,124 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Traps_H__
+#define __Traps_H__
+
+/*
+ * Set if we are dispatching a render
+ * extension request. Used to avoid
+ * reentrancy in GC operations.
+ */
+
+extern int nxagentGCTrap;
+
+/*
+ * Set if we are enqueing an internal
+ * operation, CreateWindow and Reparent-
+ * Window. Used to remove any screen operation.
+ */
+
+extern int nxagentScreenTrap;
+
+/*
+ * Set if we detected that our RENDER
+ * implementation is faulty.
+ */
+
+extern int nxagentRenderTrap;
+
+/*
+ * Set if we are executing a GC operation
+ * only on the X side. Used to avoid
+ * reentrancy in FB layer.
+ */
+
+extern int nxagentFBTrap;
+
+/*
+ * Set if we are dispatching a shared
+ * memory extension request.
+ */
+
+extern int nxagentShmTrap;
+
+/*
+ * Set if a shared pixmap operation is
+ * requested by the client.
+ */
+
+extern int nxagentShmPixmapTrap;
+
+/*
+ * Set if we are dispatching a XVideo
+ * extension request.
+ */
+
+extern int nxagentXvTrap;
+
+/*
+ * Set if we are dispatching a GLX
+ * extension request.
+ */
+
+extern int nxagentGlxTrap;
+
+/*
+ * Set while we are resuming the session.
+ */
+
+extern int nxagentReconnectTrap;
+
+/*
+ * Set if we need to realize a drawable
+ * by using a lossless encoding.
+ */
+
+extern int nxagentLosslessTrap;
+
+/*
+ * Set to force the synchronization of
+ * a drawable.
+ */
+
+extern int nxagentSplitTrap;
+
+/*
+ * Set to avoid CapsLock synchronization
+ * problems when CapsLock is the first
+ * key to be pressed in the session.
+ */
+
+extern int nxagentXkbCapsTrap;
+
+/*
+ * Set to avoid NumLock synchronization
+ * problems when NumLock is the first
+ * key to be pressed in the session.
+ */
+
+extern int nxagentXkbNumTrap;
+
+#endif /* __Trap_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
new file mode 100644
index 000000000..8a3335424
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -0,0 +1,55 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Utils_H__
+#define __Utils_H__
+
+/*
+ * Number of bits in fixed point operations.
+ */
+
+#define PRECISION 16
+
+/*
+ * "1" ratio means "don't scale".
+ */
+
+#define DONT_SCALE (1 << PRECISION)
+
+#define nxagentScale(i, ratio) (((i) * (ratio)) >> (PRECISION))
+
+#ifndef MIN
+#define MIN(A, B) ( (A) < (B) ? (A) : (B) )
+#endif
+
+#ifndef MAX
+#define MAX(A, B) ( (A) > (B) ? (A) : (B) );
+#endif
+
+static inline const char * validateString(const char *str) {
+ return str ? str : "(null)";
+}
+
+#endif /* __Utils_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
new file mode 100644
index 000000000..eebd1fcc1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -0,0 +1,167 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#include "scrnintstr.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "resource.h"
+
+#include "X.h"
+#include "Xproto.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Visual.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Predefined visual used for drawables
+ * having a 32 bits depth.
+ */
+
+Visual nxagentAlphaVisual;
+
+Visual *nxagentVisual(VisualPtr pVisual)
+{
+ XVisualInfo visual;
+
+ int i;
+
+ visual.class = pVisual->class;
+ visual.bits_per_rgb = pVisual->bitsPerRGBValue;
+ visual.colormap_size = pVisual->ColormapEntries;
+ visual.depth = pVisual->nplanes;
+ visual.red_mask = pVisual->redMask;
+ visual.green_mask = pVisual->greenMask;
+ visual.blue_mask = pVisual->blueMask;
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ if (nxagentCompareVisuals(visual, nxagentVisuals[i]) == 1)
+ {
+ return nxagentVisuals[i].visual;
+ }
+ }
+
+ return NULL;
+}
+
+Visual *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ {
+ if (pScreen->visuals[i].vid == visual)
+ {
+ return nxagentVisual(&pScreen->visuals[i]);
+ }
+ }
+
+ return NULL;
+}
+
+Colormap nxagentDefaultVisualColormap(Visual *visual)
+{
+ int i;
+
+ for (i = 0; i < nxagentNumVisuals; i++)
+ {
+ if (nxagentVisuals[i].visual == visual)
+ {
+ return nxagentDefaultColormaps[i];
+ }
+ }
+
+ return None;
+}
+
+/*
+ * This is currently unused. It should serve
+ * the scope of matching a visual whenever
+ * a drawable has a different depth than the
+ * real display.
+ */
+
+Visual *nxagentVisualFromDepth(ScreenPtr pScreen, int depth)
+{
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ {
+ if (pScreen->visuals[i].nplanes == depth)
+ {
+ return nxagentVisual(&pScreen->visuals[i]);
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Create a fake 32 bits depth visual and
+ * initialize it based on the endianess
+ * of the remote display.
+ */
+
+void nxagentInitAlphaVisual()
+{
+ nxagentAlphaVisual.visualid = XAllocID(nxagentDisplay);
+
+ /*
+ * Color masks are referred to bits inside
+ * the pixel. This is independent from the
+ * endianess.
+ */
+
+ nxagentAlphaVisual.red_mask = 0x00ff0000;
+ nxagentAlphaVisual.green_mask = 0x0000ff00;
+ nxagentAlphaVisual.blue_mask = 0x000000ff;
+
+ #ifdef TEST
+ fprintf(stderr,"nxagentInitAlphaVisual: Set alpha visual with id [0x%lx] mask [0x%lx,0x%lx,0x%lx].\n",
+ nxagentAlphaVisual.visualid, nxagentAlphaVisual.red_mask,
+ nxagentAlphaVisual.green_mask, nxagentAlphaVisual.blue_mask);
+ #endif
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
new file mode 100644
index 000000000..70799f3f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -0,0 +1,81 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef __Visual_H__
+#define __Visual_H__
+
+Visual *nxagentVisual(VisualPtr pVisual);
+Visual *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+Visual *nxagentVisualFromDepth(ScreenPtr pScreen, int depth);
+
+Colormap nxagentDefaultVisualColormap(Visual *visual);
+
+#define nxagentDefaultVisual(pScreen) \
+ nxagentVisualFromID((pScreen), (pScreen) -> rootVisual)
+
+/*
+ * Visual generated by Xorg and Xfree86 at
+ * 16-bit depth differs on the bits_per_rgb
+ * value, so we avoid checking it.
+ */
+
+/*
+ * Some Solaris X servers uses the color
+ * masks inverted, so that the red and
+ * the blue mask are switched. To reconnect
+ * the session on this displays, we do a
+ * double check, as workaround.
+ */
+
+#define nxagentCompareVisuals(v1, v2) \
+ ((v1).depth == (v2).depth && \
+ /*(v1).bits_per_rgb == (v2).bits_per_rgb &&*/ \
+ (v1).class == (v2).class && \
+ ((v1).red_mask == (v2).red_mask || \
+ (v1).red_mask == (v2).blue_mask) && \
+ (v1).green_mask == (v2).green_mask && \
+ ((v1).blue_mask == (v2).blue_mask || \
+ (v1).blue_mask == (v2).red_mask) && \
+ (v1).colormap_size == (v2).colormap_size)
+
+Visual nxagentAlphaVisual;
+
+void nxagentInitAlphaVisual();
+
+#endif /* __Visual_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
new file mode 100644
index 000000000..23e1d5452
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -0,0 +1,3930 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <unistd.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "region.h"
+#include "dixstruct.h"
+#include "selection.h"
+#include "mi.h"
+#include "fb.h"
+#include "mibstorest.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "Colormap.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Clipboard.h"
+#include "Args.h"
+#include "Trap.h"
+#include "Rootless.h"
+#include "Atoms.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Dialog.h"
+#include "Splash.h"
+#include "Holder.h"
+#include "Init.h"
+#include "Composite.h"
+#include "Events.h"
+
+#include <nx/NX.h>
+#include "compext/Compext.h"
+
+#include "Xatom.h"
+
+/*
+ * Used to register the window's privates.
+ */
+
+int nxagentWindowPrivateIndex;
+
+/*
+ * Number of windows which need synchronization.
+ */
+
+int nxagentCorruptedWindows;
+
+/*
+ * Used to track nxagent window's visibility.
+ */
+
+int nxagentVisibility = VisibilityUnobscured;
+unsigned long nxagentVisibilityTimeout = 0;
+Bool nxagentVisibilityStop = False;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Useful to test the window configuration
+ * failures.
+ */
+
+#ifdef TEST
+#define MAKE_SYNC_CONFIGURE_WINDOW XSync(nxagentDisplay, 0)
+#else
+#define MAKE_SYNC_CONFIGURE_WINDOW
+#endif
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+extern WindowPtr nxagentRootTileWindow;
+
+/*
+ * Also referenced in Events.c.
+ */
+
+int nxagentSplashCount = 0;
+
+#define RECTLIMIT 25
+#define BSPIXMAPLIMIT 128
+
+Bool nxagentExposeArrayIsInitialized = False;
+Window nxagentConfiguredSynchroWindow;
+static int nxagentExposeSerial = 0;
+
+StoringPixmapPtr nxagentBSPixmapList[BSPIXMAPLIMIT];
+
+/*
+ * Used to walk through the window hierarchy
+ * to find a window
+ */
+
+typedef struct _WindowMatch
+{
+ WindowPtr pWin;
+ Window id;
+
+} WindowMatchRec;
+
+Bool nxagentReconnectAllWindows(void *);
+
+Bool nxagentDisconnectAllWindows(void);
+
+Bool nxagentIsIconic(WindowPtr);
+
+/*
+ * From NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr, Atom, long, long, Bool, Atom, Atom*, int*,
+ unsigned long*, unsigned long*, unsigned char**);
+
+/*
+ * From NXwindow.c.
+ */
+
+void nxagentClearSplash(WindowPtr pWin);
+
+/*
+ * Other local functions.
+ */
+
+static Bool nxagentSomeWindowsAreMapped(void);
+
+static void nxagentFrameBufferPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+
+static void nxagentTraverseWindow(WindowPtr, void(*)(void *, XID, void *), void *);
+
+static void nxagentDisconnectWindow(void *, XID, void *);
+
+static Bool nxagentLoopOverWindows(void(*)(void *, XID, void *));
+
+static void nxagentReconfigureWindowCursor(void *, XID, void *);
+
+static void nxagentReconnectWindow(void *, XID, void *);
+
+static void nxagentReconfigureWindow(void *, XID, void *);
+
+static int nxagentForceExposure(WindowPtr pWin, void * ptr);
+
+/* by dimbor */
+typedef struct
+{
+ CARD32 state;
+ Window icon;
+}
+nxagentWMStateRec;
+
+/*
+ * This is currently unused.
+ */
+
+#ifdef TEST
+
+static Bool nxagentCheckWindowIntegrity(WindowPtr pWin);
+
+#endif
+
+WindowPtr nxagentGetWindowFromID(Window id)
+{
+ WindowPtr pWin = screenInfo.screens[0]->root;
+
+ while (pWin && nxagentWindowPriv(pWin))
+ {
+ if (nxagentWindow(pWin) == id)
+ {
+ return pWin;
+ }
+
+ if (pWin -> nextSib)
+ {
+ pWin = pWin -> nextSib;
+ }
+ else
+ {
+ pWin = pWin -> firstChild;
+ }
+ }
+
+ return NULL;
+}
+
+static int nxagentFindWindowMatch(WindowPtr pWin, void * ptr)
+{
+ WindowMatchRec *match = (WindowMatchRec *) ptr;
+
+ if (match -> id == nxagentWindow(pWin))
+ {
+ match -> pWin = pWin;
+
+ return WT_STOPWALKING;
+ }
+ else
+ {
+ return WT_WALKCHILDREN;
+ }
+}
+
+WindowPtr nxagentWindowPtr(Window window)
+{
+ int i;
+
+ WindowMatchRec match;
+
+ match.pWin = NullWindow;
+ match.id = window;
+
+ for (i = 0; i < nxagentNumScreens; i++)
+ {
+ WalkTree(screenInfo.screens[i], nxagentFindWindowMatch, (void *) &match);
+
+ if (match.pWin) break;
+ }
+
+ return match.pWin;
+}
+
+Bool nxagentCreateWindow(pWin)
+ WindowPtr pWin;
+{
+ unsigned long mask;
+ XSetWindowAttributes attributes;
+ Visual *visual;
+ ColormapPtr pCmap;
+
+ if (nxagentScreenTrap)
+ {
+ return True;
+ }
+
+ nxagentSplashCount++;
+
+ if (nxagentSplashCount == 2)
+ {
+ nxagentClearSplash(nxagentRootTileWindow);
+ }
+#ifdef NXAGENT_LOGO_DEBUG
+ fprintf(stderr, "nxagentSplashCount: %d\n", nxagentSplashCount);
+#endif
+
+ if (pWin->drawable.class == InputOnly) {
+ mask = CWEventMask;
+ visual = CopyFromParent;
+ }
+ else {
+ mask = CWEventMask | CWBackingStore;
+
+ if (pWin->optional)
+ {
+ mask |= CWBackingPlanes | CWBackingPixel;
+ attributes.backing_planes = pWin->optional->backingBitPlanes;
+ attributes.backing_pixel = pWin->optional->backingPixel;
+ }
+
+ attributes.backing_store = NotUseful;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateWindow: Backing store on window at %p is %d.\n",
+ (void*)pWin, attributes.backing_store);
+ #endif
+
+/*
+FIXME: We need to set save under on the real display?
+*/
+ if (nxagentSaveUnder == True)
+ {
+ mask |= CWSaveUnder;
+ attributes.save_under = False;
+ }
+
+ if (pWin->parent) {
+ if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
+ visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ mask |= CWColormap;
+ if (pWin->optional->colormap) {
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ attributes.colormap = nxagentColormap(pCmap);
+ }
+ else
+ attributes.colormap = nxagentDefaultVisualColormap(visual);
+ }
+ else if (pWin->optional)
+ visual = CopyFromParent;
+ else {
+ visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ mask |= CWColormap;
+ attributes.colormap = nxagentDefaultVisualColormap(visual);
+ }
+ }
+ else { /* root windows have their own colormaps at creation time */
+ visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ mask |= CWColormap;
+ attributes.colormap = nxagentColormap(pCmap);
+ }
+ }
+
+ if (mask & CWEventMask)
+ {
+ /* Assume that the mask fits in int... broken on Big Endian 64bit systems. */
+ Mask tmp_mask = attributes.event_mask;
+ nxagentGetEventMask(pWin, &tmp_mask);
+ attributes.event_mask = (int)tmp_mask;
+ }
+ #ifdef WARNING
+ else
+ {
+ attributes.event_mask = NoEventMask;
+ }
+ #endif
+
+ /*
+ * Select the event mask if window is a top level
+ * window. This at least makes the keyboard barely
+ * work.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateWindow: Going to create new window.\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateWindow: Creating %swindow at %p current event mask = %lX mask & CWEventMask = %ld "
+ "event_mask = %lX\n",
+ nxagentWindowTopLevel(pWin) ? "toplevel " : "", (void*)pWin, pWin -> eventMask,
+ mask & CWEventMask, attributes.event_mask);
+
+ fprintf(stderr, "nxagentCreateWindow: position [%d,%d] size [%d,%d] depth [%d] border [%d] class [%d].\n",
+ pWin->origin.x - wBorderWidth(pWin), pWin->origin.y - wBorderWidth(pWin),
+ pWin->drawable.width, pWin->drawable.height, pWin->drawable.depth, pWin->borderWidth,
+ pWin->drawable.class);
+ #endif
+
+ nxagentWindowPriv(pWin)->window = XCreateWindow(nxagentDisplay,
+ nxagentWindowParent(pWin),
+ pWin->origin.x -
+ wBorderWidth(pWin),
+ pWin->origin.y -
+ wBorderWidth(pWin),
+ pWin->drawable.width,
+ pWin->drawable.height,
+ pWin->borderWidth,
+ pWin->drawable.depth,
+ pWin->drawable.class,
+ visual,
+ mask, &attributes);
+
+ nxagentWindowPriv(pWin) -> isMapped = 0;
+ nxagentWindowPriv(pWin) -> isRedirected = 0;
+
+ nxagentWindowPriv(pWin) -> visibilityState = VisibilityUnobscured;
+
+ nxagentWindowPriv(pWin) -> corruptedRegion = RegionCreate(NULL, 1);
+
+ nxagentWindowPriv(pWin) -> hasTransparentChildren = 0;
+
+ nxagentWindowPriv(pWin) -> containGlyphs = 0;
+
+ nxagentWindowPriv(pWin) -> corruptedId = 0;
+
+ nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 0;
+
+ nxagentWindowPriv(pWin) -> synchronizationBitmap = NullPixmap;
+
+ nxagentWindowPriv(pWin) -> corruptedTimestamp = 0;
+
+ nxagentWindowPriv(pWin) -> splitResource = NULL;
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ if (pWin != nxagentRootlessWindow)
+ {
+ WindowPtr pParent = pWin -> parent;
+
+ if (pParent && nxagentWindowPriv(pParent) -> isMapped == 1)
+ {
+ nxagentWindowPriv(pWin) -> isMapped = 1;
+ }
+ else
+ {
+ nxagentWindowPriv(pWin) -> isMapped = 0;
+ }
+ }
+ else
+ {
+ nxagentWindowPriv(pWin) -> isMapped = 0;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentCreateWindow: Created new window with id [%ld].\n",
+ nxagentWindowPriv(pWin)->window);
+ #endif
+
+ /*
+ * Set the WM_DELETE_WINDOW protocols on every
+ * top level window. Also redirect the window
+ * if it is a top level.
+ */
+
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+ {
+ Atom prop = nxagentMakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), True);
+
+ XlibAtom atom = nxagentMakeAtom("WM_DELETE_WINDOW", strlen("WM_DELETE_WINDOW"), True);
+
+ XSetWMProtocols(nxagentDisplay, nxagentWindowPriv(pWin)->window, &atom, 1);
+
+ nxagentAddPropertyToList(prop, pWin);
+
+ /*
+ * Redirect the window to the off-screen
+ * memory, if the composite extension is
+ * supported on the display.
+ */
+/*
+FIXME: Do all the windows for which nxagentWindowTopLevel(pWin)
+ returns true need to be redirected?
+*/
+ nxagentRedirectWindow(pWin);
+ }
+
+ nxagentWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+ nxagentWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+ nxagentWindowPriv(pWin)->width = pWin->drawable.width;
+ nxagentWindowPriv(pWin)->height = pWin->drawable.height;
+ nxagentWindowPriv(pWin)->borderWidth = pWin->borderWidth;
+ nxagentWindowPriv(pWin)->siblingAbove = None;
+ nxagentWindowPriv(pWin)->pPicture = NULL;
+
+ if (nxagentRootTileWindow)
+ {
+ if (nxagentWindowPriv(pWin)->window != nxagentWindowPriv(nxagentRootTileWindow)->window)
+ {
+ XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow)->window);
+ }
+ }
+
+ if (pWin->nextSib)
+ {
+ nxagentWindowPriv(pWin->nextSib)->siblingAbove = nxagentWindow(pWin);
+ }
+
+#ifdef NXAGENT_SHAPE2
+#ifdef SHAPE
+ nxagentWindowPriv(pWin)->boundingShape = NULL;
+ nxagentWindowPriv(pWin)->clipShape = NULL;
+#endif /* SHAPE */
+#else
+#ifdef SHAPE
+ nxagentWindowPriv(pWin)->boundingShape = RegionCreate(NULL, 1);
+ nxagentWindowPriv(pWin)->clipShape = RegionCreate(NULL, 1);
+#endif /* SHAPE */
+#endif
+
+ fbCreateWindow(pWin);
+
+ /*
+ * Only the root window will have
+ * the right colormap.
+ */
+
+ if (!pWin->parent)
+ {
+ nxagentSetInstalledColormapWindows(pWin->drawable.pScreen);
+ }
+
+ return True;
+}
+
+Bool nxagentSomeWindowsAreMapped()
+{
+ WindowPtr pWin = screenInfo.screens[0]->root -> firstChild;
+
+ while (pWin)
+ {
+ if ((pWin -> mapped || nxagentIsIconic(pWin)) &&
+ pWin -> drawable.class == InputOutput)
+ {
+ return True;
+ }
+
+ pWin = pWin -> nextSib;
+ }
+
+ return False;
+}
+
+Bool nxagentDestroyWindow(WindowPtr pWin)
+{
+ int i;
+ int j;
+
+ nxagentPrivWindowPtr pWindowPriv;
+
+ if (nxagentScreenTrap == 1)
+ {
+ return 1;
+ }
+
+ nxagentClearClipboard(NULL, pWin);
+
+ for (j = 0; j < nxagentExposeQueue.length; j++)
+ {
+ i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+ if (nxagentExposeQueue.exposures[i].pWindow == pWin)
+ {
+ if (nxagentExposeQueue.exposures[i].localRegion != NullRegion)
+ {
+ RegionDestroy(nxagentExposeQueue.exposures[i].localRegion);
+ }
+
+ nxagentExposeQueue.exposures[i].localRegion = NullRegion;
+
+ if (nxagentExposeQueue.exposures[i].remoteRegion != NullRegion)
+ {
+ RegionDestroy(nxagentExposeQueue.exposures[i].remoteRegion);
+ }
+
+ nxagentExposeQueue.exposures[i].remoteRegion = NullRegion;
+ }
+ }
+
+ nxagentDeleteConfiguredWindow(pWin);
+
+ pWindowPriv = nxagentWindowPriv(pWin);
+
+ if (pWin->nextSib)
+ {
+ nxagentWindowPriv(pWin->nextSib)->siblingAbove =
+ pWindowPriv->siblingAbove;
+ }
+
+ #ifdef NXAGENT_SHAPE2
+
+ #ifdef SHAPE
+
+ if (pWindowPriv->boundingShape)
+ {
+ RegionDestroy(
+ pWindowPriv->boundingShape);
+ }
+
+ if (pWindowPriv->clipShape)
+ {
+ RegionDestroy(
+ pWindowPriv->clipShape);
+ }
+
+ #endif
+
+ #else
+
+ RegionDestroy(
+ pWindowPriv->boundingShape);
+
+ RegionDestroy(
+ pWindowPriv->clipShape);
+
+ #endif
+
+ if (pWindowPriv -> corruptedRegion)
+ {
+ RegionDestroy(
+ pWindowPriv -> corruptedRegion);
+
+ pWindowPriv -> corruptedRegion = NULL;
+ }
+
+ if (nxagentSynchronization.pDrawable == (DrawablePtr) pWin)
+ {
+ nxagentSynchronization.pDrawable = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyWindow: Synchronization drawable [%p] removed from resources.\n",
+ (void *) pWin);
+ #endif
+ }
+
+ nxagentDestroyCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+
+ nxagentDestroyDrawableBitmap((DrawablePtr) pWin);
+
+ if (pWindowPriv -> splitResource != NULL)
+ {
+ nxagentReleaseSplit((DrawablePtr) pWin);
+ }
+
+ XDestroyWindow(nxagentDisplay, nxagentWindow(pWin));
+
+ if (nxagentOption(Rootless))
+ {
+ nxagentRootlessDelTopLevelWindow(pWin);
+ }
+
+ nxagentSplashCount--;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentDestroyWindow: The splash counter is now [%d].\n",
+ nxagentSplashCount);
+ #endif
+
+ if (nxagentSplashCount == 1)
+ {
+ XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow) -> window);
+ }
+
+ if (pWin == nxagentRootTileWindow)
+ {
+ nxagentWindowPriv(nxagentRootTileWindow)->window = None;
+
+ nxagentRootTileWindow = None;
+ }
+
+ pWindowPriv->window = None;
+
+ if (pWin -> optional)
+ {
+ pWin -> optional -> userProps = NULL;
+ }
+
+ if (nxagentOption(Rootless) && nxagentRootlessDialogPid == 0 &&
+ nxagentLastWindowDestroyed == False && nxagentSomeWindowsAreMapped() == False)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentDestroyWindow: Last mapped window as been destroyed.\n");
+ #endif
+
+ nxagentLastWindowDestroyed = True;
+ nxagentLastWindowDestroyedTime = GetTimeInMillis();
+ }
+
+ return True;
+}
+
+Bool nxagentPositionWindow(WindowPtr pWin, int x, int y)
+{
+ if (nxagentScreenTrap == 1)
+ {
+ return True;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentPositionWindow: Changing position of window [%p][%ld] to [%d,%d].\n",
+ (void *) pWin, nxagentWindow(pWin), x, y);
+ #endif
+
+ nxagentAddConfiguredWindow(pWin, CWParent | CWX | CWY | CWWidth |
+ CWHeight | CWBorderWidth);
+
+ return True;
+}
+
+void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
+{
+ if (nxagentScreenTrap == 1)
+ {
+ return;
+ }
+
+ nxagentAddConfiguredWindow(pWin, CW_RootlessRestack);
+
+}
+
+void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
+{
+ XEvent e;
+
+ if (nxagentOption(Rootless) == 1)
+ {
+ return;
+ }
+
+ if (switchOn == 0)
+ {
+ nxagentWMDetect();
+
+ /*
+ * The smart scheduler could be stopped while
+ * waiting for the reply. In this case we need
+ * to yield explicitly to avoid to be stuck in
+ * the dispatch loop forever.
+ */
+
+ isItTimeToYield = 1;
+
+ if (nxagentWMIsRunning == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "Warning: Can't switch to window mode, no window manager "
+ "has been detected.\n");
+ #endif
+
+ return;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchFullscreen: Switching to %s mode.\n",
+ switchOn ? "fullscreen" : "windowed");
+ #endif
+
+ nxagentChangeOption(Fullscreen, switchOn);
+
+ memset(&e, 0, sizeof(e));
+
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = nxagentAtoms[13]; /* _NET_WM_STATE */
+ e.xclient.display = nxagentDisplay;
+ e.xclient.window = nxagentDefaultWindows[pScreen -> myNum];
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = nxagentOption(Fullscreen) ? 1 : 0;
+ e.xclient.data.l[1] = nxagentAtoms[14]; /* _NET_WM_STATE_FULLSCREEN */
+
+ XSendEvent(nxagentDisplay, DefaultRootWindow(nxagentDisplay), False,
+ SubstructureRedirectMask, &e);
+
+ if (switchOn == 1)
+ {
+ nxagentFullscreenWindow = nxagentDefaultWindows[pScreen -> myNum];
+
+ nxagentGrabPointerAndKeyboard(NULL);
+ }
+ else
+ {
+ nxagentFullscreenWindow = None;
+
+ nxagentUngrabPointerAndKeyboard(NULL);
+ }
+}
+
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
+{
+ Window w;
+ XSetWindowAttributes attributes;
+ unsigned long valuemask;
+
+ if (nxagentOption(Rootless))
+ {
+ return;
+ }
+
+ if (!switchOn)
+ {
+ nxagentWMDetect();
+
+ if (!nxagentWMIsRunning)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
+ #endif
+
+ return;
+ }
+ }
+
+ w = nxagentDefaultWindows[pScreen -> myNum];
+ attributes.override_redirect = switchOn;
+ valuemask = CWOverrideRedirect;
+ XUnmapWindow(nxagentDisplay, w);
+ XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+
+ XReparentWindow(nxagentDisplay, w, DefaultRootWindow(nxagentDisplay), 0, 0);
+
+ if (switchOn)
+ {
+ /*
+ * Change to fullscreen mode.
+ */
+
+ struct timeval timeout;
+ int i;
+ XEvent e;
+
+ /*
+ * Wait for window manager reparenting the default window.
+ */
+
+ for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Going to wait for the ReparentNotify event.\n");
+ #endif
+
+ if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
+ {
+ break;
+ }
+
+ /*
+ * This should also flush
+ * the NX link for us.
+ */
+
+ XSync(nxagentDisplay, 0);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 50 * 1000;
+
+ nxagentWaitEvents(nxagentDisplay, &timeout);
+ }
+
+ if (i < 100)
+ {
+ /*
+ * The window manager has done with the reparent
+ * operation. We can resize and map the window.
+ */
+
+ nxagentChangeOption(Fullscreen, True);
+ nxagentChangeOption(AllScreens, True);
+
+
+ /*
+ * Save the window-mode configuration.
+ */
+
+ nxagentChangeOption(SavedX, nxagentOption(X));
+ nxagentChangeOption(SavedY, nxagentOption(Y));
+ nxagentChangeOption(SavedWidth, nxagentOption(Width));
+ nxagentChangeOption(SavedHeight, nxagentOption(Height));
+ nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+ nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+ /*
+ * Reconf the Default window.
+ */
+
+ nxagentChangeOption(X, 0);
+ nxagentChangeOption(Y, 0);
+ nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+ nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+ /*
+ * Move the root window.
+ */
+
+ nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
+ nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
+ nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+ nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+ XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+ nxagentOption(Width), nxagentOption(Height));
+
+ nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
+ nxagentOption(RootX), nxagentOption(RootY));
+
+ /*
+ * We disable the screensaver when changing
+ * mode to fullscreen. Is it really needed?
+ */
+
+ XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+
+ if (nxagentIconWindow == None)
+ {
+ nxagentIconWindow = nxagentCreateIconWindow();
+
+ XMapWindow(nxagentDisplay, nxagentIconWindow);
+ }
+
+ XMapRaised(nxagentDisplay, w);
+ XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
+ XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
+ nxagentFullscreenWindow = w;
+
+ if (nxagentOption(DesktopResize) == 1)
+ {
+ if (nxagentOption(Shadow) == 0)
+ {
+ nxagentChangeScreenConfig(0, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+ HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)), 0, 0);
+ }
+ else
+ {
+ nxagentShadowAdaptToRatio();
+ }
+ }
+ }
+ else
+ {
+ /*
+ * We have waited for a reparent event unsuccessfully.
+ * Something happened to the window manager.
+ */
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Expected ReparentNotify event missing.\n");
+ #endif
+
+ nxagentWMIsRunning = False;
+ attributes.override_redirect = False;
+ XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+ XMapWindow(nxagentDisplay, w);
+ }
+ }
+ else
+ {
+ /*
+ * FIXME:
+ * It could be necessary:
+ * - To restore screensaver.
+ * - To set or reset nxagentForceBackingStore flag.
+ * - To propagate device settings to the X server if no WM is running.
+ */
+
+ /*
+ * Change to windowed mode.
+ */
+
+ nxagentChangeOption(Fullscreen, False);
+ nxagentChangeOption(AllScreens, False);
+
+ XDestroyWindow(nxagentDisplay, nxagentIconWindow);
+
+ nxagentIconWindow = nxagentFullscreenWindow = None;
+
+ if (nxagentOption(DesktopResize) == 1)
+ {
+ nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
+ nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
+
+ if (nxagentOption(Shadow) == 0)
+ {
+ nxagentChangeScreenConfig(0, nxagentOption(RootWidth),
+ nxagentOption(RootHeight), 0, 0);
+ }
+ }
+
+ if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
+ {
+ nxagentChangeOption(X, nxagentOption(SavedX) -
+ nxagentOption(WMBorderWidth));
+ nxagentChangeOption(Y, nxagentOption(SavedY) -
+ nxagentOption(WMTitleHeight));
+ }
+ else
+ {
+ nxagentChangeOption(X, nxagentOption(SavedX));
+ nxagentChangeOption(Y, nxagentOption(SavedY));
+ }
+
+ nxagentChangeOption(Width, nxagentOption(SavedWidth));
+ nxagentChangeOption(Height, nxagentOption(SavedHeight));
+
+ if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
+ {
+ nxagentShadowAdaptToRatio();
+ }
+
+ XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+ nxagentOption(Width), nxagentOption(Height));
+
+ nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root), 0, 0);
+ XMapWindow(nxagentDisplay, w);
+
+ nxagentChangeOption(RootX, 0);
+ nxagentChangeOption(RootY, 0);
+ }
+
+ XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+ nxagentOption(Width), nxagentOption(Height));
+
+ nxagentSetPrintGeometry(pScreen -> myNum);
+}
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentUpdateViewportFrame(int x, int y, int w, int h)
+{
+ /*
+ * Four virtual windows make a frame around the viewport. We move the frame
+ * with the viewport together. The areas going into the viewport were covered by
+ * the frame and become exposed. This make the agent send expose events to his
+ * clients.
+ */
+
+ XID values[3];
+ Mask mask;
+
+ /*
+ * nxagentScreenTrap = True;
+ */
+
+ values[2] = Above;
+
+ values[1] = nxagentOption(RootHeight);
+
+ mask = CWX | CWHeight | CWStackMode;
+ values[0] = x - NXAGENT_FRAME_WIDTH;
+ ConfigureWindow(nxagentViewportFrameLeft, mask, (XID *) &values, serverClient);
+
+ values[0] = x + w;
+ ConfigureWindow(nxagentViewportFrameRight, mask, (XID *) &values, serverClient);
+
+ values[1] = nxagentOption(RootWidth);
+
+ mask = CWY | CWWidth | CWStackMode;
+ values[0] = y - NXAGENT_FRAME_WIDTH;
+ ConfigureWindow(nxagentViewportFrameAbove, mask, (XID *) &values, serverClient);
+
+ values[0] = y + h;
+ ConfigureWindow(nxagentViewportFrameBelow, mask, (XID *) &values, serverClient);
+
+ /*
+ * nxagentScreenTrap = False;
+ */
+}
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift)
+{
+ int newX;
+ int newY;
+ int oldX;
+ int oldY;
+
+ Bool doMove = False;
+ oldX = 0;
+ oldY = 0;
+
+ if (nxagentOption(Rootless))
+ {
+ return;
+ }
+
+ /*
+ * We must keep x coordinate between viewportXSpan and zero, if viewportXSpan
+ * is less then zero. If viewportXSpan is greater or equal to zero, it means
+ * the agent root window has a size smaller than the agent default window.
+ * In this case we keep the old coordinate.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentMoveViewport: RootX[%i] RootY[%i], hShift[%i] vShift[%i].\n",
+ nxagentOption(RootX), nxagentOption(RootY), hShift, vShift);
+ #endif
+
+ nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+
+ nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+ if (nxagentOption(ViewportXSpan) < 0)
+ {
+ newX = nxagentOption(RootX) - hShift;
+
+ if (newX > 0)
+ {
+ newX = 0;
+ }
+ else if (newX < nxagentOption(ViewportXSpan))
+ {
+ newX = nxagentOption(ViewportXSpan);
+ }
+ }
+ else if (nxagentOption(ViewportXSpan) == 0)
+ {
+ newX = 0;
+ }
+ else
+ {
+ newX = nxagentOption(RootX);
+ }
+
+ if (nxagentOption(ViewportYSpan) < 0)
+ {
+ newY = nxagentOption(RootY) - vShift;
+
+ if (newY > 0)
+ {
+ newY = 0;
+ }
+ else if (newY < nxagentOption(ViewportYSpan))
+ {
+ newY = nxagentOption(ViewportYSpan);
+ }
+ }
+ else if (nxagentOption(ViewportYSpan) == 0)
+ {
+ newY = 0;
+ }
+ else
+ {
+ newY = nxagentOption(RootY);
+ }
+
+ oldX = nxagentOption(RootX);
+
+ if (newX != nxagentOption(RootX))
+ {
+ nxagentChangeOption(RootX, newX);
+
+ doMove = True;
+ }
+
+ oldY = nxagentOption(RootY);
+
+ if (newY != nxagentOption(RootY))
+ {
+ nxagentChangeOption(RootY, newY);
+
+ doMove = True;
+ }
+
+ if (doMove)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMoveViewport: New viewport geometry: (%d, %d)-"
+ "(%d, %d)\n", -nxagentOption(RootX), -nxagentOption(RootY),
+ -nxagentOption(RootX) + nxagentOption(Width),
+ -nxagentOption(RootY) + nxagentOption(Height));
+
+ fprintf(stderr, "nxagentMoveViewport: Root geometry x=[%d] y=[%d]\n",
+ pScreen->root -> drawable.x,
+ pScreen->root -> drawable.y );
+ #endif
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(pScreen->root),
+ nxagentOption(RootX), nxagentOption(RootY));
+
+ if (nxagentOption(ClientOs) == ClientOsWinnt)
+ {
+ /*
+ * If doMove is True we add exposed rectangles
+ * to the remote expose region. This is done to
+ * refresh the areas showed newly in the viewport.
+ * We create two rectangles, one for horizontal
+ * pan and one for vertical pan.
+ */
+
+ BoxRec hRect;
+ BoxRec vRect;
+
+ hRect.x1 = -newX;
+ hRect.y1 = -newY;
+
+ if (hShift < 0)
+ {
+ hRect.x2 = -oldX;
+ hRect.y2 = -newY + nxagentOption(Height);
+ }
+ else if (hShift > 0)
+ {
+ hRect.x1 = -oldX + nxagentOption(Width);
+ hRect.x2 = -newX + nxagentOption(Width);
+ hRect.y2 = -newY + nxagentOption(Height);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentMoveViewport: hRect p1[%i, %i] - p2[%i, %i].\n", hRect.x1, hRect.y1, hRect.x2, hRect.y2);
+ #endif
+
+ vRect.x1 = -newX;
+ vRect.y1 = -newY;
+
+ if (vShift < 0)
+ {
+ vRect.x2 = -newX + nxagentOption(Width);
+ vRect.y2 = -oldY;
+ }
+ else if (vShift > 0)
+ {
+ vRect.y1 = -oldY + nxagentOption(Height);
+ vRect.x2 = -newX + nxagentOption(Width);
+ vRect.y2 = -newY + nxagentOption(Height);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentMoveViewport: vRect p1[%i, %i] - p2[%i, %i].\n", vRect.x1, vRect.y1, vRect.x2, vRect.y2);
+ #endif
+
+ if (oldX != newX && hRect.x1 != hRect.x2 && hRect.y1 != hRect.y2)
+ {
+ nxagentAddRectToRemoteExposeRegion(&hRect);
+ }
+
+ if (oldY != newY && vRect.x1 != vRect.x2 && vRect.y1 != vRect.y2)
+ {
+ nxagentAddRectToRemoteExposeRegion(&vRect);
+ }
+ }
+ }
+
+ nxagentUpdateViewportFrame(-nxagentOption(RootX), -nxagentOption(RootY),
+ nxagentOption(Width), nxagentOption(Height));
+}
+
+void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask)
+{
+ unsigned int valuemask;
+ XWindowChanges values;
+ int offX, offY;
+ int i, j;
+
+ offX = nxagentWindowPriv(pWin)->x - pWin->origin.x;
+ offY = nxagentWindowPriv(pWin)->y - pWin->origin.y;
+
+ if (nxagentScreenTrap == 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: WARNING: Called with the screen trap set.\n");
+ #endif
+
+ return;
+ }
+
+ if (nxagentOption(Rootless) == 1 &&
+ nxagentWindowTopLevel(pWin) == 1)
+ {
+ mask &= ~(CWSibling | CWStackMode);
+ }
+ else
+ {
+ if (mask & CW_RootlessRestack)
+ {
+ mask = CWStackingOrder;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Called with window [%p][%ld] and mask [%x].\n",
+ (void *) pWin, nxagentWindow(pWin), mask);
+ #endif
+
+ nxagentMoveCorruptedRegion(pWin, mask);
+
+ valuemask = 0;
+
+ if (mask & CW_Update)
+ {
+ mask |= CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWStackingOrder;
+ }
+
+ if (mask & CWX)
+ {
+ valuemask |= CWX;
+
+ values.x = nxagentWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+ }
+
+ if (mask & CWY)
+ {
+ valuemask |= CWY;
+
+ values.y = nxagentWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+ }
+
+ if (mask & CWWidth)
+ {
+ valuemask |= CWWidth;
+
+ values.width = nxagentWindowPriv(pWin)->width = pWin->drawable.width;
+ }
+
+ if (mask & CWHeight)
+ {
+ valuemask |= CWHeight;
+
+ values.height = nxagentWindowPriv(pWin)->height = pWin->drawable.height;
+ }
+
+ if (mask & CWBorderWidth)
+ {
+ valuemask |= CWBorderWidth;
+
+ values.border_width = nxagentWindowPriv(pWin)->borderWidth =
+ pWin->borderWidth;
+ }
+
+ if (mask & CW_Update)
+ {
+ valuemask = 0;
+ }
+
+ if (valuemask)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Going to configure window [%p][%ld] with mask [%x].\n",
+ (void *) pWin, nxagentWindow(pWin), valuemask);
+ #endif
+
+ if (pWin->bitGravity == StaticGravity &&
+ ((mask & CWX) || (mask & CWY)) &&
+ ((mask & CWWidth) || (mask & CWHeight)))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Window has StaticGravity. Going to translate Expose events by offset [%d, %d].\n",
+ offX, offY);
+ #endif
+
+ nxagentAddStaticResizedWindow(pWin, XNextRequest(nxagentDisplay), offX, offY);
+
+ for (j = 0; j < nxagentExposeQueue.length; j++)
+ {
+ i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+ if (nxagentExposeQueue.exposures[i].pWindow == pWin &&
+ nxagentExposeQueue.exposures[i].remoteRegion != NullRegion)
+ {
+ RegionTranslate(nxagentExposeQueue.exposures[i].remoteRegion, offX, offY);
+ }
+ }
+ }
+
+ XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), valuemask, &values);
+
+ MAKE_SYNC_CONFIGURE_WINDOW;
+ }
+
+ if (mask & CWStackingOrder &&
+ nxagentWindowPriv(pWin)->siblingAbove != nxagentWindowSiblingAbove(pWin))
+ {
+ WindowPtr pSib;
+
+ /*
+ * Find the top sibling.
+ */
+
+ for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
+
+ /*
+ * Configure the top sibling.
+ */
+
+ valuemask = CWStackMode;
+
+ values.stack_mode = Above;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Going to configure top sibling [%ld] "
+ "with mask [%x] and parent [%ld].\n", nxagentWindow(pSib),
+ valuemask, nxagentWindowParent(pWin));
+ #endif
+
+ XConfigureWindow(nxagentDisplay, nxagentWindow(pSib), valuemask, &values);
+
+ MAKE_SYNC_CONFIGURE_WINDOW;
+
+ nxagentWindowPriv(pSib)->siblingAbove = None;
+
+ /*
+ * Configure the rest of siblings.
+ */
+
+ valuemask = CWSibling | CWStackMode;
+
+ values.stack_mode = Below;
+
+ for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib)
+ {
+ values.sibling = nxagentWindowSiblingAbove(pSib);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Going to configure other sibling [%ld] "
+ "with mask [%x] and parent [%ld] below [%ld].\n", nxagentWindow(pSib),
+ valuemask, nxagentWindowParent(pWin), nxagentWindowSiblingAbove(pSib));
+ #endif
+
+ XConfigureWindow(nxagentDisplay, nxagentWindow(pSib), valuemask, &values);
+
+ MAKE_SYNC_CONFIGURE_WINDOW;
+
+ nxagentWindowPriv(pSib)->siblingAbove = nxagentWindowSiblingAbove(pSib);
+ }
+
+ #ifdef TEST
+ {
+ Window root_return;
+ Window parent_return;
+ Window *children_return;
+ unsigned int nchildren_return;
+ Window *pw;
+ Status result;
+
+ result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+ &root_return, &parent_return, &children_return, &nchildren_return);
+
+ if (result)
+ {
+ pw = children_return;
+
+ fprintf(stderr, "nxagentConfigureWindow: Children of the root: ");
+ while(nchildren_return > 0)
+ {
+ pSib = nxagentWindowPtr(children_return[--nchildren_return]);
+ if (pSib)
+ {
+ fprintf(stderr, "%lu ", children_return[nchildren_return]);
+ }
+ }
+ fprintf(stderr, "\n");
+
+ if (children_return)
+ {
+ XFree(children_return);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "nxagentConfigureWindow: Failed QueryTree request.\n ");
+ }
+ }
+ #endif
+ }
+
+ #ifdef NXAGENT_SPLASH
+
+ /*
+ * This should bring again the splash window
+ * on top, so why the else clause? Is this
+ * really needed?
+ *
+ *
+ * else if (mask & CWStackingOrder)
+ * {
+ * if (nxagentSplashWindow)
+ * {
+ * valuemask = CWStackMode;
+ *
+ * values.stack_mode = Above;
+ *
+ * #ifdef TEST
+ * fprintf(stderr, "nxagentConfigureWindow: Going to configure splash window [%ld].\n",
+ * nxagentSplashWindow);
+ * #endif
+ *
+ * XConfigureWindow(nxagentDisplay, nxagentSplashWindow, valuemask, &values);
+ *
+ * MAKE_SYNC_CONFIGURE_WINDOW;
+ * }
+ * }
+ */
+
+ #endif
+
+ if (mask & CW_RootlessRestack)
+ {
+ if (!pWin -> prevSib)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Raising window [%p][%ld].\n",
+ (void *) pWin, nxagentWindow(pWin));
+ #endif
+
+ XRaiseWindow(nxagentDisplay, nxagentWindow(pWin));
+ }
+ else if (!pWin -> nextSib)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Lowering window [%p][%ld].\n",
+ (void *) pWin, nxagentWindow(pWin));
+ #endif
+
+ XLowerWindow(nxagentDisplay, nxagentWindow(pWin));
+ }
+ else
+ {
+ XlibWindow windowList[2];
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentConfigureWindow: Putting window [%p][%ld] in the middle.\n",
+ (void *) pWin, nxagentWindow(pWin));
+ #endif
+
+ windowList[0] = nxagentWindow(pWin->prevSib);
+ windowList[1] = nxagentWindow(pWin);
+
+ XRestackWindows(nxagentDisplay, windowList, 2);
+ }
+ }
+
+ #ifdef SHAPE
+
+ if (mask & CW_Shape)
+ {
+ nxagentShapeWindow(pWin);
+ }
+
+ #endif
+
+ if (mask & CW_Map &&
+ (!nxagentOption(Rootless) ||
+ nxagentRootlessWindow != pWin))
+ {
+ XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+
+ return;
+ }
+}
+
+void nxagentReparentWindow(pWin, pOldParent)
+ WindowPtr pWin;
+ WindowPtr pOldParent;
+{
+ if (nxagentScreenTrap)
+ {
+ return;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReparentWindow: window at %p [%lx] previous parent at %p [%lx].\n",
+ (void*)pWin, nxagentWindow(pWin),
+ (void*)pOldParent, nxagentWindow(pOldParent));
+ #endif
+
+ XReparentWindow(nxagentDisplay, nxagentWindow(pWin),
+ nxagentWindowParent(pWin),
+ pWin->origin.x - wBorderWidth(pWin),
+ pWin->origin.y - wBorderWidth(pWin));
+}
+
+Bool nxagentChangeWindowAttributes(pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ XSetWindowAttributes attributes;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeWindowAttributes: Changing attributes for window at [%p] with mask [%lu].\n",
+ (void *) pWin, mask);
+ #endif
+
+ if (nxagentScreenTrap)
+ {
+ return True;
+ }
+
+ if (mask & CWBackPixmap)
+ {
+ switch (pWin->backgroundState)
+ {
+ case None:
+ {
+ attributes.background_pixmap = None;
+ attributes.background_pixel = nxagentWhitePixel;
+
+ /*
+ * One of problems faced during the implementation of lazy
+ * encoding policies was due to the presence of windows with
+ * transparent background, usually created by X clients to
+ * cover some sensible areas (i.e. checkboxes used by
+ * Konqueror 3.5). The sequence of operations consists in
+ * drawing the underneath part before covering it with the
+ * transparent window, so when we synchronize the deferred
+ * drawing operation we have to bear in mind that the dest-
+ * ination area is covered by a window. By using the Inclu-
+ * deInferiors GC's property and by clipping the region to
+ * synchronize to the borderClip instead of clipList (to
+ * include the areas covered by children) we can easily take
+ * care of this situation, but there is a drawback: if the
+ * children are not transparent, we are going to synchronize
+ * invisible areas. To avoid this we have added the 'has-
+ * TransparentChildren' flag, which is set when a window has
+ * at least one child with background None. The problem is
+ * that we don't know when to reset the flag. This solution,
+ * also, doesn't take care of transparent windows which don't
+ * have childhood relationships with underneath windows.
+ * We tried to mark the whole windows as dirty when they are
+ * created to force the synchronization of transparent windows
+ * with the content of underneath windows, but, of course,
+ * this works only with the first synchronization because the
+ * transparent windows will be never marked again as dirty.
+ */
+
+ if (pWin -> parent != NULL)
+ {
+ nxagentWindowPriv(pWin -> parent) -> hasTransparentChildren = 1;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentChangeWindowAttributes: WARNING! Window at [%p] got the "
+ "hasTransparentChildren flag.\n", (void *) pWin);
+ #endif
+ }
+
+ break;
+ }
+ case ParentRelative:
+ {
+ attributes.background_pixmap = ParentRelative;
+
+ break;
+ }
+ case BackgroundPixmap:
+ {
+ /*
+ * If a window background is corrupted, we grant
+ * its usability by clearing it with a solid co-
+ * lor. When the pixmap will be fully synchroni-
+ * zed, an expose will be sent to the window's
+ * hierarchy.
+ */
+
+ if (nxagentDrawableStatus((DrawablePtr) pWin -> background.pixmap) == NotSynchronized)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeWindowAttributes: The window at [%p] has the background at [%p] "
+ "not synchronized.\n", (void *) pWin, (void *) pWin -> background.pixmap);
+ #endif
+
+ if (nxagentIsCorruptedBackground(pWin -> background.pixmap) == 0)
+ {
+ nxagentIsCorruptedBackground(pWin -> background.pixmap) = 1;
+
+ nxagentAllocateCorruptedResource((DrawablePtr) pWin -> background.pixmap, RT_NX_CORR_BACKGROUND);
+
+ /*
+ * Clearing the remote background to
+ * make it usable.
+ */
+
+ nxagentFillRemoteRegion((DrawablePtr) pWin -> background.pixmap,
+ nxagentCorruptedRegion((DrawablePtr) pWin -> background.pixmap));
+ }
+ }
+
+ attributes.background_pixmap = nxagentPixmap(pWin -> background.pixmap);
+
+ break;
+ }
+ case BackgroundPixel:
+ {
+ mask &= ~CWBackPixmap;
+
+ break;
+ }
+ }
+ }
+
+ if (mask & CWBackPixel)
+ {
+ if (pWin -> backgroundState == BackgroundPixel)
+ {
+ attributes.background_pixel = nxagentPixel(pWin -> background.pixel);
+ }
+ else
+ {
+ mask &= ~CWBackPixel;
+ }
+ }
+
+ if (mask & CWBorderPixmap)
+ {
+ if (pWin -> borderIsPixel != 0)
+ {
+ mask &= ~CWBorderPixmap;
+ }
+ else
+ {
+ attributes.border_pixmap = nxagentPixmap(pWin -> border.pixmap);
+ }
+ }
+
+ if (mask & CWBorderPixel)
+ {
+ if (pWin -> borderIsPixel != 0)
+ {
+ attributes.border_pixel = nxagentPixel(pWin -> border.pixel);
+ }
+ else
+ {
+ mask &= ~CWBorderPixel;
+ }
+ }
+
+ if (mask & CWBitGravity)
+ {
+ attributes.bit_gravity = pWin -> bitGravity;
+ }
+
+ /*
+ * As we set this bit, whe must change dix in
+ * order not to perform PositionWindow and let
+ * X move children windows for us.
+ */
+
+ if (mask & CWWinGravity)
+ {
+ attributes.win_gravity = pWin -> winGravity;
+ }
+
+/*
+FIXME: Do we need to set the attribute on the
+ remote display?
+*/
+ if (mask & CWBackingStore)
+ {
+ attributes.backing_store = pWin -> backingStore;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentChangeWindowAttributes: Changing backing store value to %d"
+ " for window at %p.\n", pWin -> backingStore, (void*)pWin);
+ #endif
+ }
+
+ if (mask & CWBackingPlanes)
+ {
+ if ((nxagentBackingStore == NotUseful) || (pWin -> optional == NULL))
+ {
+ mask &= ~CWBackingPlanes;
+ }
+ else
+ {
+ attributes.backing_planes = pWin -> optional -> backingBitPlanes;
+ }
+ }
+
+ if (mask & CWBackingPixel)
+ {
+ if ((nxagentBackingStore == NotUseful) || (pWin -> optional == NULL))
+ {
+ mask &= ~CWBackingPixel;
+ }
+ else
+ {
+ attributes.backing_pixel = pWin -> optional -> backingPixel;
+ }
+ }
+
+ if (mask & CWOverrideRedirect)
+ {
+ attributes.override_redirect = pWin -> overrideRedirect;
+ }
+
+/*
+FIXME: Do we need to set the attribute on the
+ remote display?
+*/
+ if (mask & CWSaveUnder)
+ {
+ attributes.save_under = pWin -> saveUnder;
+ }
+
+ /*
+ * Events are handled elsewhere.
+ */
+
+ if (mask & CWEventMask)
+ {
+ mask &= ~CWEventMask;
+ }
+
+ if (mask & CWDontPropagate)
+ {
+ mask &= ~CWDontPropagate;
+ }
+
+ if (mask & CWColormap)
+ {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr) LookupIDByType(wColormap(pWin), RT_COLORMAP);
+
+/*
+FIXME: When the caller is nxagentReconfigureWindow
+ sometimes wColormap(pWin) is 0. Could a window
+ have no colormap?
+*/
+ if (pCmap != NULL)
+ {
+ attributes.colormap = nxagentColormap(pCmap);
+
+ nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentChangeWindowAttributes: WARNING! Bad colormap "
+ "[%lu] for window at [%p].\n", wColormap(pWin), (void *) pWin);
+ #endif
+
+ mask &= ~CWColormap;
+ }
+ }
+
+ if (mask & CWCursor)
+ {
+ if (nxagentOption(Rootless))
+ {
+ if (pWin->cursorIsNone == 0 && pWin->optional != NULL &&
+ pWin->optional->cursor != NULL && nxagentCursorPriv(pWin ->
+ optional -> cursor, pWin -> drawable.pScreen) != NULL)
+ {
+ attributes.cursor = nxagentCursor(pWin -> optional -> cursor,
+ pWin -> drawable.pScreen);
+ }
+ else
+ {
+ attributes.cursor = None;
+ }
+ }
+ else
+ {
+ /*
+ * This is handled in cursor code
+ */
+
+ mask &= ~CWCursor;
+ }
+ }
+
+ if (mask != 0)
+ {
+ XChangeWindowAttributes(nxagentDisplay, nxagentWindow(pWin), mask, &attributes);
+ }
+
+ return 1;
+}
+
+Bool nxagentRealizeWindow(WindowPtr pWin)
+{
+ if (nxagentScreenTrap == 1)
+ {
+ return True;
+ }
+
+ /*
+ * Not needed.
+ *
+ * nxagentConfigureWindow(pWin, CWStackingOrder);
+ *
+ * nxagentFlushConfigureWindow();
+ */
+
+ nxagentAddConfiguredWindow(pWin, CWStackingOrder);
+ nxagentAddConfiguredWindow(pWin, CW_Shape);
+
+ /* add by dimbor */
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+ {
+ Atom prop = MakeAtom("WM_STATE", strlen("WM_STATE"), True);
+ nxagentWMStateRec wmState;
+ wmState.state = 1; /* NormalState */
+ wmState.icon = None;
+ if (ChangeWindowProperty(pWin, prop, prop, 32, 0, 2, &wmState, 1) != Success)
+ fprintf(stderr, "nxagentRealizeWindow: Adding WM_STATE fail.\n");
+ }
+
+ #ifdef SHAPE
+
+ /*
+ * Not needed.
+ *
+ * nxagentShapeWindow(pWin);
+ */
+
+ #endif /* SHAPE */
+
+ /*
+ * Mapping of the root window is called by
+ * InitRootWindow in DIX. Skip the operation
+ * if we are in rootless mode.
+ */
+
+ /*
+ * if (!nxagentOption(Rootless) ||
+ * nxagentRootlessWindow != pWin)
+ * {
+ * XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+ * }
+ */
+
+ #ifdef TEST
+ if (nxagentOption(Rootless) && nxagentLastWindowDestroyed)
+ {
+ fprintf(stderr, "nxagentRealizeWindow: Window realized. Stopped termination for rootless session.\n");
+ }
+ #endif
+
+ nxagentAddConfiguredWindow(pWin, CW_Map);
+
+ nxagentLastWindowDestroyed = False;
+
+ return True;
+}
+
+Bool nxagentUnrealizeWindow(pWin)
+ WindowPtr pWin;
+{
+ if (nxagentScreenTrap)
+ {
+ return True;
+ }
+
+ /* add by dimbor */
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+ {
+ Atom prop = MakeAtom("WM_STATE", strlen("WM_STATE"), True);
+ nxagentWMStateRec wmState;
+ wmState.state = 3; /* WithdrawnState */
+ wmState.icon = None;
+ if (ChangeWindowProperty(pWin, prop, prop, 32, 0, 2, &wmState, 1) != Success)
+ fprintf(stderr, "nxagentUnRealizeWindow: Changing WM_STATE failed.\n");
+ }
+
+ XUnmapWindow(nxagentDisplay, nxagentWindow(pWin));
+
+ return True;
+}
+
+void nxagentFrameBufferPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+
+ void (*PaintWindowBackgroundBackup)(WindowPtr, RegionPtr, int);
+
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pWin->background.pixmap = nxagentVirtualPixmap(pWin->background.pixmap);
+ }
+
+ if (pWin->borderIsPixel == False)
+ {
+ pWin->border.pixmap = nxagentVirtualPixmap(pWin->border.pixmap);
+ }
+
+ PaintWindowBackgroundBackup = pWin->drawable.pScreen -> PaintWindowBackground;
+
+ pWin->drawable.pScreen -> PaintWindowBackground = nxagentFrameBufferPaintWindow;
+
+ fbPaintWindow(pWin, pRegion, what);
+
+ pWin->drawable.pScreen -> PaintWindowBackground = PaintWindowBackgroundBackup;
+
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pWin->background.pixmap = nxagentRealPixmap(pWin->background.pixmap);
+ }
+
+ if (pWin->borderIsPixel == False)
+ {
+ pWin->border.pixmap = nxagentRealPixmap(pWin->border.pixmap);
+ }
+}
+
+void nxagentPaintWindowBackground(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ int i;
+
+ RegionRec temp;
+
+ if (pWin -> realized)
+ {
+ BoxPtr pBox;
+
+ pBox = RegionRects(pRegion);
+
+ for (i = 0; i < RegionNumRects(pRegion); i++)
+ {
+ XClearArea(nxagentDisplay, nxagentWindow(pWin),
+ pBox[i].x1 - pWin->drawable.x,
+ pBox[i].y1 - pWin->drawable.y,
+ pBox[i].x2 - pBox[i].x1,
+ pBox[i].y2 - pBox[i].y1,
+ False);
+ }
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "nxagentPaintWindowBackground: Saving the operation with window "
+ "at [%p] not realized.\n", (void *) pWin);
+ }
+ #endif
+
+ /*
+ * The framebuffer operations don't take care of
+ * clipping to the actual area of the framebuffer
+ * so we need to clip ourselves.
+ */
+
+ RegionInit(&temp, NullBox, 1);
+
+ RegionIntersect(&temp, pRegion, &pWin -> clipList);
+
+ nxagentFrameBufferPaintWindow(pWin, &temp, what);
+
+ RegionUninit(&temp);
+}
+
+void nxagentPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ RegionRec temp;
+
+ /*
+ * The framebuffer operations don't take care of
+ * clipping to the actual area of the framebuffer
+ * so we need to clip ourselves.
+ */
+
+ RegionInit(&temp, NullBox, 1);
+
+ RegionIntersect(&temp, pRegion, &pWin -> borderClip);
+
+ nxagentFrameBufferPaintWindow(pWin, &temp, what);
+
+ RegionUninit(&temp);
+}
+
+void nxagentCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
+{
+ fbCopyWindow(pWin, oldOrigin, oldRegion);
+}
+
+void nxagentClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ /*
+ * nxagentConfigureWindow(pWin, CWStackingOrder);
+ */
+
+ nxagentAddConfiguredWindow(pWin, CWStackingOrder);
+ nxagentAddConfiguredWindow(pWin, CW_Shape);
+
+#ifdef NXAGENT_SHAPE
+ return;
+#else
+
+#ifdef SHAPE
+
+/*
+ * nxagentShapeWindow(pWin);
+ */
+
+#endif /* SHAPE */
+
+#endif /* NXAGENT_SHAPE */
+}
+
+void nxagentWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed)
+{
+ /*
+ * The problem: we want to synthetize the expose events internally, so
+ * that we reduce the time between a window operation and the corresp-
+ * onding graphical output, but at the same time we need to take care
+ * of the remote exposures, as we need to handle those cases where our
+ * windows are covered by the windows on the real display. Handling
+ * both the local and the remote exposures we would generate the same
+ * redraws twice, something we call "double refreshes", so we must be
+ * able to identify which events have been already sent to our clients.
+ *
+ * Here is how the algorithm is working:
+ *
+ * - We collect the exposures that the agent sent to its clients in a
+ * region (the "local-region") and store the region for a given win-
+ * dow in a vector.
+ *
+ * - Another region collects the expose that were received from the
+ * real X server (the "remote-region") for the same window.
+ *
+ * - We create a "fake" off-screen window. For every generated region
+ * we send a ConfigureWindow request for that window to synchronize
+ * ourselves with both the remote X server and/or the window manager.
+ *
+ * - When the ConfigureNotify is received, we calculate the difference
+ * between the "remote-region" and the "local-region" for the window
+ * that had collected exposures.
+ *
+ * - Finally we send the resulting exposures to our clients.
+ *
+ * As you may have guessed, the windows are synchronized per-region,
+ * that is there is a single region for a set of exposures. The regions
+ * are handled in order. This means that we can always calculate the
+ * final region by referring to the first element of the vector.
+ */
+
+ RegionRec temp;
+ BoxRec box;
+
+ if (nxagentSessionState != SESSION_DOWN)
+ {
+ if (nxagentExposeArrayIsInitialized == 0)
+ {
+ int i;
+
+ XSetWindowAttributes attributes;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowExposures: Initializing expose queue.\n");
+ #endif
+
+ attributes.event_mask = StructureNotifyMask;
+
+ for (i = 0; i < EXPOSED_SIZE; i++)
+ {
+ nxagentExposeQueue.exposures[i].pWindow = NULL;
+ nxagentExposeQueue.exposures[i].localRegion = NullRegion;
+ nxagentExposeQueue.exposures[i].remoteRegion = NullRegion;
+ nxagentExposeQueue.exposures[i].remoteRegionIsCompleted = False;
+ nxagentExposeQueue.exposures[i].serial = 0;
+ }
+
+ nxagentExposeQueue.length = 0;
+
+ nxagentExposeSerial = 0;
+
+ nxagentExposeQueue.start = 0;
+
+ nxagentConfiguredSynchroWindow = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay), 0, 0,
+ 1, 1, 0, 0, InputOutput, 0, CWEventMask, &attributes);
+
+ nxagentInitRemoteExposeRegion();
+
+ nxagentExposeArrayIsInitialized = 1;
+ }
+
+ RegionInit(&temp, (BoxRec *) NULL, 1);
+
+ if (pRgn != NULL)
+ {
+ if (RegionNumRects(pRgn) > RECTLIMIT)
+ {
+ box = *RegionExtents(pRgn);
+
+ RegionEmpty(pRgn);
+ RegionInit(pRgn, &box, 1);
+ }
+
+ RegionUnion(&temp, &temp, pRgn);
+ }
+
+ if (other_exposed != NULL)
+ {
+ RegionUnion(&temp, &temp, other_exposed);
+ }
+
+ if (RegionNil(&temp) == 0)
+ {
+ RegionTranslate(&temp,
+ -(pWin -> drawable.x), -(pWin -> drawable.y));
+
+ if (nxagentExposeQueue.length < EXPOSED_SIZE)
+ {
+ int index;
+
+ index = (nxagentExposeQueue.start + nxagentExposeQueue.length) % EXPOSED_SIZE;
+
+ nxagentExposeQueue.exposures[index].pWindow = pWin;
+
+ nxagentExposeQueue.exposures[index].localRegion = RegionCreate(NULL, 1);
+
+ if (nxagentOption(Rootless) && nxagentWindowPriv(pWin) &&
+ (nxagentWindowPriv(pWin) -> isMapped == 0 ||
+ nxagentWindowPriv(pWin) -> visibilityState != VisibilityUnobscured))
+ {
+ nxagentExposeQueue.exposures[index].remoteRegion = RegionCreate(NULL, 1);
+
+ RegionUnion(nxagentExposeQueue.exposures[index].remoteRegion,
+ nxagentExposeQueue.exposures[index].remoteRegion, &temp);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowExposures: Added region to remoteRegion for window [%ld] to position [%d].\n",
+ nxagentWindow(pWin), nxagentExposeQueue.length);
+ #endif
+ }
+ else
+ {
+ RegionUnion(nxagentExposeQueue.exposures[index].localRegion,
+ nxagentExposeQueue.exposures[index].localRegion, &temp);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowExposures: Added region to localRegion for window [%ld] to position [%d].\n",
+ nxagentWindow(pWin), nxagentExposeQueue.length);
+ #endif
+ }
+
+ nxagentExposeSerial = (nxagentExposeSerial - 1) % EXPOSED_SIZE;
+
+ nxagentExposeQueue.exposures[index].serial = nxagentExposeSerial;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowExposures: Added region to queue with serial [%d].\n", nxagentExposeSerial);
+ #endif
+
+ /*
+ * Mark this region for sending a synchro,
+ * in nxagentFlushConfigureWindow().
+ */
+
+ nxagentExposeQueue.exposures[index].synchronize = 1;
+
+ nxagentExposeQueue.length++;
+
+ if (nxagentOption(Rootless) && nxagentWindowPriv(pWin) &&
+ (nxagentWindowPriv(pWin) -> isMapped == 0 ||
+ nxagentWindowPriv(pWin) -> visibilityState != VisibilityUnobscured))
+ {
+ RegionUninit(&temp);
+
+ return;
+ }
+ }
+ else
+ {
+ RegionUninit(&temp);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentWindowExposures: WARNING! Reached maximum size of collect exposures vector.\n");
+ #endif
+
+ if ((pRgn != NULL && RegionNotEmpty(pRgn) != 0) ||
+ (other_exposed != NULL && RegionNotEmpty(other_exposed) != 0))
+ {
+ nxagentUnmarkExposedRegion(pWin, pRgn, other_exposed);
+
+ miWindowExposures(pWin, pRgn, other_exposed);
+ }
+
+ return;
+ }
+ }
+
+ RegionUninit(&temp);
+ }
+
+ if ((pRgn != NULL && RegionNotEmpty(pRgn) != 0) ||
+ (other_exposed != NULL && RegionNotEmpty(other_exposed) != 0))
+ {
+ nxagentUnmarkExposedRegion(pWin, pRgn, other_exposed);
+
+ miWindowExposures(pWin, pRgn, other_exposed);
+ }
+
+ return;
+}
+
+#ifdef SHAPE
+static Bool nxagentRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
+{
+ BoxPtr pBox1, pBox2;
+ unsigned int n1, n2;
+
+ if (pReg1 == pReg2) return True;
+
+ if (pReg1 == NullRegion || pReg2 == NullRegion) return False;
+
+ pBox1 = RegionRects(pReg1);
+ n1 = RegionNumRects(pReg1);
+
+ pBox2 = RegionRects(pReg2);
+ n2 = RegionNumRects(pReg2);
+
+ if (n1 != n2) return False;
+
+ if (pBox1 == pBox2) return True;
+
+ if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec))) return False;
+
+ return True;
+}
+
+void nxagentShapeWindow(WindowPtr pWin)
+{
+ Region reg;
+ BoxPtr pBox;
+ XRectangle rect;
+ int i;
+
+ if (NXDisplayError(nxagentDisplay) == 1)
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: Window at [%p][%ld].\n",
+ (void *) pWin, nxagentWindow(pWin));
+ #endif
+
+ if (!nxagentRegionEqual(nxagentWindowPriv(pWin)->boundingShape,
+ wBoundingShape(pWin)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: Bounding shape differs.\n");
+ #endif
+
+ if (wBoundingShape(pWin))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: wBounding shape has [%ld] rects.\n",
+ RegionNumRects(wBoundingShape(pWin)));
+ #endif
+
+#ifdef NXAGENT_SHAPE2
+ if (!nxagentWindowPriv(pWin)->boundingShape)
+ {
+ nxagentWindowPriv(pWin)->boundingShape = RegionCreate(NULL, 1);
+ }
+#endif
+
+ RegionCopy(
+ nxagentWindowPriv(pWin)->boundingShape, wBoundingShape(pWin));
+
+ reg = XCreateRegion();
+ pBox = RegionRects(nxagentWindowPriv(pWin)->boundingShape);
+ for (i = 0;
+ i < RegionNumRects(nxagentWindowPriv(pWin)->boundingShape);
+ i++)
+ {
+ rect.x = pBox[i].x1;
+ rect.y = pBox[i].y1;
+ rect.width = pBox[i].x2 - pBox[i].x1;
+ rect.height = pBox[i].y2 - pBox[i].y1;
+ XUnionRectWithRegion(&rect, reg, reg);
+ }
+
+#ifndef NXAGENT_SHAPE
+ XShapeCombineRegion(nxagentDisplay, nxagentWindow(pWin),
+ ShapeBounding, 0, 0, reg, ShapeSet);
+#endif
+
+ XDestroyRegion(reg);
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: wBounding shape does not exist. Removing the shape.\n");
+ #endif
+
+ RegionEmpty(
+ nxagentWindowPriv(pWin)->boundingShape);
+
+#ifndef NXAGENT_SHAPE
+ XShapeCombineMask(nxagentDisplay, nxagentWindow(pWin),
+ ShapeBounding, 0, 0, None, ShapeSet);
+#endif
+
+ }
+ }
+
+ if (!nxagentRegionEqual(nxagentWindowPriv(pWin)->clipShape, wClipShape(pWin)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: Clip shape differs.\n");
+ #endif
+
+ if (wClipShape(pWin))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: wClip shape has [%ld] rects.\n",
+ RegionNumRects(wClipShape(pWin)));
+ #endif
+
+#ifdef NXAGENT_SHAPE2
+ if (!nxagentWindowPriv(pWin)->clipShape)
+ {
+ nxagentWindowPriv(pWin)->clipShape = RegionCreate(NULL, 1);
+ }
+#endif
+
+ RegionCopy(
+ nxagentWindowPriv(pWin)->clipShape, wClipShape(pWin));
+
+ reg = XCreateRegion();
+ pBox = RegionRects(nxagentWindowPriv(pWin)->clipShape);
+ for (i = 0;
+ i < RegionNumRects(nxagentWindowPriv(pWin)->clipShape);
+ i++)
+ {
+ rect.x = pBox[i].x1;
+ rect.y = pBox[i].y1;
+ rect.width = pBox[i].x2 - pBox[i].x1;
+ rect.height = pBox[i].y2 - pBox[i].y1;
+ XUnionRectWithRegion(&rect, reg, reg);
+ }
+
+#ifndef NXAGENT_SHAPE
+ XShapeCombineRegion(nxagentDisplay, nxagentWindow(pWin),
+ ShapeClip, 0, 0, reg, ShapeSet);
+#endif
+
+ XDestroyRegion(reg);
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentShapeWindow: wClip shape does not exist. Removing the shape.\n");
+ #endif
+
+ RegionEmpty(
+ nxagentWindowPriv(pWin)->clipShape);
+
+#ifndef NXAGENT_SHAPE
+ XShapeCombineMask(nxagentDisplay, nxagentWindow(pWin),
+ ShapeClip, 0, 0, None, ShapeSet);
+#endif
+ }
+ }
+}
+#endif /* SHAPE */
+
+static int nxagentForceExposure(WindowPtr pWin, void * ptr)
+{
+ RegionPtr exposedRgn;
+ BoxRec Box;
+ WindowPtr pRoot = pWin->drawable.pScreen->root;
+
+ if (pWin -> drawable.class != InputOnly)
+ {
+ Box.x1 = pWin->drawable.x;
+ Box.y1 = pWin->drawable.y;
+ Box.x2 = Box.x1 + pWin->drawable.width;
+ Box.y2 = Box.y1 + pWin->drawable.height;
+
+ exposedRgn = RegionCreate(&Box, 1);
+ RegionIntersect(exposedRgn, exposedRgn, &pRoot->winSize);
+
+ if (exposedRgn != NULL && RegionNotEmpty(exposedRgn) != 0)
+ {
+ miWindowExposures(pWin, exposedRgn, NullRegion);
+ }
+
+ RegionDestroy(exposedRgn);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+void nxagentRefreshWindows(WindowPtr pWin)
+{
+ int action = 1;
+
+ TraverseTree(pWin, nxagentForceExposure, &action);
+}
+
+void nxagentUnmapWindows(void)
+{
+ int i;
+
+ if (nxagentOption(Fullscreen) == 1)
+ {
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (nxagentDefaultWindows[i])
+ {
+ XUnmapWindow(nxagentDisplay, nxagentDefaultWindows[i]);
+ }
+ }
+ }
+
+ NXFlushDisplay(nxagentDisplay, NXFlushLink);
+}
+
+void nxagentMapDefaultWindows()
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ WindowPtr pWin = screenInfo.screens[i]->root;
+
+ ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+ MapWindow(pWin, serverClient);
+
+ if (nxagentOption(Rootless) == 0)
+ {
+ /*
+ * Show the NX splash screen.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentMapDefaultWindows: Showing the splash window.\n");
+ #endif
+
+ nxagentShowSplashWindow(nxagentDefaultWindows[pScreen->myNum]);
+
+ /*
+ * Map the default window. Defer the mapping if the session is
+ * of shadow type. If no WM is running on the remote display,
+ * map the window soon anyway: this avoids a flickering effect
+ * on the !M logo if the shadow session is displayed from a
+ * Windows client.
+ */
+
+ if (nxagentOption(Shadow) == 0 || nxagentWMIsRunning == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMapDefaultWindows: Mapping default window id [%ld].\n",
+ nxagentDefaultWindows[pScreen->myNum]);
+ #endif
+
+ XMapWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+
+ if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
+ {
+ nxagentMaximizeToFullScreen(pScreen);
+ }
+ }
+
+ /*
+ * Map and raise the input window.
+ */
+
+ XMapWindow(nxagentDisplay, nxagentInputWindows[pScreen->myNum]);
+
+ /*
+ * At reconnection the Input Window is
+ * raised in nxagentReconnectAllWindows,
+ * after the Root Window is mapped.
+ */
+
+ if (nxagentReconnectTrap == 0)
+ {
+ XRaiseWindow(nxagentDisplay, nxagentInputWindows[pScreen->myNum]);
+ }
+ }
+
+ /*
+ * Send a SetSelectionOwner request
+ * to notify of the agent start.
+ */
+
+ XSetSelectionOwner(nxagentDisplay, serverCutProperty,
+ nxagentDefaultWindows[i], CurrentTime);
+ }
+
+ /*
+ * Map the icon window.
+ */
+
+ if (nxagentIconWindow != 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
+ nxagentIconWindow);
+ #endif
+
+ XMapWindow(nxagentDisplay, nxagentIconWindow);
+
+ if (nxagentIpaq != 0)
+ {
+ XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+ DefaultScreen(nxagentDisplay));
+ }
+ }
+
+ /*
+ * Ensure that the fullscreen window gets the focus.
+ */
+
+ if (nxagentFullscreenWindow != 0)
+ {
+ XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
+ RevertToParent, CurrentTime);
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentMapDefaultWindows: Completed mapping of default windows.\n");
+ #endif
+}
+
+Bool nxagentDisconnectAllWindows(void)
+{
+ Bool succeded = True;
+ int i;
+ WindowPtr pWin;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+ fprintf(stderr, "nxagentDisconnectAllWindows\n");
+ #endif
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pWin = screenInfo.screens[i]->root;
+ nxagentTraverseWindow( pWin, nxagentDisconnectWindow, &succeded);
+ nxagentDefaultWindows[i] = None;
+ }
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+ fprintf(stderr, "nxagentDisconnectAllWindows: all windows disconnected\n");
+ #endif
+
+ return succeded;
+}
+
+/*
+ * FIXME: We are giving up reconnecting those void *
+ * that are not resource, and we are just disconnecting them.
+ * perhaps we could do better and reconnect them.
+ */
+
+void nxagentDisconnectWindow(void * p0, XID x1, void * p2)
+{
+ WindowPtr pWin = (WindowPtr)p0;
+ Bool* pBool = (Bool*)p2;
+ CursorPtr pCursor = wCursor(pWin);
+ ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+ if ((pCursor = wCursor(pWin)) &&
+ nxagentCursorPriv(pCursor, pScreen) &&
+ nxagentCursor(pCursor, pScreen))
+ {
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG_disabled
+ char msg[] = "nxagentDisconnectWindow:";
+
+ nxagentPrintCursorInfo(pCursor, msg);
+ #endif
+
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+ fprintf(stderr, "nxagentDisconnectWindow: window %p - disconnecting cursor %p ID %lx\n",
+ pWin, pCursor, nxagentCursor(pCursor, pScreen));
+ #endif
+
+ nxagentDisconnectCursor(pCursor, (XID)0, pBool);
+
+ if (*pBool == False)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentDisconnectWindow: WARNING failed disconnection of cursor at [%p]"
+ " for window at [%p]: ignoring it.\n", (void*)pCursor, (void*)pWin);
+ #endif
+
+ *pBool = True;
+ }
+ }
+ #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+ else if (pCursor)
+ {
+ fprintf(stderr, "nxagentDisconnectWindow: window %p - cursor %p already disconnected\n",
+ pWin, pCursor);
+ }
+ #endif
+
+ nxagentWindow(pWin) = None;
+
+ if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+ {
+ nxagentDestroyCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+ }
+}
+
+Bool nxagentReconnectAllWindows(void *p0)
+{
+ int flexibility = *(int *) p0;
+
+ flexibility = flexibility;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+ fprintf(stderr, "nxagentReconnectAllWindows\n");
+ #endif
+
+ if (screenInfo.screens[0]->root -> backgroundState == BackgroundPixmap &&
+ screenInfo.screens[0]->root -> background.pixmap == NULL)
+ {
+ FatalError("nxagentReconnectAllWindows: correct the FIXME\n");
+ }
+
+ if (nxagentOption(Fullscreen))
+ {
+ screenInfo.screens[0]->root -> origin.x = nxagentOption(RootX);
+ screenInfo.screens[0]->root -> origin.y = nxagentOption(RootY);
+ }
+
+ if (!nxagentLoopOverWindows(nxagentReconnectWindow))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectAllWindows: couldn't recreate windows\n");
+ #endif
+
+ return False;
+ }
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+ XSync(nxagentDisplay, 0);
+ fprintf(stderr, "nxagentReconnectAllWindows: all windows recreated\n");
+ #endif
+
+ if (!nxagentLoopOverWindows(nxagentReconfigureWindow))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectAllWindows: couldn't reconfigure windows\n");
+ #endif
+
+ return False;
+ }
+
+ /*
+ * After the Root Window has
+ * been mapped, the Input
+ * Windows is raised.
+ */
+
+ if (nxagentOption(Rootless) == 0)
+ {
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ XRaiseWindow(nxagentDisplay, nxagentInputWindows[i]);
+ }
+ }
+
+ nxagentFlushConfigureWindow();
+
+ if (nxagentOption(Fullscreen))
+ {
+ screenInfo.screens[0]->root -> origin.x = 0;
+ screenInfo.screens[0]->root -> origin.y = 0;
+ }
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ fprintf(stderr, "nxagentReconnectAllWindows: All windows reconfigured.\n");
+
+ #endif
+
+ if (nxagentInitClipboard(screenInfo.screens[0]->root) == -1)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectAllWindows: WARNING! Couldn't initialize the clipboard.\n");
+ #endif
+
+ return False;
+ }
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+
+ XSync(nxagentDisplay, 0);
+
+ fprintf(stderr, "nxagentReconnectAllWindows: Clipboard initialized.\n");
+
+ #endif
+
+ #ifdef VIEWPORT_FRAME
+
+ /*
+ * We move the viewport frames out of the way on the X server side.
+ */
+
+ if (nxagentViewportFrameLeft &&
+ nxagentViewportFrameRight &&
+ nxagentViewportFrameAbove &&
+ nxagentViewportFrameBelow)
+ {
+ XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameLeft),
+ -NXAGENT_FRAME_WIDTH, 0);
+ XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameRight),
+ nxagentOption(RootWidth), 0);
+ XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameAbove),
+ 0, -NXAGENT_FRAME_WIDTH);
+ XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameBelow),
+ 0, nxagentOption(RootHeight));
+ }
+
+ #endif /* #ifdef VIEWPORT_FRAME */
+
+ return True;
+}
+
+Bool nxagentSetWindowCursors(void *p0)
+{
+ int flexibility = *(int *) p0;
+
+ flexibility = flexibility;
+
+ #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+ fprintf(stderr, "nxagentSetWindowCursors: Going to loop over the windows.\n");
+ #endif
+
+ if (!nxagentLoopOverWindows(nxagentReconfigureWindowCursor))
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentSetWindowCursors: WARNING! Couldn't configure all windows' cursors.\n");
+ #endif
+
+ return False;
+ }
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+ fprintf(stderr, "nxagentLoopOverWindows: All cursors configured.\n");
+ #endif
+
+ nxagentReDisplayCurrentCursor();
+
+ return True;
+}
+
+static void nxagentTraverseWindow(
+ WindowPtr pWin,
+ void (*pF)(void *, XID, void *),
+ void * p)
+{
+ pF(pWin, 0, p);
+
+ if (pWin -> nextSib)
+ {
+ nxagentTraverseWindow(pWin -> nextSib, pF, p);
+ }
+
+ if (pWin -> firstChild)
+ {
+ nxagentTraverseWindow(pWin -> firstChild, pF, p);
+ }
+}
+
+static Bool nxagentLoopOverWindows(void (*pF)(void *, XID, void *))
+{
+ int i;
+ Bool windowSuccess = True;
+ WindowPtr pWin;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pWin = screenInfo.screens[i]->root;
+ nxagentTraverseWindow(pWin, pF, &windowSuccess);
+ }
+
+ return windowSuccess;
+}
+
+static void nxagentReconnectWindow(void * param0, XID param1, void * data_buffer)
+{
+ WindowPtr pWin = (WindowPtr)param0;
+ Bool *pBool = (Bool*)data_buffer;
+ Visual *visual;
+ unsigned long mask;
+ XSetWindowAttributes attributes;
+ ColormapPtr pCmap;
+
+ if (!pWin || !*pBool)
+ return;
+
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+ fprintf(stderr, "nxagentReconnectWindow: %p - ID %lx\n", pWin, nxagentWindow(pWin));
+ #endif
+
+ if (pWin->drawable.class == InputOnly) {
+ mask = CWEventMask;
+ visual = CopyFromParent;
+ }
+ else {
+ mask = CWEventMask | CWBackingStore;
+
+ attributes.backing_store = NotUseful;
+
+ if (pWin->optional)
+ {
+ mask |= CWBackingPlanes | CWBackingPixel;
+ attributes.backing_planes = pWin->optional->backingBitPlanes;
+ attributes.backing_pixel = pWin->optional->backingPixel;
+ }
+
+/*
+FIXME: Do we need to set save unders attribute here?
+*/
+ if (nxagentSaveUnder == True)
+ {
+ mask |= CWSaveUnder;
+ attributes.save_under = pWin->saveUnder;
+ }
+
+ if (pWin->parent) {
+ if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
+ visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ mask |= CWColormap;
+ if (pWin->optional->colormap) {
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ attributes.colormap = nxagentColormap(pCmap);
+ }
+ else
+ attributes.colormap = nxagentDefaultVisualColormap(visual);
+ }
+ else
+ visual = CopyFromParent;
+ }
+ else { /* root windows have their own colormaps at creation time */
+ visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ mask |= CWColormap;
+ attributes.colormap = nxagentColormap(pCmap);
+ }
+ }
+
+ if (mask & CWEventMask)
+ {
+ /* Assume that the mask fits in int... broken on Big Endian 64bit systems. */
+ Mask tmp_mask = attributes.event_mask;
+ nxagentGetEventMask(pWin, &tmp_mask);
+ attributes.event_mask = (int)tmp_mask;
+ }
+ #ifdef WARNING
+ else
+ {
+ attributes.event_mask = NoEventMask;
+ }
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectWindow: Going to create new window.\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectWindow: Recreating %swindow at %p current event mask = %lX mask & CWEventMask = %ld "
+ "event_mask = %lX\n",
+ nxagentWindowTopLevel(pWin) ? "toplevel " : "", (void*)pWin, pWin -> eventMask,
+ mask & CWEventMask, attributes.event_mask);
+ #endif
+
+ /*
+ * FIXME: This quick hack is intended to solve a
+ * problem of NXWin X server for windows.
+ * The NXWin minimize the windows moving them
+ * out of the screen area, this behaviour
+ * can cause problem when a rootless session
+ * is disconnected and an apps is minimized.
+ * It will be solved with new Xorg version of
+ * the NXWin server.
+ */
+
+ if (nxagentOption(Rootless))
+ {
+ if (pWin -> drawable.x == -32000 && pWin -> drawable.y == -32000)
+ {
+ pWin -> drawable.x = (pWin -> drawable.pScreen -> width - pWin -> drawable.width) / 2;
+ pWin -> drawable.y = (pWin -> drawable.pScreen -> height - pWin -> drawable.height) /2;
+ }
+
+ if (pWin -> origin.x == -32000 && pWin -> origin.y == -32000)
+ {
+ pWin -> origin.x = (pWin -> drawable.pScreen -> width - pWin -> drawable.width) / 2;
+ pWin -> origin.y = (pWin -> drawable.pScreen -> height - pWin -> drawable.height) / 2;
+ }
+ }
+
+ nxagentWindow(pWin) = XCreateWindow(nxagentDisplay,
+ nxagentWindowParent(pWin),
+ pWin->origin.x -
+ wBorderWidth(pWin),
+ pWin->origin.y -
+ wBorderWidth(pWin),
+ pWin->drawable.width,
+ pWin->drawable.height,
+ pWin->borderWidth,
+ pWin->drawable.depth,
+ pWin->drawable.class,
+ visual,
+ mask,
+ &attributes);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectWindow: Created new window with id [%ld].\n",
+ nxagentWindowPriv(pWin)->window);
+ #endif
+
+ /*
+ * We have to set the WM_DELETE_WINDOW protocols
+ * on every top level window, because we don't know
+ * if a client handles this.
+ */
+
+ if (nxagentOption(Rootless) && (pWin != screenInfo.screens[0]->root))
+ {
+ if (nxagentWindowTopLevel(pWin))
+ {
+ Atom prop = nxagentMakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), True);
+
+ XlibAtom atom = nxagentMakeAtom("WM_DELETE_WINDOW", strlen("WM_DELETE_WINDOW"), True);
+
+ XSetWMProtocols(nxagentDisplay, nxagentWindow(pWin), &atom, 1);
+
+ nxagentAddPropertyToList(prop, pWin);
+ }
+
+ nxagentExportAllProperty(pWin);
+
+ if (nxagentWindowTopLevel(pWin))
+ {
+ int ret;
+ Atom type;
+ int format;
+ unsigned long nItems, bytesLeft;
+ XSizeHints *props, hints;
+ unsigned char *data = NULL;
+
+ #ifdef _XSERVER64
+
+ unsigned char *data64 = NULL;
+ unsigned int i;
+
+ #endif
+
+ hints.flags = 0;
+
+ ret = GetWindowProperty(pWin,
+ XA_WM_NORMAL_HINTS,
+ 0, sizeof(XSizeHints),
+ False, XA_WM_SIZE_HINTS,
+ &type, &format, &nItems, &bytesLeft, &data);
+
+ /*
+ * 72 is the number of bytes returned by
+ * sizeof(XSizeHints) on 32 bit platforms.
+ */
+
+ if (ret == Success &&
+ ((format >> 3) * nItems) == 72 &&
+ bytesLeft == 0 &&
+ type == XA_WM_SIZE_HINTS)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentReconnectWindow: setting WMSizeHints on window %p [%lx - %lx].\n",
+ (void*)pWin, pWin -> drawable.id, nxagentWindow(pWin));
+ #endif
+
+ #ifdef _XSERVER64
+
+ data64 = (unsigned char *) malloc(sizeof(XSizeHints) + 4);
+
+ for (i = 0; i < 4; i++)
+ {
+ *(data64 + i) = *(data + i);
+ }
+
+ *(((int *) data64) + 1) = 0;
+
+ for (i = 8; i < sizeof(XSizeHints) + 4; i++)
+ {
+ *(data64 + i) = *(data + i - 4);
+ }
+
+ props = (XSizeHints *) data64;
+
+ #else
+
+ props = (XSizeHints *) data;
+
+ #endif /* _XSERVER64 */
+
+ hints = *props;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconnectWindow: Failed to get property WM_NORMAL_HINTS on window %p\n",
+ (void*)pWin);
+ #endif
+ }
+
+ hints.flags |= (USPosition | PWinGravity);
+ hints.x = pWin -> drawable.x;
+ hints.y = pWin -> drawable.y;
+ hints.win_gravity = StaticGravity;
+
+ XSetWMNormalHints(nxagentDisplay,
+ nxagentWindow(pWin),
+ &hints);
+
+ #ifdef _XSERVER64
+
+ if (data64 != NULL)
+ {
+ free(data64);
+ }
+
+ #endif
+ }
+ }
+
+ if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+ {
+ nxagentAllocateCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+ }
+}
+
+static void nxagentReconfigureWindowCursor(void * param0, XID param1, void * data_buffer)
+{
+ WindowPtr pWin = (WindowPtr)param0;
+ Bool *pBool = (Bool*)data_buffer;
+ CursorPtr pCursor;
+ ScreenPtr pScreen;
+
+ if (!pWin || !*pBool || !(pCursor = wCursor(pWin)))
+ return;
+
+ pScreen = pWin -> drawable.pScreen;
+
+ if (!(nxagentCursorPriv(pCursor, pScreen)))
+ {
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconfigureWindowCursor: %p - ID %lx geometry (%d,%d,%d,%d) "
+ "cursor %p - ID %lx\n",
+ pWin, nxagentWindow(pWin),
+ pWin -> drawable.x,
+ pWin -> drawable.y,
+ pWin -> drawable.width,
+ pWin -> drawable.height,
+ pCursor, nxagentCursor(pCursor, pScreen));
+ #endif
+
+ if (nxagentCursor(pCursor, pScreen) == None)
+ {
+ #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+ fprintf(stderr, "nxagentReconfigureWindowCursor: reconnecting valid cursor %lx\n",
+ (void*)pCursor);
+ #endif
+
+ nxagentReconnectCursor(pCursor, 0, pBool);
+
+ if (!*pBool)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentReconfigureWindowCursor: WARNING "
+ "failed reconnection of cursor at [%p] for window at [%p]: ignoring it.\n",
+ (void*)pCursor, (void*)pWin);
+ #endif
+
+ *pBool = True;
+ }
+ }
+
+ if (nxagentOption(Rootless))
+ {
+ XDefineCursor(nxagentDisplay,nxagentWindow(pWin),nxagentCursor(pCursor,pScreen));
+ }
+}
+
+static void nxagentReconfigureWindow(void * param0, XID param1, void * data_buffer)
+{
+ WindowPtr pWin = (WindowPtr)param0;
+ unsigned long mask = 0;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentReconfigureWindow: pWin %p - ID %lx\n", pWin, nxagentWindow(pWin));
+ #endif
+
+ if (pWin -> drawable.class == InputOnly)
+ mask = CWWinGravity | CWEventMask | CWDontPropagate | CWOverrideRedirect | CWCursor;
+ else
+ mask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBorderPixel |
+ CWBitGravity | CWWinGravity | CWBackingStore | CWBackingPlanes |
+ CWBackingPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask |
+ CWDontPropagate | CWColormap | CWCursor;
+
+ nxagentChangeWindowAttributes(pWin, mask);
+
+#ifdef SHAPE
+ if (nxagentWindowPriv(pWin) -> boundingShape)
+ {
+ RegionDestroy(
+ nxagentWindowPriv(pWin) -> boundingShape);
+ nxagentWindowPriv(pWin) -> boundingShape = NULL;
+ }
+
+ if (nxagentWindowPriv(pWin) -> clipShape)
+ {
+ RegionDestroy(
+ nxagentWindowPriv(pWin) -> clipShape);
+ nxagentWindowPriv(pWin) -> clipShape = NULL;
+ }
+ nxagentShapeWindow(pWin);
+#endif
+
+ if (pWin != screenInfo.screens[0]->root)
+ {
+ if (pWin->realized)
+ {
+ nxagentRealizeWindow (pWin);
+ }
+/*
+XXX: This would break Motif menus.
+ If pWin is mapped but not realized, a followin UnmapWindow() wouldn't
+ do anything, leaving this mapped window around. XMapWindow()
+ is called in nxagentRealizeWindow() and there it is enough.
+
+ else if (pWin->mapped)
+ {
+ XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+ }
+*/
+ else if (nxagentOption(Rootless) && pWin -> overrideRedirect == 0 &&
+ nxagentWindowTopLevel(pWin) && nxagentIsIconic(pWin))
+ {
+ MapWindow(pWin, serverClient);
+ XIconifyWindow(nxagentDisplay, nxagentWindow(pWin), pWin -> drawable.pScreen -> myNum);
+ }
+ }
+ else if (nxagentOption(Rootless) == 0)
+ {
+ /*
+ * Map the root window.
+ */
+
+ XMoveWindow(nxagentDisplay, nxagentWindow(pWin),
+ nxagentOption(RootX), nxagentOption(RootY));
+
+ XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+ }
+}
+
+Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask)
+{
+ Mask invalidMask = SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask;
+
+ if (nxagentOption(Rootless) &&
+ pWin == screenInfo.screens[0]->root &&
+ (mask & invalidMask))
+ {
+ return True;
+ }
+
+ return False;
+}
+
+#ifdef TEST
+
+Bool nxagentCheckWindowIntegrity(WindowPtr pWin)
+{
+ Bool integrity = True;
+ XImage *image;
+ char *data;
+ int format;
+ unsigned long plane_mask = AllPlanes;
+ unsigned int width, height, length, depth;
+
+ width = pWin -> drawable.width;
+ height = pWin -> drawable.height;
+ depth = pWin -> drawable.depth;
+ format = (depth == 1) ? XYPixmap : ZPixmap;
+
+ if (width && height)
+ {
+ length = nxagentImageLength(width, height, format, 0, depth);
+ data = malloc(length);
+
+ if (data == NULL)
+ {
+ FatalError("nxagentCheckWindowIntegrity: Failed to allocate a buffer of size %d.\n", length);
+ }
+
+ memset(data, 0, length);
+
+ image = XGetImage(nxagentDisplay, nxagentWindow(pWin), 0, 0,
+ width, height, plane_mask, format);
+ if (image == NULL)
+ {
+ fprintf(stderr, "XGetImage: Failed.\n");
+ return False;
+ }
+
+ fbGetImage((DrawablePtr)pWin, 0, 0, width, height, format, plane_mask, data);
+
+ if (image && memcmp(image->data, data, length) != 0)
+ {
+ #ifdef TEST
+ int i;
+ char *p, *q;
+ #endif
+
+ integrity = False;
+
+ #ifdef TEST
+ for (i = 0, p = image->data, q = data; i < length; i++)
+ {
+ if (p[i] != q[i])
+ {
+ fprintf(stderr, "[%d] %d - %d !!!!!!!!!!!!!!!!!!! **************** !!!!!!!!!!!!!!!!!\n", i, p[i], q[i]);
+ }
+ else
+ {
+ fprintf(stderr, "[%d] %d - %d\n", i, p[i], q[i]);
+ }
+ }
+ #endif
+
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckWindowIntegrity: Window %p width %d, height %d, has been realized "
+ "but the data buffer still differs.\n", (void*) pWin, width, height);
+ fprintf(stderr, "nxagentCheckWindowIntegrity: bytes_per_line = %d byte pad %d format %d.\n",
+ image -> bytes_per_line, nxagentImagePad(width, height, 0, depth), image->format);
+
+ fprintf(stderr, "nxagentCheckWindowIntegrity: image is corrupted!!\n");
+ #endif
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckWindowIntegrity: Window %p has been realized "
+ "now remote and frambuffer data are synchronized.\n", (void*) pWin);
+ #endif
+ }
+
+ if (image)
+ {
+ XDestroyImage(image);
+ }
+
+ if (data)
+ {
+ free(data);
+ }
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCheckWindowIntegrity: ignored window %p with geometry (%d,%d).\n",
+ (void*) pWin, width, height);
+ #endif
+ }
+
+ return integrity;
+}
+
+#endif
+
+Bool nxagentIsIconic(WindowPtr pWin)
+{
+ int iReturn;
+ unsigned long ulReturnItems;
+ unsigned long ulReturnBytesLeft;
+ Atom atomReturnType;
+ int iReturnFormat;
+ unsigned char *pszReturnData = NULL;
+
+ if (!wUserProps (pWin))
+ {
+ return 0;
+ }
+
+ iReturn = GetWindowProperty(pWin, MakeAtom("WM_STATE", 8, False), 0, sizeof(CARD32), False,
+ AnyPropertyType, &atomReturnType, &iReturnFormat,
+ &ulReturnItems, &ulReturnBytesLeft, &pszReturnData);
+
+ if (iReturn == Success)
+ {
+ return (((CARD32 *)pszReturnData)[0] == IconicState);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void nxagentSetTopLevelEventMask(pWin)
+ WindowPtr pWin;
+{
+ unsigned long mask = CWEventMask;
+ XSetWindowAttributes attributes;
+
+ if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+ {
+ /* Assume that the mask fits in int... broken on Big Endian 64bit systems. */
+ Mask tmp_mask = attributes.event_mask = NoEventMask;
+ nxagentGetEventMask(pWin, &tmp_mask);
+ attributes.event_mask = (int)tmp_mask;
+
+ XChangeWindowAttributes(nxagentDisplay, nxagentWindow(pWin), mask, &attributes);
+ }
+}
+
+/*
+ * This function must return 1 if we want the
+ * exposures to be sent as the window's extents.
+ * This is actually a harmless, but useful hack,
+ * as it speeds up the window redraws considera-
+ * bly, when using a very popular WM theme.
+ */
+
+int nxagentExtentsPredicate(int total)
+{
+ #ifdef TEST
+
+ if (total == 6 || total == 11 || total == 10)
+ {
+ fprintf(stderr, "nxagentExtentsPredicate: WARNING! Returning [%d] with [%d] rectangles.\n",
+ (total == 6 || total == 11 || total == 10), total);
+ }
+
+ #endif
+
+ return (total == 6 || total == 11 || total == 10);
+}
+
+void nxagentFlushConfigureWindow(void)
+{
+ ConfiguredWindowStruct *index;
+ XWindowChanges changes;
+ int i;
+ int j;
+
+ index = nxagentConfiguredWindowList;
+
+ while (index)
+ {
+ if (index -> next == NULL)
+ {
+ break;
+ }
+
+ index = index -> next;
+ }
+
+ while (index)
+ {
+ ConfiguredWindowStruct *tmp;
+
+ WindowPtr pWin = index -> pWin;
+ unsigned int valuemask = index -> valuemask;
+
+ if (pWin && valuemask)
+ {
+ nxagentConfigureWindow(pWin, valuemask);
+ }
+
+ tmp = index;
+
+ if (index == nxagentConfiguredWindowList)
+ {
+ free(tmp);
+ break;
+ }
+
+ index = index -> prev;
+ free(tmp);
+ }
+
+ nxagentConfiguredWindowList = NULL;
+
+ for (j = 0; j < nxagentExposeQueue.length; j++)
+ {
+ i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+ if (nxagentExposeQueue.exposures[i].synchronize == 1)
+ {
+ changes.x = nxagentExposeQueue.exposures[i].serial;
+ changes.y = -2;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentFlushConfigureWindow: Sending synch ConfigureWindow for "
+ "index [%d] serial [%d].\n", i, nxagentExposeQueue.exposures[i].serial);
+ #endif
+
+ XConfigureWindow(nxagentDisplay, nxagentConfiguredSynchroWindow,
+ CWX | CWY, &changes);
+
+ nxagentExposeQueue.exposures[i].synchronize = 0;
+ }
+ }
+
+ nxagentSendDeferredBackgroundExposures();
+
+ return;
+}
+
+void nxagentPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+/*
+FIXME: Do we need this here?
+
+ nxagentFlushConfigureWindow();
+*/
+
+ return;
+}
+
+void nxagentAddConfiguredWindow(WindowPtr pWin, unsigned int valuemask)
+{
+ unsigned int mask;
+
+ mask = valuemask & (CWParent | CWX | CWY | CWWidth | CWHeight |
+ CWBorderWidth | CWStackingOrder | CW_Map | CW_Update | CW_Shape);
+
+ valuemask &= ~(CWParent | CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWStackingOrder);
+
+ if (mask & CWX &&
+ nxagentWindowPriv(pWin)->x !=
+ pWin->origin.x - wBorderWidth(pWin))
+ {
+ valuemask |= CWX;
+ }
+
+ if (mask & CWY &&
+ nxagentWindowPriv(pWin)->y !=
+ pWin->origin.y - wBorderWidth(pWin))
+ {
+ valuemask |= CWY;
+ }
+
+ if (mask & CWWidth &&
+ nxagentWindowPriv(pWin)->width !=
+ pWin->drawable.width)
+ {
+ valuemask |= CWWidth;
+ }
+
+ if (mask & CWHeight &&
+ nxagentWindowPriv(pWin)->height !=
+ pWin->drawable.height)
+ {
+ valuemask |= CWHeight;
+ }
+
+ if (mask & CWBorderWidth &&
+ nxagentWindowPriv(pWin)->borderWidth !=
+ pWin->borderWidth)
+ {
+ valuemask |= CWBorderWidth;
+ }
+
+ if (mask & CWStackingOrder &&
+ nxagentWindowPriv(pWin)->siblingAbove !=
+ nxagentWindowSiblingAbove(pWin))
+ {
+ valuemask |= CWStackingOrder;
+ }
+
+ if (nxagentConfiguredWindowList == NULL)
+ {
+ nxagentConfiguredWindowList = malloc(sizeof(ConfiguredWindowStruct));
+ nxagentConfiguredWindowList -> next = NULL;
+ nxagentConfiguredWindowList -> prev = NULL;
+
+ nxagentConfiguredWindowList -> pWin = pWin;
+ }
+ else
+ {
+ ConfiguredWindowStruct *tmp;
+
+ tmp = malloc(sizeof(ConfiguredWindowStruct));
+
+ tmp -> next = nxagentConfiguredWindowList;
+ nxagentConfiguredWindowList -> prev = tmp;
+ tmp -> prev = NULL;
+ nxagentConfiguredWindowList = tmp;
+ nxagentConfiguredWindowList -> pWin = pWin;
+ }
+
+ nxagentConfiguredWindowList -> valuemask = valuemask;
+
+ return;
+}
+
+void nxagentDeleteConfiguredWindow(WindowPtr pWin)
+{
+ ConfiguredWindowStruct *index, *previous, *tmp;
+
+ index = nxagentConfiguredWindowList;
+
+ while (index)
+ {
+ WindowPtr pDel = index -> pWin;
+
+ if (pDel == pWin)
+ {
+ if (index -> prev == NULL && index -> next == NULL)
+ {
+ free(nxagentConfiguredWindowList);
+ nxagentConfiguredWindowList = NULL;
+
+ return;
+ }
+ else if (index -> prev == NULL)
+ {
+ tmp = nxagentConfiguredWindowList;
+ index = nxagentConfiguredWindowList = tmp -> next;
+ free(tmp);
+ nxagentConfiguredWindowList -> prev = NULL;
+
+ continue;
+ }
+ else if (index -> next == NULL)
+ {
+ tmp = index;
+ index = index -> prev;
+ free(tmp);
+ index -> next = NULL;
+
+ return;
+ }
+
+ previous = index -> prev;
+ tmp = index;
+ index = index -> next;
+ previous -> next = index;
+ index -> prev = previous;
+ free(tmp);
+
+ continue;
+ }
+
+ index = index -> next;
+ }
+
+ return;
+}
+
+void nxagentAddStaticResizedWindow(WindowPtr pWin, unsigned long sequence, int offX, int offY)
+{
+ if (nxagentStaticResizedWindowList == NULL)
+ {
+ nxagentStaticResizedWindowList = malloc(sizeof(StaticResizedWindowStruct));
+ nxagentStaticResizedWindowList -> next = NULL;
+ nxagentStaticResizedWindowList -> prev = NULL;
+ }
+ else
+ {
+ StaticResizedWindowStruct *tmp;
+
+ tmp = malloc(sizeof(StaticResizedWindowStruct));
+
+ tmp -> next = nxagentStaticResizedWindowList;
+ nxagentStaticResizedWindowList -> prev = tmp;
+ tmp -> prev = NULL;
+ nxagentStaticResizedWindowList = tmp;
+ }
+
+ nxagentStaticResizedWindowList -> pWin = pWin;
+ nxagentStaticResizedWindowList -> sequence = sequence;
+ nxagentStaticResizedWindowList -> offX = offX;
+ nxagentStaticResizedWindowList -> offY = offY;
+}
+
+void nxagentDeleteStaticResizedWindow(unsigned long sequence)
+{
+ StaticResizedWindowStruct *index, *previous, *tmp;
+
+ index = nxagentStaticResizedWindowList;
+
+ while (index)
+ {
+ if (index -> sequence <= sequence)
+ {
+ if (index -> prev == NULL && index -> next == NULL)
+ {
+ free(nxagentStaticResizedWindowList);
+ nxagentStaticResizedWindowList = NULL;
+
+ return;
+ }
+ else if (index -> prev == NULL)
+ {
+ tmp = nxagentStaticResizedWindowList;
+ index = nxagentStaticResizedWindowList = tmp -> next;
+ free(tmp);
+ nxagentStaticResizedWindowList -> prev = NULL;
+
+ continue;
+ }
+ else if (index -> next == NULL)
+ {
+ tmp = index;
+ index = index -> prev;
+ free(tmp);
+ index -> next = NULL;
+
+ return;
+ }
+
+ previous = index -> prev;
+ tmp = index;
+ index = index -> next;
+ previous -> next = index;
+ index -> prev = previous;
+ free(tmp);
+
+ continue;
+ }
+
+ index = index -> next;
+ }
+
+ return;
+}
+
+StaticResizedWindowStruct *nxagentFindStaticResizedWindow(unsigned long sequence)
+{
+ StaticResizedWindowStruct *index;
+ StaticResizedWindowStruct *ret = NULL;
+
+ if (nxagentStaticResizedWindowList == NULL)
+ {
+ return NULL;
+ }
+
+ index = nxagentStaticResizedWindowList;
+
+ while (index && index -> sequence > sequence)
+ {
+ ret = index;
+ index = index -> next;
+ }
+
+ return ret;
+}
+
+void nxagentEmptyBackingStoreRegion(void * param0, XID param1, void * data_buffer)
+{
+ WindowPtr pWin = (WindowPtr) param0;
+
+ miBSWindowPtr pBackingStore = (miBSWindowPtr)pWin->backStorage;
+
+ if (pBackingStore != NULL)
+ {
+ RegionEmpty(&pBackingStore->SavedRegion);
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentEmptyBackingStoreRegion: Emptying saved region for window at [%p].\n", (void*) pWin);
+ #endif
+
+ if (pBackingStore -> pBackingPixmap != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentEmptyBackingStoreRegion: Emptying corrupted region for drawable at [%p].\n",
+ (void*) pBackingStore -> pBackingPixmap);
+ #endif
+
+ nxagentUnmarkCorruptedRegion((DrawablePtr) pBackingStore -> pBackingPixmap, NullRegion);
+ }
+ }
+}
+
+void nxagentEmptyAllBackingStoreRegions(void)
+{
+ if (nxagentLoopOverWindows(nxagentEmptyBackingStoreRegion) == 0)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentEmptyAllSavedRegions: Failed to empty backing store saved regions.\n");
+ #endif
+ }
+}
+
+void nxagentInitBSPixmapList(void)
+{
+ memset(nxagentBSPixmapList, 0, BSPIXMAPLIMIT * sizeof( StoringPixmapPtr));
+}
+
+int nxagentAddItemBSPixmapList(unsigned long id, PixmapPtr pPixmap, WindowPtr pWin, int bsx, int bsy)
+{
+ int i;
+
+ for (i = 0; i < BSPIXMAPLIMIT; i++)
+ {
+ if (nxagentBSPixmapList[i] == NULL)
+ {
+ nxagentBSPixmapList[i] = malloc(sizeof(StoringPixmapRec));
+
+ if (nxagentBSPixmapList[i] == NULL)
+ {
+ FatalError("nxagentAddItemBSPixmapList: Failed to allocate memory for nxagentBSPixmapList.\n");
+ }
+
+ nxagentBSPixmapList[i] -> storingPixmapId = id;
+ nxagentBSPixmapList[i] -> pStoringPixmap = pPixmap;
+ nxagentBSPixmapList[i] -> pSavedWindow = pWin;
+ nxagentBSPixmapList[i] -> backingStoreX = bsx;
+ nxagentBSPixmapList[i] -> backingStoreY = bsy;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddItemBSPixmapList: Added Pixmap with id [%lu] to nxagentBSPixmapList.\n", id);
+ #endif
+
+ return 1;
+ }
+
+ if (nxagentBSPixmapList[i] -> storingPixmapId == id)
+ {
+ nxagentBSPixmapList[i] -> pStoringPixmap = pPixmap;
+ nxagentBSPixmapList[i] -> pSavedWindow = pWin;
+ nxagentBSPixmapList[i] -> backingStoreX = bsx;
+ nxagentBSPixmapList[i] -> backingStoreY = bsy;
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddItemBSPixmapList: Updated existing item for id [%lu].\n", id);
+ #endif
+
+ return 1;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentAddItemBSPixmapList: WARNING! List item full.\n");
+ #endif
+
+ return 0;
+}
+
+int nxagentRemoveItemBSPixmapList(unsigned long pixmapId)
+{
+ int i;
+ int j;
+
+ if (pixmapId == 0 || nxagentBSPixmapList[0] == NULL)
+ {
+ return 0;
+ }
+
+ for (i = 0; i < BSPIXMAPLIMIT; i++)
+ {
+ if ((nxagentBSPixmapList[i] != NULL) &&
+ (nxagentBSPixmapList[i] -> storingPixmapId == pixmapId))
+ {
+ free(nxagentBSPixmapList[i]);
+ nxagentBSPixmapList[i] = NULL;
+
+ if (i < BSPIXMAPLIMIT - 1)
+ {
+ for (j = i; j < BSPIXMAPLIMIT -1; j++)
+ {
+ nxagentBSPixmapList[j] = nxagentBSPixmapList[j + 1];
+ }
+
+ if (nxagentBSPixmapList[j] == nxagentBSPixmapList[j - 1])
+ {
+ nxagentBSPixmapList[j] = NULL;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemoveItemBSPixmapList: Removed Pixmap with id [%lu] from list.\n",
+ pixmapId);
+ #endif
+
+ return 1;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentRemoveItemBSPixmapList: WARNING! Can't remove item [%lu]: item not found.\n",
+ pixmapId);
+ #endif
+
+ return 0;
+}
+
+int nxagentEmptyBSPixmapList()
+{
+ int i;
+
+ for (i = 0; i < BSPIXMAPLIMIT; i++)
+ {
+ if (nxagentBSPixmapList[i] != NULL)
+ {
+ free(nxagentBSPixmapList[i]);
+ nxagentBSPixmapList[i] = NULL;
+ }
+ }
+
+ return 1;
+}
+
+StoringPixmapPtr nxagentFindItemBSPixmapList(unsigned long pixmapId)
+{
+ int i;
+
+ for (i = 0; i < BSPIXMAPLIMIT; i++)
+ {
+ if ((nxagentBSPixmapList[i] != NULL) &&
+ (nxagentBSPixmapList[i] -> storingPixmapId == pixmapId))
+ {
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindItemBSPixmapList: pixmapId [%lu].\n", pixmapId);
+ fprintf(stderr, "nxagentFindItemBSPixmapList: nxagentBSPixmapList[%d] -> storingPixmapId [%lu].\n",
+ i, nxagentBSPixmapList[i] -> storingPixmapId);
+ #endif
+
+ return nxagentBSPixmapList[i];
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindItemBSPixmapList: WARNING! Item not found.\n");
+ #endif
+
+ #ifdef TEST
+ fprintf(stderr, "nxagentFindItemBSPixmapList: Pixmap with id [%lu] not found.\n",
+ pixmapId);
+ fprintf(stderr, "nxagentBSPixmapList[%d] = [%p].\n",
+ i, (void *) nxagentBSPixmapList[i]);
+ #endif
+
+ return NULL;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
new file mode 100644
index 000000000..8612cdf82
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -0,0 +1,328 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef __Window_H__
+#define __Window_H__
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Pixmaps.h"
+
+#include "validate.h"
+
+typedef struct
+{
+ Window window;
+ int x;
+ int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int borderWidth;
+ Window siblingAbove;
+ int backingStore;
+#ifdef SHAPE
+ RegionPtr boundingShape;
+ RegionPtr clipShape;
+#endif /* SHAPE */
+
+ void *pPicture;
+
+ /*
+ * Set if the window is mapped
+ * on the remote server.
+ */
+
+ int isMapped;
+
+ /*
+ * Set if the window on the remote
+ * server is redirected by using
+ * the composite extension.
+ */
+
+ int isRedirected;
+
+ int visibilityState;
+
+ RegionPtr corruptedRegion;
+
+ int hasTransparentChildren;
+
+ int containGlyphs;
+
+ int deferredBackgroundExpose;
+
+ XID corruptedId;
+
+ PixmapPtr synchronizationBitmap;
+
+ Time corruptedTimestamp;
+
+ SplitResourcePtr splitResource;
+
+} nxagentPrivWindowRec;
+
+typedef nxagentPrivWindowRec *nxagentPrivWindowPtr;
+
+typedef struct
+{
+ unsigned long storingPixmapId;
+
+ PixmapPtr pStoringPixmap;
+
+ WindowPtr pSavedWindow;
+
+ int backingStoreX;
+
+ int backingStoreY;
+
+} StoringPixmapRec;
+
+typedef StoringPixmapRec *StoringPixmapPtr;
+
+int nxagentAddItemBSPixmapList(unsigned long, PixmapPtr, WindowPtr, int, int);
+int nxagentRemoveItemBSPixmapList(unsigned long);
+void nxagentInitBSPixmapList(void);
+int nxagentEmptyBSPixmapList(void);
+StoringPixmapPtr nxagentFindItemBSPixmapList (unsigned long);
+
+extern int nxagentWindowPrivateIndex;
+
+#define nxagentWindowPriv(pWin) \
+ ((nxagentPrivWindowPtr)((pWin)->devPrivates[nxagentWindowPrivateIndex].ptr))
+
+#define nxagentWindow(pWin) (nxagentWindowPriv(pWin)->window)
+
+/*
+ * Window is either a child of our root
+ * or a child of the root of the real X
+ * server.
+ */
+
+#define nxagentWindowParent(pWin) \
+ (nxagentOption(Rootless) ? \
+ nxagentRootlessWindowParent(pWin) : \
+ ((pWin)->parent ? \
+ nxagentWindow((pWin)->parent) : \
+ nxagentDefaultWindows[pWin->drawable.pScreen->myNum]))
+
+/*
+ * True if this is a top level window.
+ */
+
+#define nxagentWindowTopLevel(pWin) \
+ (pWin && (pWin -> parent == NULL || \
+ pWin->parent == nxagentRootlessWindow))
+
+#define nxagentWindowSiblingAbove(pWin) \
+ ((pWin)->prevSib ? nxagentWindow((pWin)->prevSib) : None)
+
+#define nxagentWindowSiblingBelow(pWin) \
+ ((pWin)->nextSib ? nxagentWindow((pWin)->nextSib) : None)
+
+#define nxagentWindowCorruptedRegion(pWin) \
+ (nxagentWindowPriv(pWin) -> corruptedRegion)
+
+#define nxagentWindowContainGlyphs(pWin) \
+ (nxagentWindowPriv(pWin) -> containGlyphs)
+
+#define nxagentWindowTimestamp(pWin) \
+ (nxagentWindowPriv(pWin) -> corruptedTimestamp)
+
+#define nxagentWindowIsVisible(pWin) \
+ ((pWin) -> viewable == 1 && \
+ (pWin) -> drawable.class != InputOnly && \
+ (pWin) -> visibility != VisibilityFullyObscured)
+
+#define nxagentDefaultWindowIsVisible() \
+ (nxagentVisibility != VisibilityFullyObscured)
+
+#define CWParent CWSibling
+#define CWStackingOrder CWStackMode
+
+#define CW_Map (1 << 15)
+#define CW_Update (1 << 16)
+#define CW_Shape (1 << 17)
+#define CW_RootlessRestack (1 << 18)
+
+/*
+ * This force the agent to send exposures
+ * for all windows.
+ */
+
+#define nxagentRefreshScreen() \
+do\
+{\
+ nxagentRefreshWindows(screenInfo.screens[0]->root);\
+} while (0)
+
+WindowPtr nxagentWindowPtr(Window window);
+
+extern Atom serverCutProperty;
+
+/*
+ * If the rectangles in an exposed region exceed
+ * the number of 4, we let the function decide if
+ * it is better to send the window extents rather
+ * than the rectangles in the region.
+ */
+
+int nxagentExtentsPredicate(int total);
+
+/*
+ * Agent's nested window procedures. Look also
+ * at Rootless.h for the rootless counterparts.
+ */
+
+Bool nxagentCreateWindow(WindowPtr pWin);
+
+Bool nxagentDestroyWindow(WindowPtr pWin);
+
+Bool nxagentPositionWindow(WindowPtr pWin, int x, int y);
+
+Bool nxagentChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
+
+Bool nxagentRealizeWindow(WindowPtr pWin);
+
+Bool nxagentUnrealizeWindow(WindowPtr pWin);
+
+Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask);
+
+void nxagentWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed);
+
+void nxagentPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what);
+
+void nxagentPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what);
+
+void nxagentCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
+
+void nxagentClipNotify(WindowPtr pWin, int dx, int dy);
+
+void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
+
+void nxagentReparentWindow(WindowPtr pWin, WindowPtr pOldParent);
+
+void nxagentRefreshWindows(WindowPtr pWin);
+
+void nxagentSetTopLevelEventMask(WindowPtr pWin);
+
+void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn);
+
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn);
+
+void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift);
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentUpdateViewportFrame(int x, int y, int w, int h);
+
+#else /* #ifdef VIEWPORT_FRAME */
+
+#define nxagentUpdateViewportFrame(x, y, w, h)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentUnmapWindows(void);
+
+void nxagentMapDefaultWindows(void);
+
+Bool nxagentSetWindowCursors(void *p0);
+
+/*
+ * The ConfigureWindow procedure has not
+ * a pointer in the screen structure.
+ */
+
+void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask);
+
+/*
+ * Used to track nxagent window's visibility.
+ */
+
+extern int nxagentVisibility;
+extern unsigned long nxagentVisibilityTimeout;
+extern Bool nxagentVisibilityStop;
+
+/*
+ * Return the pointer to the window given the
+ * remote id. It tries to match the id from
+ * the last matched window before iterating
+ * through the hierarchy.
+ */
+
+WindowPtr nxagentGetWindowFromID(Window id);
+
+/*
+ * Handle the shape bitmap for windows.
+ */
+
+#ifdef SHAPE
+
+void nxagentShapeWindow(WindowPtr pWin);
+
+#endif
+
+extern Window nxagentConfiguredSynchroWindow;
+extern Bool nxagentExposeArrayIsInitialized;
+
+typedef struct _ConfiguredWindow
+{
+ WindowPtr pWin;
+ struct _ConfiguredWindow *next;
+ struct _ConfiguredWindow *prev;
+ unsigned int valuemask;
+} ConfiguredWindowStruct;
+
+ConfiguredWindowStruct *nxagentConfiguredWindowList;
+
+typedef struct _StaticResizedWindow
+{
+ WindowPtr pWin;
+ struct _StaticResizedWindow *next;
+ struct _StaticResizedWindow *prev;
+ unsigned long sequence;
+ int offX;
+ int offY;
+} StaticResizedWindowStruct;
+
+StaticResizedWindowStruct *nxagentStaticResizedWindowList;
+
+void nxagentPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind);
+
+void nxagentFlushConfigureWindow(void);
+
+void nxagentAddConfiguredWindow(WindowPtr pWin, unsigned int valuemask);
+
+void nxagentDeleteConfiguredWindow(WindowPtr pWin);
+
+void nxagentAddStaticResizedWindow(WindowPtr pWin, unsigned long sequence, int offX, int offY);
+
+void nxagentDeleteStaticResizedWindow(unsigned long sequence);
+
+StaticResizedWindowStruct *nxagentFindStaticResizedWindow(unsigned long sequence);
+
+void nxagentEmptyAllBackingStoreRegions(void);
+
+#endif /* __Window_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xcomposite_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xcomposite_nxagent.h
new file mode 100644
index 000000000..ba3668015
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xcomposite_nxagent.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+/*
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+/*
+ * This file is a reduced version of the header file of
+ * <X11/extensions/Xcomposite.h>
+ *
+ * This copy of code has been introduced to allow a clear namespace
+ * separation between <X11/...> and <nx-X11/...> header files.
+ *
+ * This version of the Xcomposite library header file only contains symbols
+ * required by nxagent and strictly avoids indirectly including
+ * from an X11 library that is also shipped in nx-X11/lib/.
+ *
+ * When using <X11/extensions/Xcomposite.h> instead for inclusion in
+ * nxagent, it will attempt pulling in the <X11/extensions/Xlib.h>.
+ * However, the headers of the same name from <nx-X11/...> should be
+ * used instead.
+ *
+ * FIXME: Once the nxagent Xserver starts using libX11 from X.Org, this
+ * hack can be removed.
+ *
+ * 2016/04/07, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifndef _XCOMPOSITE_H_
+#define _XCOMPOSITE_H_
+
+#include <X11/extensions/composite.h>
+#include <nx-X11/Xfuncproto.h>
+
+/*
+ * This revision number also appears in configure.ac, they have
+ * to be manually synchronized
+ */
+#define XCOMPOSITE_MAJOR COMPOSITE_MAJOR
+#define XCOMPOSITE_MINOR COMPOSITE_MINOR
+#define XCOMPOSITE_REVISION 2
+#define XCOMPOSITE_VERSION ((XCOMPOSITE_MAJOR * 10000) + (XCOMPOSITE_MINOR * 100) + (XCOMPOSITE_REVISION))
+
+_XFUNCPROTOBEGIN
+
+Bool XCompositeQueryExtension (Display *dpy,
+ int *event_base_return,
+ int *error_base_return);
+
+Status XCompositeQueryVersion (Display *dpy,
+ int *major_version_return,
+ int *minor_version_return);
+
+void
+XCompositeRedirectWindow (Display *dpy, Window window, int update);
+
+void
+XCompositeRedirectSubwindows (Display *dpy, Window window, int update);
+
+void
+XCompositeUnredirectWindow (Display *dpy, Window window, int update);
+
+void
+XCompositeUnredirectSubwindows (Display *dpy, Window window, int update);
+
+_XFUNCPROTOEND
+
+#endif /* _XCOMPOSITE_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xfixes_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xfixes_nxagent.h
new file mode 100644
index 000000000..cbe64fbba
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xfixes_nxagent.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+/*
+ * This file is a reduced version of the header file of
+ * <X11/extensions/Xfixes.h>
+ *
+ * This copy of code has been introduced to allow a clear namespace
+ * separation between <X11/...> and <nx-X11/...> header files.
+ *
+ * This version of the Xfixes library header file only contains symbols
+ * required by nxagent and strictly avoids indirectly including
+ * from an X11 library that is also shipped in nx-X11/lib/.
+ *
+ * When using <X11/extensions/Xfixes.h> instead for inclusion in
+ * nxagent, it will attempt pulling in the <X11/extensions/Xlib.h>.
+ * However, the headers of the same name from <nx-X11/...> should be
+ * used instead.
+ *
+ * FIXME: Once the nxagent Xserver starts using libX11 from X.Org, this
+ * hack can be removed.
+ *
+ * 2015/12/28, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifndef _XFIXES_H_
+#define _XFIXES_H_
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ Window window;
+ int subtype;
+ Window owner;
+ Atom selection;
+ Time timestamp;
+ Time selection_timestamp;
+} XFixesSelectionNotifyEvent;
+
+void
+XFixesSelectSelectionInput (Display *dpy,
+ Window win,
+ Atom selection,
+ unsigned long eventMask);
+
+#endif /* _XFIXES_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xinerama_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xinerama_nxagent.h
new file mode 100644
index 000000000..210c4b5e7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xinerama_nxagent.h
@@ -0,0 +1,74 @@
+/*
+
+Copyright 2003 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.
+
+*/
+
+#ifndef _Xinerama_h
+#define _Xinerama_h
+
+#include <nx-X11/Xlib.h>
+
+typedef struct {
+ int screen_number;
+ short x_org;
+ short y_org;
+ short width;
+ short height;
+} XineramaScreenInfo;
+
+_XFUNCPROTOBEGIN
+
+Bool XineramaQueryExtension (
+ Display *dpy,
+ int *event_base,
+ int *error_base
+);
+
+Status XineramaQueryVersion(
+ Display *dpy,
+ int *major_versionp,
+ int *minor_versionp
+);
+
+Bool 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().
+*/
+
+XineramaScreenInfo *
+XineramaQueryScreens(
+ Display *dpy,
+ int *number
+);
+
+_XFUNCPROTOEND
+
+#endif /* _Xinerama_h */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrandr_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrandr_nxagent.h
new file mode 100644
index 000000000..02f3356e4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrandr_nxagent.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett-Packard Company, Inc.
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+/*
+ * This file is a reduced version of the header file of
+ * <X11/extensions/Xrandr.h>
+ *
+ * This copy of code has been introduced to allow a clear namespace
+ * separation between <X11/...> and <nx-X11/...> header files.
+ *
+ * This version of the Xrandr library header file only contains symbols
+ * required by nxagent and strictly avoids indirectly including
+ * from an X11 library that is also shipped in nx-X11/lib/.
+ *
+ * When using <X11/extensions/Xrandr.h> instead for inclusion in
+ * nxagent, it will attempt pulling in the <X11/extensions/Xrender.h>
+ * header which in turn will include <X11/Xlib.h>. However, the headers of
+ * the same name from <nx-X11/...> should be used instead.
+ *
+ * FIXME: Once the nxagent Xserver starts using libXrender from X.Org, this
+ * hack can be removed.
+ *
+ * 2015/06/26, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifndef _XRANDR_H_
+#define _XRANDR_H_
+
+#include <nx-X11/extensions/randr.h>
+#include <nx-X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+/*
+ * Events.
+ */
+
+typedef struct {
+ int type; /* event base */
+ 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 */
+ Window window; /* window which selected for this event */
+ Window root; /* Root window for changed screen */
+ Time timestamp; /* when the screen change occurred */
+ Time config_timestamp; /* when the last configuration change */
+ SizeID size_index;
+ SubpixelOrder subpixel_order;
+ Rotation rotation;
+ int width;
+ int height;
+ int mwidth;
+ int mheight;
+} XRRScreenChangeNotifyEvent;
+
+_XFUNCPROTOEND
+
+#endif /* _XRANDR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrender_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrender_nxagent.h
new file mode 100644
index 000000000..488132172
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrender_nxagent.h
@@ -0,0 +1,528 @@
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _XRENDER_H_
+#define _XRENDER_H_
+
+#include <nx-X11/Xlib.h>
+#include <nx-X11/Xfuncproto.h>
+#include <nx-X11/Xosdefs.h>
+#include <nx-X11/Xutil.h>
+
+#include <nx-X11/extensions/render.h>
+
+typedef struct {
+ short red;
+ short redMask;
+ short green;
+ short greenMask;
+ short blue;
+ short blueMask;
+ short alpha;
+ short alphaMask;
+} XRenderDirectFormat;
+
+typedef struct {
+ PictFormat id;
+ int type;
+ int depth;
+ XRenderDirectFormat direct;
+ Colormap colormap;
+} XRenderPictFormat;
+
+#define PictFormatID (1 << 0)
+#define PictFormatType (1 << 1)
+#define PictFormatDepth (1 << 2)
+#define PictFormatRed (1 << 3)
+#define PictFormatRedMask (1 << 4)
+#define PictFormatGreen (1 << 5)
+#define PictFormatGreenMask (1 << 6)
+#define PictFormatBlue (1 << 7)
+#define PictFormatBlueMask (1 << 8)
+#define PictFormatAlpha (1 << 9)
+#define PictFormatAlphaMask (1 << 10)
+#define PictFormatColormap (1 << 11)
+
+typedef struct _XRenderPictureAttributes {
+ int repeat;
+ Picture alpha_map;
+ int alpha_x_origin;
+ int alpha_y_origin;
+ int clip_x_origin;
+ int clip_y_origin;
+ Pixmap clip_mask;
+ Bool graphics_exposures;
+ int subwindow_mode;
+ int poly_edge;
+ int poly_mode;
+ Atom dither;
+ Bool component_alpha;
+} XRenderPictureAttributes;
+
+typedef struct {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ unsigned short alpha;
+} XRenderColor;
+
+typedef struct _XGlyphInfo {
+ unsigned short width;
+ unsigned short height;
+ short x;
+ short y;
+ short xOff;
+ short yOff;
+} XGlyphInfo;
+
+typedef struct _XGlyphElt8 {
+ GlyphSet glyphset;
+ _Xconst char *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt8;
+
+typedef struct _XGlyphElt16 {
+ GlyphSet glyphset;
+ _Xconst unsigned short *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt16;
+
+typedef struct _XGlyphElt32 {
+ GlyphSet glyphset;
+ _Xconst unsigned int *chars;
+ int nchars;
+ int xOff;
+ int yOff;
+} XGlyphElt32;
+
+typedef double XDouble;
+
+typedef struct _XPointDouble {
+ XDouble x, y;
+} XPointDouble;
+
+#define XDoubleToFixed(f) ((XFixed) ((f) * 65536))
+#define XFixedToDouble(f) (((XDouble) (f)) / 65536)
+
+typedef int XFixed;
+
+typedef struct _XPointFixed {
+ XFixed x, y;
+} XPointFixed;
+
+typedef struct _XLineFixed {
+ XPointFixed p1, p2;
+} XLineFixed;
+
+typedef struct _XTriangle {
+ XPointFixed p1, p2, p3;
+} XTriangle;
+
+typedef struct _XCircle {
+ XFixed x;
+ XFixed y;
+ XFixed radius;
+} XCircle;
+
+typedef struct _XTrapezoid {
+ XFixed top, bottom;
+ XLineFixed left, right;
+} XTrapezoid;
+
+typedef struct _XTransform {
+ XFixed matrix[3][3];
+} XTransform;
+
+typedef struct _XFilters {
+ int nfilter;
+ char **filter;
+ int nalias;
+ short *alias;
+} XFilters;
+
+typedef struct _XIndexValue {
+ unsigned long pixel;
+ unsigned short red, green, blue, alpha;
+} XIndexValue;
+
+typedef struct _XAnimCursor {
+ Cursor cursor;
+ unsigned long delay;
+} XAnimCursor;
+
+typedef struct _XSpanFix {
+ XFixed left, right, y;
+} XSpanFix;
+
+typedef struct _XTrap {
+ XSpanFix top, bottom;
+} XTrap;
+
+typedef struct _XLinearGradient {
+ XPointFixed p1;
+ XPointFixed p2;
+} XLinearGradient;
+
+typedef struct _XRadialGradient {
+ XCircle inner;
+ XCircle outer;
+} XRadialGradient;
+
+typedef struct _XConicalGradient {
+ XPointFixed center;
+ XFixed angle; /* in degrees */
+} XConicalGradient;
+
+_XFUNCPROTOBEGIN
+
+Bool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep);
+
+Status XRenderQueryVersion (Display *dpy,
+ int *major_versionp,
+ int *minor_versionp);
+
+Status XRenderQueryFormats (Display *dpy);
+
+int XRenderQuerySubpixelOrder (Display *dpy, int screen);
+
+Bool XRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel);
+
+XRenderPictFormat *
+XRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual);
+
+XRenderPictFormat *
+XRenderFindFormat (Display *dpy,
+ unsigned long mask,
+ _Xconst XRenderPictFormat *templ,
+ int count);
+
+#define PictStandardARGB32 0
+#define PictStandardRGB24 1
+#define PictStandardA8 2
+#define PictStandardA4 3
+#define PictStandardA1 4
+#define PictStandardNUM 5
+
+XRenderPictFormat *
+XRenderFindStandardFormat (Display *dpy,
+ int format);
+
+XIndexValue *
+XRenderQueryPictIndexValues(Display *dpy,
+ _Xconst XRenderPictFormat *format,
+ int *num);
+
+Picture
+XRenderCreatePicture (Display *dpy,
+ Drawable drawable,
+ _Xconst XRenderPictFormat *format,
+ unsigned long valuemask,
+ _Xconst XRenderPictureAttributes *attributes);
+
+void
+XRenderChangePicture (Display *dpy,
+ Picture picture,
+ unsigned long valuemask,
+ _Xconst XRenderPictureAttributes *attributes);
+
+void
+XRenderSetPictureClipRectangles (Display *dpy,
+ Picture picture,
+ int xOrigin,
+ int yOrigin,
+ _Xconst XRectangle *rects,
+ int n);
+
+void
+XRenderSetPictureClipRegion (Display *dpy,
+ Picture picture,
+ Region r);
+
+void
+XRenderSetPictureTransform (Display *dpy,
+ Picture picture,
+ XTransform *transform);
+
+void
+XRenderFreePicture (Display *dpy,
+ Picture picture);
+
+void
+XRenderComposite (Display *dpy,
+ int op,
+ Picture src,
+ Picture mask,
+ Picture dst,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height);
+
+GlyphSet
+XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format);
+
+GlyphSet
+XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing);
+
+void
+XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset);
+
+void
+XRenderAddGlyphs (Display *dpy,
+ GlyphSet glyphset,
+ _Xconst Glyph *gids,
+ _Xconst XGlyphInfo *glyphs,
+ int nglyphs,
+ _Xconst char *images,
+ int nbyte_images);
+
+void
+XRenderFreeGlyphs (Display *dpy,
+ GlyphSet glyphset,
+ _Xconst Glyph *gids,
+ int nglyphs);
+
+void
+XRenderCompositeString8 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst char *string,
+ int nchar);
+
+void
+XRenderCompositeString16 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst unsigned short *string,
+ int nchar);
+
+void
+XRenderCompositeString32 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ GlyphSet glyphset,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst unsigned int *string,
+ int nchar);
+
+void
+XRenderCompositeText8 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt8 *elts,
+ int nelt);
+
+void
+XRenderCompositeText16 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt16 *elts,
+ int nelt);
+
+void
+XRenderCompositeText32 (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XGlyphElt32 *elts,
+ int nelt);
+
+void
+XRenderFillRectangle (Display *dpy,
+ int op,
+ Picture dst,
+ _Xconst XRenderColor *color,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+
+void
+XRenderFillRectangles (Display *dpy,
+ int op,
+ Picture dst,
+ _Xconst XRenderColor *color,
+ _Xconst XRectangle *rectangles,
+ int n_rects);
+
+void
+XRenderCompositeTrapezoids (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XTrapezoid *traps,
+ int ntrap);
+
+void
+XRenderCompositeTriangles (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XTriangle *triangles,
+ int ntriangle);
+
+void
+XRenderCompositeTriStrip (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XPointFixed *points,
+ int npoint);
+
+void
+XRenderCompositeTriFan (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ _Xconst XPointFixed *points,
+ int npoint);
+
+void
+XRenderCompositeDoublePoly (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XPointDouble *fpoints,
+ int npoints,
+ int winding);
+Status
+XRenderParseColor(Display *dpy,
+ char *spec,
+ XRenderColor *def);
+
+Cursor
+XRenderCreateCursor (Display *dpy,
+ Picture source,
+ unsigned int x,
+ unsigned int y);
+
+XFilters *
+XRenderQueryFilters (Display *dpy, Drawable drawable);
+
+void
+XRenderSetPictureFilter (Display *dpy,
+ Picture picture,
+ const char *filter,
+ XFixed *params,
+ int nparams);
+
+Cursor
+XRenderCreateAnimCursor (Display *dpy,
+ int ncursor,
+ XAnimCursor *cursors);
+
+
+void
+XRenderAddTraps (Display *dpy,
+ Picture picture,
+ int xOff,
+ int yOff,
+ _Xconst XTrap *traps,
+ int ntrap);
+
+Picture XRenderCreateSolidFill (Display *dpy,
+ const XRenderColor *color);
+
+Picture XRenderCreateLinearGradient (Display *dpy,
+ const XLinearGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+Picture XRenderCreateRadialGradient (Display *dpy,
+ const XRadialGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+Picture XRenderCreateConicalGradient (Display *dpy,
+ const XConicalGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nstops);
+
+_XFUNCPROTOEND
+
+#endif /* _XRENDER_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrenderint_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrenderint_nxagent.h
new file mode 100644
index 000000000..ff14aa26a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/Xrenderint_nxagent.h
@@ -0,0 +1,106 @@
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _XRENDERINT_H_
+#define _XRENDERINT_H_
+
+#include <nx-X11/Xlibint.h>
+#include <nx-X11/Xutil.h>
+#include <nx-X11/extensions/renderproto.h>
+#include "Xrender_nxagent.h"
+
+typedef struct {
+ Visual *visual;
+ XRenderPictFormat *format;
+} XRenderVisual;
+
+typedef struct {
+ int depth;
+ int nvisuals;
+ XRenderVisual *visuals;
+} XRenderDepth;
+
+typedef struct {
+ XRenderDepth *depths;
+ int ndepths;
+ XRenderPictFormat *fallback;
+ int subpixel;
+} XRenderScreen;
+
+typedef struct _XRenderInfo {
+ int major_version;
+ int minor_version;
+ XRenderPictFormat *format;
+ int nformat;
+ XRenderScreen *screen;
+ int nscreen;
+ XRenderDepth *depth;
+ int ndepth;
+ XRenderVisual *visual;
+ int nvisual;
+ int *subpixel;
+ int nsubpixel;
+ char **filter;
+ int nfilter;
+ short *filter_alias;
+ int nfilter_alias;
+} XRenderInfo;
+
+/* replaces XRenderExtDisplayInfo */
+typedef struct _XRenderExtDisplayInfo {
+ struct _XRenderExtDisplayInfo *next; /* keep a linked list */
+ Display *display; /* which display this is */
+ XExtCodes *codes; /* the extension protocol codes */
+ XRenderInfo *info; /* extra data for the extension to use */
+} XRenderExtDisplayInfo;
+
+/* replaces XExtensionInfo */
+typedef struct _XRenderExtInfo {
+ XRenderExtDisplayInfo *head; /* start of the list */
+ XRenderExtDisplayInfo *cur; /* most recently used */
+ int ndisplays; /* number of displays */
+} XRenderExtInfo;
+
+extern XRenderExtInfo XRenderExtensionInfo;
+extern char XRenderExtensionName[];
+
+XRenderExtDisplayInfo *
+XRenderFindDisplay (Display *dpy);
+
+#define RenderHasExtension(i) ((i) && ((i)->codes))
+
+#define RenderCheckExtension(dpy,i,val) \
+ if (!RenderHasExtension(i)) { return val; }
+
+#define RenderSimpleCheckExtension(dpy,i) \
+ if (!RenderHasExtension(i)) { return; }
+
+/*
+ * Xlib uses long for 32-bit values. Xrender uses int. This
+ * matters on alpha. Note that this macro assumes that int is 32 bits.
+ */
+
+#define DataInt32(dpy,d,len) Data(dpy,(char *) (d),len)
+
+#endif /* _XRENDERINT_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X11/include/xpm_nxagent.h b/nx-X11/programs/Xserver/hw/nxagent/X11/include/xpm_nxagent.h
new file mode 100644
index 000000000..b02e5a913
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X11/include/xpm_nxagent.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * 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
+ * GROUPE BULL 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 GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* xpm.h: *
+* *
+* XPM library *
+* Include file *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+/*
+ * This file is a reduced version of the header file of
+ * <X11/xpm.h>
+ *
+ * This copy of code has been introduced to allow a clear namespace
+ * separation between <X11/...> and <nx-X11/...> header files.
+ *
+ * This version of the Xpm library header file only contains symbols
+ * required by nxagent and strictly avoids indirectly including
+ * from an X11 library that is also shipped in nx-X11/lib/.
+ *
+ * When using <X11/xpm.h> instead for inclusion in nxagent, it will
+ * attempt pulling in the <X11/extensions/Xlib.h> header file.
+ * However, the headers of the same name from <nx-X11/...> should be
+ * used instead.
+ *
+ * FIXME: Once the nxagent Xserver starts using libX11 from X.Org, this
+ * hack can be removed.
+ *
+ * 2015/06/26, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ */
+
+#ifndef XPM_h
+#define XPM_h
+
+/*
+ * first some identification numbers:
+ * the version and revision numbers are determined with the following rule:
+ * SO Major number = LIB minor version number.
+ * SO Minor number = LIB sub-minor version number.
+ * e.g: Xpm version 3.2f
+ * we forget the 3 which is the format number, 2 gives 2, and f gives 6.
+ * thus we have XpmVersion = 2 and XpmRevision = 6
+ * which gives SOXPMLIBREV = 2.6
+ *
+ * Then the XpmIncludeVersion number is built from these numbers.
+ */
+#define XpmFormat 3
+#define XpmVersion 4
+#define XpmRevision 11
+#define XpmIncludeVersion ((XpmFormat * 100 + XpmVersion) * 100 + XpmRevision)
+
+#ifndef XPM_NUMBERS
+
+/* let's define Pixel if it is not done yet */
+#if ! defined(_XtIntrinsic_h) && ! defined(PIXEL_ALREADY_TYPEDEFED)
+typedef unsigned long Pixel; /* Index into colormap */
+# define PIXEL_ALREADY_TYPEDEFED
+#endif
+
+/* include headers from <nx-X11/...> instead of <X11/...> */
+#include <nx-X11/Xlib.h>
+#include <nx-X11/Xutil.h>
+
+/* Return ErrorStatus codes:
+ * null if full success
+ * positive if partial success
+ * negative if failure
+ */
+
+#define XpmColorError 1
+#define XpmSuccess 0
+#define XpmOpenFailed -1
+#define XpmFileInvalid -2
+#define XpmNoMemory -3
+#define XpmColorFailed -4
+
+typedef struct {
+ char *name; /* Symbolic color name */
+ char *value; /* Color value */
+ Pixel pixel; /* Color pixel */
+} XpmColorSymbol;
+
+typedef struct {
+ char *name; /* name of the extension */
+ unsigned int nlines; /* number of lines in this extension */
+ char **lines; /* pointer to the extension array of strings */
+} XpmExtension;
+
+typedef struct {
+ char *string; /* characters string */
+ char *symbolic; /* symbolic name */
+ char *m_color; /* monochrom default */
+ char *g4_color; /* 4 level grayscale default */
+ char *g_color; /* other level grayscale default */
+ char *c_color; /* color default */
+} XpmColor;
+
+typedef struct {
+ unsigned int width; /* image width */
+ unsigned int height; /* image height */
+ unsigned int cpp; /* number of characters per pixel */
+ unsigned int ncolors; /* number of colors */
+ XpmColor *colorTable; /* list of related colors */
+ unsigned int *data; /* image data */
+} XpmImage;
+
+typedef struct {
+ unsigned long valuemask; /* Specifies which attributes are defined */
+ char *hints_cmt; /* Comment of the hints section */
+ char *colors_cmt; /* Comment of the colors section */
+ char *pixels_cmt; /* Comment of the pixels section */
+ unsigned int x_hotspot; /* Returns the x hotspot's coordinate */
+ unsigned int y_hotspot; /* Returns the y hotspot's coordinate */
+ unsigned int nextensions; /* number of extensions */
+ XpmExtension *extensions; /* pointer to array of extensions */
+} XpmInfo;
+
+typedef int (*XpmAllocColorFunc)(
+ Display* /* display */,
+ Colormap /* colormap */,
+ char* /* colorname */,
+ XColor* /* xcolor */,
+ void* /* closure */
+);
+
+typedef int (*XpmFreeColorsFunc)(
+ Display* /* display */,
+ Colormap /* colormap */,
+ Pixel* /* pixels */,
+ int /* npixels */,
+ void* /* closure */
+);
+
+
+/* required struct for hw/nxagent/Holder.c */
+typedef struct {
+ unsigned long valuemask; /* Specifies which attributes are
+ defined */
+
+ Visual *visual; /* Specifies the visual to use */
+ Colormap colormap; /* Specifies the colormap to use */
+ unsigned int depth; /* Specifies the depth */
+ unsigned int width; /* Returns the width of the created
+ pixmap */
+ unsigned int height; /* Returns the height of the created
+ pixmap */
+ unsigned int x_hotspot; /* Returns the x hotspot's
+ coordinate */
+ unsigned int y_hotspot; /* Returns the y hotspot's
+ coordinate */
+ unsigned int cpp; /* Specifies the number of char per
+ pixel */
+ Pixel *pixels; /* List of used color pixels */
+ unsigned int npixels; /* Number of used pixels */
+ XpmColorSymbol *colorsymbols; /* List of color symbols to override */
+ unsigned int numsymbols; /* Number of symbols */
+ char *rgb_fname; /* RGB text file name */
+ unsigned int nextensions; /* Number of extensions */
+ XpmExtension *extensions; /* List of extensions */
+
+ unsigned int ncolors; /* Number of colors */
+ XpmColor *colorTable; /* List of colors */
+/* 3.2 backward compatibility code */
+ char *hints_cmt; /* Comment of the hints section */
+ char *colors_cmt; /* Comment of the colors section */
+ char *pixels_cmt; /* Comment of the pixels section */
+/* end 3.2 bc */
+ unsigned int mask_pixel; /* Color table index of transparent
+ color */
+
+ /* Color Allocation Directives */
+ Bool exactColors; /* Only use exact colors for visual */
+ unsigned int closeness; /* Allowable RGB deviation */
+ unsigned int red_closeness; /* Allowable red deviation */
+ unsigned int green_closeness; /* Allowable green deviation */
+ unsigned int blue_closeness; /* Allowable blue deviation */
+ int color_key; /* Use colors from this color set */
+
+ Pixel *alloc_pixels; /* Returns the list of alloc'ed color
+ pixels */
+ int nalloc_pixels; /* Returns the number of alloc'ed
+ color pixels */
+
+ Bool alloc_close_colors; /* Specify whether close colors should
+ be allocated using XAllocColor
+ or not */
+ int bitmap_format; /* Specify the format of 1bit depth
+ images: ZPixmap or XYBitmap */
+
+ /* Color functions */
+ XpmAllocColorFunc alloc_color; /* Application color allocator */
+ XpmFreeColorsFunc free_colors; /* Application color de-allocator */
+ void *color_closure; /* Application private data to pass to
+ alloc_color and free_colors */
+
+} XpmAttributes;
+
+/* XpmAttributes value masks bits */
+
+/* required masks bits for hw/nxagent/Holder.c */
+#define XpmDepth (1L<<2)
+#define XpmSize (1L<<3) /* width & height */
+
+/* macros for forward declarations of functions with prototypes */
+#define FUNC(f, t, p) extern t f p
+#define LFUNC(f, t, p) static t f p
+
+
+/*
+ * functions declarations (for building nxagent against system wide libXpm4,
+ * but also against libNX_X11 (as opposed to system-wide libX11).
+ */
+
+_XFUNCPROTOBEGIN
+
+/* Keep for hw/nxagent/Holder.c */
+FUNC(XpmCreatePixmapFromData, int, (Display *display,
+ Drawable d,
+ char **data,
+ Pixmap *pixmap_return,
+ Pixmap *shapemask_return,
+ XpmAttributes *attributes));
+/* Keep for hw/nxagent/Display.c */
+FUNC(XpmReadFileToPixmap, int, (Display *display,
+ Drawable d,
+ const char *filename,
+ Pixmap *pixmap_return,
+ Pixmap *shapemask_return,
+ XpmAttributes *attributes));
+
+_XFUNCPROTOEND
+
+#endif /* XPM_NUMBERS */
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c
new file mode 100644
index 000000000..11450d69d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.c
@@ -0,0 +1,50 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <zlib.h>
+
+#include "Compext.h"
+
+#include "Alpha.h"
+#include "Z.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define ALPHA_COMPRESSION_LEVEL 1
+#define ALPHA_COMPRESSION_THRESHOLD 32
+#define ALPHA_COMPRESSION_STRATEGY Z_RLE
+
+static int alphaCompressionLevel = ALPHA_COMPRESSION_LEVEL;
+static int alphaCompressionThreshold = ALPHA_COMPRESSION_THRESHOLD;
+static int alphaCompressionStrategy = ALPHA_COMPRESSION_STRATEGY;
+
+char *AlphaCompressData(const char *data, unsigned int size, unsigned int *compressed_size)
+{
+ return ZCompressData(data, size, alphaCompressionThreshold, alphaCompressionLevel,
+ alphaCompressionStrategy, compressed_size);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h
new file mode 100644
index 000000000..d7ac4e78e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Alpha.h
@@ -0,0 +1,45 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Alpha_H
+#define Alpha_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *AlphaCompressData(
+#if NeedFunctionPrototypes
+ const char* /* data */,
+ unsigned int /* size */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Alpha_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c
new file mode 100644
index 000000000..d906118d0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.c
@@ -0,0 +1,120 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Compext.h"
+
+#include "Bitmap.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+char *BitmapCompressData(XImage *image, unsigned int *size)
+{
+ if (image -> bits_per_pixel != 32)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******BitmapCompressData: Nothing to do with image of [%d] bpp and size [%d].\n",
+ image -> bits_per_pixel, image -> bytes_per_line * image -> height);
+ #endif
+
+ *size = image -> bytes_per_line * image -> height;
+
+ return image -> data;
+ }
+ else
+ {
+ /*
+ * Remove the 4th byte from the bitmap.
+ */
+
+ char *data;
+
+ char *next_src;
+ char *next_dst;
+
+ #ifdef TEST
+
+ if (image -> bytes_per_line != 4 * image -> width)
+ {
+ fprintf(stderr, "******BitmapCompressData: PANIC! Image as [%d] bytes per line with expected [%d].\n",
+ image -> bytes_per_line, 4 * image -> width);
+
+ return NULL;
+ }
+
+ #endif
+
+ *size = image -> width * image -> height * 3;
+
+ data = Xmalloc(*size);
+
+ if (data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******BitmapCompressData: PANIC! Failed to allocate [%d] bytes for the destination.\n",
+ *size);
+ #endif
+
+ *size = image -> bytes_per_line * image -> height;
+
+ return image -> data;
+ }
+
+ next_src = image -> data;
+ next_dst = data;
+
+ if (image -> byte_order == LSBFirst)
+ {
+ while (next_src < image -> data +
+ image -> bytes_per_line * image -> height)
+ {
+ *next_dst++ = *next_src++;
+ *next_dst++ = *next_src++;
+ *next_dst++ = *next_src++;
+
+ next_src++;
+ }
+ }
+ else
+ {
+ while (next_src < image -> data +
+ image -> bytes_per_line * image -> height)
+ {
+ next_src++;
+
+ *next_dst++ = *next_src++;
+ *next_dst++ = *next_src++;
+ *next_dst++ = *next_src++;
+ }
+ }
+
+ return data;
+ }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h
new file mode 100644
index 000000000..e45836d11
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Bitmap.h
@@ -0,0 +1,44 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Bitmap_H
+#define Bitmap_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *BitmapCompressData(
+#if NeedFunctionPrototypes
+ XImage* /* image */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Bitmap_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c
new file mode 100644
index 000000000..7a6d81b6b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.c
@@ -0,0 +1,349 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <signal.h>
+
+#include "os.h"
+
+#include "Compext.h"
+
+#include "Clean.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+int CleanXYImage(XImage *image)
+{
+ int i, j, k, plane;
+
+ int bitsToClean = (image -> bytes_per_line << 3) - image -> width - image -> xoffset;
+
+ unsigned int bytesToClean = bitsToClean >> 3;
+
+ bitsToClean &= 7;
+
+ for (k = 0; k < image -> depth; k++)
+ {
+ plane = k * (image -> bytes_per_line * image -> height);
+
+ for (i = 1; i <= image -> height; i++)
+ {
+ if (image -> byte_order == image -> bitmap_bit_order)
+ {
+ for (j = 1; j <= bytesToClean; j++)
+ {
+ image -> data[plane + i * (image -> bytes_per_line) - j] = 0x00;
+ }
+ }
+ else
+ {
+ for (j = bytesToClean; j >= 1; j--)
+ {
+ image -> data[plane + i * (image -> bytes_per_line) - j] = 0x00;
+ }
+ }
+
+ if (image -> bitmap_bit_order == MSBFirst)
+ {
+ image -> data[plane + i * (image -> bytes_per_line) - j] &= 0xff << bitsToClean;
+ }
+ else
+ {
+ image -> data[plane + i * (image -> bytes_per_line) - j] &= 0xff >> bitsToClean;
+ }
+ }
+ }
+
+ return 1;
+}
+
+int CleanZImage(XImage *image)
+{
+ unsigned int bytesToClean;
+ unsigned int j;
+ unsigned int imageLength;
+
+ #ifdef TEST
+ fprintf(stderr, "*****CleanZImage: Going to clean image of [%d] bits per pixel.\n",
+ image -> bits_per_pixel);
+ #endif
+
+ switch (image -> bits_per_pixel)
+ {
+ case 32:
+ {
+ /*
+ * The caller should pay attention at extracting
+ * the alpha channel prior to cleaning the image.
+ * Cleaning an image which is carrying the alpha
+ * channel will result in the image being treated
+ * as fully transparent.
+ */
+
+ register int i;
+
+ bytesToClean = image -> bytes_per_line * image -> height;
+
+ #ifdef DEBUG
+ fprintf(stderr, "*****CleanZImage: Cleaning [%d] bytes with bits per pixel [%d] "
+ "width [%d] bytes per line [%d] height [%d].\n", bytesToClean,
+ image -> bits_per_pixel, image -> width, image ->
+ bytes_per_line, image -> height);
+ #endif
+
+ if (image -> byte_order == LSBFirst)
+ {
+ for (i = 3; i < bytesToClean; i += 4)
+ {
+ ((unsigned char *) image -> data)[i] = 0x00;
+ }
+ }
+ else
+ {
+ for (i = 0; i < bytesToClean; i += 4)
+ {
+ ((unsigned char *) image -> data)[i] = 0x00;
+ }
+ }
+
+ break;
+ }
+ case 24:
+ case 15:
+ case 16:
+ case 8:
+ {
+ register int i, j;
+
+ bytesToClean = image -> bytes_per_line -
+ ((image -> width * image -> bits_per_pixel) >> 3);
+
+ for (i = 1; i <= image -> height; i++)
+ {
+ for (j = bytesToClean; j > 0; j--)
+ {
+ ((unsigned char *) image -> data)[(i * image -> bytes_per_line) - j] = 0x00;
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ #ifdef PANIC
+ fprintf(stderr, "*****CleanZImage: PANIC! Cannot clean image with [%d] bits per pixel.\n",
+ image -> bits_per_pixel);
+ #endif
+ }
+ }
+
+ /*
+ * Clean the padding bytes at the real
+ * end of the buffer.
+ */
+
+ imageLength = image -> bytes_per_line * image -> height;
+
+ bytesToClean = imageLength % 4;
+
+ for (j = 0; j < bytesToClean; j++)
+ {
+ ((unsigned char *)image -> data)[(imageLength + j)] = 0x00;
+ }
+
+ return 1;
+}
+
+/*
+ * Copy a clean version of src_image into dst_image.
+ * This code is not taking care of the image format.
+ * The agent doesn't use it and you have to consider
+ * it unsupported.
+ */
+
+int CopyAndCleanImage(XImage *src_image, XImage *dst_image)
+{
+ register long data_size;
+ register int i;
+
+ data_size = (src_image -> bytes_per_line * src_image -> height) >> 2;
+
+ #ifdef WARNING
+ fprintf(stderr, "******CleanImage: WARNING! Function called with image of [%d] bits per pixel.\n",
+ src_image -> bits_per_pixel);
+ #endif
+
+ switch (src_image -> bits_per_pixel)
+ {
+ case 32:
+ {
+ unsigned int mask;
+
+ if (src_image -> byte_order == MSBFirst)
+ {
+ mask = 0xffffff00;
+ }
+ else
+ {
+ mask = 0x00ffffff;
+ }
+ for (i = 0; i < data_size; i++)
+ {
+ ((unsigned int *)dst_image -> data)[i] = ((unsigned int *)src_image -> data)[i] & mask;
+ }
+
+ break;
+ }
+
+ case 24:
+ {
+ unsigned int bytes_to_clean;
+
+ for (i = 0; i < data_size; i++)
+ {
+ ((unsigned int *)dst_image -> data)[i] = ((unsigned int *)src_image -> data)[i];
+ }
+
+ bytes_to_clean = dst_image -> bytes_per_line - ((dst_image -> width *
+ dst_image -> bits_per_pixel) >> 3);
+
+ if (bytes_to_clean)
+ {
+ register unsigned int mask = 0xffffffff;
+ register int line_size;
+ register int i;
+
+ line_size = dst_image -> bytes_per_line >> 2;
+
+ if (dst_image -> byte_order == MSBFirst)
+ {
+ mask = mask << (bytes_to_clean << 3);
+ }
+ else
+ {
+ mask = mask >> (bytes_to_clean << 3);
+ }
+
+ for (i = 0; i < dst_image -> height;)
+ {
+ ((unsigned char *)dst_image -> data)[(++i * line_size) -1] &= mask;
+ }
+ }
+
+ break;
+ }
+
+ case 15:
+ case 16:
+ {
+ for (i = 0; i < data_size; i++)
+ {
+ ((unsigned int *) dst_image -> data)[i] = ((unsigned int *) src_image -> data)[i];
+ }
+
+ if (src_image -> width & 0x00000001)
+ {
+ int card32_per_line = dst_image -> bytes_per_line >> 2;
+
+ for (i = 0; i < dst_image -> height;)
+ {
+ ((unsigned int *) dst_image -> data)[(++i * card32_per_line) -1] &= 0x0000ffff;
+ }
+ }
+
+ break;
+ }
+
+ case 8:
+ {
+ unsigned int mask = 0x00000000;
+
+ switch (dst_image -> width % 4)
+ {
+ case 3:
+ {
+ mask = 0x00ffffff;
+
+ break;
+ }
+ case 2:
+ {
+ mask = 0x0000ffff;
+
+ break;
+ }
+ case 1:
+ {
+ mask = 0x000000ff;
+
+ break;
+ }
+ default:
+ {
+ /*
+ * Nothing to clean.
+ */
+
+ break;
+ }
+ }
+
+ for (i = 0; i < data_size; i++)
+ {
+ ((unsigned int *) dst_image -> data)[i] = ((unsigned int *) src_image -> data)[i];
+ }
+
+ if (mask)
+ {
+ int card32_per_line;
+ int i;
+
+ card32_per_line = dst_image -> bytes_per_line >> 2;
+
+ for (i = 0; i < dst_image -> height; i++)
+ {
+ ((unsigned int *) dst_image -> data)[(++i * card32_per_line) -1] &= mask;
+ }
+ }
+
+ break;
+ }
+
+ default:
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******CleanImage: PANIC! Cannot clean image of [%d] bits per pixel.\n",
+ src_image -> bits_per_pixel);
+ #endif
+
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h
new file mode 100644
index 000000000..510af1dfb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Clean.h
@@ -0,0 +1,44 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Clean_H
+#define Clean_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nx-X11/Xlib.h>
+
+int CleanXYImage(XImage *image);
+int CleanZImage(XImage *image);
+
+int CopyAndCleanImage(XImage *src_image, XImage *dst_image);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Clean_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c
new file mode 100644
index 000000000..6b025542d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.c
@@ -0,0 +1,50 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <zlib.h>
+
+#include "Compext.h"
+
+#include "Colormap.h"
+#include "Z.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define COLORMAP_COMPRESSION_LEVEL 4
+#define COLORMAP_COMPRESSION_THRESHOLD 32
+#define COLORMAP_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
+
+static int colormapCompressionLevel = COLORMAP_COMPRESSION_LEVEL;
+static int colormapCompressionThreshold = COLORMAP_COMPRESSION_THRESHOLD;
+static int colormapCompressionStrategy = COLORMAP_COMPRESSION_STRATEGY;
+
+char *ColormapCompressData(const char *data, unsigned int size, unsigned int *compressed_size)
+{
+ return ZCompressData(data, size, colormapCompressionThreshold, colormapCompressionLevel,
+ colormapCompressionStrategy, compressed_size);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h
new file mode 100644
index 000000000..e30f4fdab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Colormap.h
@@ -0,0 +1,45 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef ColormapComp_H
+#define ColormapComp_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *ColormapCompressData(
+#if NeedFunctionPrototypes
+ const char* /* data */,
+ unsigned int /* size */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ColormapComp_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c
new file mode 100644
index 000000000..8a53da376
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.c
@@ -0,0 +1,4778 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#undef _XSERVER64
+
+#include <sys/socket.h>
+
+#ifndef __sun
+#include <strings.h>
+#endif
+
+#include "dix.h"
+#include "os.h"
+
+/*
+ * Needed to enable definition of the callback
+ * functions.
+ */
+
+#define NX_TRANS_SOCKET
+
+#include <nx-X11/Xlib.h>
+#include <nx-X11/Xutil.h>
+#include <nx-X11/Xlibint.h>
+
+#include "Compext.h"
+
+#include <nx/NX.h>
+#include <nx/NXproto.h>
+#include <nx/NXpack.h>
+#include <nx/MD5.h>
+
+#include "Clean.h"
+#include "Mask.h"
+#include "Colormap.h"
+#include "Alpha.h"
+#include "Bitmap.h"
+#include "Jpeg.h"
+#include "Png.h"
+#include "Rgb.h"
+#include "Rle.h"
+#include "Z.h"
+
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+/*
+ * Maximum number of colors allowed in
+ * Png encoding.
+ */
+
+#define NB_COLOR_MAX 256
+
+/*
+ * Dummy error handlers used internally to catch
+ * Xlib failures in replies.
+ */
+
+static int _NXInternalReplyErrorFunction(Display *dpy, XErrorEvent *error);
+
+static void _NXInternalLostSequenceFunction(Display *dpy, unsigned long newseq,
+ unsigned long lastseq, unsigned int type);
+
+/*
+ * Resource ids that can be requested by
+ * the client for use in split or unpack
+ * operations.
+ */
+
+static unsigned char _NXSplitResources[NXNumberOfResources];
+static unsigned char _NXUnpackResources[NXNumberOfResources];
+
+static Display *_NXDisplayInitialized = NULL;
+
+/*
+ * Used in asynchronous handling of
+ * GetImage replies.
+ */
+
+typedef struct
+{
+ unsigned long sequence;
+ unsigned int resource;
+ unsigned long mask;
+ int format;
+ int width;
+ int height;
+ _XAsyncHandler *handler;
+ XImage *image;
+} _NXCollectImageState;
+
+static _NXCollectImageState *_NXCollectedImages[NXNumberOfResources];
+
+/*
+ * Used in asynchronous handling of
+ * GetProperty replies.
+ */
+
+typedef struct
+{
+ unsigned long sequence;
+ unsigned int resource;
+ Window window;
+ Atom property;
+ Atom type;
+ int format;
+ unsigned long items;
+ unsigned long after;
+ _XAsyncHandler *handler;
+ char *data;
+} _NXCollectPropertyState;
+
+static _NXCollectPropertyState *_NXCollectedProperties[NXNumberOfResources];
+
+/*
+ * Used in asynchronous handling of
+ * GrabPointer replies.
+ */
+
+typedef struct
+{
+ unsigned long sequence;
+ unsigned int resource;
+ int status;
+ _XAsyncHandler *handler;
+} _NXCollectGrabPointerState;
+
+static _NXCollectGrabPointerState *_NXCollectedGrabPointers[NXNumberOfResources];
+
+/*
+ * Used in asynchronous handling of
+ * GetInputFocus replies.
+ */
+
+typedef struct
+{
+ unsigned long sequence;
+ unsigned int resource;
+ Window focus;
+ int revert_to;
+ _XAsyncHandler *handler;
+} _NXCollectInputFocusState;
+
+static _NXCollectInputFocusState *_NXCollectedInputFocuses[NXNumberOfResources];
+
+/*
+ * Used by functions handling cache of
+ * packed images.
+ */
+
+#define MD5_LENGTH 16
+
+typedef struct
+{
+ md5_byte_t *md5;
+ XImage *image;
+ unsigned int method;
+} _NXImageCacheEntry;
+
+int NXImageCacheSize = 0;
+int NXImageCacheHits = 0;
+int NXImageCacheOps = 0;
+
+_NXImageCacheEntry *NXImageCache = NULL;
+
+#ifdef DUMP
+
+void _NXCacheDump(const char *label);
+
+void _NXDumpData(const unsigned char *buffer, unsigned int size);
+
+#endif
+
+/*
+ * From X11/PutImage.c.
+ *
+ * Cancel a GetReq operation, before doing
+ * _XSend or Data.
+ */
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define UnGetReq(name)\
+ dpy->bufptr -= SIZEOF(x##name##Req);\
+ dpy->request--
+#else
+#define UnGetReq(name)\
+ dpy->bufptr -= SIZEOF(x/**/name/**/Req);\
+ dpy->request--
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define UnGetEmptyReq()\
+ dpy->bufptr -= 4;\
+ dpy->request--
+#else
+#define UnGetEmptyReq(name)\
+ dpy->bufptr -= 4;\
+ dpy->request--
+#endif
+
+/*
+ * From X11/ImUtil.c.
+ */
+
+extern int _XGetBitsPerPixel(Display *dpy, int depth);
+extern int _XGetScanlinePad(Display *dpy, int depth);
+
+#define ROUNDUP(nbytes, pad) (((nbytes) + ((pad) - 1)) & \
+ ~(long)((pad) - 1))
+
+static unsigned int DepthOnes(unsigned long mask)
+{
+ register unsigned long y;
+
+ y = (mask >> 1) &033333333333;
+ y = mask - y - ((y >>1) & 033333333333);
+ return ((unsigned int) (((y + (y >> 3)) &
+ 030707070707) % 077));
+}
+
+#define CanMaskImage(image, mask) \
+\
+(image -> format == ZPixmap && mask != NULL && \
+ (image -> depth == 32 || image -> depth == 24 || \
+ (image -> depth == 16 && (image -> red_mask == 0xf800 && \
+ image -> green_mask == 0x7e0 && image -> blue_mask == 0x1f))))
+
+#define ShouldMaskImage(image, mask) (mask -> color_mask != 0xff)
+
+/*
+ * Initialize and reset the internal structures.
+ */
+
+extern int _NXInternalInitResources(Display *dpy);
+extern int _NXInternalResetResources(Display *dpy);
+extern int _NXInternalInitEncoders(Display *dpy);
+extern int _NXInternalResetEncoders(Display *dpy);
+
+int NXInitDisplay(Display *dpy)
+{
+ #ifdef TEST
+ fprintf(stderr, "******NXInitDisplay: Called for display at [%p].\n", (void *) dpy);
+ #endif
+
+ if (_NXDisplayInitialized == NULL)
+ {
+ _NXInternalInitResources(dpy);
+
+ _NXInternalInitEncoders(dpy);
+
+ _NXDisplayInitialized = dpy;
+
+ return 1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInitDisplay: WARNING! Internal structures already initialized.\n");
+ #endif
+
+ return 0;
+}
+
+int NXResetDisplay(Display *dpy)
+{
+ #ifdef TEST
+ fprintf(stderr, "******NXResetDisplay: Called for display at [%p].\n", (void *) dpy);
+ #endif
+
+ if (_NXDisplayInitialized != NULL)
+ {
+ _NXInternalResetResources(dpy);
+
+ _NXInternalResetEncoders(dpy);
+
+ _NXDisplayInitialized = NULL;
+
+ return 1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXResetDisplay: WARNING! Internal structures already reset.\n");
+ #endif
+
+ return 0;
+}
+
+int _NXInternalInitResources(Display *dpy)
+{
+ return _NXInternalResetResources(dpy);
+}
+
+int _NXInternalResetResources(Display *dpy)
+{
+ int i;
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalResetResources: Clearing all the internal structures.\n");
+ #endif
+
+ for (i = 0; i < NXNumberOfResources; i++)
+ {
+ _NXSplitResources[i] = 0;
+ _NXUnpackResources[i] = 0;
+
+ if (_NXCollectedImages[i] != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect image data "
+ "for resource [%d].\n", i);
+ #endif
+
+ if (_NXCollectedImages[i] -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, _NXCollectedImages[i] -> handler);
+
+ Xfree(_NXCollectedImages[i] -> handler);
+ }
+
+ if (_NXCollectedImages[i] -> image != NULL)
+ {
+ XDestroyImage(_NXCollectedImages[i] -> image);
+ }
+
+ Xfree(_NXCollectedImages[i]);
+
+ _NXCollectedImages[i] = NULL;
+ }
+
+ if (_NXCollectedProperties[i] != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect property data "
+ "for resource [%d].\n", i);
+ #endif
+
+ if (_NXCollectedProperties[i] -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, _NXCollectedProperties[i] -> handler);
+
+ Xfree(_NXCollectedProperties[i] -> handler);
+ }
+
+ if (_NXCollectedProperties[i] -> data != NULL)
+ {
+ Xfree(_NXCollectedProperties[i] -> data);
+ }
+
+ Xfree(_NXCollectedProperties[i]);
+
+ _NXCollectedProperties[i] = NULL;
+ }
+
+ if (_NXCollectedGrabPointers[i] != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing grab pointer data "
+ "for resource [%d].\n", i);
+ #endif
+
+ if (_NXCollectedGrabPointers[i] -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, _NXCollectedGrabPointers[i] -> handler);
+
+ Xfree(_NXCollectedGrabPointers[i] -> handler);
+ }
+
+ Xfree(_NXCollectedGrabPointers[i]);
+
+ _NXCollectedGrabPointers[i] = NULL;
+ }
+
+ if (_NXCollectedInputFocuses[i] != NULL)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalResetResources: WARNING! Clearing collect input focus data "
+ "for resource [%d].\n", i);
+ #endif
+
+ if (_NXCollectedInputFocuses[i] -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, _NXCollectedInputFocuses[i] -> handler);
+
+ Xfree(_NXCollectedInputFocuses[i] -> handler);
+ }
+
+ Xfree(_NXCollectedInputFocuses[i]);
+
+ _NXCollectedInputFocuses[i] = NULL;
+ }
+ }
+
+ return 1;
+}
+
+int _NXInternalInitEncoders(Display *dpy)
+{
+ ZInitEncoder();
+
+ return 1;
+}
+
+int _NXInternalResetEncoders(Display *dpy)
+{
+ ZResetEncoder();
+
+ return 1;
+}
+
+int NXSetDisplayPolicy(Display *dpy, int policy)
+{
+ if (policy == NXPolicyImmediate)
+ {
+ return NXTransPolicy(NX_FD_ANY, NX_POLICY_IMMEDIATE);
+ }
+ else
+ {
+ return NXTransPolicy(NX_FD_ANY, NX_POLICY_DEFERRED);
+ }
+}
+
+int NXSetDisplayBuffer(Display *dpy, int size)
+{
+ /*
+ * This is not multi-thread safe, so,
+ * if you have threads, be sure that
+ * they are stopped.
+ */
+
+ char *buffer;
+
+ XFlush(dpy);
+
+ if (dpy -> bufmax - size == dpy -> buffer)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayBuffer: Nothing to do with buffer size matching.\n");
+ #endif
+
+ return 1;
+ }
+ else if (dpy -> bufptr != dpy -> buffer)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXSetDisplayBuffer: PANIC! The display buffer is not empty.\n");
+ #endif
+
+ return -1;
+ }
+ else if ((buffer = Xcalloc(1, size)) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXSetDisplayBuffer: PANIC! Can't allocate [%d] bytes for the buffer.\n",
+ size);
+ #endif
+
+ return -1;
+ }
+
+ if (dpy -> buffer != NULL)
+ {
+ Xfree(dpy -> buffer);
+ }
+
+ dpy -> buffer = buffer;
+ dpy -> bufptr = dpy -> buffer;
+ dpy -> bufmax = dpy -> bufptr + size;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayBuffer: Set the display output buffer size to [%d].\n",
+ size);
+ #endif
+
+ return 1;
+}
+
+/*
+ * If set, the Popen() function in the X server
+ * wil remove the LD_LIBRARY_PATH variable from
+ * the environment before calling the execl()
+ * function on the child process.
+ */
+
+int NXUnsetLibraryPath(int value)
+{
+ int previous = _NXUnsetLibraryPath;
+
+ _NXUnsetLibraryPath = value;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXUnsetLibraryPath: Set the flag to [%d] with previous value [%d].\n",
+ value, previous);
+ #endif
+
+ return previous;
+}
+
+/*
+ * If set, the Xlib I/O error handler will simply
+ * return, instead of quitting the program. This
+ * leaves to the application the responsibility
+ * of checking the state of the XlibDisplayIOEr-
+ * ror flag.
+ */
+
+int NXHandleDisplayError(int value)
+{
+ int previous = _NXHandleDisplayError;
+
+ _NXHandleDisplayError = value;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXHandleDisplayError: Set the flag to [%d] with previous value [%d].\n",
+ value, previous);
+ #endif
+
+ return previous;
+}
+
+/*
+ * Shutdown the display descriptor and force Xlib
+ * to set the I/O error flag.
+ */
+
+Bool NXForceDisplayError(Display *dpy)
+{
+ if (dpy != NULL)
+ {
+ NXTransClose(dpy -> fd);
+
+ if (!(dpy -> flags & XlibDisplayIOError))
+ {
+ shutdown(dpy -> fd, SHUT_RDWR);
+
+ _XIOError(dpy);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Check if the display has become invalid. Similarly
+ * to the modified Xlib, we call the predicate funct-
+ * ion with the value of the XlibDisplayIOError flag
+ * only if the I/O error was not encountered already.
+ * The application can use this function to query the
+ * XlibDisplayIOError flag because Xlib doesn't expose
+ * the internals of the display structure to the appli-
+ * cation.
+ */
+
+int NXDisplayError(Display *dpy)
+{
+ if (dpy != NULL)
+ {
+ return (_XGetIOError(dpy) ||
+ (_NXDisplayErrorFunction != NULL &&
+ (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy))));
+ }
+
+ return 1;
+}
+
+/*
+ * Various queries related to the state of the
+ * display connection.
+ */
+
+int NXDisplayReadable(Display *dpy)
+{
+ int result;
+ int readable;
+
+ result = NXTransReadable(dpy -> fd, &readable);
+
+ if (result == 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXDisplayReadable: Returning [%d] bytes readable from fd [%d].\n",
+ readable, dpy -> fd);
+ #endif
+
+ return readable;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXDisplayReadable: WARNING! Error detected on display fd [%d].\n",
+ dpy -> fd);
+ #endif
+
+ return -1;
+}
+
+int NXDisplayFlushable(Display *dpy)
+{
+ #ifdef DEBUG
+
+ int flushable;
+
+ flushable = NXTransFlushable(dpy -> fd) +
+ (dpy -> bufptr - dpy -> buffer);
+
+ fprintf(stderr, "******NXDisplayFlushable: Returning [%d+%d=%d] bytes flushable "
+ "to fd [%d].\n", (int) (dpy -> bufptr - dpy -> buffer),
+ (int) (flushable - (dpy -> bufptr - dpy -> buffer)),
+ flushable, dpy -> fd);
+
+ return flushable;
+
+ #else
+
+ return NXTransFlushable(dpy -> fd) + (dpy -> bufptr - dpy -> buffer);
+
+ #endif
+}
+
+int NXDisplayCongestion(Display *dpy)
+{
+ #ifdef DEBUG
+
+ int congestion = NXTransCongestion(dpy -> fd);
+
+ fprintf(stderr, "******NXDisplayCongestion: Returning [%d] as congestion level for fd [%d].\n",
+ congestion, dpy -> fd);
+
+ return congestion;
+
+ #else
+
+ return NXTransCongestion(dpy -> fd);
+
+ #endif
+}
+
+int NXFlushDisplay(Display *dpy, int what)
+{
+ if (!(dpy -> flags & XlibDisplayWriting) &&
+ dpy -> bufptr - dpy -> buffer > 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXFlushDisplay: Writing with [%d] bytes in the buffer.\n",
+ (int) (dpy -> bufptr - dpy -> buffer));
+ #endif
+
+ XFlush(dpy);
+ }
+
+ if (what == NXFlushBuffer)
+ {
+ return 0;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXFlushDisplay: Flushing with [%d] bytes in the NX transport.\n",
+ NXDisplayFlushable(dpy));
+ #endif
+
+ return NXTransFlush(dpy -> fd);
+}
+
+NXDisplayErrorPredicate NXSetDisplayErrorPredicate(NXDisplayErrorPredicate predicate)
+{
+ NXDisplayErrorPredicate previous = _NXDisplayErrorFunction;
+
+ _NXDisplayErrorFunction = predicate;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayErrorPredicate: Set the predicate to [%p] with previous value [%p].\n",
+ predicate, previous);
+ #endif
+
+ return previous;
+}
+
+NXDisplayBlockHandler NXSetDisplayBlockHandler(NXDisplayBlockHandler handler)
+{
+ NXDisplayBlockHandler previous = _NXDisplayBlockFunction;
+
+ _NXDisplayBlockFunction = handler;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayBlockHandler: Set the handler to [%p] with previous value [%p].\n",
+ handler, previous);
+ #endif
+
+ return previous;
+}
+
+NXDisplayWriteHandler NXSetDisplayWriteHandler(NXDisplayWriteHandler handler)
+{
+ NXDisplayWriteHandler previous = _NXDisplayWriteFunction;
+
+ _NXDisplayWriteFunction = handler;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayWriteHandler: Set the handler to [%p] with previous value [%p].\n",
+ handler, previous);
+ #endif
+
+ return previous;
+}
+
+NXDisplayFlushHandler NXSetDisplayFlushHandler(NXDisplayFlushHandler handler, Display *display)
+{
+ NXDisplayFlushHandler previous = _NXDisplayFlushFunction;
+
+ _NXDisplayFlushFunction = handler;
+
+ NXTransHandler(NX_FD_ANY, NX_HANDLER_FLUSH,
+ (void (*)(void *, int)) handler, (void *) display);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayFlushHandler: Set the handler to [%p] with display [%p] "
+ "and previous value [%p].\n", handler, display, previous);
+ #endif
+
+ return previous;
+}
+
+NXDisplayStatisticsHandler NXSetDisplayStatisticsHandler(NXDisplayStatisticsHandler handler, char **buffer)
+{
+ NXDisplayStatisticsHandler previous = _NXDisplayStatisticsFunction;
+
+ _NXDisplayStatisticsFunction = handler;
+
+ /*
+ * Propagate the handler.
+ */
+
+ NXTransHandler(NX_FD_ANY, NX_HANDLER_STATISTICS,
+ (void (*)(void *, int)) handler, (void *) buffer);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetDisplayStatisticsHandler: Set the handler to [%p] with buffer pointer [%p] "
+ "and previous value [%p].\n", handler, buffer, previous);
+ #endif
+
+ return previous;
+}
+
+NXLostSequenceHandler NXSetLostSequenceHandler(NXLostSequenceHandler handler)
+{
+ NXLostSequenceHandler previous = _NXLostSequenceFunction;
+
+ _NXLostSequenceFunction = handler;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetLostSequenceHandler: Set the handler to [%p] with previous value [%p].\n",
+ handler, previous);
+ #endif
+
+ return previous;
+}
+
+int _NXInternalReplyErrorFunction(Display *dpy, XErrorEvent *error)
+{
+ #ifdef TEST
+ fprintf(stderr, "******_NXInternalReplyErrorFunction: Internal error handler called.\n");
+ #endif
+
+ return 0;
+}
+
+void _NXInternalLostSequenceFunction(Display *dpy, unsigned long newseq,
+ unsigned long lastseq, unsigned int type)
+{
+ #ifdef TEST
+
+ fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Sequence lost with new "
+ "sequence %ld last request %ld.\n", newseq, dpy -> request);
+
+ /*
+ * TODO: Reply or event info must be implemented.
+ *
+ * fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Expected event or reply "
+ * "was %ld with sequence %ld.\n", (long) rep -> type, (long) rep -> sequenceNumber);
+ */
+
+ fprintf(stderr, "******_NXInternalLostSequenceFunction: WARNING! Last sequence read "
+ "was %ld display request is %ld.\n", lastseq & 0xffff, dpy -> request & 0xffff);
+
+ #endif
+}
+
+Status NXGetControlParameters(Display *dpy, unsigned int *link_type, unsigned int *local_major,
+ unsigned int *local_minor, unsigned int *local_patch,
+ unsigned int *remote_major, unsigned int *remote_minor,
+ unsigned int *remote_patch, int *split_timeout, int *motion_timeout,
+ int *split_mode, int *split_size, unsigned int *pack_method,
+ unsigned int *pack_quality, int *data_level, int *stream_level,
+ int *delta_level, unsigned int *load_cache,
+ unsigned int *save_cache, unsigned int *startup_cache)
+{
+ xNXGetControlParametersReply rep;
+
+ _X_UNUSED register xReq *req;
+
+ LockDisplay(dpy);
+
+ GetEmptyReq(NXGetControlParameters, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetControlParameters: Sending message opcode [%d].\n",
+ X_NXGetControlParameters);
+ #endif
+
+ if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == xFalse)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetControlParameters: Error receiving reply.\n");
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetControlParameters: Got reply with link type [%u].\n", rep.linkType);
+
+ fprintf(stderr, "******NXGetControlParameters: Local protocol major [%u] minor [%u] patch [%u].\n",
+ rep.localMajor, rep.localMinor, rep.localPatch);
+
+ fprintf(stderr, "******NXGetControlParameters: Remote protocol major [%u] minor [%u] patch [%u].\n",
+ rep.remoteMajor, rep.remoteMinor, rep.remotePatch);
+
+ fprintf(stderr, "******NXGetControlParameters: Split timeout [%d] motion timeout [%d].\n",
+ (int) rep.splitTimeout, (int) rep.motionTimeout);
+
+ fprintf(stderr, "******NXGetControlParameters: Split mode [%d] split size [%d].\n",
+ (int) rep.splitMode, (int) rep.splitSize);
+
+ fprintf(stderr, "******NXGetControlParameters: Preferred pack method [%d] pack quality [%d].\n",
+ (int) rep.packMethod, (int) rep.packQuality);
+
+ fprintf(stderr, "******NXGetControlParameters: Data level [%d] stream level [%d] delta level [%d].\n",
+ rep.dataLevel, rep.streamLevel, rep.deltaLevel);
+ #endif
+
+ *link_type = rep.linkType;
+
+ *local_major = rep.localMajor;
+ *local_minor = rep.localMinor;
+ *local_patch = rep.localPatch;
+
+ *remote_major = rep.remoteMajor;
+ *remote_minor = rep.remoteMinor;
+ *remote_patch = rep.remotePatch;
+
+ *split_timeout = rep.splitTimeout;
+ *motion_timeout = rep.motionTimeout;
+
+ *split_mode = rep.splitMode;
+ *split_size = rep.splitSize;
+
+ *pack_method = rep.packMethod;
+ *pack_quality = rep.packQuality;
+
+ *data_level = rep.dataLevel;
+ *stream_level = rep.streamLevel;
+ *delta_level = rep.deltaLevel;
+
+ *load_cache = rep.loadCache;
+ *save_cache = rep.saveCache;
+ *startup_cache = rep.startupCache;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ /*
+ * Install our internal out-of-sync handler.
+ */
+
+ _NXLostSequenceFunction = _NXInternalLostSequenceFunction;
+
+ return 1;
+}
+
+/*
+ * Which unpack methods are supported by the
+ * remote proxy?
+ */
+
+Status NXGetUnpackParameters(Display *dpy, unsigned int *entries, unsigned char supported_methods[])
+{
+ register xNXGetUnpackParametersReq *req;
+
+ xNXGetUnpackParametersReply rep;
+
+ register unsigned n;
+
+ #ifdef TEST
+ register unsigned i;
+ #endif
+
+ if (*entries < NXNumberOfPackMethods)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetUnpackParameters: Requested only [%d] entries while they should be [%d].\n",
+ *entries, NXNumberOfPackMethods);
+ #endif
+
+ return 0;
+ }
+
+ LockDisplay(dpy);
+
+ GetReq(NXGetUnpackParameters, req);
+
+ req -> entries = *entries;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetUnpackParameters: Sending message opcode [%d] with [%d] requested entries.\n",
+ X_NXGetUnpackParameters, *entries);
+ #endif
+
+ if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == xFalse || rep.length == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetUnpackParameters: Error receiving reply.\n");
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ if ((n = rep.length << 2) > *entries)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetUnpackParameters: Got [%d] bytes of reply data while they should be [%d].\n",
+ n, *entries);
+ #endif
+
+ _XEatData(dpy, (unsigned long) n);
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ *entries = n;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetUnpackParameters: Reading [%d] bytes of reply data.\n", n);
+ #endif
+
+ _XReadPad(dpy, (char *) supported_methods, n);
+
+ #ifdef TEST
+
+ fprintf(stderr, "******NXGetUnpackParameters: Got reply with methods: ");
+
+ for (i = 0; i < n; i++)
+ {
+ if (supported_methods[i] != 0)
+ {
+ fprintf(stderr, "[%d]", i);
+ }
+ }
+
+ fprintf(stderr, ".\n");
+
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Query and enable the MIT-SHM support between the
+ * proxy and the X server. The 'enable' flags must be
+ * true if shared memory PutImages and PutPackedImages
+ * are desired. On return the flags will say if support
+ * has been successfully enabled.
+ *
+ * Note that the the client part is not useful and not
+ * implemented. The size of the segment is chosen by
+ * the proxy. The main purpose of the message is to
+ * reserve the XID that will be used by the remote.
+ */
+
+Status NXGetShmemParameters(Display *dpy, unsigned int *enable_client,
+ unsigned int *enable_server, unsigned int *client_segment,
+ unsigned int *server_segment, unsigned int *client_size,
+ unsigned int *server_size)
+{
+ register xNXGetShmemParametersReq *req;
+
+ register int stage;
+
+ xNXGetShmemParametersReply rep;
+
+ /*
+ * Save the previous handler.
+ */
+
+ int (*handler)(Display *, XErrorEvent *) = _XErrorFunction;
+
+ *client_segment = 0;
+ *server_segment = 0;
+
+ if (*enable_client)
+ {
+ *client_segment = XAllocID(dpy);
+ }
+
+ if (*enable_server)
+ {
+ *server_segment = XAllocID(dpy);
+ }
+
+ LockDisplay(dpy);
+
+ _XErrorFunction = _NXInternalReplyErrorFunction;
+
+ for (stage = 0; stage < 3; stage++)
+ {
+ GetReq(NXGetShmemParameters, req);
+
+ req -> stage = stage;
+
+ req -> enableClient = (*enable_client != 0 ? 1 : 0);
+ req -> enableServer = (*enable_server != 0 ? 1 : 0);
+
+ req -> clientSegment = *client_segment;
+ req -> serverSegment = *server_segment;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetShmemParameters: Sending message opcode [%d] at stage [%d].\n",
+ X_NXGetShmemParameters, stage);
+ #endif
+
+ #ifdef TEST
+
+ if (stage == 0)
+ {
+ fprintf(stderr, "******NXGetShmemParameters: Enable client is [%u] enable server is [%u].\n",
+ *enable_client, *enable_server);
+
+ fprintf(stderr, "******NXGetShmemParameters: Client segment is [%u] server segment is [%u].\n",
+ *client_segment, *server_segment);
+ }
+
+ #endif
+
+ /*
+ * There isn't X server reply in the second stage.
+ * The procedure followed at X server side is:
+ *
+ * Stage 0: Send X_QueryExtension and masquerade
+ * the reply.
+ *
+ * Stage 1: Allocate the shared memory and send
+ * X_ShmAttach to the X server.
+ *
+ * Stage 2: Send X_GetInputFocus and masquerade
+ * the reply.
+ *
+ * The last message is used to force a reply and
+ * collect any X error caused by a failure in the
+ * shared memory initialization.
+ */
+
+ if (stage != 1)
+ {
+ /*
+ * We are only interested in the final reply.
+ */
+
+ if (_XReply(dpy, (xReply *) &rep, 0, xTrue) == xFalse)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetShmemParameters: Error receiving reply.\n");
+ #endif
+
+ _XErrorFunction = handler;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * Return the settings to client.
+ */
+
+ *enable_client = rep.clientEnabled;
+ *enable_server = rep.serverEnabled;
+
+ *client_size = rep.clientSize;
+ *server_size = rep.serverSize;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetShmemParameters: Got final reply with enabled client [%u] and server [%u].\n",
+ *enable_client, *enable_server);
+
+ fprintf(stderr, "******NXGetShmemParameters: Client segment size [%u] server segment size [%u].\n",
+ *client_size, *server_size);
+ #endif
+
+ _XErrorFunction = handler;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Get the path to the font server that can be used by the X
+ * server to tunnel the font connections across the NX link.
+ * The path actually represents the TCP port where the proxy
+ * on the NX client side is listening. The agent can tempora-
+ * rily enable the tunneling when it needs a font that is not
+ * available on the client, for example when the session is
+ * migrated from a different X server.
+ *
+ * Note that it is not advisable to use the font server chan-
+ * nel for other purposes than restoring a font that is found
+ * missing at the time the session is migrated to a different
+ * display. This is because the agent implements a caching of
+ * the list of fonts supported by the client as it needs to
+ * advertise only the fonts that can be opened at both sides.
+ */
+
+Status NXGetFontParameters(Display *dpy, unsigned int path_length, char path_data[])
+{
+ _X_UNUSED register xNXGetFontParametersReq *req;
+
+ xNXGetFontParametersReply rep;
+
+ register unsigned n;
+
+ #ifdef TEST
+ register unsigned i;
+ #endif
+
+ if (path_length < 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: No room to store the reply.\n");
+ #endif
+
+ return 0;
+ }
+
+ *path_data = '\0';
+
+ LockDisplay(dpy);
+
+ GetReq(NXGetFontParameters, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: Sending message opcode [%d].\n",
+ X_NXGetFontParameters);
+ #endif
+
+ if (_XReply(dpy, (xReply *) &rep, 0, xFalse) == xFalse || rep.length == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: Error receiving reply.\n");
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ if ((n = rep.length << 2) > path_length)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: Got [%d] bytes of reply data with only room for [%d].\n",
+ n, path_length);
+ #endif
+
+ _XEatData(dpy, (unsigned long) n);
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: Reading [%d] bytes of reply data.\n", n);
+ #endif
+
+ _XReadPad(dpy, (char *) path_data, n);
+
+ /*
+ * Check if the string can be fully
+ * contained by the buffer.
+ */
+
+ if (*path_data > path_length - 1)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXGetFontParameters: Inconsistent length in the returned string.\n");
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 0;
+ }
+
+ #ifdef TEST
+
+ fprintf(stderr, "******NXGetFontParameters: Got font path of [%d] bytes and value [",
+ (int) *path_data);
+
+ for (i = 0; i < *path_data; i++)
+ {
+ fprintf(stderr, "%c", *(path_data + i + 1));
+ }
+
+ fprintf(stderr, "].\n");
+
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+unsigned int NXAllocSplit(Display *dpy, unsigned int resource)
+{
+ if (resource == NXAnyResource)
+ {
+ for (resource = 0; resource < NXNumberOfResources; resource++)
+ {
+ if (_NXSplitResources[resource] == 0)
+ {
+ _NXSplitResources[resource] = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXAllocSplit: Reserved resource [%u].\n",
+ resource);
+ #endif
+
+ return resource;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXAllocSplit: WARNING! Resource limit exausted.\n");
+ #endif
+
+ return NXNoResource;
+ }
+ else if (resource >= 0 && resource < NXNumberOfResources)
+ {
+ #ifdef TEST
+
+ if (_NXSplitResources[resource] == 0)
+ {
+ fprintf(stderr, "******NXAllocSplit: Reserved requested resource [%u].\n",
+ resource);
+ }
+ else
+ {
+ fprintf(stderr, "******NXAllocSplit: Requested resource [%u] already reserved.\n",
+ resource);
+ }
+
+ #endif
+
+ _NXSplitResources[resource] = 1;
+ }
+
+ #ifdef PANIC
+ fprintf(stderr, "******NXAllocSplit: PANIC! Can't reserve requested resource [%u].\n",
+ resource);
+ #endif
+
+ return NXNoResource;
+}
+
+/*
+ * Tell the proxy to split the next messages.
+ */
+
+int NXStartSplit(Display *dpy, unsigned int resource, unsigned int mode)
+{
+ register xNXStartSplitReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXStartSplit, req);
+
+ req -> resource = resource;
+ req -> mode = mode;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXStartSplit: Sending opcode [%d] with resource [%d] mode [%d].\n",
+ X_NXStartSplit, resource, mode);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Send the closure of the split sequence and
+ * tell the proxy to send the results.
+ */
+
+int NXEndSplit(Display *dpy, unsigned int resource)
+{
+ register xNXEndSplitReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXEndSplit, req);
+
+ req -> resource = resource;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXEndSplit: Sending opcode [%d] with resource [%d].\n",
+ X_NXStartSplit, resource);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * This message must be sent whenever the proxy notifies
+ * the client of the completion of a split. If the 'pro-
+ * pagate' field is 0, the proxy will not send the ori-
+ * ginal request to the X server, but will only free the
+ * internal state.
+ */
+
+int NXCommitSplit(Display *dpy, unsigned int resource, unsigned int propagate,
+ unsigned char request, unsigned int position)
+{
+ register xNXCommitSplitReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXCommitSplit, req);
+
+ req -> resource = resource;
+ req -> propagate = propagate;
+ req -> request = request;
+ req -> position = position;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXCommitSplit: Sending opcode [%d] with resource [%d] propagate [%d] "
+ "request [%d] position [%d].\n", X_NXCommitSplit, resource,
+ propagate, request, position);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+int NXAbortSplit(Display *dpy, unsigned int resource)
+{
+ register xNXAbortSplitReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXAbortSplit, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXAbortSplit: Sending message opcode [%d] with resource [%u].\n",
+ X_NXAbortSplit, resource);
+ #endif
+
+ req -> resource = resource;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+int NXFinishSplit(Display *dpy, unsigned int resource)
+{
+ register xNXFinishSplitReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXFinishSplit, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXFinishSplit: Sending message opcode [%d] with resource [%u].\n",
+ X_NXFinishSplit, resource);
+ #endif
+
+ req -> resource = resource;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+int NXFreeSplit(Display *dpy, unsigned int resource)
+{
+ register xNXFreeSplitReq *req;
+
+ if (_NXSplitResources[resource] != 0)
+ {
+ LockDisplay(dpy);
+
+ GetReq(NXFreeSplit, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXFreeSplit: Sending message opcode [%d] with resource [%u].\n",
+ X_NXFreeSplit, resource);
+ #endif
+
+ req -> resource = resource;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ #ifdef TEST
+ fprintf(stderr, "******NXFreeSplit: Making the resource [%u] newly available.\n",
+ resource);
+ #endif
+
+ _NXSplitResources[resource] = 0;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "******NXFreeSplit: Nothing to do for resource [%u].\n",
+ resource);
+ }
+ #endif
+
+ return 1;
+}
+
+/*
+ * Tell to remote proxy to discard expose events
+ * of one or more types.
+ */
+
+int NXSetExposeParameters(Display *dpy, int expose, int graphics_expose, int no_expose)
+{
+ register xNXSetExposeParametersReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetExposeParameters, req);
+
+ req -> expose = expose;
+ req -> graphicsExpose = graphics_expose;
+ req -> noExpose = no_expose;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetExposeParameters: Sending message opcode [%d] with flags [%d][%d][%d].\n",
+ X_NXSetExposeParameters, req -> expose, req -> graphicsExpose, req -> noExpose);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Tell to the local proxy how to handle the next requests.
+ */
+
+int NXSetCacheParameters(Display *dpy, int enable_cache, int enable_split,
+ int enable_save, int enable_load)
+{
+ register xNXSetCacheParametersReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetCacheParameters, req);
+
+ req -> enableCache = enable_cache;
+ req -> enableSplit = enable_split;
+ req -> enableSave = enable_save;
+ req -> enableLoad = enable_load;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetCacheParameters: Sending message opcode [%d] with "
+ "flags [%d][%d][%d][%d].\n", X_NXSetCacheParameters, req -> enableCache,
+ req -> enableSplit, req -> enableSave, req -> enableLoad);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+unsigned int NXAllocUnpack(Display *dpy, unsigned int resource)
+{
+ if (resource == NXAnyResource)
+ {
+ for (resource = 0; resource < NXNumberOfResources; resource++)
+ {
+ if (_NXUnpackResources[resource] == 0)
+ {
+ _NXUnpackResources[resource] = 1;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXAllocUnpack: Reserved resource [%u].\n",
+ resource);
+ #endif
+
+ return resource;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXAllocUnpack: WARNING! Resource limit exausted.\n");
+ #endif
+
+ return NXNoResource;
+ }
+ else if (resource >= 0 && resource < NXNumberOfResources)
+ {
+ #ifdef TEST
+
+ if (_NXUnpackResources[resource] == 0)
+ {
+ fprintf(stderr, "******NXAllocUnpack: Reserved requested resource [%u].\n",
+ resource);
+ }
+ else
+ {
+ fprintf(stderr, "******NXAllocUnpack: Requested resource [%u] already reserved.\n",
+ resource);
+ }
+
+ #endif
+
+ _NXUnpackResources[resource] = 1;
+ }
+
+ #ifdef PANIC
+ fprintf(stderr, "******NXAllocUnpack: PANIC! Can't reserve requested resource [%u].\n",
+ resource);
+ #endif
+
+ return NXNoResource;
+}
+
+int NXSetUnpackGeometry(Display *dpy, unsigned int resource, Visual *visual)
+{
+ register xNXSetUnpackGeometryReq *req;
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetUnpackGeometry, req);
+
+ req -> resource = resource;
+
+ req -> depth1Bpp = _XGetBitsPerPixel(dpy, 1);
+ req -> depth4Bpp = _XGetBitsPerPixel(dpy, 4);
+ req -> depth8Bpp = _XGetBitsPerPixel(dpy, 8);
+ req -> depth16Bpp = _XGetBitsPerPixel(dpy, 16);
+ req -> depth24Bpp = _XGetBitsPerPixel(dpy, 24);
+ req -> depth32Bpp = _XGetBitsPerPixel(dpy, 32);
+
+ if (visual != NULL)
+ {
+ req -> redMask = visual -> red_mask;
+ req -> greenMask = visual -> green_mask;
+ req -> blueMask = visual -> blue_mask;
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXSetUnpackGeometry: PANIC! Can't set the geometry without a visual.\n");
+ #endif
+
+ UnGetReq(NXSetUnpackGeometry);
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetUnpackGeometry: Resource [%u] Depth/Bpp [1/%d][4/%d][8/%d]"
+ "[16/%d][24/%d][32/%d].\n", resource, req -> depth1Bpp, req -> depth4Bpp,
+ req -> depth8Bpp, req -> depth16Bpp, req -> depth24Bpp, req -> depth32Bpp);
+
+ fprintf(stderr, "******NXSetUnpackGeometry: red [0x%x] green [0x%x] blue [0x%x].\n",
+ (unsigned) req -> redMask, (unsigned) req -> greenMask, (unsigned) req -> blueMask);
+ #endif
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Store a colormap table on the remote side.
+ * The colormap can then be used to unpack
+ * an image.
+ */
+
+int NXSetUnpackColormap(Display *dpy, unsigned int resource, unsigned int method,
+ unsigned int entries, const char *data, unsigned int data_length)
+{
+ register xNXSetUnpackColormapReq *req;
+
+ register int dst_data_length;
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetUnpackColormap, req);
+
+ req -> resource = resource;
+ req -> method = method;
+
+ req -> srcLength = data_length;
+ req -> dstLength = entries << 2;
+
+ dst_data_length = ROUNDUP(data_length, 4);
+
+ req -> length += (dst_data_length >> 2);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetUnpackColormap: Resource [%u] data size [%u] destination "
+ "data size [%u].\n", resource, data_length, dst_data_length);
+ #endif
+
+ if (data_length > 0)
+ {
+ if (dpy -> bufptr + dst_data_length <= dpy -> bufmax)
+ {
+ /*
+ * Clean the padding bytes in the request.
+ */
+
+ *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0;
+
+ memcpy(dpy -> bufptr, data, data_length);
+
+ dpy -> bufptr += dst_data_length;
+ }
+ else
+ {
+ /*
+ * The _XSend() will pad the request for us.
+ */
+
+ _XSend(dpy, data, data_length);
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Store data of the alpha blending channel
+ * that will be combined with the next image
+ * to be unpacked.
+ */
+
+int NXSetUnpackAlpha(Display *dpy, unsigned int resource, unsigned int method,
+ unsigned int entries, const char *data, unsigned int data_length)
+{
+ register xNXSetUnpackAlphaReq *req;
+
+ register unsigned int dst_data_length;
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetUnpackAlpha, req);
+
+ req -> resource = resource;
+ req -> method = method;
+
+ req -> srcLength = data_length;
+ req -> dstLength = entries;
+
+ dst_data_length = ROUNDUP(data_length, 4);
+
+ req -> length += (dst_data_length >> 2);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetUnpackAlpha: Resource [%u] data size [%u] destination data size [%u].\n",
+ resource, data_length, dst_data_length);
+ #endif
+
+ if (data_length > 0)
+ {
+ if (dpy -> bufptr + dst_data_length <= dpy -> bufmax)
+ {
+ /*
+ * Clean the padding bytes in the request.
+ */
+
+ *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0;
+
+ memcpy(dpy -> bufptr, data, data_length);
+
+ dpy -> bufptr += dst_data_length;
+ }
+ else
+ {
+ /*
+ * The _XSend() will pad the request for us.
+ */
+
+ _XSend(dpy, data, data_length);
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Compatibility versions to be used when
+ * connected to a 1.X.X proxy.
+ */
+
+/*
+ * These are for compatibility with the 1.X.X
+ * versions.
+ */
+
+#define sz_xNXSetUnpackColormapCompatReq 8
+
+typedef struct _NXSetUnpackColormapCompatReq {
+ CARD8 reqType;
+ CARD8 resource;
+ CARD16 length B16;
+ CARD32 entries B32;
+} xNXSetUnpackColormapCompatReq;
+
+#define X_NXSetUnpackColormapCompat X_NXSetUnpackColormap
+
+int NXSetUnpackColormapCompat(Display *dpy, unsigned int resource,
+ unsigned int entries, const char *data)
+{
+ register xNXSetUnpackColormapCompatReq *req;
+
+ register char *dst_data;
+
+ register int dst_data_length;
+
+ #ifdef DUMP
+
+ int i;
+
+ #endif
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetUnpackColormapCompat, req);
+
+ req -> resource = resource;
+ req -> entries = entries;
+
+ dst_data_length = entries << 2;
+
+ req -> length += (dst_data_length >> 2);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetUnpackColormapCompat: Resource [%u] number of entries [%u] "
+ "destination data size [%u].\n", resource, entries, dst_data_length);
+ #endif
+
+ if (entries > 0)
+ {
+ if ((dpy -> bufptr + dst_data_length) <= dpy -> bufmax)
+ {
+ dst_data = dpy -> bufptr;
+ }
+ else
+ {
+ if ((dst_data = _XAllocScratch(dpy, dst_data_length)) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXSetUnpackColormapCompat: PANIC! Cannot allocate memory.\n");
+ #endif
+
+ UnGetReq(NXSetUnpackColormapCompat);
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+ }
+
+ memcpy(dst_data, data, entries << 2);
+
+ #ifdef DUMP
+
+ fprintf(stderr, "******NXSetUnpackColormapCompat: Dumping colormap entries:\n");
+
+ for (i = 0; i < entries; i++)
+ {
+ fprintf(stderr, "******NXSetUnpackColormapCompat: [%d] -> [0x%x].\n",
+ i, *((int *) (dst_data + (i * 4))));
+ }
+
+ #endif
+
+ if (dst_data == dpy -> bufptr)
+ {
+ dpy -> bufptr += dst_data_length;
+ }
+ else
+ {
+ _XSend(dpy, dst_data, dst_data_length);
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+#define sz_xNXSetUnpackAlphaCompatReq 8
+
+typedef struct _NXSetUnpackAlphaCompatReq {
+ CARD8 reqType;
+ CARD8 resource;
+ CARD16 length B16;
+ CARD32 entries B32;
+} xNXSetUnpackAlphaCompatReq;
+
+#define X_NXSetUnpackAlphaCompat X_NXSetUnpackAlpha
+
+int NXSetUnpackAlphaCompat(Display *dpy, unsigned int resource,
+ unsigned int entries, const char *data)
+{
+ register xNXSetUnpackAlphaCompatReq *req;
+
+ register char *dst_data;
+
+ register unsigned int dst_data_length;
+
+ #ifdef DUMP
+
+ int i;
+
+ #endif
+
+ LockDisplay(dpy);
+
+ GetReq(NXSetUnpackAlphaCompat, req);
+
+ req -> resource = resource;
+ req -> entries = entries;
+
+ dst_data_length = ROUNDUP(entries, 4);
+
+ req -> length += (dst_data_length >> 2);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXSetUnpackAlphaCompat: Resource [%u] number of entries [%u] "
+ "destination data size [%u].\n", resource, entries, dst_data_length);
+ #endif
+
+ if (entries > 0)
+ {
+ if ((dpy -> bufptr + dst_data_length) <= dpy -> bufmax)
+ {
+ dst_data = dpy -> bufptr;
+ }
+ else
+ {
+ if ((dst_data = _XAllocScratch(dpy, dst_data_length)) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXSetUnpackAlphaCompat: PANIC! Cannot allocate memory.\n");
+ #endif
+
+ UnGetReq(NXSetUnpackAlphaCompat);
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+ }
+
+ memcpy(dst_data, data, entries);
+
+ if (dst_data_length != entries)
+ {
+ memset(dst_data + entries, 0, dst_data_length - entries);
+ }
+
+ #ifdef DUMP
+
+ fprintf(stderr, "******NXSetUnpackAlphaCompat: Dumping alpha channel data:\n");
+
+ for (i = 0; i < dst_data_length; i++)
+ {
+ fprintf(stderr, "******NXSetUnpackAlphaCompat: [%d] -> [0x%02x].\n",
+ i, ((unsigned int) *(dst_data + i)) & 0xff);
+ }
+
+ #endif
+
+ if (dst_data == dpy -> bufptr)
+ {
+ dpy -> bufptr += dst_data_length;
+ }
+ else
+ {
+ _XSend(dpy, dst_data, dst_data_length);
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+/*
+ * Free any geometry, colormap and alpha channel
+ * data stored by the remote proxy to unpack the
+ * image. Resource, as usual, must be a value
+ * between 0 and 255.
+ */
+
+int NXFreeUnpack(Display *dpy, unsigned int resource)
+{
+ register xNXFreeUnpackReq *req;
+
+ if (_NXUnpackResources[resource] != 0)
+ {
+ LockDisplay(dpy);
+
+ GetReq(NXFreeUnpack, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXFreeUnpack: Sending message opcode [%d] with resource [%u].\n",
+ X_NXFreeUnpack, resource);
+ #endif
+
+ req -> resource = resource;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ #ifdef TEST
+ fprintf(stderr, "******NXFreeUnpack: Making the resource [%u] newly available.\n",
+ resource);
+ #endif
+
+ _NXUnpackResources[resource] = 0;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "******NXFreeUnpack: Nothing to do for resource [%u].\n",
+ resource);
+ }
+ #endif
+
+ return 1;
+}
+
+/*
+ * Wrapper of XCreateImage(). Note that we use offset
+ * field of XImage to store size of source image in
+ * packed format. Note also that method is currently
+ * not stored in the NXignored.
+ */
+
+NXPackedImage *NXCreatePackedImage(Display *dpy, Visual *visual, unsigned int method,
+ unsigned int depth, int format, char *data,
+ int data_length, unsigned int width,
+ unsigned int height, int bitmap_pad,
+ int bytes_per_line)
+{
+ XImage* image;
+
+ image = XCreateImage(dpy, visual, depth, format, 0, data,
+ width, height, bitmap_pad, bytes_per_line);
+
+ if (image != NULL)
+ {
+ image -> xoffset = data_length;
+ }
+
+ return (NXPackedImage *) image;
+}
+
+/*
+ * Wrapper of XDestroyImage().
+ */
+
+int NXDestroyPackedImage(NXPackedImage *image)
+{
+ return XDestroyImage((XImage *) image);
+}
+
+/*
+ * Clean the image data directly in the current buffer.
+ */
+
+int NXCleanImage(XImage *image)
+{
+ #ifdef TEST
+ fprintf(stderr, "******NXCleanImage: Cleaning image with format [%d] depth [%d] "
+ "bits per pixel [%d].\n", image -> format, image -> depth,
+ image -> bits_per_pixel);
+ #endif
+
+ if (image -> format == ZPixmap)
+ {
+ if (image -> depth == 1)
+ {
+ return CleanXYImage(image);
+ }
+ else
+ {
+ return CleanZImage(image);
+ }
+ }
+ else
+ {
+ return CleanXYImage(image);
+ }
+}
+
+NXPackedImage *NXPackImage(Display *dpy, XImage *src_image, unsigned int method)
+{
+ XImage *dst_image;
+
+ const ColorMask *mask;
+
+ unsigned int dst_data_size;
+ unsigned int dst_packed_data_size;
+
+ unsigned int dst_bits_per_pixel;
+ unsigned int dst_packed_bits_per_pixel;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPackImage: Going to pack a new image with method [%d].\n",
+ method);
+ #endif
+
+ /*
+ * Get the mask out of the method and
+ * check if the visual is supported by
+ * the color reduction algorithm.
+ */
+
+ mask = MethodColorMask(method);
+
+ if (mask == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: WARNING! No mask to apply for pack method [%d].\n",
+ method);
+ #endif
+
+ return NULL;
+ }
+ else if (CanMaskImage(src_image, mask) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n",
+ src_image -> format, src_image -> depth, src_image -> bits_per_pixel);
+
+ fprintf(stderr, "******NXPackImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n",
+ src_image -> red_mask, src_image -> green_mask, src_image -> blue_mask);
+ #endif
+
+ return NULL;
+ }
+
+ /*
+ * Create a destination image from
+ * source and apply the color mask.
+ */
+
+ if ((dst_image = (XImage *) Xmalloc(sizeof(XImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Cannot allocate [%d] bytes for the image.\n",
+ (int) sizeof(XImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPackImage: Source width [%d], bytes per line [%d] with depth [%d].\n",
+ src_image -> width, src_image -> bytes_per_line, src_image -> depth);
+ #endif
+
+ dst_data_size = src_image -> bytes_per_line * src_image -> height;
+
+ dst_image -> data = Xmalloc(dst_data_size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Cannot allocate [%d] bytes for masked image data.\n",
+ dst_data_size);
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * If the pixel resulting from the mask
+ * needs more bits than available, then
+ * just clean the padding bits in the
+ * image.
+ */
+
+ dst_bits_per_pixel = dst_image -> bits_per_pixel;
+ dst_packed_bits_per_pixel = MethodBitsPerPixel(method);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPackImage: Destination depth [%d], bits per pixel [%d], packed bits per pixel [%d].\n",
+ dst_image -> depth, dst_bits_per_pixel, dst_packed_bits_per_pixel);
+ #endif
+
+ if (dst_packed_bits_per_pixel > dst_bits_per_pixel ||
+ ShouldMaskImage(src_image, mask) == 0)
+ {
+ /*
+ * Should use the same data for source
+ * and destination to avoid the memcpy.
+ */
+
+ if (CopyAndCleanImage(src_image, dst_image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Failed to clean the image.\n");
+ #endif
+
+ Xfree(dst_image -> data);
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+ }
+ else if (MaskImage(mask, src_image, dst_image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Failed to apply the color mask.\n");
+ #endif
+
+ Xfree(dst_image -> data);
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Let's pack the same pixels in fewer bytes.
+ * Note that we save a new memory allocation
+ * by using the same image as source and des-
+ * tination. This means that PackImage() must
+ * be able to handle ovelapping areas.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPackImage: Plain bits per pixel [%d], data size [%d].\n",
+ dst_bits_per_pixel, dst_data_size);
+ #endif
+
+ dst_packed_data_size = dst_data_size * dst_packed_bits_per_pixel /
+ dst_bits_per_pixel;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPackImage: Packed bits per pixel [%d], data size [%d].\n",
+ dst_packed_bits_per_pixel, dst_packed_data_size);
+ #endif
+
+ if (PackImage(method, dst_data_size, dst_image,
+ dst_packed_data_size, dst_image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXPackImage: PANIC! Failed to pack image from [%d] to [%d] bits per pixel.\n",
+ dst_bits_per_pixel, dst_packed_bits_per_pixel);
+ #endif
+
+ Xfree(dst_image -> data);
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Save data size in xoffset field
+ * to comply with NX packed images.
+ */
+
+ dst_image -> xoffset = dst_packed_data_size;
+
+ return dst_image;
+}
+
+/*
+ * NXInPlacePackImage creates a NXPackedImage
+ * from a XImage, sharing the same data buffer.
+ * Is up to the caller to free the data buffer
+ * only once.
+ */
+
+XImage *NXInPlacePackImage(Display *dpy, XImage *src_image, unsigned int method)
+{
+ XImage *dst_image;
+
+ const ColorMask *mask;
+
+ unsigned int dst_data_size;
+ unsigned int dst_packed_data_size;
+
+ unsigned int dst_bits_per_pixel;
+ unsigned int dst_packed_bits_per_pixel;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Going to pack a new image with method [%d].\n",
+ method);
+ #endif
+
+ /*
+ * Get mask out of method and check if
+ * visual is supported by current color
+ * reduction algorithm.
+ */
+
+ mask = MethodColorMask(method);
+
+ if (mask == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXInPlacePackImage: WARNING! No mask to apply for pack method [%d].\n",
+ method);
+ #endif
+
+ return NULL;
+ }
+ else if (CanMaskImage(src_image, mask) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXInPlacePackImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n",
+ src_image -> format, src_image -> depth, src_image -> bits_per_pixel);
+
+ fprintf(stderr, "******NXInPlacePackImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n",
+ src_image -> red_mask, src_image -> green_mask, src_image -> blue_mask);
+ #endif
+ return NULL;
+ }
+
+ /*
+ * Create a destination image from
+ * source and apply the color mask.
+ */
+
+ if ((dst_image = (XImage *) Xmalloc(sizeof(XImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXInPlacePackImage: PANIC! Cannot allocate [%d] bytes for the image.\n",
+ (int) sizeof(XImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Source width [%d], bytes per line [%d] with depth [%d].\n",
+ src_image -> width, src_image -> bytes_per_line, src_image -> depth);
+ #endif
+
+ dst_data_size = src_image -> bytes_per_line * src_image -> height;
+
+ dst_image -> data = src_image -> data;
+
+ /*
+ * If pixel resulting from mask needs
+ * more bits than available, then just
+ * clean the pad bits in image.
+ */
+
+ dst_bits_per_pixel = dst_image -> bits_per_pixel;
+ dst_packed_bits_per_pixel = MethodBitsPerPixel(method);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Destination depth [%d], bits per pixel [%d], packed bits per pixel [%d].\n",
+ dst_image -> depth, dst_bits_per_pixel, dst_packed_bits_per_pixel);
+ #endif
+
+ if (dst_packed_bits_per_pixel > dst_bits_per_pixel ||
+ ShouldMaskImage(src_image, mask) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Just clean image packed_bits_per_pixel[%d], bits_per_pixel[%d].\n",
+ dst_packed_bits_per_pixel, dst_bits_per_pixel);
+ #endif
+
+ if (NXCleanImage(dst_image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXInPlacePackImage: PANIC! Failed to clean the image.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+ }
+ else if (MaskInPlaceImage(mask, dst_image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXInPlacePackImage: PANIC! Failed to apply the color mask.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Let's pack the same pixels in fewer bytes.
+ * Note that we save a new memory allocation
+ * by using the same image as source and des-
+ * tination. This means that PackImage() must
+ * be able to handle ovelapping areas.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Plain bits per pixel [%d], data size [%d].\n",
+ dst_bits_per_pixel, dst_data_size);
+ #endif
+
+ dst_packed_data_size = dst_data_size * dst_packed_bits_per_pixel /
+ dst_bits_per_pixel;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXInPlacePackImage: Packed bits per pixel [%d], data size [%d].\n",
+ dst_packed_bits_per_pixel, dst_packed_data_size);
+ #endif
+
+ /*
+ * Save data size in xoffset field
+ * to comply with NX packed images.
+ */
+
+ dst_image -> xoffset = dst_packed_data_size;
+
+ return dst_image;
+}
+
+int NXPutPackedImage(Display *dpy, unsigned int resource, Drawable drawable,
+ void *gc, NXPackedImage *image, unsigned int method,
+ unsigned int depth, int src_x, int src_y, int dst_x,
+ int dst_y, unsigned int width, unsigned int height)
+{
+ register xNXPutPackedImageReq *req;
+
+ register unsigned int src_data_length;
+ register unsigned int dst_data_length;
+
+ LockDisplay(dpy);
+
+ FlushGC(dpy, (GC) gc);
+
+ GetReq(NXPutPackedImage, req);
+
+ req -> resource = resource;
+ req -> drawable = drawable;
+ req -> gc = ((GC) gc) -> gid;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPutPackedImage: Image resource [%d] drawable [%d] gc [%d].\n",
+ req -> resource, (int) req -> drawable, (int) req -> gc);
+ #endif
+
+ /*
+ * There is no leftPad field in request. We only
+ * support a leftPad of 0. Anyway, X imposes a
+ * leftPad of 0 in case of ZPixmap format.
+ */
+
+ req -> format = image -> format;
+
+ /*
+ * Source depth, as well as width and height,
+ * are taken from the image structure.
+ */
+
+ req -> srcDepth = image -> depth;
+
+ req -> srcX = src_x;
+ req -> srcY = src_y;
+
+ req -> srcWidth = image -> width;
+ req -> srcHeight = image -> height;
+
+ /*
+ * The destination depth is provided
+ * by the caller.
+ */
+
+ req -> dstDepth = depth;
+
+ req -> dstX = dst_x;
+ req -> dstY = dst_y;
+
+ req -> dstWidth = width;
+ req -> dstHeight = height;
+
+ req -> method = method;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPutPackedImage: Source image depth [%d] destination depth [%d] "
+ "method [%d].\n", req -> srcDepth, req -> dstDepth, req -> method);
+ #endif
+
+ /*
+ * Source data length is the size of image in packed format,
+ * as stored in xoffset field of XImage. Destination data
+ * size is calculated according to bytes per line of target
+ * image, so the caller must provide the right depth at the
+ * time XImage structure is created.
+ */
+
+ req -> srcLength = image -> xoffset;
+
+ if (image -> width == (int) width &&
+ image -> height == (int) height)
+ {
+ req -> dstLength = image -> bytes_per_line * image -> height;
+ }
+ else if (image -> format == ZPixmap)
+ {
+ req -> dstLength = ROUNDUP((image -> bits_per_pixel * width),
+ image -> bitmap_pad) * height >> 3;
+ }
+ else
+ {
+ req -> dstLength = ROUNDUP(width, image -> bitmap_pad) * height >> 3;
+ }
+
+ src_data_length = image -> xoffset;
+
+ dst_data_length = ROUNDUP(src_data_length, 4);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXPutPackedImage: Source data length [%d] request data length [%d].\n",
+ src_data_length, dst_data_length);
+ #endif
+
+ req -> length += (dst_data_length >> 2);
+
+ if (src_data_length > 0)
+ {
+ if (dpy -> bufptr + dst_data_length <= dpy -> bufmax)
+ {
+ /*
+ * Clean the padding bytes in the request.
+ */
+
+ *((int *) (dpy -> bufptr + dst_data_length - 4)) = 0x0;
+
+ memcpy(dpy -> bufptr, image -> data, src_data_length);
+
+ dpy -> bufptr += dst_data_length;
+ }
+ else
+ {
+ /*
+ * The _XSend() will pad the request for us.
+ */
+
+ _XSend(dpy, image -> data, src_data_length);
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+int NXAllocColors(Display *dpy, Colormap colormap, unsigned int entries,
+ XColor screens_in_out[], Bool results_in_out[])
+{
+ Status result = 0;
+ xAllocColorReply rep;
+ register xAllocColorReq *req;
+
+ Bool alloc_error = False;
+
+ register unsigned int i;
+
+ LockDisplay(dpy);
+
+ for (i = 0; i < entries; i++)
+ {
+ GetReq(AllocColor, req);
+
+ req -> cmap = colormap;
+
+ req -> red = screens_in_out[i].red;
+ req -> green = screens_in_out[i].green;
+ req -> blue = screens_in_out[i].blue;
+ }
+
+ for (i = 0; i < entries; i++)
+ {
+ result = _XReply(dpy, (xReply *) &rep, 0, xTrue);
+
+ if (result)
+ {
+ screens_in_out[i].pixel = rep.pixel;
+
+ screens_in_out[i].red = rep.red;
+ screens_in_out[i].green = rep.green;
+ screens_in_out[i].blue = rep.blue;
+
+ results_in_out[i] = True;
+ }
+ else
+ {
+ results_in_out[i] = False;
+
+ alloc_error = True;
+ }
+ }
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return (alloc_error == False);
+}
+
+char *NXEncodeColormap(const char *src_data, unsigned int src_size, unsigned int *dst_size)
+{
+ return ColormapCompressData(src_data, src_size, dst_size);
+}
+
+char *NXEncodeAlpha(const char *src_data, unsigned int src_size, unsigned int *dst_size)
+{
+ return AlphaCompressData(src_data, src_size, dst_size);
+}
+
+NXPackedImage *NXEncodeRgb(XImage *src_image, unsigned int method, unsigned int quality)
+{
+ NXPackedImage *dst_image = NULL;
+
+ unsigned int dst_size;
+
+ /*
+ * Create a new image structure as a copy
+ * of the source.
+ */
+
+ if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeRgb: PANIC! Cannot allocate [%d] bytes for the image.\n",
+ (int) sizeof(XImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ dst_image -> data = RgbCompressData(src_image, &dst_size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeRgb: PANIC! Rgb compression failed.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Store the Rgb size in the xoffset field.
+ */
+
+ dst_image -> xoffset = dst_size;
+
+ return dst_image;
+}
+
+NXPackedImage *NXEncodeRle(XImage *src_image, unsigned int method, unsigned int quality)
+{
+ NXPackedImage *dst_image = NULL;
+
+ unsigned int dst_size;
+
+ /*
+ * Create a new image structure as a copy
+ * of the source.
+ */
+
+ if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeRle: PANIC! Cannot allocate [%d] bytes for the image.\n",
+ (int) sizeof(XImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ dst_image -> data = RleCompressData(src_image, &dst_size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeRle: PANIC! Rle compression failed.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Store the Rle size in the xoffset field.
+ */
+
+ dst_image -> xoffset = dst_size;
+
+ return dst_image;
+}
+
+NXPackedImage *NXEncodeBitmap(XImage *src_image, unsigned int method, unsigned int quality)
+{
+ NXPackedImage *dst_image = NULL;
+
+ unsigned int dst_size;
+
+ /*
+ * Create a new image structure as a copy
+ * of the source.
+ */
+
+ if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeBitmap: PANIC! Cannot allocate [%d] bytes for the image.\n",
+ (int) sizeof(XImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ dst_image -> data = BitmapCompressData(src_image, &dst_size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeBitmap: PANIC! Bitmap compression failed.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Store the bitmap size in the xoffset field.
+ */
+
+ dst_image -> xoffset = dst_size;
+
+ return dst_image;
+}
+
+NXPackedImage *NXEncodeJpeg(XImage *src_image, unsigned int method, unsigned int quality)
+{
+ NXPackedImage *dst_image = NULL;
+
+ int size;
+
+ /*
+ * Check if the bpp of the image is valid
+ * for the Jpeg compression.
+ */
+
+ if (src_image -> bits_per_pixel < 15)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeJpeg: PANIC! Invalid bpp for Jpeg compression [%d]\n.",
+ src_image -> bits_per_pixel);
+ #endif
+
+ return NULL;
+ }
+
+ /*
+ * Create the destination image as a copy
+ * of the source.
+ */
+
+ if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeJpeg: PANIC! Cannot allocate [%d] bytes for the Jpeg image.\n",
+ (int) sizeof(NXPackedImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ dst_image -> data = JpegCompressData(src_image, quality, &size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodeJpeg: PANIC! Jpeg compression failed.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Store the Jpeg size in the xoffset field.
+ */
+
+ dst_image -> xoffset = size;
+
+ return dst_image;
+}
+
+NXPackedImage *NXEncodePng(XImage *src_image, unsigned int method, unsigned int quality)
+{
+ NXPackedImage *dst_image = NULL;
+
+ int size;
+
+ /*
+ * Check if the bpp of the image is valid
+ * for png compression.
+ */
+
+ if (src_image -> bits_per_pixel < 15)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodePng: PANIC! Invalid bpp for Png compression [%d].\n",
+ src_image -> bits_per_pixel);
+ #endif
+
+ return NULL;
+ }
+
+ if ((dst_image = (NXPackedImage *) Xmalloc(sizeof(NXPackedImage))) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodePng: PANIC! Cannot allocate [%d] bytes for the Png image.\n",
+ (int) sizeof(NXPackedImage));
+ #endif
+
+ return NULL;
+ }
+
+ *dst_image = *src_image;
+
+ dst_image -> data = PngCompressData(dst_image, &size);
+
+ if (dst_image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXEncodePng: PANIC! Png compression failed.\n");
+ #endif
+
+ Xfree(dst_image);
+
+ return NULL;
+ }
+
+ /*
+ * Store the Png size in the xoffset field.
+ */
+
+ dst_image -> xoffset = size;
+
+ return dst_image;
+}
+
+int NXEncodeColors(XImage *src_image, NXColorTable *color_table, int nb_max)
+{
+ int x, y, t, p;
+
+ long pixel;
+
+ /*
+ * We need a smarter way to extract
+ * the colors from the image and
+ * create a color table.
+ */
+
+ memset(color_table, 0, nb_max * sizeof(NXColorTable));
+
+ for (x = 0, p = 0; x < src_image -> width; x++)
+ {
+ for (y = 0; y < src_image -> height; y++)
+ {
+ pixel = XGetPixel(src_image, x, y);
+
+ for (t = 0; t < nb_max; t++)
+ {
+ if ( color_table[t].found == 0)
+ {
+ color_table[t].pixel = pixel;
+ color_table[t].found = 1;
+
+ p++;
+
+ break;
+ }
+ else if ((color_table[t].pixel) == pixel)
+ {
+ break;
+ }
+ }
+
+ if (p == nb_max)
+ {
+ return nb_max + 1;
+ }
+ }
+ }
+
+ return p;
+}
+
+void NXMaskImage(XImage *image, unsigned int method)
+{
+ unsigned int maskMethod;
+
+ const ColorMask *mask;
+
+ /*
+ * Choose the correct mask method
+ */
+
+ switch(method)
+ {
+ case PACK_JPEG_8_COLORS:
+ case PACK_PNG_8_COLORS:
+ {
+ maskMethod = MASK_8_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_8_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_64_COLORS:
+ case PACK_PNG_64_COLORS:
+ {
+ maskMethod = MASK_64_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_64K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_256_COLORS:
+ case PACK_PNG_256_COLORS:
+ {
+ maskMethod = MASK_256_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_256_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_512_COLORS:
+ case PACK_PNG_512_COLORS:
+ {
+ maskMethod = MASK_512_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_512K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_4K_COLORS:
+ case PACK_PNG_4K_COLORS:
+ {
+ maskMethod = MASK_4K_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_4K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_32K_COLORS:
+ case PACK_PNG_32K_COLORS:
+ {
+ maskMethod = MASK_32K_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_32K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_64K_COLORS:
+ case PACK_PNG_64K_COLORS:
+ {
+ maskMethod = MASK_64K_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_64K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_256K_COLORS:
+ case PACK_PNG_256K_COLORS:
+ {
+ maskMethod = MASK_256K_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_256K_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_2M_COLORS:
+ case PACK_PNG_2M_COLORS:
+ {
+ maskMethod = MASK_2M_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_2M_COLORS\n");
+ #endif
+
+ break;
+ }
+ case PACK_JPEG_16M_COLORS:
+ case PACK_PNG_16M_COLORS:
+ {
+ maskMethod = MASK_16M_COLORS;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXMaskImage: Method is MASK_16M_COLORS\n");
+ #endif
+
+ break;
+ }
+ default:
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXMaskImage: PANIC! Cannot find mask method for pack method [%d]\n",
+ method);
+ #endif
+
+ return;
+ }
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******NXMaskImage: packMethod[%d] => maskMethod[%d]\n",
+ method, maskMethod);
+ #endif
+
+ /*
+ * Get mask out of method and check if
+ * visual is supported by current color
+ * reduction algorithm.
+ */
+
+ mask = MethodColorMask(maskMethod);
+
+ if (mask == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXMaskImage: PANIC! No mask to apply for pack method [%d].\n",
+ method);
+ #endif
+
+ return;
+ }
+ else if (CanMaskImage(image, mask) == 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXMaskImage: PANIC! Invalid source with format [%d] depth [%d] bits per pixel [%d].\n",
+ image -> format, image -> depth, image -> bits_per_pixel);
+
+ fprintf(stderr, "******NXMaskImage: PANIC! Visual colormask is red 0x%lx green 0x%lx blue 0x%lx.\n",
+ image -> red_mask, image -> green_mask, image -> blue_mask);
+ #endif
+
+ return;
+ }
+
+ /*
+ * Calling ShouldMaskImage you get 0 in the case
+ * of MASK_256_COLORS and MASK_64K_COLORS, which
+ * means that the image should not be masked.
+ */
+
+ if (ShouldMaskImage(image, mask) == 0)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******NXMaskImage: the image will not be masked\n");
+ #endif
+ }
+ else
+ {
+ if (MaskInPlaceImage(mask, image) <= 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXMaskImage: PANIC! Failed to apply the color mask in place.\n");
+ #endif
+ }
+ }
+}
+
+/*
+ * The display parameter is ignored.
+ */
+
+void NXInitCache(Display *dpy, int entries)
+{
+ if (NXImageCache != NULL && NXImageCacheSize == entries)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXInitCache: Nothing to do with image cache at [%p] and [%d] entries.\n",
+ NXImageCache, NXImageCacheSize);
+ #endif
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXInitCache: Initializing the cache with [%d] entries.\n",
+ entries);
+ #endif
+
+ NXImageCacheSize = 0;
+
+ if (NXImageCache != NULL)
+ {
+ Xfree(NXImageCache);
+
+ NXImageCache = NULL;
+ }
+
+ if (entries > 0)
+ {
+ NXImageCache = Xmalloc(entries * sizeof(_NXImageCacheEntry));
+
+ if (NXImageCache != NULL)
+ {
+ memset(NXImageCache, 0, entries * sizeof(_NXImageCacheEntry));
+
+ NXImageCacheSize = entries;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXInitCache: Image cache initialized with [%d] entries.\n", entries);
+ #endif
+ }
+ }
+}
+
+#ifdef DUMP
+
+void _NXCacheDump(const char *label)
+{
+ char s[MD5_LENGTH * 2 + 1];
+
+ int i;
+ int j;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Dumping the content of image cache:\n", label);
+ #endif
+
+ for (i = 0; i < NXImageCacheSize; i++)
+ {
+ if (NXImageCache[i].image == NULL)
+ {
+ break;
+ }
+
+ for (j = 0; j < MD5_LENGTH; j++)
+ {
+ sprintf(s + (j * 2), "%02X", ((unsigned char *) NXImageCache[i].md5)[j]);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: [%d][%s].\n", label, i, s);
+ #endif
+ }
+}
+
+#endif
+
+XImage *NXCacheFindImage(NXPackedImage *src_image, unsigned int *method, unsigned char **md5)
+{
+ md5_state_t new_state;
+ md5_byte_t *new_md5;
+ unsigned int data_size, i;
+
+ if (NXImageCache == NULL)
+ {
+ return NULL;
+ }
+
+ /*
+ * Will return the allocated checksum
+ * if the image is not found.
+ */
+
+ *md5 = NULL;
+
+ if ((new_md5 = Xmalloc(MD5_LENGTH)) == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCacheFindImage: Can't allocate memory for the checksum.\n");
+ #endif
+
+ return NULL;
+ }
+
+ data_size = (src_image -> bytes_per_line * src_image -> height);
+
+ md5_init(&new_state);
+
+ md5_append(&new_state, (unsigned char *) &src_image -> width, sizeof(int));
+ md5_append(&new_state, (unsigned char *) &src_image -> height, sizeof(int));
+
+ md5_append(&new_state, (unsigned char *) src_image -> data, data_size);
+
+ md5_finish(&new_state, new_md5);
+
+ for (i = 0; i < NXImageCacheSize; i++)
+ {
+ if (NXImageCache[i].image != NULL)
+ {
+ if (memcmp(NXImageCache[i].md5, new_md5, MD5_LENGTH) == 0)
+ {
+ _NXImageCacheEntry found;
+
+ found.image = NXImageCache[i].image;
+ found.method = NXImageCache[i].method;
+ found.md5 = NXImageCache[i].md5;
+
+ *method = found.method;
+
+ NXImageCacheHits++;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXCacheFindImage: Found at position [%d] with hits [%d] and [%d] packs.\n",
+ i, NXImageCacheHits, NXImageCacheOps);
+ #endif
+
+ Xfree(new_md5);
+
+ /*
+ * Move the images down one slot, from
+ * the head of the list, and place the
+ * image just found at top.
+ */
+
+ if (i > 16)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXCacheFindImage: Moving the image at the head of the list.\n");
+ #endif
+
+ memmove(&NXImageCache[1], &NXImageCache[0], (i * sizeof(_NXImageCacheEntry)));
+
+ NXImageCache[0].image = found.image;
+ NXImageCache[0].method = found.method;
+ NXImageCache[0].md5 = found.md5;
+
+ #ifdef DUMP
+
+ _NXCacheDump("******NXCacheFindImage");
+
+ #endif
+ }
+
+ /*
+ * Return the checksum and image
+ * structure allocated in cache.
+ */
+
+ *md5 = found.md5;
+
+ return found.image;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ *md5 = new_md5;
+
+ return NULL;
+}
+
+/*
+ * Add a packed image to the cache. A new image
+ * structure is allocated and copied, data and
+ * checksum are inherited from the passed image.
+ */
+
+int NXCacheAddImage(NXPackedImage *image, unsigned int method, unsigned char *md5)
+{
+ unsigned int i;
+
+ if (image == NULL || image -> data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCacheAddImage: PANIC! Invalid image passed to function.\n");
+ #endif
+
+ return -1;
+ }
+
+ i = (NXImageCacheOps < NXImageCacheSize) ? NXImageCacheOps : NXImageCacheSize;
+
+ if (NXImageCacheOps >= NXImageCacheSize)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXCacheAddImage: Freeing up the oldest entry.\n");
+ #endif
+
+ i--;
+
+ Xfree(NXImageCache[NXImageCacheSize - 1].image -> data);
+ Xfree(NXImageCache[NXImageCacheSize - 1].image);
+ Xfree(NXImageCache[NXImageCacheSize - 1].md5);
+ }
+
+ if (i > 0)
+ {
+ memmove(&NXImageCache[1], &NXImageCache[0], i * sizeof(_NXImageCacheEntry));
+ }
+
+ NXImageCacheOps++;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXCacheAddImage: Going to add new image with data size [%d].\n",
+ image -> xoffset);
+ #endif
+
+ NXImageCache[0].image = image;
+ NXImageCache[0].method = method;
+ NXImageCache[0].md5 = md5;
+
+ #ifdef DUMP
+
+ _NXCacheDump("******NXCacheAddImage");
+
+ #endif
+
+ return 1;
+}
+
+/*
+ * The display parameter is ignored.
+ */
+
+void NXFreeCache(Display *dpy)
+{
+ int i;
+
+ if (NXImageCache == NULL)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******NXFreeCache: Nothing to do with a null image cache.\n");
+ #endif
+
+ return;
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******NXFreeCache: Freeing the cache with [%d] entries.\n",
+ NXImageCacheSize);
+ #endif
+
+ for (i = 0; i < NXImageCacheSize; i++)
+ {
+ if (NXImageCache[i].image != NULL)
+ {
+ if (NXImageCache[i].image -> data != NULL)
+ {
+ Xfree(NXImageCache[i].image -> data);
+ }
+
+ Xfree(NXImageCache[i].image);
+
+ NXImageCache[i].image = NULL;
+ }
+
+ if (NXImageCache[i].md5 != NULL)
+ {
+ Xfree(NXImageCache[i].md5);
+
+ NXImageCache[i].md5 = NULL;
+ }
+ }
+
+ Xfree(NXImageCache);
+
+ NXImageCache = NULL;
+
+ NXImageCacheSize = 0;
+ NXImageCacheHits = 0;
+ NXImageCacheOps = 0;
+}
+
+static void _NXNotifyImage(Display *dpy, int resource, Bool success)
+{
+ XEvent async_event;
+
+ /*
+ * Enqueue an event to tell client
+ * the result of GetImage.
+ */
+
+ async_event.type = ClientMessage;
+
+ async_event.xclient.serial = _NXCollectedImages[resource] -> sequence;
+
+ async_event.xclient.window = 0;
+ async_event.xclient.message_type = 0;
+ async_event.xclient.format = 32;
+
+ async_event.xclient.data.l[0] = NXCollectImageNotify;
+ async_event.xclient.data.l[1] = resource;
+ async_event.xclient.data.l[2] = success;
+
+ XPutBackEvent(dpy, &async_event);
+}
+
+static Bool _NXCollectImageHandler(Display *dpy, xReply *rep, char *buf,
+ int len, XPointer data)
+{
+ register _NXCollectImageState *state;
+
+ register xGetImageReply *async_rep;
+
+ char *async_head;
+ char *async_data;
+
+ int async_size;
+
+ state = (_NXCollectImageState *) data;
+
+ if ((rep -> generic.sequenceNumber % 65536) !=
+ ((int)(state -> sequence) % 65536))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Unmatched sequence [%d] for opcode [%d] "
+ "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type,
+ (int) rep -> generic.length << 2);
+ #endif
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Going to handle asynchronous GetImage reply.\n");
+ #endif
+
+ /*
+ * As even reply data is managed asynchronously,
+ * we can use state to get to vector and vector
+ * to get to handler. In this way, we can safely
+ * dequeue and free the handler itself.
+ */
+
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+
+ state -> handler = NULL;
+
+ if (rep -> generic.type == X_Error)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Error received from X server for resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, False);
+
+ _NXCollectedImages[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Matched request with sequence [%ld].\n",
+ state -> sequence);
+ #endif
+
+ async_size = SIZEOF(xGetImageReply);
+
+ async_head = Xmalloc(async_size);
+
+ if (async_head == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, False);
+
+ _NXCollectedImages[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Going to get reply with size [%d].\n",
+ (int) rep -> generic.length << 2);
+ #endif
+
+ async_rep = (xGetImageReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False);
+
+ if (async_rep == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to get reply with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, False);
+
+ _NXCollectedImages[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Got reply with depth [%d] visual [%d] size [%d].\n",
+ async_rep -> depth, (int) async_rep -> visual, (int) async_rep -> length << 2);
+ #endif
+
+ async_size = async_rep -> length << 2;
+
+ if (async_size > 0)
+ {
+ async_data = Xmalloc(async_size);
+
+ if (async_data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, False);
+
+ _NXCollectedImages[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Going to get data with size [%d].\n",
+ async_size);
+ #endif
+
+ _XGetAsyncData(dpy, async_data, buf, len, SIZEOF(xGetImageReply), async_size, async_size);
+
+ /*
+ * From now on we can return True, as all
+ * data has been consumed from buffer.
+ */
+
+ if (state -> format == XYPixmap)
+ {
+ unsigned long depth = DepthOnes(state -> mask & (((unsigned long)0xFFFFFFFF) >>
+ (32 - async_rep -> depth)));
+
+ state -> image = XCreateImage(dpy, _XVIDtoVisual(dpy, async_rep -> visual),
+ depth, XYPixmap, 0, async_data, state -> width,
+ state -> height, dpy -> bitmap_pad, 0);
+ }
+ else
+ {
+ state -> image = XCreateImage(dpy, _XVIDtoVisual(dpy, async_rep -> visual),
+ async_rep -> depth, ZPixmap, 0, async_data, state -> width,
+ state -> height, _XGetScanlinePad(dpy, async_rep -> depth), 0);
+ }
+
+ if (state -> image == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectImageHandler: PANIC! Failed to create image for resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, False);
+
+ _NXCollectedImages[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+ Xfree(async_data);
+
+ return True;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectImageHandler: Successfully stored image data for resource [%d].\n",
+ state -> resource);
+ #endif
+ }
+ #ifdef WARNING
+ else
+ {
+ fprintf(stderr, "******_NXCollectImageHandler: WARNING! Null image data stored for resource [%d].\n",
+ state -> resource);
+ }
+ #endif
+
+ _NXNotifyImage(dpy, state -> resource, True);
+
+ Xfree(async_head);
+
+ return True;
+}
+
+int NXGetCollectImageResource(Display *dpy)
+{
+ int i;
+
+ for (i = 0; i < NXNumberOfResources; i++)
+ {
+ if (_NXCollectedImages[i] == NULL)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int NXCollectImage(Display *dpy, unsigned int resource, Drawable drawable,
+ int src_x, int src_y, unsigned int width, unsigned int height,
+ unsigned long plane_mask, int format)
+{
+ register xGetImageReq *req;
+
+ _NXCollectImageState *state;
+ _XAsyncHandler *handler;
+
+ if (resource >= NXNumberOfResources)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectImage: PANIC! Provided resource [%u] is out of range.\n",
+ resource);
+ #endif
+
+ return -1;
+ }
+
+ state = _NXCollectedImages[resource];
+
+ if (state != NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectImage: PANIC! Having to remove previous state for resource [%u].\n",
+ resource);
+ #endif
+
+ if (state -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+ }
+
+ if (state -> image != NULL)
+ {
+ XDestroyImage(state -> image);
+ }
+
+ Xfree(state);
+
+ _NXCollectedImages[resource] = NULL;
+ }
+
+ LockDisplay(dpy);
+
+ GetReq(GetImage, req);
+
+ req -> format = format;
+ req -> drawable = drawable;
+ req -> x = src_x;
+ req -> y = src_y;
+ req -> width = width;
+ req -> height = height;
+ req -> planeMask = plane_mask;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXCollectImage: Sending message opcode [%d] sequence [%ld] for resource [%d].\n",
+ X_GetImage, dpy -> request, resource);
+
+ fprintf(stderr, "******NXCollectImage: Format [%d] drawable [%d] src_x [%d] src_y [%d].\n",
+ req -> format, (int) req -> drawable, req -> x, req -> y);
+
+ fprintf(stderr, "******NXCollectImage: Width [%d] height [%d] plane_mask [%x].\n",
+ req -> width, req -> height, (int) req -> planeMask);
+ #endif
+
+ state = Xmalloc(sizeof(_NXCollectImageState));
+ handler = Xmalloc(sizeof(_XAsyncHandler));
+
+ if (state == NULL || handler == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectImage: PANIC! Failed to allocate memory with resource [%d].\n",
+ resource);
+ #endif
+
+ UnGetReq(GetImage);
+
+ if (state != NULL)
+ {
+ Xfree(state);
+ }
+
+ if (handler != NULL)
+ {
+ Xfree(handler);
+ }
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+
+ state -> sequence = dpy -> request;
+ state -> resource = resource;
+ state -> mask = plane_mask;
+ state -> format = format;
+ state -> width = width;
+ state -> height = height;
+ state -> image = NULL;
+
+ state -> handler = handler;
+
+ handler -> next = dpy -> async_handlers;
+ handler -> handler = _NXCollectImageHandler;
+ handler -> data = (XPointer) state;
+ dpy -> async_handlers = handler;
+
+ _NXCollectedImages[resource] = state;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return 1;
+}
+
+int NXGetCollectedImage(Display *dpy, unsigned int resource, XImage **image)
+{
+ register _NXCollectImageState *state;
+
+ state = _NXCollectedImages[resource];
+
+ if (state == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXGetCollectedImage: PANIC! No image collected for resource [%u].\n",
+ resource);
+ #endif
+
+ return 0;
+ }
+
+ _NXCollectedImages[resource] = NULL;
+
+ *image = state -> image;
+
+ Xfree(state);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetCollectedImage: Returning GetImage data for resource [%u].\n",
+ resource);
+ #endif
+
+ return 1;
+}
+
+static void _NXNotifyProperty(Display *dpy, int resource, Bool success)
+{
+ XEvent async_event;
+
+ /*
+ * Enqueue an event to tell client
+ * the result of GetProperty.
+ */
+
+ async_event.type = ClientMessage;
+
+ async_event.xclient.serial = _NXCollectedProperties[resource] -> sequence;
+
+ async_event.xclient.window = 0;
+ async_event.xclient.message_type = 0;
+ async_event.xclient.format = 32;
+
+ async_event.xclient.data.l[0] = NXCollectPropertyNotify;
+ async_event.xclient.data.l[1] = resource;
+ async_event.xclient.data.l[2] = success;
+
+ XPutBackEvent(dpy, &async_event);
+}
+
+static Bool _NXCollectPropertyHandler(Display *dpy, xReply *rep, char *buf,
+ int len, XPointer data)
+{
+ register _NXCollectPropertyState *state;
+
+ register xGetPropertyReply *async_rep;
+
+ char *async_head;
+ char *async_data;
+
+ int async_size;
+
+ state = (_NXCollectPropertyState *) data;
+
+ if ((rep -> generic.sequenceNumber % 65536) !=
+ ((int)(state -> sequence) % 65536))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Unmatched sequence [%d] for opcode [%d] "
+ "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type,
+ (int) rep -> generic.length << 2);
+ #endif
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Going to handle asynchronous GetProperty reply.\n");
+ #endif
+
+ /*
+ * Reply data is managed asynchronously. We can
+ * use state to get to vector and vector to get
+ * to handler. In this way, we can dequeue and
+ * free the handler itself.
+ */
+
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+
+ state -> handler = NULL;
+
+ if (rep -> generic.type == X_Error)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Error received from X server for resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyProperty(dpy, state -> resource, False);
+
+ _NXCollectedProperties[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Matched request with sequence [%ld].\n",
+ state -> sequence);
+ #endif
+
+ async_size = SIZEOF(xGetPropertyReply);
+
+ async_head = Xmalloc(async_size);
+
+ if (async_head == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyProperty(dpy, state -> resource, False);
+
+ _NXCollectedProperties[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Going to get reply with size [%d].\n",
+ (int) rep -> generic.length << 2);
+ #endif
+
+ async_rep = (xGetPropertyReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False);
+
+ if (async_rep == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to get reply with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyProperty(dpy, state -> resource, False);
+
+ _NXCollectedProperties[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Got reply with format [%d] type [%d] size [%d].\n",
+ async_rep -> format, (int) async_rep -> propertyType, (int) async_rep -> length << 2);
+
+ fprintf(stderr, "******_NXCollectPropertyHandler: Bytes after [%d] number of items [%d].\n",
+ (int) async_rep -> bytesAfter, (int) async_rep -> nItems);
+ #endif
+
+ state -> format = async_rep -> format;
+ state -> type = async_rep -> propertyType;
+ state -> items = async_rep -> nItems;
+ state -> after = async_rep -> bytesAfter;
+
+ async_size = async_rep -> length << 2;
+
+ if (async_size > 0)
+ {
+ async_data = Xmalloc(async_size);
+
+ if (async_data == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectPropertyHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyProperty(dpy, state -> resource, False);
+
+ _NXCollectedProperties[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Going to get data with size [%d].\n",
+ async_size);
+ #endif
+
+ _XGetAsyncData(dpy, async_data, buf, len, SIZEOF(xGetPropertyReply), async_size, async_size);
+
+ /*
+ * From now on we can return True, as all
+ * data has been consumed from buffer.
+ */
+
+ state -> data = async_data;
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectPropertyHandler: Successfully stored property data for resource [%d].\n",
+ state -> resource);
+ #endif
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "******_NXCollectPropertyHandler: WARNING! Null property data stored for resource [%d].\n",
+ state -> resource);
+ }
+ #endif
+
+ _NXNotifyProperty(dpy, state -> resource, True);
+
+ Xfree(async_head);
+
+ return True;
+}
+
+int NXGetCollectPropertyResource(Display *dpy)
+{
+ int i;
+
+ for (i = 0; i < NXNumberOfResources; i++)
+ {
+ if (_NXCollectedProperties[i] == NULL)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int NXCollectProperty(Display *dpy, unsigned int resource, Window window, Atom property,
+ long long_offset, long long_length, Bool delete, Atom req_type)
+{
+ register xGetPropertyReq *req;
+
+ _NXCollectPropertyState *state;
+ _XAsyncHandler *handler;
+
+ if (resource >= NXNumberOfResources)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectProperty: PANIC! Provided resource [%u] is out of range.\n",
+ resource);
+ #endif
+
+ return -1;
+ }
+
+ state = _NXCollectedProperties[resource];
+
+ if (state != NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectProperty: PANIC! Having to remove previous state for resource [%u].\n",
+ resource);
+ #endif
+
+ if (state -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+ }
+
+ if (state -> data != NULL)
+ {
+ Xfree(state -> data);
+ }
+
+ Xfree(state);
+
+ _NXCollectedProperties[resource] = NULL;
+ }
+
+ LockDisplay(dpy);
+
+ GetReq(GetProperty, req);
+
+ req -> delete = delete;
+ req -> window = window;
+ req -> property = property;
+ req -> type = req_type;
+ req -> longOffset = long_offset;
+ req -> longLength = long_length;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXCollectProperty: Sending message opcode [%d] sequence [%ld] for resource [%d].\n",
+ X_GetProperty, dpy -> request, resource);
+
+ fprintf(stderr, "******NXCollectProperty: Delete [%u] window [%d] property [%d] type [%d].\n",
+ req -> delete, (int) req -> window, (int) req -> property, (int) req -> type);
+
+ fprintf(stderr, "******NXCollectProperty: Long offset [%d] long length [%d].\n",
+ (int) req -> longOffset, (int) req -> longLength);
+ #endif
+
+ state = Xmalloc(sizeof(_NXCollectPropertyState));
+ handler = Xmalloc(sizeof(_XAsyncHandler));
+
+ if (state == NULL || handler == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectProperty: Failed to allocate memory with resource [%d].\n",
+ resource);
+ #endif
+
+ if (state != NULL)
+ {
+ Xfree(state);
+ }
+
+ if (handler != NULL)
+ {
+ Xfree(handler);
+ }
+
+ UnGetReq(GetProperty);
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+
+ state -> sequence = dpy -> request;
+ state -> resource = resource;
+ state -> window = window;
+ state -> property = property;
+ state -> type = 0;
+ state -> format = 0;
+ state -> items = 0;
+ state -> after = 0;
+ state -> data = NULL;
+
+ state -> handler = handler;
+
+ handler -> next = dpy -> async_handlers;
+ handler -> handler = _NXCollectPropertyHandler;
+ handler -> data = (XPointer) state;
+ dpy -> async_handlers = handler;
+
+ _NXCollectedProperties[resource] = state;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return True;
+}
+
+int NXGetCollectedProperty(Display *dpy, unsigned int resource, Atom *actual_type_return,
+ int *actual_format_return, unsigned long *nitems_return,
+ unsigned long *bytes_after_return, unsigned char **data)
+{
+ register _NXCollectPropertyState *state;
+
+ state = _NXCollectedProperties[resource];
+
+ if (state == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXGetCollectedProperty: PANIC! No data collected for resource [%u].\n",
+ resource);
+ #endif
+
+ return 0;
+ }
+
+ *actual_type_return = state -> type;
+ *actual_format_return = state -> format;
+ *nitems_return = state -> items;
+ *bytes_after_return = state -> after;
+
+ *data = (unsigned char *) _NXCollectedProperties[resource] -> data;
+
+ Xfree(state);
+
+ _NXCollectedProperties[resource] = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetCollectedProperty: Returning GetProperty data for resource [%u].\n",
+ resource);
+ #endif
+
+ return True;
+}
+
+static void _NXNotifyGrabPointer(Display *dpy, int resource, Bool success)
+{
+ XEvent async_event;
+
+ async_event.type = ClientMessage;
+
+ async_event.xclient.serial = _NXCollectedGrabPointers[resource] -> sequence;
+
+ async_event.xclient.window = 0;
+ async_event.xclient.message_type = 0;
+ async_event.xclient.format = 32;
+
+ async_event.xclient.data.l[0] = NXCollectGrabPointerNotify;
+ async_event.xclient.data.l[1] = resource;
+ async_event.xclient.data.l[2] = success;
+
+ XPutBackEvent(dpy, &async_event);
+}
+
+static Bool _NXCollectGrabPointerHandler(Display *dpy, xReply *rep, char *buf,
+ int len, XPointer data)
+{
+ register _NXCollectGrabPointerState *state;
+
+ register xGrabPointerReply *async_rep;
+
+ char *async_head;
+
+ int async_size;
+
+ state = (_NXCollectGrabPointerState *) data;
+
+ if ((rep -> generic.sequenceNumber % 65536) !=
+ ((int)(state -> sequence) % 65536))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Unmatched sequence [%d] for opcode [%d] "
+ "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type,
+ (int) rep -> generic.length << 2);
+ #endif
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Going to handle asynchronous GrabPointer reply.\n");
+ #endif
+
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+
+ state -> handler = NULL;
+
+ if (rep -> generic.type == X_Error)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Error received from X server for resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyGrabPointer(dpy, state -> resource, False);
+
+ _NXCollectedGrabPointers[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Matched request with sequence [%ld].\n",
+ state -> sequence);
+ #endif
+
+ async_size = SIZEOF(xGrabPointerReply);
+
+ async_head = Xmalloc(async_size);
+
+ if (async_head == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyGrabPointer(dpy, state -> resource, False);
+
+ _NXCollectedGrabPointers[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Going to get reply with size [%d].\n",
+ (int) rep -> generic.length << 2);
+ #endif
+
+ async_rep = (xGrabPointerReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False);
+
+ if (async_rep == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: PANIC! Failed to get reply with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyGrabPointer(dpy, state -> resource, False);
+
+ _NXCollectedGrabPointers[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectGrabPointerHandler: Got reply with status [%d] size [%d].\n",
+ async_rep -> status, (int) async_rep -> length << 2);
+ #endif
+
+ state -> status = async_rep -> status;
+
+ _NXNotifyGrabPointer(dpy, state -> resource, True);
+
+ Xfree(async_head);
+
+ return True;
+}
+
+int NXGetCollectGrabPointerResource(Display *dpy)
+{
+ int i;
+
+ for (i = 0; i < NXNumberOfResources; i++)
+ {
+ if (_NXCollectedGrabPointers[i] == NULL)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int NXCollectGrabPointer(Display *dpy, unsigned int resource, Window grab_window, Bool owner_events,
+ unsigned int event_mask, int pointer_mode, int keyboard_mode,
+ Window confine_to, Cursor cursor, Time time)
+{
+ register xGrabPointerReq *req;
+
+ _NXCollectGrabPointerState *state;
+ _XAsyncHandler *handler;
+
+ if (resource >= NXNumberOfResources)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectGrabPointer: PANIC! Provided resource [%u] is out of range.\n",
+ resource);
+ #endif
+
+ return -1;
+ }
+
+ state = _NXCollectedGrabPointers[resource];
+
+ if (state != NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectGrabPointer: PANIC! Having to remove previous state for resource [%u].\n",
+ resource);
+ #endif
+
+ if (state -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+ }
+
+ Xfree(state);
+
+ _NXCollectedGrabPointers[resource] = NULL;
+ }
+
+ LockDisplay(dpy);
+
+ GetReq(GrabPointer, req);
+
+ req -> grabWindow = grab_window;
+ req -> ownerEvents = owner_events;
+ req -> eventMask = event_mask;
+ req -> pointerMode = pointer_mode;
+ req -> keyboardMode = keyboard_mode;
+ req -> confineTo = confine_to;
+ req -> cursor = cursor;
+ req -> time = time;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXCollectGrabPointer: Sending message opcode [%d] sequence [%ld] "
+ "for resource [%d].\n", X_GrabPointer, dpy -> request, resource);
+ #endif
+
+ state = Xmalloc(sizeof(_NXCollectGrabPointerState));
+ handler = Xmalloc(sizeof(_XAsyncHandler));
+
+ if (state == NULL || handler == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectGrabPointer: Failed to allocate memory with resource [%d].\n",
+ resource);
+ #endif
+
+ if (state != NULL)
+ {
+ Xfree(state);
+ }
+
+ if (handler != NULL)
+ {
+ Xfree(handler);
+ }
+
+ UnGetReq(GrabPointer);
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+
+ state -> sequence = dpy -> request;
+ state -> resource = resource;
+ state -> status = 0;
+
+ state -> handler = handler;
+
+ handler -> next = dpy -> async_handlers;
+ handler -> handler = _NXCollectGrabPointerHandler;
+ handler -> data = (XPointer) state;
+ dpy -> async_handlers = handler;
+
+ _NXCollectedGrabPointers[resource] = state;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return True;
+}
+
+int NXGetCollectedGrabPointer(Display *dpy, unsigned int resource, int *status)
+{
+ register _NXCollectGrabPointerState *state;
+
+ state = _NXCollectedGrabPointers[resource];
+
+ if (state == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXGetCollectedGrabPointer: PANIC! No data collected for resource [%u].\n",
+ resource);
+ #endif
+
+ return 0;
+ }
+
+ *status = state -> status;
+
+ Xfree(state);
+
+ _NXCollectedGrabPointers[resource] = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetCollectedGrabPointer: Returning GrabPointer data for resource [%u].\n",
+ resource);
+ #endif
+
+ return True;
+}
+
+static void _NXNotifyInputFocus(Display *dpy, int resource, Bool success)
+{
+ XEvent async_event;
+
+ async_event.type = ClientMessage;
+
+ async_event.xclient.serial = _NXCollectedInputFocuses[resource] -> sequence;
+
+ async_event.xclient.window = 0;
+ async_event.xclient.message_type = 0;
+ async_event.xclient.format = 32;
+
+ async_event.xclient.data.l[0] = NXCollectInputFocusNotify;
+ async_event.xclient.data.l[1] = resource;
+ async_event.xclient.data.l[2] = success;
+
+ XPutBackEvent(dpy, &async_event);
+}
+
+static Bool _NXCollectInputFocusHandler(Display *dpy, xReply *rep, char *buf,
+ int len, XPointer data)
+{
+ register _NXCollectInputFocusState *state;
+
+ register xGetInputFocusReply *async_rep;
+
+ char *async_head;
+
+ int async_size;
+
+ state = (_NXCollectInputFocusState *) data;
+
+ if ((rep -> generic.sequenceNumber % 65536) !=
+ ((int)(state -> sequence) % 65536))
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Unmatched sequence [%d] for opcode [%d] "
+ "with length [%d].\n", rep -> generic.sequenceNumber, rep -> generic.type,
+ (int) rep -> generic.length << 2);
+ #endif
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Going to handle asynchronous GetInputFocus reply.\n");
+ #endif
+
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+
+ state -> handler = NULL;
+
+ if (rep -> generic.type == X_Error)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Error received from X server for resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyInputFocus(dpy, state -> resource, False);
+
+ _NXCollectedInputFocuses[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Matched request with sequence [%ld].\n",
+ state -> sequence);
+ #endif
+
+ async_size = SIZEOF(xGetInputFocusReply);
+
+ async_head = Xmalloc(async_size);
+
+ if (async_head == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectInputFocusHandler: PANIC! Failed to allocate memory with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyInputFocus(dpy, state -> resource, False);
+
+ _NXCollectedInputFocuses[state -> resource] = NULL;
+
+ Xfree(state);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Going to get reply with size [%d].\n",
+ (int) rep -> generic.length << 2);
+ #endif
+
+ async_rep = (xGetInputFocusReply *) _XGetAsyncReply(dpy, async_head, rep, buf, len, 0, False);
+
+ if (async_rep == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******_NXCollectInputFocusHandler: PANIC! Failed to get reply with resource [%d].\n",
+ state -> resource);
+ #endif
+
+ _NXNotifyInputFocus(dpy, state -> resource, False);
+
+ _NXCollectedInputFocuses[state -> resource] = NULL;
+
+ Xfree(state);
+
+ Xfree(async_head);
+
+ return False;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******_NXCollectInputFocusHandler: Got reply with focus [%d] revert to [%d] "
+ "size [%d].\n", (int) async_rep -> focus, (int) async_rep -> revertTo,
+ (int) async_rep -> length << 2);
+ #endif
+
+ state -> focus = async_rep -> focus;
+ state -> revert_to = async_rep -> revertTo;
+
+ _NXNotifyInputFocus(dpy, state -> resource, True);
+
+ Xfree(async_head);
+
+ return True;
+}
+
+int NXGetCollectInputFocusResource(Display *dpy)
+{
+ int i;
+
+ for (i = 0; i < NXNumberOfResources; i++)
+ {
+ if (_NXCollectedInputFocuses[i] == NULL)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int NXCollectInputFocus(Display *dpy, unsigned int resource)
+{
+ _X_UNUSED register xReq *req;
+
+ _NXCollectInputFocusState *state;
+ _XAsyncHandler *handler;
+
+ if (resource >= NXNumberOfResources)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectInputFocus: PANIC! Provided resource [%u] is out of range.\n",
+ resource);
+ #endif
+
+ return -1;
+ }
+
+ state = _NXCollectedInputFocuses[resource];
+
+ if (state != NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectInputFocus: PANIC! Having to remove previous state for resource [%u].\n",
+ resource);
+ #endif
+
+ if (state -> handler != NULL)
+ {
+ DeqAsyncHandler(dpy, state -> handler);
+
+ Xfree(state -> handler);
+ }
+
+ Xfree(state);
+
+ _NXCollectedInputFocuses[resource] = NULL;
+ }
+
+ LockDisplay(dpy);
+
+ GetEmptyReq(GetInputFocus, req);
+
+ #ifdef TEST
+ fprintf(stderr, "******NXCollectInputFocus: Sending message opcode [%d] sequence [%ld] for resource [%d].\n",
+ X_GetInputFocus, dpy -> request, resource);
+ #endif
+
+ state = Xmalloc(sizeof(_NXCollectInputFocusState));
+ handler = Xmalloc(sizeof(_XAsyncHandler));
+
+ if (state == NULL || handler == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXCollectInputFocus: Failed to allocate memory with resource [%d].\n",
+ resource);
+ #endif
+
+ if (state != NULL)
+ {
+ Xfree(state);
+ }
+
+ if (handler != NULL)
+ {
+ Xfree(handler);
+ }
+
+ UnGetEmptyReq();
+
+ UnlockDisplay(dpy);
+
+ return -1;
+ }
+
+ state -> sequence = dpy -> request;
+ state -> resource = resource;
+ state -> focus = 0;
+ state -> revert_to = 0;
+
+ state -> handler = handler;
+
+ handler -> next = dpy -> async_handlers;
+ handler -> handler = _NXCollectInputFocusHandler;
+ handler -> data = (XPointer) state;
+ dpy -> async_handlers = handler;
+
+ _NXCollectedInputFocuses[resource] = state;
+
+ UnlockDisplay(dpy);
+
+ SyncHandle();
+
+ return True;
+}
+
+int NXGetCollectedInputFocus(Display *dpy, unsigned int resource,
+ Window *focus_return, int *revert_to_return)
+{
+ register _NXCollectInputFocusState *state;
+
+ state = _NXCollectedInputFocuses[resource];
+
+ if (state == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******NXGetCollectedInputFocus: PANIC! No data collected for resource [%u].\n",
+ resource);
+ #endif
+
+ return 0;
+ }
+
+ *focus_return = state -> focus;
+ *revert_to_return = state -> revert_to;
+
+ Xfree(state);
+
+ _NXCollectedInputFocuses[resource] = NULL;
+
+ #ifdef TEST
+ fprintf(stderr, "******NXGetCollectedInputFocus: Returning GetInputFocus data for resource [%u].\n",
+ resource);
+ #endif
+
+ return True;
+}
+
+#ifdef DUMP
+
+void _NXDumpData(const unsigned char *buffer, unsigned int size)
+{
+ if (buffer != NULL)
+ {
+ unsigned int i = 0;
+
+ unsigned int ii;
+
+ while (i < size)
+ {
+ fprintf(stderr, "[%d]\t", i);
+
+ for (ii = 0; i < size && ii < 8; i++, ii++)
+ {
+ fprintf(stderr, "%d\t", (unsigned int) (buffer[i]));
+ }
+
+ fprintf(stderr, "\n");
+ }
+ }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h
new file mode 100644
index 000000000..ecd7d1e18
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Compext.h
@@ -0,0 +1,912 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef NXlib_H
+#define NXlib_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xlib.h>
+
+#include <nx/NX.h>
+#include <nx/NXpack.h>
+#include <nx/NXproto.h>
+#include <nx/NXvars.h>
+
+/*
+ * All the NX code should use these.
+ */
+
+#define Xmalloc(size) malloc((size))
+#define Xfree(ptr) free((ptr))
+
+/*
+ * Maximum number of supported pack methods.
+ */
+
+#define NXNumberOfPackMethods 128
+
+/*
+ * Assume this as the limit of resources that
+ * can be provided to the split and unpack
+ * requests.
+ */
+
+#define NXNumberOfResources 256
+
+#define NXNoResource 256 + 1
+#define NXAnyResource 256 + 2
+
+/*
+ * Initialize the internal structures used by
+ * the library. Should be executed again after
+ * having reopened the display.
+ */
+
+extern int NXInitDisplay(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Reset all the internal structures. Should be
+ * executed after closing the display.
+ */
+
+extern int NXResetDisplay(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Set the NX display flush policy. The policy can
+ * be either NXFlushDeferred or NXFlushImmediate.
+ */
+
+extern int NXSetDisplayPolicy(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* policy */
+#endif
+);
+
+/*
+ * Set the display output buffer size.
+ */
+
+extern int NXSetDisplayBuffer(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* size */
+#endif
+);
+
+/*
+ * If set, the Popen() function in the X server
+ * wil remove the LD_LIBRARY_PATH variable from
+ * the environment before calling the execl()
+ * function on the child process. The function
+ * returns the previous value.
+ */
+
+extern int NXUnsetLibraryPath(
+#if NeedFunctionPrototypes
+ int /* value */
+#endif
+);
+
+/*
+ * If the parameter is true, the Xlib I/O error
+ * handler will return, instead of quitting the
+ * program. The function returns the previous
+ * value.
+ */
+
+extern int NXHandleDisplayError(
+#if NeedFunctionPrototypes
+ int /* value */
+#endif
+);
+
+/*
+ * Shutdown the display descriptor and force Xlib
+ * to set the I/O error flag.
+ */
+
+extern Bool NXForceDisplayError(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Check the value of the XlibDisplayIOError flag.
+ * If not set, try to call the display error hand-
+ * ler to give to the application a chance to see
+ * whether it needs to close the connection.
+ */
+
+extern int NXDisplayError(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Query the number of bytes readable from the
+ * display connection.
+ */
+
+extern int NXDisplayReadable(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Query the number of the outstanding bytes to
+ * flush to the display connection.
+ */
+
+extern int NXDisplayFlushable(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Return a value between 0 and 9 indicating the
+ * congestion level of the NX transport based on
+ * the tokens remaining. A value of 9 means that
+ * the link is congested and no further data can
+ * be sent.
+ */
+
+extern int NXDisplayCongestion(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+/*
+ * Flush the Xlib display buffer and/or the
+ * outstanding data accumulated by the NX
+ * transport.
+ */
+
+extern int NXFlushDisplay(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* what */
+#endif
+);
+
+/*
+ * Public interfaces used to set the handlers.
+ * They all return the previous handler.
+ */
+
+extern NXDisplayErrorPredicate NXSetDisplayErrorPredicate(
+#if NeedFunctionPrototypes
+ NXDisplayErrorPredicate /* predicate */
+#endif
+);
+
+/*
+ * Called when the display blocks waiting to read or
+ * write more data.
+ */
+
+extern NXDisplayBlockHandler NXSetDisplayBlockHandler(
+#if NeedFunctionPrototypes
+ NXDisplayBlockHandler /* handler */
+#endif
+);
+
+/*
+ * Called after more data is written to the display.
+ * When the NX transport is running, data may be queued
+ * until an explicit flush.
+ */
+
+extern NXDisplayWriteHandler NXSetDisplayWriteHandler(
+#if NeedFunctionPrototypes
+ NXDisplayWriteHandler /* handler */
+#endif
+);
+
+/*
+ * Called after more data is sent to the remote proxy.
+ *
+ * Here the display pointer is passed as the second
+ * parameter to make clear that the function does not
+ * tie the callback to the display, but, similarly to
+ * all the Xlib error handlers, to a global variable
+ * shared by all the Xlib functions. The display
+ * pointer will be passed back by nxcomp at the time
+ * it will call the handler. This is because nxcomp
+ * doesn't have access to the display structure.
+ */
+
+extern NXDisplayFlushHandler NXSetDisplayFlushHandler(
+#if NeedFunctionPrototypes
+ NXDisplayFlushHandler /* handler */,
+ Display* /* display */
+#endif
+);
+
+/*
+ * Get an arbitrary null terminated buffer to be added
+ * to the NX statistics.
+ */
+
+extern NXDisplayStatisticsHandler NXSetDisplayStatisticsHandler(
+#if NeedFunctionPrototypes
+ NXDisplayStatisticsHandler /* handler */,
+ char ** /* buffer */
+#endif
+);
+
+/*
+ * Redefine the function called by Xlib in the case of
+ * an out-of-order sequence number received in the X
+ * protocol stream.
+ */
+
+extern NXLostSequenceHandler NXSetLostSequenceHandler(
+#if NeedFunctionPrototypes
+ NXLostSequenceHandler /* handler */
+#endif
+);
+
+/*
+ * The agent should get the NX parameters at startup, just after
+ * having opened the display. If the agent is not able to satisfy
+ * the pack method set by user (because a method is not applica-
+ * ble, it is not supported by the remote or it simply requires a
+ * screen depth greater than the depth available), it should fall
+ * back to the nearest method of the same type.
+ */
+
+extern Status NXGetControlParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int* /* link_type */,
+ unsigned int* /* local_major */,
+ unsigned int* /* local_minor */,
+ unsigned int* /* local_patch */,
+ unsigned int* /* remote_major */,
+ unsigned int* /* remote_minor */,
+ unsigned int* /* remote_patch */,
+ int* /* frame_timeout */,
+ int* /* ping_timeout */,
+ int* /* split_mode */,
+ int* /* split_size */,
+ unsigned int* /* pack_method */,
+ unsigned int* /* pack_quality */,
+ int* /* data_level */,
+ int* /* stream_level */,
+ int* /* delta_level */,
+ unsigned int* /* load_cache */,
+ unsigned int* /* save_cache */,
+ unsigned int* /* startup_cache */
+#endif
+);
+
+/*
+ * Which unpack methods are supported by the remote proxy?
+ */
+
+extern Status NXGetUnpackParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int* /* entries */,
+ unsigned char[] /* supported_methods */
+#endif
+);
+
+/*
+ * Query and enable shared memory support on path agent to X
+ * client proxy and X server proxy to real X server. At the
+ * moment only the path proxy to real X server is implemented.
+ * On return flags will say if support has been successfully
+ * activated. Segments will contain the XID associated to the
+ * shared memory blocks. A MIT-SHM compliant protocol is used
+ * between proxy and the real server, while a simplified
+ * version is used between the agent and the client proxy to
+ * accomodate both packed images and plain X bitmaps.
+ */
+
+extern Status NXGetShmemParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int* /* enable_client */,
+ unsigned int* /* enable_server */,
+ unsigned int* /* client_segment */,
+ unsigned int* /* server_segment */,
+ unsigned int* /* client_size */,
+ unsigned int* /* server_size */
+#endif
+);
+
+/*
+ * Get the path to the font server that can be used by the X
+ * server to tunnel the font connections across the NX link.
+ * The path actually represents the TCP port where the proxy
+ * on the NX client side is listening. The agent can tempora-
+ * rily enable the tunneling when it needs a font that is not
+ * available on the client, for example when the session is
+ * migrated from a different X server.
+ */
+
+extern Status NXGetFontParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* path_length */,
+ char[] /* path_data */
+#endif
+);
+
+/*
+ * This set of functions is used to leverage the image stream-
+ * ing capabilities built in nxcomp. An image can be streamed
+ * by sending a start-split message, followed by the X messages
+ * that will have to be split by the proxy, followed by an end-
+ * split closure. Usually, in the middle of a start-split/end-
+ * split sequence there will be a single PutImage() or PutPack-
+ * edImage(), that, in turn, can generate multiple partial
+ * requests, like a SetUnpackColormap() and SetUnpackAlpha()
+ * that will be later used to decompress the image to its ori-
+ * ginal form. Multiple requests may be also generated because
+ * of the maximum size of a X request being exceeded, so that
+ * Xlib has to divide the single image in multiple sub-image re-
+ * quests. The agent doesn't need to take care of these details
+ * but will rather have to track the result of the split opera-
+ * tion. By monitoring the notify events sent by the proxy, the
+ * agent will have to implement its own strategy to deal with
+ * the resources. For example, it will be able to:
+ *
+ * - Mark a drawable as dirty, if the image was not sent
+ * synchronously, in the main X oputput stream.
+ *
+ * - Choose to commit or discard the original image, at the
+ * time it will be recomposed at the remote side. This may
+ * include all the messages that were part of the split
+ * (the colormap, the alpha channel, etc.)
+ *
+ * - Mark the drawable as clean again, if the image was
+ * committed and the drawable didn't change in the mean-
+ * while.
+ *
+ * At the time the proxy receives the end-split, it reports the
+ * result of the operation to the agent. The agent will be able
+ * to identify the original split operation (the one referenced
+ * in the start-split/end-split sequence) by the small integer
+ * number (0-255) named 'resource' sent in the events.
+ *
+ * One of the following cases may be encountered:
+ *
+ *
+ * NXNoSplitNotify All messages were sent in the main out-
+ * put stream, so that no split actually
+ * took place.
+ *
+ * NXStartSplitNotify One or more messages were split, so,
+ * at discrection of the agent, the client
+ * may be suspended until the transferral
+ * is completed.
+ *
+ * NXCommitSplitNotify One of the requests that made up the
+ * split was recomposed. The agent should
+ * either commit the given request or tell
+ * the proxy to discard it.
+ *
+ * NXEndSplitNotify The split was duly completed. The agent
+ * can restart the client.
+ *
+ * NXEmptySplitNotify No more split operation are pending.
+ * The agent can use this information to
+ * implement specific strategies requiring
+ * that all messages have been recomposed
+ * at the remote end, like updating the
+ * drawables that were not synchronized
+ * because of the lazy encoding.
+ *
+ * The 'mode' field that is sent by the agent in the start-split
+ * request, determines the strategy that the proxy will adopt to
+ * deal with the image. If set to 'eager', the proxy will only
+ * split the messages whose size exceeds the split threshold (the
+ * current threshold can be found in the NXGetControlParameters()
+ * reply). If the mode is set to lazy, the proxy will split any
+ * image that would have generated an actual transfer of the data
+ * part (in practice all images that are not found in the cache).
+ * This second strategy can be leveraged by an agent to further
+ * reduce the bandwidth requirements. For example, by setting the
+ * mode to lazy and by monitoring the result, an agent can easi-
+ * ly verify if the drawable was successfully updated, mark the
+ * drawable if not, and synchronize it at later time.
+ *
+ * See NXproto.h for the definition of the available modes.
+ */
+
+extern unsigned int NXAllocSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXStartSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* mode */
+#endif
+);
+
+extern int NXEndSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXCommitSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* propagate */,
+ unsigned char /* request */,
+ unsigned int /* position */
+#endif
+);
+
+extern int NXAbortSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXFinishSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXFreeSplit(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXSetExposeParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* expose */,
+ int /* graphics_expose */,
+ int /* no_expose */
+#endif
+);
+
+extern int NXSetCacheParameters(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* enable_cache */,
+ int /* enable_split */,
+ int /* enable_save */,
+ int /* enable_load */
+#endif
+);
+
+extern unsigned int NXAllocUnpack(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXSetUnpackGeometry(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Visual* /* visual */
+#endif
+);
+
+extern int NXSetUnpackColormap(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* method */,
+ unsigned int /* entries */,
+ const char* /* data */,
+ unsigned int /* data_length */
+#endif
+);
+
+extern int NXSetUnpackAlpha(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* method */,
+ unsigned int /* entries */,
+ const char* /* data */,
+ unsigned int /* data_length */
+#endif
+);
+
+extern int NXSetUnpackColormapCompat(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* entries */,
+ const char* /* data */
+#endif
+);
+
+extern int NXSetUnpackAlphaCompat(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ unsigned int /* entries */,
+ const char* /* data */
+#endif
+);
+
+extern int NXFreeUnpack(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+/*
+ * A packed image is a XImage but with
+ * offset field containing total amount
+ * of packed image data.
+ */
+
+typedef XImage NXPackedImage;
+
+NXPackedImage *NXCreatePackedImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Visual* /* visual */,
+ unsigned int /* method */,
+ unsigned int /* depth */,
+ int /* format */,
+ char* /* data */,
+ int /* data_length */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ int /* bitmap_pad */,
+ int /* bytes_per_line */
+#endif
+);
+
+extern int NXDestroyPackedImage(
+#if NeedFunctionPrototypes
+ NXPackedImage* /* image */
+#endif
+);
+
+NXPackedImage *NXPackImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XImage* /* src_image */,
+ unsigned int /* method */
+#endif
+);
+
+NXPackedImage *NXInPlacePackImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ XImage* /* src_image */,
+ unsigned int /* method */
+#endif
+);
+
+/*
+ * GC is declared void * to get rid of mess
+ * with different GC definitions in some X
+ * server code (like in nxagent).
+ */
+
+extern int NXPutPackedImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Drawable /* drawable */,
+ void* /* gc */,
+ NXPackedImage* /* image */,
+ unsigned int /* method */,
+ unsigned int /* depth */,
+ int /* src_x */,
+ int /* src_y */,
+ int /* dst_x */,
+ int /* dst_y */,
+ unsigned int /* width */,
+ unsigned int /* height */
+#endif
+);
+
+/*
+ * Get multiple colors with a single call by
+ * pipelining X_AllocColor requests/replies.
+ */
+
+extern int NXAllocColors(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Colormap /* colormap */,
+ unsigned int /* entries */,
+ XColor[] /* screens_in_out */,
+ Bool [] /* flags allocation errors */
+#endif
+);
+
+/*
+ * Encode the data in the given format.
+ */
+
+extern char *NXEncodeColormap(
+#if NeedFunctionPrototypes
+ const char* /* src_data */,
+ unsigned int /* src_size */,
+ unsigned int* /* dst_size */
+#endif
+);
+
+extern char *NXEncodeAlpha(
+#if NeedFunctionPrototypes
+ const char* /* src_data */,
+ unsigned int /* src_size */,
+ unsigned int* /* dst_size */
+#endif
+);
+
+extern NXPackedImage *NXEncodeRgb(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ unsigned int /* method */,
+ unsigned int /* quality */
+#endif
+);
+
+extern NXPackedImage *NXEncodeRle(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ unsigned int /* method */,
+ unsigned int /* quality */
+#endif
+);
+
+extern NXPackedImage *NXEncodeJpeg(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ unsigned int /* method */,
+ unsigned int /* quality */
+#endif
+);
+
+typedef struct
+{
+ long pixel;
+ int found;
+
+} NXColorTable;
+
+extern int NXEncodeColors(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ NXColorTable* /* color_table */,
+ int /* nb_max */
+#endif
+);
+
+extern NXPackedImage *NXEncodePng(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ unsigned int /* method */,
+ unsigned int /* quality */
+#endif
+);
+
+extern NXPackedImage *NXEncodeBitmap(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ unsigned int /* method */,
+ unsigned int /* quality */
+#endif
+);
+
+extern int NXCleanImage(
+#if NeedFunctionPrototypes
+ XImage*
+#endif
+);
+
+extern void NXMaskImage(
+#if NeedFunctionPrototypes
+ XImage* /* pointer to image to mask */ ,
+ unsigned int /* method */
+#endif
+);
+
+extern int NXImageCacheSize;
+
+extern void NXInitCache(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ int /* entries in image cache */
+#endif
+);
+
+extern void NXFreeCache(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+extern XImage *NXCacheFindImage(
+#if NeedFunctionPrototypes
+ NXPackedImage* /* packed image to find */,
+ unsigned int* /* pointer to the pack method if found */,
+ unsigned char** /* pointer to the calculated MD5 if found */
+#endif
+);
+
+extern int NXCacheAddImage(
+#if NeedFunctionPrototypes
+ NXPackedImage* /* packed image to be added to the cache */,
+ unsigned int /* pack method of the image to add */,
+ unsigned char* /* pointer to MD5 of the original unpacked image */
+#endif
+);
+
+
+extern int NXGetCollectImageResource(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+extern int NXCollectImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Drawable /* drawable */,
+ int /* src_x */,
+ int /* src_y */,
+ unsigned int /* width */,
+ unsigned int /* height */,
+ unsigned long /* plane_mask */,
+ int /* format */
+#endif
+);
+
+extern int NXGetCollectedImage(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ XImage** /* image */
+#endif
+);
+
+extern int NXGetCollectPropertyResource(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+extern int NXCollectProperty(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Window /* window */,
+ Atom /* property */,
+ long /* long_offset */,
+ long /* long_length */,
+ Bool /* delete */,
+ Atom /* req_type */
+#endif
+);
+
+extern int NXGetCollectedProperty(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Atom* /* actual_type_return */,
+ int* /* actual_format_return */,
+ unsigned long* /* nitems_return */,
+ unsigned long* /* bytes_after_return */,
+ unsigned char** /* data */
+#endif
+);
+
+extern int NXGetCollectGrabPointerResource(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+extern int NXCollectGrabPointer(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Window /* grab_window */,
+ Bool /* owner_events */,
+ unsigned int /* event_mask */,
+ int /* pointer_mode */,
+ int /* keyboard_mode */,
+ Window /* confine_to */,
+ Cursor /* cursor */,
+ Time /* time */
+#endif
+);
+
+extern int NXGetCollectedGrabPointer(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ int* /* status */
+#endif
+);
+
+extern int NXGetCollectInputFocusResource(
+#if NeedFunctionPrototypes
+ Display* /* display */
+#endif
+);
+
+extern int NXCollectInputFocus(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */
+#endif
+);
+
+extern int NXGetCollectedInputFocus(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ unsigned int /* resource */,
+ Window* /* focus_return */,
+ int* /* revert_to_return */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NXlib_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile
new file mode 100644
index 000000000..8f0f17d1e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Imakefile
@@ -0,0 +1,48 @@
+NULL =
+
+#include <Server.tmpl>
+
+SRCS = \
+ Alpha.c \
+ Bitmap.c \
+ Clean.c \
+ Colormap.c \
+ Compext.c \
+ Jpeg.c \
+ Mask.c \
+ Png.c \
+ Rgb.c \
+ Rle.c \
+ Z.c \
+ $(NULL)
+
+OBJS = \
+ Alpha.o \
+ Bitmap.o \
+ Clean.o \
+ Colormap.o \
+ Compext.o \
+ Jpeg.o \
+ Mask.o \
+ Png.o \
+ Rgb.o \
+ Rle.o \
+ Z.o \
+ $(NULL)
+
+ INCLUDES = -I$(SERVERSRC)/include \
+ -I$(XBUILDINCDIR) \
+ `pkg-config --cflags-only-I pixman-1` \
+ `pkg-config --cflags-only-I zlib` \
+ `pkg-config --cflags-only-I libpng` \
+ $(NULL)
+
+ LINTLIBS = $(SERVERSRC)/dix/llib-ldix.ln \
+ $(NULL)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(compext,$(OBJS))
+LintLibraryTarget(compext,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c
new file mode 100644
index 000000000..690a934f6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.c
@@ -0,0 +1,480 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xlib.h>
+#include <nx-X11/Xmd.h>
+
+#include <jpeglib.h>
+
+#include "Compext.h"
+
+#include "Mask.h"
+#include "Jpeg.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define JPEG_DEST_SIZE(width, height) ((width) * 3 * (height) + 1024)
+
+/*
+ * Local function prototypes.
+ */
+
+static void PrepareRowForJpeg(CARD8 *dst, int y, int count);
+static void PrepareRowForJpeg24(CARD8 *dst, int y, int count);
+static void PrepareRowForJpeg16(CARD8 *dst, int y, int count);
+static void PrepareRowForJpeg32(CARD8 *dst, int y, int count);
+
+static int JpegEmptyOutputBuffer(j_compress_ptr cinfo);
+
+static void JpegInitDestination(j_compress_ptr cinfo);
+static void JpegTermDestination(j_compress_ptr cinfo);
+static void JpegSetDstManager(j_compress_ptr cinfo);
+
+/*
+ * Quality levels.
+ */
+
+static int jpegQuality[10] = {20, 30, 40, 50, 55, 60, 65, 70, 75, 80};
+
+/*
+ * Image characteristics.
+ */
+
+static int bytesPerLine;
+
+static CARD8 bitsPerPixel;
+static CARD16 redMax, greenMax, blueMax;
+static CARD8 redShift, greenShift, blueShift;
+static int byteOrder;
+
+/*
+ * Other variables used for the Jpeg
+ * encoding.
+ */
+
+static char *jpegBeforeBuf = NULL;
+static char *jpegCompBuf;
+static int jpegCompBufSize;
+static int jpegError;
+static int jpegDstDataLen;
+
+static struct jpeg_destination_mgr jpegDstManager;
+
+/*
+ * Just for debugging purpose.
+ */
+
+#ifdef DEBUG
+
+static int jpegId;
+static char jpegName[10];
+static FILE *jpegFile;
+
+#endif
+
+/*
+ * Function declarations
+ */
+
+char *JpegCompressData(XImage *image, int level, int *compressed_size)
+{
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+
+ CARD8 *srcBuf;
+ JSAMPROW rowPointer[1];
+
+ int dy, w, h;
+
+ *compressed_size = 0;
+
+ /*
+ * Initialize the image stuff
+ */
+
+ bitsPerPixel = image -> bits_per_pixel;
+ bytesPerLine = image -> bytes_per_line;
+ byteOrder = image -> byte_order;
+
+ #ifdef TEST
+ fprintf(stderr, "******JpegCompressData: Image byte order [%d] bitmap bit order [%d].\n",
+ image -> byte_order, image -> bitmap_bit_order);
+
+ fprintf(stderr, "******JpegCompressData: Bits per pixel [%d] bytes per line [%d].\n",
+ bitsPerPixel, bytesPerLine);
+ #endif
+
+ redShift = FindLSB(image -> red_mask) - 1;
+ greenShift = FindLSB(image -> green_mask) - 1;
+ blueShift = FindLSB(image -> blue_mask) - 1;
+
+ #ifdef TEST
+ fprintf(stderr, "******JpegCompressData: Red mask [0x%lx] green mask [0x%lx] blue mask [0x%lx].\n",
+ image -> red_mask, image -> green_mask, image -> blue_mask);
+
+ fprintf(stderr, "******JpegCompressData: Red shift [%d] green shift [%d] blue shift [%d].\n",
+ redShift, greenShift, blueShift);
+ #endif
+
+ redMax = image -> red_mask >> redShift;
+ greenMax = image -> green_mask >> greenShift;
+ blueMax = image -> blue_mask >> blueShift;
+
+ #ifdef TEST
+ fprintf(stderr, "******JpegCompressData: Red max [0x%x] green max [0x%x] blue max [0x%x].\n",
+ redMax, greenMax, blueMax);
+ #endif
+
+ w = image -> width;
+ h = image -> height;
+
+ jpegBeforeBuf = image -> data;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******JpegCompressData: Width [%d] height [%d] level [%d].\n",
+ w, h, level);
+ #endif
+
+ if (bitsPerPixel == 1 ||
+ bitsPerPixel == 8)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******JpegCompressData: PANIC! Invalid bits per pixel [%d].\n",
+ bitsPerPixel);
+ #endif
+
+ return NULL;
+ }
+
+ /*
+ * Allocate space for one line of the
+ * resulting image, 3 bytes per pixel.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the scanline.\n",
+ w * 3);
+ #endif
+
+ srcBuf = (CARD8 *) malloc(w * 3);
+
+ if (srcBuf == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******JpegCompressData: PANIC! Cannot allocate [%d] bytes.\n",
+ w * 3);
+ #endif
+
+ return NULL;
+ }
+
+ rowPointer[0] = srcBuf;
+
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jpeg_create_compress(&cinfo);
+
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, jpegQuality[level], 1);
+
+ /*
+ * Allocate memory for the destination
+ * buffer.
+ */
+
+ jpegCompBufSize = JPEG_DEST_SIZE(w, h);
+
+ #ifdef TEST
+ fprintf(stderr, "******JpegCompressData: Allocating [%d] bytes for the destination data.\n",
+ jpegCompBufSize);
+ #endif
+
+ jpegCompBuf = malloc(jpegCompBufSize);
+
+ if (jpegCompBuf == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******JpegCompressData: PANIC! Error allocating [%d] bytes for the Jpeg data.\n",
+ jpegCompBufSize);
+ #endif
+
+ return NULL;
+ }
+
+ JpegSetDstManager(&cinfo);
+
+ jpeg_start_compress(&cinfo, 1);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******JpegCompressedData: Initialization finished.\n");
+ #endif
+
+ for (dy = 0; dy < h; dy++)
+ {
+ PrepareRowForJpeg(srcBuf, dy, w);
+
+ jpeg_write_scanlines(&cinfo, rowPointer, 1);
+
+ if (jpegError != 0)
+ {
+ break;
+ }
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******JpegCompressedData: Compression finished. Lines handled [%d,%d]. Error is [%d].\n",
+ dy, h, jpegError);
+ #endif
+
+ if (jpegError == 0)
+ {
+ jpeg_finish_compress(&cinfo);
+ }
+
+ jpeg_destroy_compress(&cinfo);
+
+ free((char *) srcBuf);
+
+ if (jpegError != 0)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******JpegCompressedData: PANIC! Compression failed. Error is [%d].\n",
+ jpegError);
+ #endif
+
+ free(jpegCompBuf);
+
+ return NULL;
+ }
+
+ /*
+ * Check the size of the resulting data.
+ */
+
+ if (jpegDstDataLen > 0)
+ {
+ /*
+ * Save the image on disk to help with
+ * the debug.
+ */
+
+ #ifdef DEBUG
+
+ int i = 0;
+
+ fprintf(stderr, "******JpegCompressedData: Compressed size [%d].\n",
+ jpegDstDataLen);
+
+ jpegId++;
+
+ sprintf(jpegName, "jpeg%d", jpegId);
+
+ jpegFile = fopen(jpegName, "w");
+
+ for (i = 0; i < jpegDstDataLen; i++)
+ {
+ fprintf(jpegFile, "%c", *(jpegCompBuf + i));
+ }
+
+ fclose(jpegFile);
+
+ #endif
+
+ *compressed_size = jpegDstDataLen;
+
+ return jpegCompBuf;
+ }
+ else
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******JpegCompressedData: PANIC! Invalid size of the compressed data [%d].\n",
+ jpegDstDataLen);
+ #endif
+
+ free(jpegCompBuf);
+
+ return NULL;
+ }
+}
+
+void PrepareRowForJpeg(CARD8 *dst, int y, int count)
+{
+ if (bitsPerPixel == 32)
+ {
+ if (redMax == 0xff &&
+ greenMax == 0xff &&
+ blueMax == 0xff)
+ {
+ PrepareRowForJpeg24(dst, y, count);
+ }
+ else
+ {
+ PrepareRowForJpeg32(dst, y, count);
+ }
+ }
+ else if (bitsPerPixel == 24)
+ {
+ memcpy(dst, jpegBeforeBuf + y * bytesPerLine, count * 3);
+ }
+ else
+ {
+ /*
+ * 16 bpp assumed.
+ */
+
+ PrepareRowForJpeg16(dst, y, count);
+ }
+}
+
+void PrepareRowForJpeg24(CARD8 *dst, int y, int count)
+{
+ CARD8 *fbptr;
+ CARD32 pix;
+
+ fbptr = (CARD8 *) (jpegBeforeBuf + y * bytesPerLine);
+
+ while (count--)
+ {
+ if (byteOrder == LSBFirst)
+ {
+ pix = (CARD32) *(fbptr + 2);
+ pix = (pix << 8) | (CARD32) *(fbptr+1);
+ pix = (pix << 8) | (CARD32) *fbptr;
+ }
+ else
+ {
+ pix = (CARD32) *(fbptr + 1);
+ pix = (pix << 8) | (CARD32) *(fbptr + 2);
+ pix = (pix << 8) | (CARD32) *(fbptr + 3);
+ }
+
+ *dst++ = (CARD8)(pix >> redShift);
+ *dst++ = (CARD8)(pix >> greenShift);
+ *dst++ = (CARD8)(pix >> blueShift);
+
+ fbptr+=4;
+ }
+}
+
+#define DEFINE_JPEG_GET_ROW_FUNCTION(bpp) \
+ \
+void PrepareRowForJpeg##bpp(CARD8 *dst, int y, int count) \
+{ \
+ CARD8 *fbptr; \
+ CARD##bpp pix; \
+ int inRed, inGreen, inBlue; \
+ int i; \
+ \
+ fbptr = (CARD8 *) (jpegBeforeBuf + y * bytesPerLine); \
+ \
+ while (count--) \
+ { \
+ pix = 0; \
+ \
+ if (byteOrder == LSBFirst) \
+ { \
+ for (i = (bpp >> 3) - 1; i >= 0; i--) \
+ { \
+ pix = (pix << 8) | (CARD32) *(fbptr + i); \
+ } \
+ } \
+ else \
+ { \
+ for (i = 0; i < (bpp >> 3); i++) \
+ { \
+ pix = (pix << 8) | (CARD32) *(fbptr + i); \
+ } \
+ } \
+ \
+ fbptr += bpp >> 3; \
+ \
+ inRed = (int) \
+ (pix >> redShift & redMax); \
+ inGreen = (int) \
+ (pix >> greenShift & greenMax); \
+ inBlue = (int) \
+ (pix >> blueShift & blueMax); \
+ \
+ *dst++ = (CARD8)((inRed * 255 + redMax / 2) / \
+ redMax); \
+ *dst++ = (CARD8)((inGreen * 255 + greenMax / 2) / \
+ greenMax); \
+ *dst++ = (CARD8)((inBlue * 255 + blueMax / 2) / \
+ blueMax); \
+ } \
+}
+
+DEFINE_JPEG_GET_ROW_FUNCTION(16)
+DEFINE_JPEG_GET_ROW_FUNCTION(32)
+
+/*
+ * Destination manager implementation for JPEG library.
+ */
+
+void JpegInitDestination(j_compress_ptr cinfo)
+{
+ jpegError = 0;
+
+ jpegDstManager.next_output_byte = (JOCTET *) jpegCompBuf;
+ jpegDstManager.free_in_buffer = (size_t) jpegCompBufSize;
+}
+
+int JpegEmptyOutputBuffer(j_compress_ptr cinfo)
+{
+ jpegError = 1;
+
+ jpegDstManager.next_output_byte = (JOCTET *) jpegCompBuf;
+ jpegDstManager.free_in_buffer = (size_t) jpegCompBufSize;
+
+ return 1;
+}
+
+void JpegTermDestination(j_compress_ptr cinfo)
+{
+ jpegDstDataLen = jpegCompBufSize - jpegDstManager.free_in_buffer;
+}
+
+void JpegSetDstManager(j_compress_ptr cinfo)
+{
+ jpegDstManager.init_destination = JpegInitDestination;
+ jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer;
+ jpegDstManager.term_destination = JpegTermDestination;
+
+ cinfo -> dest = &jpegDstManager;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h
new file mode 100644
index 000000000..b50efd3ec
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Jpeg.h
@@ -0,0 +1,46 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Jpeg_H
+#define Jpeg_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *JpegCompressData(
+#if NeedFunctionPrototypes
+ XImage* /* image */,
+ int /* level */,
+ int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Jpeg_H */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c
new file mode 100644
index 000000000..cdcb8d3c0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.c
@@ -0,0 +1,802 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+
+#include <nx-X11/Xlib.h>
+
+#include <nx/NXpack.h>
+
+#include "Mask.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Try first to reduce to a white or black
+ * pixel. If not possible, apply the mask.
+ * Note that correction is applied at the
+ * time pixel is unpacked.
+ */
+
+#define MaskPixel(red, green, blue, mask) \
+\
+if (red > mask -> white_threshold && \
+ green > mask -> white_threshold && \
+ blue > mask -> white_threshold) \
+{ \
+ red = green = blue = 0xff; \
+} \
+else if (red < mask -> black_threshold && \
+ green < mask -> black_threshold && \
+ blue < mask -> black_threshold) \
+{ \
+ red = green = blue = 0x00; \
+} \
+else \
+{ \
+ red = red & mask -> color_mask; \
+ green = green & mask -> color_mask; \
+ blue = blue & mask -> color_mask; \
+}
+
+int MaskImage(const ColorMask *mask, XImage *src_image, XImage *dst_image)
+{
+ unsigned long pixel;
+
+ register unsigned int red;
+ register unsigned int green;
+ register unsigned int blue;
+
+ register unsigned long data_size;
+
+ register unsigned int i;
+
+ data_size = (src_image -> bytes_per_line * src_image -> height) >> 2;
+
+ #ifdef TEST
+ fprintf(stderr, "******MaskImage: Going to mask image with [%d] bits per pixel.\n",
+ src_image -> bits_per_pixel);
+ #endif
+
+ if (src_image -> bits_per_pixel == 24 || src_image -> bits_per_pixel == 32)
+ {
+ register unsigned char *pixel_addr;
+
+ for (i = 0; i < data_size; i++)
+ {
+ pixel = ((unsigned long *) src_image -> data)[i];
+
+ pixel_addr = (unsigned char *) &pixel;
+
+ red = pixel_addr[2];
+ green = pixel_addr[1];
+ blue = pixel_addr[0];
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 24/32 bits original R [%d] G [%d] B [%d] A [%d].\n",
+ red, green, blue, pixel_addr[3]);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 24/32 bits masked R [%d] G [%d] B [%d] A [%d].\n",
+ red, green, blue, pixel_addr[3]);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 24/32 bits pixel 0x%lx", pixel);
+ #endif
+
+ pixel_addr[2] = red;
+ pixel_addr[1] = green;
+ pixel_addr[0] = blue;
+
+ ((unsigned long*)dst_image -> data)[i] = pixel;
+
+ #ifdef DEBUG
+ fprintf(stderr, " -> 0x%lx\n", pixel);
+ #endif
+ }
+
+ return 1;
+ }
+ else if (src_image -> bits_per_pixel == 16)
+ {
+ /*
+ * FIXME: Masking doesn't work in 16 bpp.
+ *
+
+ unsigned long src_addr, *dst_addr;
+ unsigned short *src_pixels_addr, *dst_pixels_addr;
+
+ for (i = 0; i < data_size; i++)
+ {
+ src_addr = ((unsigned long *)src_image -> data)[i];
+ dst_addr = (unsigned long *)((unsigned long *)dst_image -> data + i);
+
+ src_pixels_addr = ((unsigned short *) &src_addr);
+ dst_pixels_addr = ((unsigned short *) dst_addr);
+
+ red = (src_pixels_addr[0] & src_image -> red_mask) >> 8;
+ green = (src_pixels_addr[0] & src_image -> green_mask) >> 3;
+ blue = (src_pixels_addr[0] & src_image -> blue_mask) << 3;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits original R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits masked R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ dst_pixels_addr[0] = ((red << 8) & src_image -> red_mask) |
+ ((green << 3) & src_image -> green_mask) |
+ ((blue >> 3) & src_image -> blue_mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits pixel 0x%x", dst_pixels_addr[0]);
+ #endif
+
+ red = (src_pixels_addr[1] & src_image -> red_mask) >> 8;
+ green = (src_pixels_addr[1] & src_image -> green_mask) >> 3;
+ blue = (src_pixels_addr[1] & src_image -> blue_mask) << 3;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits original R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits masked R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ dst_pixels_addr[1] = ((red << 8) & src_image -> red_mask) |
+ ((green << 3) & src_image -> green_mask) |
+ ((blue >> 3) & src_image -> blue_mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskImage: 16 bits pixel 0x%x", dst_pixels_addr[0]);
+ #endif
+ }
+
+ if (dst_image -> width & 0x00000001)
+ {
+ int card32_per_line;
+ int i;
+
+ card32_per_line = dst_image -> bytes_per_line >> 2;
+
+ for (i = 0; i < dst_image -> height;)
+ {
+ ((CARD32 *) dst_image -> data)[(++i * card32_per_line) - 1] &= 0x0000ffff;
+ }
+ }
+
+ *
+ * End of FIXME.
+ */
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "******MaskImage: PANIC! Cannot apply mask with [%d] bits per pixel.\n",
+ src_image -> bits_per_pixel);
+ #endif
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int MaskInPlaceImage(const ColorMask *mask, XImage *image)
+{
+ unsigned long pixel;
+
+ register unsigned int red;
+ register unsigned int green;
+ register unsigned int blue;
+
+ register unsigned int i;
+
+ register unsigned long data_size;
+
+ data_size = (image -> bytes_per_line * image -> height)>>2;
+
+ #ifdef TEST
+ fprintf(stderr, "******MaskInPlaceImage: Going to mask image with [%d] bits per pixel.\n",
+ image -> bits_per_pixel);
+ #endif
+
+ if (image -> bits_per_pixel == 24 || image -> bits_per_pixel == 32)
+ {
+ register unsigned char *pixel_addr;
+
+ for (i = 0; i < data_size; i++)
+ {
+ pixel = ((unsigned long *) image -> data)[i];
+
+ pixel_addr = (unsigned char *) &pixel;
+
+ red = pixel_addr[2];
+ green = pixel_addr[1];
+ blue = pixel_addr[0];
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 24/32 bits original R [%d] G [%d] B [%d] A [%d].\n",
+ red, green, blue, pixel_addr[3]);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 24/32 bits masked R [%d] G [%d] B [%d] A [%d].\n",
+ red, green, blue, pixel_addr[3]);
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 24/32 bits pixel 0x%lx", pixel);
+ #endif
+
+ pixel_addr[2] = red;
+ pixel_addr[1] = green;
+ pixel_addr[0] = blue;
+
+ ((unsigned long *) image -> data)[i] = pixel;
+
+ #ifdef DEBUG
+ fprintf(stderr, " -> 0x%lx\n", pixel);
+ #endif
+ }
+
+ return 1;
+ }
+ else if (image -> bits_per_pixel == 16)
+ {
+ /*
+ * FIXME: Mask doesn't still work for 16 bits.
+ *
+
+ unsigned long addr;
+ register unsigned short *pixels_addr;
+
+ for (i = 0; i < data_size; i++)
+ {
+ addr = ((unsigned long *) image -> data)[i];
+
+ pixels_addr = ((unsigned short *) &addr);
+
+ red = (pixels_addr[0] & image -> red_mask) >> 8;
+ green = (pixels_addr[0] & image -> green_mask) >> 3;
+ blue = (pixels_addr[0] & image -> blue_mask) << 3;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits original R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits masked R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ pixels_addr[0] = ((red << 8) & image -> red_mask) |
+ ((green << 3) & image -> green_mask) |
+ ((blue >> 3) & image -> blue_mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits pixel 0x%x", pixels_addr[0]);
+ #endif
+
+ red = (pixels_addr[1] & image -> red_mask) >> 8;
+ green = (pixels_addr[1] & image -> green_mask) >> 3;
+ blue = (pixels_addr[1] & image -> blue_mask) << 3;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits original R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ MaskPixel(red, green, blue, mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits masked R [%d] G [%d] B [%d].\n",
+ red, green, blue);
+ #endif
+
+ pixels_addr[1] = ((red << 8) & image -> red_mask) |
+ ((green << 3) & image -> green_mask) |
+ ((blue >> 3) & image -> blue_mask);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******MaskInPlaceImage: 16 bits pixel 0x%x", pixels_addr[1]);
+ #endif
+ }
+
+ if (image -> width & 0x00000001)
+ {
+ int card32_per_line;
+ int i;
+
+ card32_per_line = image -> bytes_per_line >> 2;
+
+ for (i = 0; i < image -> height;)
+ {
+ ((CARD32 *) image -> data)[(++i * card32_per_line) - 1] &= 0x0000ffff;
+ }
+ }
+
+ *
+ * End of FIXME.
+ */
+ }
+ else
+ {
+ #ifdef TEST
+ fprintf(stderr, "******MaskImage: PANIC! Cannot apply mask with [%d] bits per pixel.\n",
+ image -> bits_per_pixel);
+ #endif
+
+ return 0;
+ }
+
+ return 1;
+}
+
+static int Pack16To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned short *src_pixel = (unsigned short *) src_image -> data;
+ unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ while (src_pixel < ((unsigned short *) (src_image -> data + src_data_size)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, *src_pixel, (*src_pixel & 0xc000) >> 8,
+ ((*src_pixel & 0x600) >> 3), (*src_pixel & 0x18) << 3);
+ #endif
+
+ if (*src_pixel == 0x0)
+ {
+ *dst_pixel = 0x0;
+ }
+ else if (*src_pixel == 0xffff)
+ {
+ *dst_pixel = 0xff;
+ }
+ else
+ {
+ *dst_pixel = ((*src_pixel & 0xc000) >> 10) |
+ ((*src_pixel & 0x600) >> 7) |
+ ((*src_pixel & 0x18) >> 3);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
+ counter++, *dst_pixel);
+ #endif
+
+ src_pixel++;
+ dst_pixel++;
+ }
+
+ return 1;
+}
+
+static int Pack24To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned char *src_pixel = (unsigned char *) src_image -> data;
+ unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
+
+ int i;
+
+ unsigned int bytes_per_line = src_image -> bytes_per_line;
+
+ unsigned char *end_of_line = (unsigned char *) (src_pixel + bytes_per_line);
+
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ for (i = 0; i < src_image -> height; i++ )
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x%x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, src_pixel[0], src_pixel[1], src_pixel[2], src_pixel[0] & 0xc0,
+ src_pixel[1] & 0xc0, src_pixel[2] & 0xc0);
+ #endif
+
+ while(src_pixel < end_of_line - 2)
+ {
+ if (src_pixel[0] == 0x00 &&
+ src_pixel[1] == 0x00 &&
+ src_pixel[2] == 0x00)
+ {
+ *dst_pixel = 0x0;
+ }
+ else if (src_pixel[0] == 0xff &&
+ src_pixel[1] == 0xff &&
+ src_pixel[2] == 0xff)
+ {
+ *dst_pixel = 0xff;
+ }
+ else
+ {
+ /*
+ * Pixel layout:
+ *
+ * 24 bit RRRRR000 GGGGG000 BBBBB000 -> 8 bit 00RRGGBB
+ */
+
+ *dst_pixel = (src_pixel[0] & 0xc0) >> 2 |
+ ((src_pixel[1] & 0xc0) >> 4) |
+ ((src_pixel[2] & 0xc0) >> 6);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
+ counter++, *dst_pixel);
+ #endif
+
+ src_pixel += 3;
+ dst_pixel += 1;
+ }
+
+ src_pixel = end_of_line;
+ end_of_line += bytes_per_line;
+ }
+
+ return 1;
+}
+
+static int Pack24To16(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned char *src_pixel = (unsigned char *) src_image -> data;
+ unsigned short *dst_pixel = (unsigned short *) dst_image -> data;
+
+ int i;
+
+ unsigned int bytes_per_line = src_image -> bytes_per_line;
+
+ unsigned char *end_of_line = (unsigned char *) (src_pixel + bytes_per_line);
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ for (i = 0; i < src_image -> height; i++ )
+ {
+ while(src_pixel < end_of_line - 2)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x%x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, src_pixel[0], src_pixel[1], src_pixel[2], src_pixel[0] & 0xf8,
+ src_pixel[1] & 0xf8, src_pixel[2] & 0xf8);
+ #endif
+
+ if (src_pixel[0] == 0x00 &&
+ src_pixel[1] == 0x00 &&
+ src_pixel[2] == 0x00)
+ {
+ *dst_pixel = 0x0;
+ }
+ else if (src_pixel[0] == 0xff &&
+ src_pixel[1] == 0xff &&
+ src_pixel[2] == 0xff)
+ {
+ *dst_pixel = 0xffff;
+ }
+ else
+ {
+ /*
+ * Pixel layout:
+ *
+ * 24 bit RRRRR000 GGGGG000 BBBBB000 -> 16 bit 0RRRRRGG GGGBBBBB
+ */
+
+ *dst_pixel = ((src_pixel[0] & 0xf8) << 7) |
+ ((src_pixel[1] & 0xf8) << 2) |
+ ((src_pixel[2] & 0xf8) >> 3);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
+ counter++, *dst_pixel);
+ #endif
+
+ src_pixel += 3;
+ dst_pixel += 1;
+ }
+
+ src_pixel = end_of_line;
+ end_of_line += bytes_per_line;
+ }
+
+ return 1;
+}
+
+static int Pack32To8(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned int *src_pixel = (unsigned int *) src_image -> data;
+ unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, *src_pixel, (*src_pixel & 0xc00000),
+ (*src_pixel & 0xc000), (*src_pixel & 0xc0));
+ #endif
+
+ if (*src_pixel == 0x0)
+ {
+ *dst_pixel = 0x0;
+ }
+ else if (*src_pixel == 0xffffff)
+ {
+ *dst_pixel = 0xff;
+ }
+ else
+ {
+ *dst_pixel = ((*src_pixel & 0xc00000) >> 18) |
+ ((*src_pixel & 0xc000) >> 12) |
+ ((*src_pixel & 0xc0) >> 6);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
+ counter++, *dst_pixel);
+ #endif
+
+ src_pixel++;
+ dst_pixel++;
+ }
+
+ return 1;
+}
+
+static int Pack32To16(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned int *src_pixel = (unsigned int *) src_image -> data;
+ unsigned short *dst_pixel = (unsigned short *) dst_image -> data;
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, *src_pixel, (*src_pixel & 0xf80000),
+ (*src_pixel & 0xf800), (*src_pixel & 0xf8));
+ #endif
+
+ if (*src_pixel == 0x0)
+ {
+ *dst_pixel = 0x0;
+ }
+ else if (*src_pixel == 0xffffff)
+ {
+ *dst_pixel = 0xffff;
+ }
+ else
+ {
+ *dst_pixel = ((*src_pixel & 0xf80000) >> 9) |
+ ((*src_pixel & 0xf800) >> 6) |
+ ((*src_pixel & 0xf8) >> 3);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x].\n",
+ counter++, *dst_pixel);
+ #endif
+
+ src_pixel++;
+ dst_pixel++;
+ }
+
+ return 1;
+}
+
+static int Pack32To24(unsigned int src_data_size, XImage *src_image, XImage *dst_image)
+{
+ unsigned int *src_pixel = (unsigned int *) src_image -> data;
+ unsigned char *dst_pixel = (unsigned char *) dst_image -> data;
+
+ #ifdef DEBUG
+ unsigned int counter = 0;
+ #endif
+
+ while (src_pixel < ((unsigned int *) (src_image -> data + src_data_size)))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] value [0x%x] red [0x%x] green [0x%x] blue [0x%x].\n",
+ counter, *src_pixel, ((*src_pixel & 0xff0000) >> 16),
+ ((*src_pixel & 0x00ff00) >> 8), (*src_pixel & 0xff));
+ #endif
+
+ if (*src_pixel == 0x0)
+ {
+ dst_pixel[0] = dst_pixel[1] = dst_pixel[2] = 0x0;
+ }
+ else if (*src_pixel == 0xffffff)
+ {
+ dst_pixel[0] = dst_pixel[1] = dst_pixel[2] = 0xff;
+ }
+ else
+ {
+ dst_pixel[0] = (*src_pixel & 0xff0000) >> 16;
+ dst_pixel[1] = (*src_pixel & 0x00ff00) >> 8;
+ dst_pixel[2] = (*src_pixel & 0x0000ff);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PackImage: Pixel [%d] destination [0x%x], [0x%x], [0x%x].\n",
+ counter++, dst_pixel[0], dst_pixel[1], dst_pixel[2]);
+ #endif
+
+ src_pixel += 1;
+ dst_pixel += 3;
+ }
+
+ return 1;
+}
+
+int PackImage(unsigned int method, unsigned int src_data_size, XImage *src_image,
+ unsigned int dst_data_size, XImage *dst_image)
+{
+ unsigned int src_bits_per_pixel;
+ unsigned int dst_bits_per_pixel;
+
+ src_bits_per_pixel = src_image -> bits_per_pixel;
+ dst_bits_per_pixel = MethodBitsPerPixel(method);
+
+ #ifdef TEST
+ fprintf(stderr, "******PackImage: Source bits per pixel [%d], destination bits per pixel [%d].\n",
+ src_bits_per_pixel, dst_bits_per_pixel);
+
+ fprintf(stderr, "******PackImage: Source data size [%d], destination data size [%d].\n",
+ src_data_size, dst_data_size);
+ #endif
+
+ if (dst_bits_per_pixel >= src_bits_per_pixel)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PackImage: PANIC! Cannot pack image from [%d] to [%d] bytes per pixel.\n",
+ src_bits_per_pixel, dst_bits_per_pixel);
+ #endif
+
+ return 0;
+ }
+
+ switch (src_bits_per_pixel)
+ {
+ case 16:
+ {
+ switch (dst_bits_per_pixel)
+ {
+ case 8:
+ {
+ return Pack16To8(src_data_size, src_image, dst_image);
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+ }
+ case 24:
+ {
+ switch (dst_bits_per_pixel)
+ {
+ case 8:
+ {
+ return Pack24To8(src_data_size, src_image, dst_image);
+ }
+ case 16:
+ {
+ return Pack24To16(src_data_size, src_image, dst_image);
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+ }
+ case 32:
+ {
+ switch (dst_bits_per_pixel)
+ {
+ case 8:
+ {
+ return Pack32To8(src_data_size, src_image, dst_image);
+ }
+ case 16:
+ {
+ return Pack32To16(src_data_size, src_image, dst_image);
+ }
+ case 24:
+ {
+ return Pack32To24(src_data_size, src_image, dst_image);
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+}
+
+/*
+ * Replace the ffs() call that may be not
+ * present on some systems.
+ */
+
+int FindLSB(int word)
+{
+ int t = word;
+
+ int m = 1;
+ int i = 0;
+
+ for (; i < sizeof(word) << 3; i++, m <<= 1)
+ {
+ if (t & m)
+ {
+ return i + 1;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h
new file mode 100644
index 000000000..1b6fe6d99
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Mask.h
@@ -0,0 +1,48 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Mask_H
+#define Mask_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Xlib.h"
+
+extern int MaskImage(const ColorMask *mask, XImage *src_image, XImage *dst_image);
+
+extern int MaskInPlaceImage(const ColorMask *mask, XImage *image);
+
+extern int PackImage(unsigned int method, unsigned int src_data_size, XImage *src_image,
+ unsigned int dst_data_size, XImage *dst_image);
+
+int FindLSB(int word);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Mask_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Png.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Png.c
new file mode 100644
index 000000000..b235e095e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Png.c
@@ -0,0 +1,730 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nx-X11/Xutil.h>
+
+#include "Compext.h"
+
+#include "Mask.h"
+#include "Png.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+/*
+ * Selected ZLIB compression level.
+ */
+
+#define PNG_Z_LEVEL 4
+
+/*
+ * Local function prototypes.
+ */
+
+static void PrepareRowForPng(CARD8 *dst, int y, int count);
+static void PrepareRowForPng24(CARD8 *dst, int y, int count);
+static void PrepareRowForPng16(CARD8 *dst, int y, int count);
+static void PrepareRowForPng32(CARD8 *dst, int y, int count);
+
+static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length);
+static void PngFlushData(png_structp png_ptr);
+
+/*
+ * Image characteristics.
+ */
+
+static int bytesPerLine;
+static int byteOrder;
+
+static CARD8 bitsPerPixel;
+static CARD16 redMax, greenMax, blueMax;
+static CARD8 redShift, greenShift, blueShift;
+
+/*
+ * Other variables used for the Png
+ * encoding.
+ */
+
+png_byte color_type;
+png_structp png_ptr;
+png_infop info_ptr;
+png_colorp palette;
+static char *pngCompBuf;
+static int pngDataLen;
+static char *pngBeforeBuf = NULL;
+
+/*
+ * Allocate data for the compressed image.
+ * We need to ensure that there is enough
+ * space to include the palette and the
+ * header.
+ */
+
+#define PNG_DEST_SIZE(width, height) ((width) * 3 * (height) + 1024 + 256)
+
+/*
+ * Just for debug purposes.
+ */
+
+#ifdef DEBUG
+
+static int pngId;
+static char pngName[10];
+static FILE *pngFile;
+
+#endif
+
+int PngCompareColorTable(NXColorTable *c1, NXColorTable *c2)
+{
+ return (c1 -> pixel - c2 -> pixel);
+}
+
+#define NB_COLOR_MAX 256
+
+int NXCreatePalette32(XImage *src_image, NXColorTable *color_table, CARD8 *image_index, int nb_max)
+{
+ int x, y, t, p;
+ CARD8 *fbptr;
+ CARD32 pixel;
+
+ fbptr = (CARD8 *) (src_image -> data);
+
+ /*
+ * TODO: Find a more intelligent way to
+ * estimate the number of colors.
+ */
+
+ memset(color_table, 0, nb_max * sizeof(NXColorTable));
+
+ for (x = 0, p = 0; x < src_image -> height; x++)
+ {
+ for (y = 0; y < src_image -> width; y++)
+ {
+ if (byteOrder == LSBFirst)
+ {
+ pixel = (CARD32) *(fbptr + 3);
+ pixel = (pixel << 8) | (CARD32) *(fbptr + 2);
+ pixel = (pixel << 8) | (CARD32) *(fbptr + 1);
+ pixel = (pixel << 8) | (CARD32) *fbptr;
+ }
+ else
+ {
+ pixel = (CARD32) *fbptr;
+ pixel = (pixel << 8) | (CARD32) *(fbptr + 1);
+ pixel = (pixel << 8) | (CARD32) *(fbptr + 2);
+ pixel = (pixel << 8) | (CARD32) *(fbptr + 3);
+ }
+
+ fbptr += 4;
+
+ for (t = 0; t < nb_max; t++)
+ {
+ if (color_table[t].found == 0)
+ {
+ color_table[t].pixel = pixel;
+ color_table[t].found = 1;
+ p++;
+ image_index[((x * src_image -> width) + y)] = t;
+
+ break;
+ }
+ else if ((CARD32)(color_table[t].pixel) == pixel)
+ {
+ image_index[((x * src_image -> width) + y)] = t;
+
+ break;
+ }
+ }
+
+ if (p == nb_max)
+ {
+ return nb_max + 1;
+ }
+ }
+ }
+ return p;
+}
+
+int NXCreatePalette16(XImage *src_image, NXColorTable *color_table, CARD8 *image_index, int nb_max)
+{
+ int x, y, t, p;
+ CARD8 *fbptr;
+ CARD16 pixel;
+
+ fbptr = (CARD8 *) (src_image -> data);
+
+ /*
+ * TODO: Find a more intelligent way to
+ * estimate the number of colors.
+ */
+
+ memset(color_table, 0, nb_max * sizeof(NXColorTable));
+
+ for (x = 0, p = 0; x < src_image -> height; x++)
+ {
+ for (y = 0; y < src_image -> width; y++)
+ {
+ if (byteOrder == LSBFirst)
+ {
+ pixel = (CARD16) *(fbptr + 1);
+ pixel = (pixel << 8) | (CARD16) *fbptr;
+ }
+ else
+ {
+ pixel = (CARD16) *fbptr;
+ pixel = (pixel << 8) | (CARD16) *(fbptr + 1);
+ }
+
+ fbptr += 2;
+
+ for (t = 0; t < nb_max; t++)
+ {
+ if (color_table[t].found == 0)
+ {
+ color_table[t].pixel = pixel;
+ color_table[t].found = 1;
+ p++;
+ image_index[((x * src_image -> width) + y)] = t;
+
+ break;
+ }
+ else if ((color_table[t].pixel) == pixel)
+ {
+ image_index[((x * src_image -> width) + y)] = t;
+
+ break;
+ }
+ }
+
+ /*
+ * In case the number of 16bit words is not even
+ * we have 2 padding bytes that we have to skip.
+ */
+
+ if ((y == src_image -> width - 1) && (src_image -> width % 2 == 1)) fbptr += 2;
+
+ if (p == nb_max)
+ {
+ return nb_max + 1;
+ }
+ }
+ }
+
+ return p;
+}
+
+char *PngCompressData(XImage *image, int *compressed_size)
+{
+ unsigned int num = 0;
+ CARD8 *srcBuf;
+
+ int dy, w, h;
+
+ int nb_colors;
+
+ NXColorTable color_table[NB_COLOR_MAX];
+ CARD8 *image_index;
+
+ image_index = (CARD8 *) malloc((image -> height) * (image -> width) * sizeof(CARD8));
+
+ /*
+ * TODO: Be sure the padded bytes are cleaned.
+ * It would be better to set to zero the bytes
+ * that are not alligned to the word boundary
+ * at the end of the procedure.
+ */
+
+ memset(image_index, 0, (image -> height) * (image -> width) * sizeof(CARD8));
+
+ *compressed_size = 0;
+
+ pngDataLen = 0;
+
+ /*
+ * Initialize the image stuff.
+ */
+
+ bitsPerPixel = image -> bits_per_pixel;
+ bytesPerLine = image -> bytes_per_line;
+ byteOrder = image -> byte_order;
+
+ if (bitsPerPixel < 15)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Can't compress images with [%d] bits per pixel.\n",
+ bitsPerPixel);
+ #endif
+
+ return NULL;
+ }
+
+ redShift = FindLSB(image -> red_mask) - 1;
+ greenShift = FindLSB(image -> green_mask) - 1;
+ blueShift = FindLSB(image -> blue_mask) - 1;
+
+ redMax = image -> red_mask >> redShift;
+ greenMax = image -> green_mask >> greenShift;
+ blueMax = image -> blue_mask >> blueShift;
+
+ w = image -> width;
+ h = image -> height;
+ pngBeforeBuf = image -> data;
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressData: Compressing image with width [%d] height [%d].\n",
+ w, h );
+ #endif
+
+ /*
+ * Initialize the PNG stuff.
+ */
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+
+ if (png_ptr == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Failed creating the png_create_write_struct.\n");
+ #endif
+
+ return NULL;
+ }
+
+ info_ptr = png_create_info_struct(png_ptr);
+
+ if (info_ptr == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Failed creating the png_create_info_struct.\n");
+ #endif
+
+ png_destroy_write_struct(&png_ptr, NULL);
+
+ return NULL;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Error during compression initialization.\n");
+ #endif
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ return NULL;
+ }
+
+ /*
+ * Be sure we allocate enough data.
+ */
+
+ #ifdef TEST
+ fprintf(stderr, "******PngCompressData: Allocating [%d] bytes for the destination data.\n",
+ PNG_DEST_SIZE(w, h));
+ #endif
+
+ pngCompBuf = malloc(PNG_DEST_SIZE(w, h));
+
+ if (pngCompBuf == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Error allocating [%d] bytes for the Png data.\n",
+ PNG_DEST_SIZE(w, h));
+ #endif
+
+ return NULL;
+ }
+
+ png_set_write_fn(png_ptr, (void *) pngCompBuf, PngWriteData, PngFlushData);
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Error writing the header.\n");
+ #endif
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ free(pngCompBuf);
+
+ return NULL;
+ }
+
+ png_set_compression_level(png_ptr, PNG_Z_LEVEL);
+
+ if (bitsPerPixel == 16)
+ {
+ nb_colors = NXCreatePalette16(image, color_table, image_index, NB_COLOR_MAX);
+ }
+ else
+ {
+ nb_colors = NXCreatePalette32(image, color_table, image_index, NB_COLOR_MAX);
+ }
+
+ if (nb_colors <= NB_COLOR_MAX)
+ {
+ color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ else
+ {
+ color_type = PNG_COLOR_TYPE_RGB;
+ }
+
+ png_set_IHDR(png_ptr, info_ptr, w, h,
+ 8, color_type, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ palette = png_malloc(png_ptr, sizeof(*palette) * 256);
+
+ /*
+ * TODO: Do we need to clean these bytes?
+ *
+ * memset(palette, 0, sizeof(*palette) * 256);
+ */
+
+ for (num = 0; num < 256 && color_table[num].found != 0; num++)
+ {
+ if (bitsPerPixel == 24)
+ {
+ palette[num].red = (color_table[num].pixel >> redShift) & redMax;
+ palette[num].green = (color_table[num].pixel >> greenShift) & greenMax;
+ palette[num].blue = color_table[num].pixel >> blueShift & blueMax;
+ }
+ else
+ {
+ int inRed, inGreen, inBlue;
+
+ inRed = (color_table[num].pixel >> redShift) & redMax;
+ inGreen = (color_table[num].pixel >> greenShift) & greenMax;
+ inBlue = color_table[num].pixel >> blueShift & blueMax;
+
+ palette[num].red = (CARD8)((inRed * 255 + redMax / 2) / redMax);
+ palette[num].green = (CARD8)((inGreen * 255 + greenMax / 2) / greenMax);
+ palette[num].blue = (CARD8)((inBlue * 255 + blueMax / 2) / blueMax);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressData: pixel[%d] r[%d] g[%d] b[%d].\n",
+ (int) color_table[num].pixel,palette[num].red,palette[num].green,palette[num].blue);
+ #endif
+ }
+
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressedData: Setting palette.\n");
+ #endif
+ }
+
+ /*
+ * End of palette.
+ */
+
+ png_write_info(png_ptr, info_ptr);
+
+ /*
+ * Allocate space for one line of
+ * the image, 3 bytes per pixel.
+ */
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressedData: Initialization finished.\n");
+ #endif
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Error while writing the image rows.\n");
+ #endif
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ free(pngCompBuf);
+
+ return NULL;
+ }
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ srcBuf = (CARD8 *) malloc(w * sizeof(CARD8));
+
+ if (srcBuf == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Cannot allocate [%d] bytes.\n",
+ (int) (w * sizeof(CARD8)));
+ #endif
+
+ return NULL;
+ }
+
+ /*
+ * TODO: Be sure the padded bytes are cleaned.
+ * It would be better to set to zero the bytes
+ * that are not alligned to the word boundary
+ * at the end of the procedure.
+ */
+
+ memset(srcBuf, 0, w * sizeof(CARD8));
+ }
+ else
+ {
+ srcBuf = (CARD8 *) malloc(w * 3 * sizeof(CARD8));
+
+ /*
+ * TODO: See above.
+ */
+
+ memset(srcBuf, 0, w * 3 * sizeof(CARD8));
+ }
+
+ if (srcBuf == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! Cannot allocate [%d] bytes.\n",
+ w * 3);
+ #endif
+
+ free(pngCompBuf);
+
+ return NULL;
+ }
+
+ for (dy = 0; dy < h; dy++)
+ {
+ if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ PrepareRowForPng(srcBuf, dy, w);
+ }
+ else
+ {
+ memcpy(srcBuf, image_index + (dy * w), w);
+ }
+
+ png_write_row(png_ptr, srcBuf);
+ }
+
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressedData: Compression finished. Lines handled [%d,%d].\n",
+ dy, h);
+ #endif
+
+ free(srcBuf);
+ free(image_index);
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******PngCompressData: PANIC! error during end of write.\n");
+ #endif
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ free(pngCompBuf);
+
+ return NULL;
+ }
+
+ png_write_end(png_ptr, NULL);
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_free(png_ptr, palette);
+ }
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ /*
+ * Check the size of the resulting data.
+ */
+
+ if (pngDataLen > 0)
+ {
+ #ifdef DEBUG
+
+ int i = 0;
+
+ fprintf(stderr, "******PngCompressedData: Compressed size [%d].\n",
+ pngDataLen);
+
+ pngId++;
+ sprintf(pngName, "png%d", pngId);
+ pngFile = fopen(pngName, "w");
+
+ for (i = 0; i < pngDataLen; i++)
+ {
+ fprintf(pngFile, "%c", *(pngCompBuf + i));
+ }
+
+ fclose(pngFile);
+
+ #endif
+
+ *compressed_size = pngDataLen;
+
+ return pngCompBuf;
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "******PngCompressedData: PANIC! Invalid size of the compressed data [%d].\n",
+ pngDataLen);
+ #endif
+
+ free(pngCompBuf);
+
+ return NULL;
+ }
+}
+
+static void PngWriteData(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ memcpy(((char *) png_get_io_ptr(png_ptr) + pngDataLen), data, length);
+
+ pngDataLen += length;
+}
+
+static void PngFlushData(png_structp png_ptr)
+{
+}
+
+void PrepareRowForPng(CARD8 *dst, int y, int count)
+{
+ if (bitsPerPixel == 32)
+ {
+ if (redMax == 0xff &&
+ greenMax == 0xff &&
+ blueMax == 0xff)
+ {
+ PrepareRowForPng24(dst, y, count);
+ }
+ else
+ {
+ PrepareRowForPng32(dst, y, count);
+ }
+ }
+ else if (bitsPerPixel == 24)
+ {
+ memcpy(dst, pngBeforeBuf + y * bytesPerLine, count * 3);
+ }
+ else
+ {
+ /*
+ * 16 bpp assumed.
+ */
+
+ PrepareRowForPng16(dst, y, count);
+ }
+}
+
+
+
+void PrepareRowForPng24(CARD8 *dst, int y, int count)
+{
+ CARD8 *fbptr;
+ CARD32 pix;
+
+ fbptr = (CARD8 *) (pngBeforeBuf + y * bytesPerLine);
+
+ while (count--)
+ {
+ if (byteOrder == LSBFirst)
+ {
+ pix = (CARD32) *(fbptr + 2);
+ pix = (pix << 8) | (CARD32) *(fbptr+1);
+ pix = (pix << 8) | (CARD32) *fbptr;
+ }
+ else
+ {
+ pix = (CARD32) *(fbptr + 1);
+ pix = (pix << 8) | (CARD32) *(fbptr + 2);
+ pix = (pix << 8) | (CARD32) *(fbptr + 3);
+ }
+
+ *dst++ = (CARD8)(pix >> redShift);
+ *dst++ = (CARD8)(pix >> greenShift);
+ *dst++ = (CARD8)(pix >> blueShift);
+
+ fbptr+=4;
+ }
+}
+
+#define DEFINE_PNG_GET_ROW_FUNCTION(bpp) \
+ \
+void PrepareRowForPng##bpp(CARD8 *dst, int y, int count) \
+{ \
+ CARD8 *fbptr; \
+ CARD##bpp pix; \
+ int inRed, inGreen, inBlue; \
+ int i; \
+ \
+ fbptr = (CARD8 *) (pngBeforeBuf + y * bytesPerLine); \
+ \
+ while (count--) \
+ { \
+ pix = 0; \
+ \
+ if (byteOrder == LSBFirst) \
+ { \
+ for (i = (bpp >> 3) - 1; i >= 0; i--) \
+ { \
+ pix = (pix << 8) | (CARD32) *(fbptr + i); \
+ } \
+ } \
+ else \
+ { \
+ for (i = 0; i < (bpp >> 3); i++) \
+ { \
+ pix = (pix << 8) | (CARD32) *(fbptr + i); \
+ } \
+ } \
+ \
+ fbptr += (bpp >> 3); \
+ \
+ inRed = (int) \
+ (pix >> redShift & redMax); \
+ inGreen = (int) \
+ (pix >> greenShift & greenMax); \
+ inBlue = (int) \
+ (pix >> blueShift & blueMax); \
+ *dst++ = (CARD8)((inRed * 255 + redMax / 2) / \
+ redMax); \
+ *dst++ = (CARD8)((inGreen * 255 + greenMax / 2) / \
+ greenMax); \
+ *dst++ = (CARD8)((inBlue * 255 + blueMax / 2) / \
+ blueMax); \
+ } \
+}
+
+DEFINE_PNG_GET_ROW_FUNCTION(16)
+DEFINE_PNG_GET_ROW_FUNCTION(32)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Png.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Png.h
new file mode 100644
index 000000000..0e0621627
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Png.h
@@ -0,0 +1,76 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Png_H
+#define Png_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xlib.h>
+#include <nx-X11/Xmd.h>
+
+#include <png.h>
+
+extern int PngCompareColorTable(
+#if NeedFunctionPrototypes
+ NXColorTable* /* color_table_1 */,
+ NXColorTable* /* color_table_2 */
+#endif
+);
+
+extern char *PngCompressData(
+#if NeedFunctionPrototypes
+ XImage* /* image */,
+ int* /* compressed_size */
+#endif
+);
+
+int NXCreatePalette16(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ NXColorTable* /* color_table */,
+ CARD8* /* image_index */,
+ int /* nb_max */
+#endif
+);
+
+int NXCreatePalette32(
+#if NeedFunctionPrototypes
+ XImage* /* src_image */,
+ NXColorTable* /* color_table */,
+ CARD8* /* image_index */,
+ int /* nb_max */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Png_H */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c
new file mode 100644
index 000000000..fc53ded92
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.c
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <zlib.h>
+
+#include "Compext.h"
+
+#include "Rgb.h"
+#include "Z.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define RGB_COMPRESSION_LEVEL 4
+#define RGB_COMPRESSION_THRESHOLD 32
+#define RGB_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
+
+static int rgbCompressionLevel = RGB_COMPRESSION_LEVEL;
+static int rgbCompressionThreshold = RGB_COMPRESSION_THRESHOLD;
+static int rgbCompressionStrategy = RGB_COMPRESSION_STRATEGY;
+
+char *RgbCompressData(XImage *image, unsigned int *size)
+{
+ return ZCompressData(image -> data, image -> bytes_per_line * image -> height,
+ rgbCompressionThreshold, rgbCompressionLevel,
+ rgbCompressionStrategy, size);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h
new file mode 100644
index 000000000..fd53ffbf9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Rgb.h
@@ -0,0 +1,44 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Rgb_H
+#define Rgb_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *RgbCompressData(
+#if NeedFunctionPrototypes
+ XImage* /* image */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Rgb_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c
new file mode 100644
index 000000000..3f1da0de4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.c
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <zlib.h>
+
+#include "Compext.h"
+
+#include "Rle.h"
+#include "Z.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define RLE_COMPRESSION_LEVEL 1
+#define RLE_COMPRESSION_THRESHOLD 32
+#define RLE_COMPRESSION_STRATEGY Z_RLE
+
+static int rleCompressionLevel = RLE_COMPRESSION_LEVEL;
+static int rleCompressionThreshold = RLE_COMPRESSION_THRESHOLD;
+static int rleCompressionStrategy = RLE_COMPRESSION_STRATEGY;
+
+char *RleCompressData(XImage *image, unsigned int *size)
+{
+ return ZCompressData(image -> data, image -> bytes_per_line * image -> height,
+ rleCompressionThreshold, rleCompressionLevel,
+ rleCompressionStrategy, size);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h
new file mode 100644
index 000000000..a32812657
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Rle.h
@@ -0,0 +1,44 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Rle_H
+#define Rle_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *RleCompressData(
+#if NeedFunctionPrototypes
+ XImage* /* image */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Rle_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c
new file mode 100644
index 000000000..6ee08e236
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.c
@@ -0,0 +1,309 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <zlib.h>
+
+#include "Compext.h"
+
+#include "Z.h"
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define Z_COMPRESSION_LEVEL 4
+#define Z_COMPRESSION_THRESHOLD 32
+#define Z_COMPRESSION_STRATEGY Z_DEFAULT_STRATEGY
+
+static int zCompressionLevel = Z_COMPRESSION_LEVEL;
+static int zCompressionStrategy = Z_COMPRESSION_STRATEGY;
+
+static z_stream *zStream;
+
+static int zInitialized;
+
+static int ZConfigure(int level, int strategy);
+
+static int ZDeflate(char *dest, unsigned int *destLen,
+ const char *source, unsigned int sourceLen);
+
+char *ZCompressData(const char *plainData, unsigned int plainSize, int threshold,
+ int level, int strategy, unsigned int *compressedSize)
+{
+ char *compressedData;
+
+ /*
+ * Determine the size of the source image
+ * data and make sure there is enough
+ * space in the destination buffer.
+ */
+
+ *compressedSize = plainSize + (plainSize / 1000) + 12 + 1;
+
+ compressedData = Xmalloc(*compressedSize);
+
+ if (compressedData == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******ZCompressData: PANIC! Failed to allocate [%d] bytes for the destination.\n",
+ *compressedSize);
+ #endif
+
+ *compressedSize = 0;
+
+ return NULL;
+ }
+
+ if (level == Z_NO_COMPRESSION || plainSize < threshold)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******ZCompressData: Not compressing [%d] bytes with level [%d] and "
+ "threshold [%d].\n", plainSize, level, threshold);
+ #endif
+
+ /*
+ * Tell in the first byte of the buffer
+ * if the remaining data is compressed
+ * or not. This same byte can be used
+ * in future to store some other flag.
+ */
+
+ *compressedData = 0;
+
+ memcpy(compressedData + 1, plainData, plainSize);
+
+ *compressedSize = plainSize + 1;
+
+ return compressedData;
+ }
+ else
+ {
+ int result;
+
+ /*
+ * Reconfigure the stream if needed.
+ */
+
+ if (zCompressionLevel != level ||
+ zCompressionStrategy != strategy)
+ {
+ ZConfigure(level, strategy);
+
+ zCompressionLevel = level;
+ zCompressionStrategy = strategy;
+ }
+
+ result = ZDeflate(compressedData + 1, compressedSize, plainData, plainSize);
+
+ if (result != Z_OK)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******ZCompressData: PANIC! Failed to compress [%d] bytes with error [%s].\n",
+ plainSize, zError(result));
+ #endif
+
+ Xfree(compressedData);
+
+ *compressedSize = 0;
+
+ return NULL;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "******ZCompressData: Source data of [%d] bytes compressed to [%d].\n",
+ plainSize, *compressedSize);
+ #endif
+
+ *compressedData = 1;
+
+ *compressedSize = *compressedSize + 1;
+
+ return compressedData;
+ }
+}
+
+int ZConfigure(int level, int strategy)
+{
+ /*
+ * ZLIB wants the avail_out to be
+ * non zero, even if the stream was
+ * already flushed.
+ */
+
+ unsigned char dest[1];
+
+ zStream -> next_out = dest;
+ zStream -> avail_out = 1;
+
+ if (deflateParams(zStream, level, strategy) != Z_OK)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******ZConfigure: PANIC! Failed to set level to [%d] and strategy to [%d].\n",
+ level, strategy);
+ #endif
+
+ return -1;
+ }
+ #ifdef TEST
+ else
+ {
+ fprintf(stderr, "******ZConfigure: Reconfigured the stream with level [%d] and strategy [%d].\n",
+ level, strategy);
+ }
+ #endif
+
+ return 1;
+}
+
+int ZDeflate(char *dest, unsigned int *destLen, const char *source, unsigned int sourceLen)
+{
+ int saveOut;
+ int result;
+
+ /*
+ * Deal with the possible overflow.
+ */
+
+ if (zStream -> total_out & 0x80000000)
+ {
+ #ifdef TEST
+ fprintf(stderr, "******ZDeflate: Reset Z stream counters with total in [%ld] total out [%ld].\n",
+ zStream -> total_in, zStream -> total_out);
+ #endif
+
+ zStream -> total_in = 0;
+ zStream -> total_out = 0;
+ }
+
+ saveOut = zStream -> total_out;
+
+ zStream -> next_in = (Bytef *) source;
+ zStream -> avail_in = (uInt) sourceLen;
+
+ #ifdef MAXSEG_64K
+
+ /*
+ * Check if the source is greater
+ * than 64K on a 16-bit machine.
+ */
+
+ if ((uLong) zStream -> avail_in != sourceLen) return Z_BUF_ERROR;
+
+ #endif
+
+ zStream -> next_out = (unsigned char *) dest;
+ zStream -> avail_out = (uInt) *destLen;
+
+ if ((uLong) zStream -> avail_out != *destLen) return Z_BUF_ERROR;
+
+ result = deflate(zStream, Z_FINISH);
+
+ if (result != Z_STREAM_END)
+ {
+ deflateReset(zStream);
+
+ return (result == Z_OK ? Z_BUF_ERROR : result);
+ }
+
+ *destLen = zStream -> total_out - saveOut;
+
+ result = deflateReset(zStream);
+
+ return result;
+}
+
+int ZInitEncoder()
+{
+ if (zInitialized == 0)
+ {
+ int result;
+
+ zStream = Xmalloc(sizeof(z_stream));
+
+ if (zStream == NULL)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******ZInitEncoder: PANIC! Failed to allocate memory for the stream.\n");
+ #endif
+
+ return -1;
+ }
+
+ zStream -> zalloc = (alloc_func) 0;
+ zStream -> zfree = (free_func) 0;
+ zStream -> opaque = (voidpf) 0;
+
+ #ifdef TEST
+ fprintf(stderr, "******ZInitEncoder: Initializing compressor with level [%d] and startegy [%d].\n",
+ zCompressionLevel, zCompressionStrategy);
+ #endif
+
+ result = deflateInit2(zStream, zCompressionLevel, Z_DEFLATED,
+ 15, 9, zCompressionStrategy);
+
+ if (result != Z_OK)
+ {
+ #ifdef PANIC
+ fprintf(stderr, "******ZInitEncoder: Failed to initialize the compressor with error [%s].\n",
+ zError(result));
+ #endif
+
+ return -1;
+ }
+
+ zInitialized = 1;
+ }
+
+ return zInitialized;
+}
+
+int ZResetEncoder()
+{
+ int result;
+
+ if (zInitialized == 1)
+ {
+ result = deflateEnd(zStream);
+
+ if (result != Z_OK)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "******ZResetEncoder: WARNING! Failed to deinitialize the compressor with error [%s].\n",
+ zError(result));
+ #endif
+ }
+
+ Xfree(zStream);
+ }
+
+ zInitialized = 0;
+
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/compext/Z.h b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.h
new file mode 100644
index 000000000..8133f0c73
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/compext/Z.h
@@ -0,0 +1,60 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMPEXT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifndef Z_H
+#define Z_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ZInitEncoder(
+#if NeedFunctionPrototypes
+void
+#endif
+);
+
+int ZResetEncoder(
+#if NeedFunctionPrototypes
+void
+#endif
+);
+
+extern char *ZCompressData(
+#if NeedFunctionPrototypes
+ const char* /* data */,
+ unsigned int /* size */,
+ int /* threshold */,
+ int /* level */,
+ int /* strategy */,
+ unsigned int* /* compressed_size */
+#endif
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Z_H */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
new file mode 100644
index 000000000..1abec5753
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1
@@ -0,0 +1,1050 @@
+
+.\" Copyright 1984 - 1991, 1993, 1994, 1998 The Open Group
+.\" Copyright 2011 - 2016, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+.\"
+.\" 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.
+.ds q \N'34'
+.TH nxagent 1 "April 2017" "Version 3.6.x" "NX Agent (Xserver)"
+.SH NAME
+nxagent \- nested Xserver optimized for remote computing
+.SH SYNOPSIS
+.B nxagent
+.I "[options]"
+.SH DESCRIPTION
+\fBnxagent\fR is an X server for remote application/desktop access
+similar to Xnest or Xephyr.
+.PP
+\fBnxagent\fR implements a very efficient compression of the X11
+protocol, called the NX protocol.
+.PP
+The NX protocol increases performance when using X applications over high
+latency and low bandwidth networks, while providing a local (LAN-like)
+usage experience even if connecting from off-site locations (via cable
+modem or GSM).
+.PP
+\fBnxagent\fR can be used standalone as a nested X server (with NX
+protocol disabled), but its real benefits are gained when using it over
+remote connections via the nxcomp compression library. The counterpart
+application on the other end (i.e. the client) is called
+\fBnxproxy\fR.
+.PP
+When used in proxy <-> agent mode, \fBnxagent\fR adds the feature of
+being suspendible. Sessions can be started from one client, suspended and
+then resumed from another (or the same) client.
+.PP
+\fBnxagent\fR and \fBnxproxy\fR are utilized by various remote
+application/desktop frameworks for providing server-side GUI application
+access from remote client systems.
+.PP
+Currently, \fBnxagent\fR is co-maintained by three of these projects: The
+Arctica Project, TheQVD and X2Go.
+.PP
+
+.SH "STARTING THE SERVER"
+\fBnxagent\fR should be run in user space. Other than the system's
+local X.org server, \fBnxagent\fR does not require to be run as root.
+When bundled with a remote application framework, you normally don't have
+to launch \fBnxagent\fR manually. \fBnxagent\fR startup is usually
+managed by the underlying framework (e.g. Arctica Session Manager, X2Go
+Server, etc.).
+.PP
+When \fBnxagent\fR starts up (e.g. by typing 'nxagent -ac :1' in a
+terminal window), it typically launches in "windowed desktop" mode. On
+your local X server a new window appears being an X server itself.
+.PP
+However, \fBnxagent\fR also supports rootless (or seamless) application
+mode and a shadow session mode (similar to what VNC does).
+.PP
+Example: You can launch a complete desktop session inside this nested X
+server now:
+.TP 8
+The Debian way...
+.PP
+.nf
+ $ export DISPLAY=:1
+ $ STARTUP=mate-session /etc/X11/Xsession
+.fi
+.TP 8
+The Fedora / Gentoo / openSUSE way...
+.PP
+.nf
+ ### FIXME / TODO ###
+.fi
+.PP
+However, \fBnxagent\fR also supports rootless (or seamless) application
+mode and a shadow session mode (similar to what VNC does).
+
+.SH OPTIONS
+\fBnxagent\fR accepts a range of default X server options as described
+below. Those default options have to be provided via the command line.
+
+Furthermore, \fBnxagent\fR accepts some nx-X11 specific options,
+described further below.
+
+Last but not least, \fBnxagent\fR accepts several more options, the
+so-called nx/nx options, provided via the $DISPLAY environment
+variable or the -options command line option. See below for further
+details.
+
+.SH STANDARD XSERVER OPTIONS
+.TP 8
+.B :\fIdisplaynumber\fP
+The X server runs as the given \fIdisplaynumber\fP, which by default is 0.
+If multiple X servers are to run simultaneously on a host, each must have
+a unique display number. See the DISPLAY
+NAMES section of the \fIX\fP(__miscmansuffix__) manual page to learn how to
+specify which display number clients should try to use.
+.TP 8
+.B \-a \fInumber\fP
+sets pointer acceleration (i.e. the ratio of how much is reported to how much
+the user actually moved the pointer).
+.TP 8
+.B \-ac
+disables host-based access control mechanisms. Enables access by any host,
+and permits any host to modify the access control list.
+Use with extreme caution.
+This option exists primarily for running test suites remotely.
+.TP 8
+.B \-audit \fIlevel\fP
+sets the audit trail level. The default level is 1, meaning only connection
+rejections are reported. Level 2 additionally reports all successful
+connections and disconnects. Level 4 enables messages from the
+SECURITY extension, if present, including generation and revocation of
+authorizations and violations of the security policy.
+Level 0 turns off the audit trail.
+Audit lines are sent as standard error output.
+.TP 8
+.B \-auth \fIauthorization-file\fP
+specifies a file which contains a collection of authorization records used
+to authenticate access. See also the \fIxdm\fP(1) and
+\fIXsecurity\fP(__miscmansuffix__) manual pages.
+.TP 8
+.B bc
+disables certain kinds of error checking, for bug compatibility with
+previous releases (e.g., to work around bugs in R2 and R3 xterms and toolkits).
+Deprecated.
+.TP 8
+.B \-bs
+disables backing store support on all screens.
+.TP 8
+.B \-br
+sets the default root window to solid black instead of the standard root weave
+pattern.
+.TP 8
+.B \-c
+turns off key-click.
+.TP 8
+.B c \fIvolume\fP
+sets key-click volume (allowable range: 0-100).
+.TP 8
+.B \-cc \fIclass\fP
+sets the visual class for the root window of color screens.
+The class numbers are as specified in the X protocol.
+Not obeyed by all servers.
+.ig
+.TP 8
+.B \-config \fIfilename\fP
+reads more options from the given file. Options in the file may be separated
+by newlines if desired. If a '#' character appears on a line, all characters
+between it and the next newline are ignored, providing a simple commenting
+facility. The \fB\-config\fP option itself may appear in the file.
+.BR NOTE :
+This option is disabled when the Xserver is run with an effective uid
+different from the user's real uid.
+..
+.TP 8
+.B \-core
+causes the server to generate a core dump on fatal errors.
+.TP 8
+.B \-displayfd \fIfd\fP
+specifies a file descriptor in the launching process. Rather than specifying
+a display number, the X server will attempt to listen on successively higher
+display numbers, and upon finding a free one, will write the port number back
+on this file descriptor as a newline-terminated string. The \fB\-pn\fR option is
+ignored when using \fB\-displayfd\fR.
+
+nxagent specific:
+
+(1) Other than in X.org's Xserver, you can use \fB\-displayfd\fR in
+conjunction with an explicit display number. If the explicit display number
+is not available (i.e., already in use), nxagent tries to figure out the next
+available display number,
+
+e.g.:
+
+ \fBnxagent\fR \fI\-displayfd 2 :50\fR
+
+(2) If -displayfd <X> is given with <X> equaling 2 (STDERR), then the
+display number string written to STDERR is beautified with some human-readable
+(machine-parseable) text.
+.TP 8
+.B \-deferglyphs \fIwhichfonts\fP
+specifies the types of fonts for which the server should attempt to use
+deferred glyph loading. \fIwhichfonts\fP can be all (all fonts),
+none (no fonts), or 16 (16 bit fonts only).
+.TP 8
+.B \-dpi \fIresolution\fP
+sets the resolution for all screens, in dots per inch.
+To be used when the server cannot determine the screen size(s) from the
+hardware.
+.TP 8
+.B dpms
+enables DPMS (display power management services), where supported. The
+default state is platform and configuration specific.
+.TP 8
+.B \-dpms
+disables DPMS (display power management services). The default state
+is platform and configuration specific.
+.TP 8
+.B \-f \fIvolume\fP
+sets feep (bell) volume (allowable range: 0-100).
+.TP 8
+.B \-fc \fIcursorFont\fP
+sets default cursor font.
+.TP 8
+.B \-fn \fIfont\fP
+sets the default font.
+.TP 8
+.B \-fp \fIfontPath\fP
+sets the search path for fonts. This path is a comma separated list
+of directories which the X server searches for font databases.
+See the FONTS section of this manual page for more information and the default
+list.
+.TP 8
+.B \-help
+prints a usage message.
+.TP 8
+.B \-I
+causes all remaining command line arguments to be ignored.
+.TP 8
+.B \-maxbigreqsize \fIsize\fP
+sets the maximum big request to
+.I size
+MB.
+.TP 8
+.B \-nolisten \fItrans-type\fP
+disables a transport type. For example, TCP/IP connections can be disabled
+with
+.BR "\-nolisten tcp" .
+This option may be issued multiple times to disable listening to different
+transport types.
+.TP 8
+.B \-noreset
+prevents a server reset when the last client connection is closed. This
+overrides a previous
+.B \-terminate
+command line option.
+.TP 8
+.B \-p \fIminutes\fP
+sets screen-saver pattern cycle time in minutes.
+.TP 8
+.B \-pn
+permits the server to continue running if it fails to establish all of
+its well-known sockets (connection points for clients), but
+establishes at least one. This option is set by default.
+.TP 8
+.B \-nopn
+causes the server to exit if it fails to establish all of its well-known
+sockets (connection points for clients).
+.TP 8
+.B \-r
+turns off auto-repeat.
+.TP 8
+.B r
+turns on auto-repeat.
+.TP 8
+.B \-s \fIminutes\fP
+sets screen-saver timeout time in minutes.
+.TP 8
+.B \-su
+disables save under support on all screens.
+.TP 8
+.B \-t \fInumber\fP
+sets pointer acceleration threshold in pixels (i.e. after how many pixels
+pointer acceleration should take effect).
+.TP 8
+.B \-terminate
+causes the server to terminate at server reset, instead of continuing to run.
+This overrides a previous
+.B \-noreset
+command line option.
+.TP 8
+.B \-to \fIseconds\fP
+sets default connection timeout in seconds.
+.TP 8
+.B \-tst
+disables all testing extensions.
+.TP 8
+.B tty\fIxx\fP
+ignored, for servers started the ancient way (from init).
+.TP 8
+.B v
+sets video-off screen-saver preference.
+.TP 8
+.B \-v
+sets video-on screen-saver preference.
+.TP 8
+.B \-wm
+forces the default backing-store of all windows to be WhenMapped. This
+is a backdoor way of getting backing-store to apply to all windows.
+Although all mapped windows will have backing store, the backing store
+attribute value reported by the server for a window will be the last
+value established by a client. If it has never been set by a client,
+the server will report the default value, NotUseful. This behavior is
+required by the X protocol, which allows the server to exceed the
+client's backing store expectations but does not provide a way to tell
+the client that it is doing so.
+.TP 8
+.B [+-]xinerama
+enables(+) or disables(-) XINERAMA provided via the PanoramiX extension. This is
+set to off by default.
+.TP 8
+.B [+-]rrxinerama
+enables(+) or disables(-) XINERAMA provided via the RandR extension. By
+default, this feature is enabled. To disable XINERAMA completely, make
+sure to use both options (-xinerama -rrxinerama) on the command line.
+
+.SH SERVER DEPENDENT OPTIONS
+\fBnxagent\fR additionally accepts the following non-standard options:
+.TP 8
+.B \-logo
+turns on the X Window System logo display in the screen-saver.
+There is currently no way to change this from a client.
+.TP 8
+.B nologo
+turns off the X Window System logo display in the screen-saver.
+There is currently no way to change this from a client.
+.TP 8
+.B \-render
+
+.BR default | mono | gray | color
+
+sets the color allocation policy that will be used by the render extension.
+.RS 8
+.TP 8
+.I default
+selects the default policy defined for the display depth of the X
+server.
+.TP 8
+.I mono
+don't use any color cell.
+.TP 8
+.I gray
+use a gray map of 13 color cells for the X render extension.
+.TP 8
+.I color
+use a color cube of at most 4*4*4 colors (that is 64 color cells).
+.RE
+.TP 8
+.B \-dumbSched
+disables smart scheduling on platforms that support the smart scheduler.
+.TP
+.B \-schedInterval \fIinterval\fP
+sets the smart scheduler's scheduling interval to
+.I interval
+milliseconds.
+.SH NXAGENT SPECIFIC OPTIONS
+The nx-X11 system adds the following command line arguments:
+.TP 8
+.B \-forcenx
+force use of NX protocol messages assuming communication through nxproxy
+.TP 8
+.B \-timeout \fIint\fP
+auto-disconnect timeout in seconds (minimum allowed: 60)
+.TP 8
+.B \-norootlessexit
+don't exit if there are no clients in rootless mode
+.TP 8
+.B \-norender
+disable the use of the render extension
+.TP 8
+.B \-nocomposite
+disable the use of the composite extension
+.TP 8
+.B \-nopersistent
+disable disconnection/reconnection to the X display on SIGHUP
+.TP 8
+.B \-noshmem
+disable use of shared memory extension
+.TP 8
+.B \-shmem
+enable use of shared memory extension
+.TP 8
+.B \-noshpix
+disable use of shared pixmaps
+.TP 8
+.B \-shpix
+enable use of shared pixmaps
+.TP 8
+.B \-noignore
+don't ignore pointer and keyboard configuration changes mandated by clients
+.TP 8
+.B \-nokbreset
+don't reset keyboard device if the session is resumed
+.TP 8
+.B \-noxkblock
+always allow applications to change layout through XKEYBOARD
+.TP 8
+.B \-tile WxH
+size of image tiles (minimum allowed: 32x32)
+.TP 8
+.B \-D
+enable desktop mode (default)
+.TP 8
+.B \-R
+enable rootless mode
+.TP 8
+.B \-S
+enable shadow mode
+.TP 8
+.B \-B
+enable proxy binding mode
+.TP 8
+.B \-options \fIfilename\fP
+path to an options file containing nx/nx options (see below).
+.PP
+Other than the command line options, \fBnxagent\fR can be configured at
+session startup and at runtime (i.e. when resuming a suspended session)
+by so-called nx/nx options.
+.PP
+As nx/nx options all options supported by nxcomp (see \fBnxproxy\fR man
+page) and all \fBnxagent\fR nx/nx options (see below) can be used.
+.
+When launching an nxcomp based \fBnxagent\fR session (i.e. proxy <->
+agent), you will normally set the $DISPLAY variable like this:
+.PP
+.nf
+ $ export DISPLAY=nx/nx,listen=<proxy-port>,options=<options.file>:<nx-display-port>
+ $ nxagent <cmdline-options> :<nx-display-port>
+.fi
+.PP
+The value for <nx-display-port> is some value of a not-yet-used X11
+display (e.g. :50).
+.PP
+Using an options file is recommended, but you can also put available
+nx/nx options (see below) into the DISPLAY variable directly. Note, that
+the $DISPLAY variable field is of limited length.
+.PP
+As <proxy-port> you can pick an arbitrary (unused) TCP port or Unix
+socket file path. This is the port / socket that you have to connect to
+with the \fBnxproxy\fR application.
+.PP
+Available \fBnxagent\fR options (as an addition to nx/nx options supported
+by nxcomp already):
+.TP 8
+.B options=<string>
+read options from file, this text file can contain a single loooong line with comma-separated nx/nx options
+.TP 8
+.B rootless=<bool>
+start \fBnxagent\fR in rootless mode, matches \-R given on the command line, no-op when resuming (default: false)
+.TP 8
+.B geometry=<string>
+desktop geometry when starting or resuming a session, no-op in rootless mode (default 66% of the underlying X server geometry)
+.TP 8
+.B resize=<bool>
+set resizing support (default: true)
+.TP 8
+.B fullscreen=<bool>
+start or resume a session in fullscreen mode (default: off)
+.TP 8
+.B keyboard=<string>
+set remote keyboard layout
+.TP 8
+.B clipboard=<string>
+
+.BR both | client | server | none
+
+enable / disable (set to: \fInone\fR) clipboard support, uni-directional (\fIserver\fR or \fIclient\fR) or bi-directional (\fIboth\fR, default setting) support
+.TP 8
+.B streaming=<int>
+streaming support for images, not fully implemented yet and thus non-functional
+.TP 8
+.B backingstore=<int>
+disable or enforce backing store support (default: BackingStoreUndefined)
+.TP 8
+.B composite=<int>
+enable or disable Compsite support in \fBnxagent\fR (default: enabled)
+.TP 8
+.B xinerama=<int>
+enable or disable XINERAMA support in \fBnxagent\fR (default: enabled)
+.TP 8
+.B shmem=<bool>
+enable using shared memory
+.TP 8
+.B shpix=<bool>
+enable shared pixmaps support
+.TP 8
+.B kbtype=<string>
+set remote keyboard type
+.TP 8
+.B client=<string>
+type of connecting operating system (supported: \fIlinux\fR, \fIwindows\fR, \fIsolaris\fR and \fImacosx\fR)
+.TP 8
+.B shadow=<int>
+start \fBnxagent\fR in shadow mode, matches \-S given on the command line, no-op when resuming (default: false)
+.TP 8
+.B shadowuid=<int>
+unique identifier for the shadow session
+.TP 8
+.B shadowmode=<string>
+full access (set to \fI1\fR) or viewing-only (set to \fI0\fR, default)
+.TP 8
+.B defer=<int>
+defer image updates (enabled for all connection types except LAN), accepts values \fI0\fR, \fI1\fR and \fI2\fR
+
+The default value can be set via the cmd line (\-defer). The value
+provided as nx/nx option is set when resuming a session, thus it
+overrides the cmd line default.
+.TP 8
+.B tile=<string>
+set the tile size in pixels (\fI<W>x<H>\fR) for bitmap data sent over the wire
+
+The default value can be set via the cmd line (\-tile). The value
+provided as nx/nx option is set when resuming a session, thus it
+overrides the cmd line default.
+.TP 8
+.B menu=<int>
+support pulldown menu in \fBnxagent\fR session (only available on proxy <-> agent remote sessions)
+.TP 8
+.B sleep=<int>
+delay X server operations when suspended (provided in msec), set to \fI0\fR to keep \fBnxagent\fR session
+fully functional when suspended (e.g. useful when mirroring an \fBnxagent\fR session via VNC)
+.TP 8
+.B tolerancechecks=<string>
+
+.BR strict|safe|risky|bypass
+.RS 8
+.TP 8
+.I strict
+means that the number of internal and external pixmap formats must
+match exactly and every internal pixmap format must be available in the
+external pixmap format array. This is the default.
+.TP 8
+.I safe
+means that the number of pixmap formats might diverge, but all
+internal pixmap formats must also be included in the external pixmap
+formats array. This is recommended, because it allows clients with more
+pixmap formats to still connect, but not lose functionality.
+.TP 8
+.I risky
+means that the internal pixmap formats array is allowed to be
+smaller than the external pixmap formats array, but at least one pixmap
+format must be included in both. This is potentially unsafe.
+.TP 8
+.I bypass
+means that all of these checks are essentially
+deactivated. This is a very bad idea.
+.RE
+
+If you want to use \fBnxagent\fR as a replacement for Xnest or Xephyr you
+can pass options like this:
+.PP
+.nf
+ $ echo nx/nx,fullscreen=1$DISPLAY >/tmp/opt
+ $ nxagent <cmdline-options> -options /tmp/opt :<nx-display-port>
+.fi
+
+.SH XDMCP OPTIONS
+X servers that support XDMCP have the following options.
+See the \fIX Display Manager Control Protocol\fP specification for more
+information.
+.TP 8
+.B \-query \fIhostname\fP
+enables XDMCP and sends Query packets to the specified
+.IR hostname .
+.TP 8
+.B \-broadcast
+enable XDMCP and broadcasts BroadcastQuery packets to the network. The
+first responding display manager will be chosen for the session.
+.TP 8
+.B \-multicast [\fIaddress\fP [\fIhop count\fP]]
+Enable XDMCP and multicast BroadcastQuery packets to the network.
+The first responding display manager is chosen for the session. If an
+address is specified, the multicast is sent to that address. If no
+address is specified, the multicast is sent to the default XDMCP IPv6
+multicast group. If a hop count is specified, it is used as the maximum
+hop count for the multicast. If no hop count is specified, the multicast
+is set to a maximum of 1 hop, to prevent the multicast from being routed
+beyond the local network.
+.TP 8
+.B \-indirect \fIhostname\fP
+enables XDMCP and send IndirectQuery packets to the specified
+.IR hostname .
+.TP 8
+.B \-port \fIport-number\fP
+uses the specified \fIport-number\fP for XDMCP packets, instead of the
+default. This option must be specified before any \-query, \-broadcast,
+\-multicast, or \-indirect options.
+.TP 8
+.B \-from \fIlocal-address\fP
+specifies the local address to connect from (useful if the connecting host
+has multiple network interfaces). The \fIlocal-address\fP may be expressed
+in any form acceptable to the host platform's \fIgethostbyname\fP(3)
+implementation.
+.TP 8
+.B \-once
+causes the server to terminate (rather than reset) when the XDMCP session
+ends.
+.TP 8
+.B \-class \fIdisplay-class\fP
+XDMCP has an additional display qualifier used in resource lookup for
+display-specific options. This option sets that value, by default it
+is "MIT-Unspecified" (not a very useful value).
+.TP 8
+.B \-cookie \fIxdm-auth-bits\fP
+When testing XDM-AUTHENTICATION-1, a private key is shared between the
+server and the manager. This option sets the value of that private
+data (not that it is very private, being on the command line!).
+.TP 8
+.B \-displayID \fIdisplay-id\fP
+Yet another XDMCP specific value, this one allows the display manager to
+identify each display so that it can locate the shared key.
+
+.SH XKEYBOARD OPTIONS
+X servers that support the XKEYBOARD (a.k.a. \*qXKB\*q) extension accept the
+following options. All layout files specified on the command line must be
+located in the XKB base directory or a subdirectory, and specified as the
+relative path from the XKB base directory. The default XKB base directory is
+.IR /usr/share/X11/xkb .
+.TP 8
+.B [+-]kb
+enables(+) or disables(-) the XKEYBOARD extension.
+.TP 8
+.BR [+-]accessx " [ \fItimeout\fP [ \fItimeout_mask\fP [ \fIfeedback\fP [ \fIoptions_mask\fP ] ] ] ]"
+enables(+) or disables(-) AccessX key sequences.
+.TP 8
+.B \-xkbdir \fIdirectory\fP
+base directory for keyboard layout files. This option is not available
+for setuid X servers (i.e., when the X server's real and effective uids
+are different).
+.TP 8
+.B \-ar1 \fImilliseconds\fP
+sets the autorepeat delay (length of time in milliseconds that a key must
+be depressed before autorepeat starts).
+.TP 8
+.B \-ar2 \fImilliseconds\fP
+sets the autorepeat interval (length of time in milliseconds that should
+elapse between autorepeat-generated keystrokes).
+.TP 8
+.B \-noloadxkb
+disables loading of an XKB keymap description on server startup.
+.TP 8
+.B \-xkbdb \fIfilename\fP
+uses \fIfilename\fP for default keyboard keymaps.
+.TP 8
+.B \-xkbmap \fIfilename\fP
+loads keyboard description in \fIfilename\fP on server startup.
+
+.SH SECURITY EXTENSION OPTIONS
+X servers that support the SECURITY extension accept the following option:
+.TP 8
+.B \-sp \fIfilename\fP
+causes the server to attempt to read and interpret filename as a security
+policy file with the format described below. The file is read at server
+startup and reread at each server reset.
+.PP
+The syntax of the security policy file is as follows.
+Notation: "*" means zero or more occurrences of the preceding element,
+and "+" means one or more occurrences. To interpret <foo/bar>, ignore
+the text after the /; it is used to distinguish between instances of
+<foo> in the next section.
+.PP
+.nf
+<policy file> ::= <version line> <other line>*
+
+<version line> ::= <string/v> '\en'
+
+<other line > ::= <comment> | <access rule> | <site policy> | <blank line>
+
+<comment> ::= # <not newline>* '\en'
+
+<blank line> ::= <space> '\en'
+
+<site policy> ::= sitepolicy <string/sp> '\en'
+
+<access rule> ::= property <property/ar> <window> <perms> '\en'
+
+<property> ::= <string>
+
+<window> ::= any | root | <required property>
+
+<required property> ::= <property/rp> | <property with value>
+
+<property with value> ::= <property/rpv> = <string/rv>
+
+<perms> ::= [ <operation> | <action> | <space> ]*
+
+<operation> ::= r | w | d
+
+<action> ::= a | i | e
+
+<string> ::= <dbl quoted string> | <single quoted string> | <unqouted string>
+
+<dbl quoted string> ::= <space> " <not dqoute>* " <space>
+
+<single quoted string> ::= <space> ' <not squote>* ' <space>
+
+<unquoted string> ::= <space> <not space>+ <space>
+
+<space> ::= [ ' ' | '\et' ]*
+
+Character sets:
+
+<not newline> ::= any character except '\en'
+<not dqoute> ::= any character except "
+<not squote> ::= any character except '
+<not space> ::= any character except those in <space>
+.fi
+.PP
+The semantics associated with the above syntax are as follows.
+.PP
+<version line>, the first line in the file, specifies the file format
+version. If the server does not recognize the version <string/v>, it
+ignores the rest of the file. The version string for the file format
+described here is "version-1" .
+.PP
+Once past the <version line>, lines that do not match the above syntax
+are ignored.
+.PP
+<comment> lines are ignored.
+.PP
+<sitepolicy> lines are currently ignored. They are intended to
+specify the site policies used by the XC-QUERY-SECURITY-1
+authorization method.
+.PP
+<access rule> lines specify how the server should react to untrusted
+client requests that affect the X Window property named <property/ar>.
+The rest of this section describes the interpretation of an
+<access rule>.
+.PP
+For an <access rule> to apply to a given instance of <property/ar>,
+<property/ar> must be on a window that is in the set of windows
+specified by <window>. If <window> is any, the rule applies to
+<property/ar> on any window. If <window> is root, the rule applies to
+<property/ar> only on root windows.
+.PP
+If <window> is <required property>, the following apply. If <required
+property> is a <property/rp>, the rule applies when the window also
+has that <property/rp>, regardless of its value. If <required
+property> is a <property with value>, <property/rpv> must also have
+the value specified by <string/rv>. In this case, the property must
+have type STRING and format 8, and should contain one or more
+null-terminated strings. If any of the strings match <string/rv>, the
+rule applies.
+.PP
+The definition of string matching is simple case-sensitive string
+comparison with one elaboration: the occurrence of the character '*' in
+<string/rv> is a wildcard meaning "any string." A <string/rv> can
+contain multiple wildcards anywhere in the string. For example, "x*"
+matches strings that begin with x, "*x" matches strings that end with
+x, "*x*" matches strings containing x, and "x*y*" matches strings that
+start with x and subsequently contain y.
+.PP
+There may be multiple <access rule> lines for a given <property/ar>.
+The rules are tested in the order that they appear in the file. The
+first rule that applies is used.
+.PP
+<perms> specify operations that untrusted clients may attempt, and
+the actions that the server should take in response to those operations.
+.PP
+<operation> can be r (read), w (write), or d (delete). The following
+table shows how X Protocol property requests map to these operations
+in The Open Group server implementation.
+.PP
+.nf
+GetProperty r, or r and d if delete = True
+ChangeProperty w
+RotateProperties r and w
+DeleteProperty d
+ListProperties none, untrusted clients can always list all properties
+.fi
+.PP
+<action> can be a (allow), i (ignore), or e (error). Allow means
+execute the request as if it had been issued by a trusted client.
+Ignore means treat the request as a no-op. In the case of
+GetProperty, ignore means return an empty property value if the
+property exists, regardless of its actual value. Error means do not
+execute the request and return a BadAtom error with the atom set to
+the property name. Error is the default action for all properties,
+including those not listed in the security policy file.
+.PP
+An <action> applies to all <operation>s that follow it, until the next
+<action> is encountered. Thus, irwad means ignore read and write,
+allow delete.
+.PP
+GetProperty and RotateProperties may do multiple operations (r and d,
+or r and w). If different actions apply to the operations, the most
+severe action is applied to the whole request; there is no partial
+request execution. The severity ordering is: allow < ignore < error.
+Thus, if the <perms> for a property are ired (ignore read, error
+delete), and an untrusted client attempts GetProperty on that property
+with delete = True, an error is returned, but the property value is
+not. Similarly, if any of the properties in a RotateProperties do not
+allow both read and write, an error is returned without changing any
+property values.
+.PP
+Here is an example security policy file.
+.PP
+.ta 3i 4i
+.nf
+version-1
+
+# Allow reading of application resources, but not writing.
+property RESOURCE_MANAGER root ar iw
+property SCREEN_RESOURCES root ar iw
+
+# Ignore attempts to use cut buffers. Giving errors causes apps to crash,
+# and allowing access may give away too much information.
+property CUT_BUFFER0 root irw
+property CUT_BUFFER1 root irw
+property CUT_BUFFER2 root irw
+property CUT_BUFFER3 root irw
+property CUT_BUFFER4 root irw
+property CUT_BUFFER5 root irw
+property CUT_BUFFER6 root irw
+property CUT_BUFFER7 root irw
+
+# If you are using Motif, you probably want these.
+property _MOTIF_DEFAULT_BINDINGS root ar iw
+property _MOTIF_DRAG_WINDOW root ar iw
+property _MOTIF_DRAG_TARGETS any ar iw
+property _MOTIF_DRAG_ATOMS any ar iw
+property _MOTIF_DRAG_ATOM_PAIRS any ar iw
+
+# The next two rules let xwininfo -tree work when untrusted.
+property WM_NAME any ar
+
+# Allow read of WM_CLASS, but only for windows with WM_NAME.
+# This might be more restrictive than necessary, but demonstrates
+# the <required property> facility, and is also an attempt to
+# say "top level windows only."
+property WM_CLASS WM_NAME ar
+
+# These next three let xlsclients work untrusted. Think carefully
+# before including these; giving away the client machine name and command
+# may be exposing too much.
+property WM_STATE WM_NAME ar
+property WM_CLIENT_MACHINE WM_NAME ar
+property WM_COMMAND WM_NAME ar
+
+# To let untrusted clients use the standard colormaps created by
+# xstdcmap, include these lines.
+property RGB_DEFAULT_MAP root ar
+property RGB_BEST_MAP root ar
+property RGB_RED_MAP root ar
+property RGB_GREEN_MAP root ar
+property RGB_BLUE_MAP root ar
+property RGB_GRAY_MAP root ar
+
+# To let untrusted clients use the color management database created
+# by xcmsdb, include these lines.
+property XDCCC_LINEAR_RGB_CORRECTION root ar
+property XDCCC_LINEAR_RGB_MATRICES root ar
+property XDCCC_GRAY_SCREENWHITEPOINT root ar
+property XDCCC_GRAY_CORRECTION root ar
+
+# To let untrusted clients use the overlay visuals that many vendors
+# support, include this line.
+property SERVER_OVERLAY_VISUALS root ar
+
+# Dumb examples to show other capabilities.
+
+# oddball property names and explicit specification of error conditions
+property "property with spaces" 'property with "' aw er ed
+
+# Allow deletion of Woo-Hoo if window also has property OhBoy with value
+# ending in "son". Reads and writes will cause an error.
+property Woo-Hoo OhBoy = "*son" ad
+
+.fi
+.SH "NETWORK CONNECTIONS"
+The X server supports client connections via a platform-dependent subset of
+the following transport types: TCP\/IP, Unix Domain sockets
+and several varieties of SVR4 local connections. See the DISPLAY
+NAMES section of the \fIX\fP(__miscmansuffix__) manual page to learn how to
+specify which transport type clients should try to use.
+
+.SH GRANTING ACCESS
+The X server implements a platform-dependent subset of the following
+authorization protocols: MIT-MAGIC-COOKIE-1, XDM-AUTHORIZATION-1,
+XDM-AUTHORIZATION-2, SUN-DES-1, and MIT-KERBEROS-5. See the
+\fIXsecurity\fP(__miscmansuffix__) manual page for information on the
+operation of these protocols.
+.PP
+Authorization data required by the above protocols is passed to the
+server in a private file named with the \fB\-auth\fP command line
+option. Each time the server is about to accept the first connection
+after a reset (or when the server is starting), it reads this file.
+If this file contains any authorization records, the local host is not
+automatically allowed access to the server, and only clients which
+send one of the authorization records contained in the file in the
+connection setup information will be allowed access. See the
+\fIXau\fP manual page for a description of the binary format of this
+file. See \fIxauth\fP(1) for maintenance of this file, and distribution
+of its contents to remote hosts.
+.PP
+The X server also uses a host-based access control list for deciding
+whether or not to accept connections from clients on a particular machine.
+If no other authorization mechanism is being used,
+this list initially consists of the host on which the server is running as
+well as any machines listed in the file \fI/etc/X\fBn\fI.hosts\fR, where
+\fBn\fP is the display number of the server. Each line of the file should
+contain either an Internet hostname (e.g. expo.lcs.mit.edu) or a complete
+name in the format \fIfamily\fP:\fIname\fP as described in the
+\fIxhost\fP(1) manual page.
+There should be no leading or trailing spaces on any lines. For example:
+.sp
+.in +8
+.nf
+joesworkstation
+corporate.company.com
+star::
+inet:bigcpu
+local:
+.fi
+.in -8
+.PP
+Users can add or remove hosts from this list and enable or disable access
+control using the \fIxhost\fP command from the same machine as the server.
+.PP
+If the X FireWall Proxy (\fIxfwp\fP) is being used without a sitepolicy,
+host-based authorization must be turned on for clients to be able to
+connect to the X server via the \fIxfwp\fP. If \fIxfwp\fP is run without
+a configuration file and thus no sitepolicy is defined, if \fIxfwp\fP
+is using an X server where xhost + has been run to turn off host-based
+authorization checks, when a client tries to connect to this X server
+via \fIxfwp\fP, the X server will deny the connection. See \fIxfwp\fP(1)
+for more information about this proxy.
+.PP
+The X protocol intrinsically does not have any notion of window operation
+permissions or place any restrictions on what a client can do; if a program can
+connect to a display, it has full run of the screen.
+X servers that support the SECURITY extension fare better because clients
+can be designated untrusted via the authorization they use to connect; see
+the \fIxauth\fP(1) manual page for details. Restrictions are imposed
+on untrusted clients that curtail the mischief they can do. See the SECURITY
+extension specification for a complete list of these restrictions.
+.PP
+Sites that have better
+authentication and authorization systems might wish to make
+use of the hooks in the libraries and the server to provide additional
+security models.
+.SH SIGNALS
+The X server attaches special meaning to the following signals:
+.TP 8
+.I SIGHUP
+This signal causes the server to close all existing connections, free all
+resources, and restore all defaults. It is sent by the display manager
+whenever the main user's main application (usually an \fIxterm\fP or window
+manager) exits to force the server to clean up and prepare for the next
+user.
+.TP 8
+.I SIGTERM
+This signal causes the server to exit cleanly.
+.TP 8
+.I SIGUSR1
+This signal is used quite differently from either of the above. When the
+server starts, it checks to see if it has inherited SIGUSR1 as SIG_IGN
+instead of the usual SIG_DFL. In this case, the server sends a SIGUSR1 to
+its parent process after it has set up the various connection schemes.
+\fIXdm\fP uses this feature to recognize when connecting to the server
+is possible.
+.SH FONTS
+The X server
+can obtain fonts from directories and/or from font servers.
+The list of directories and font servers
+the X server uses when trying to open a font is controlled
+by the \fIfont path\fP.
+.LP
+The default font path is
+__default_font_path__ .
+.LP
+The font path can be set with the \fB\-fp\fP option or by \fIxset\fP(1)
+after the server has started.
+.SH FILES
+.TP 30
+.I /etc/X\fBn\fP.hosts
+Initial access control list for display number \fBn\fP
+.TP 30
+.IR /usr/share/fonts/X11/misc,
+ /usr/share/fonts/X11/75dpi,
+ /usr/share/fonts/X11/100dpi
+Bitmap font directories
+.TP 30
+.IR /usr/share/fonts/X11/Type1
+Outline font directories
+.TP 30
+.I /usr/share/nx/rgb
+Color database
+.TP 30
+.I /tmp/.X11-unix/X\fBn\fP
+Unix domain socket for display number \fBn\fP
+.TP 30
+.IR /tmp/rcX\fBn\fP
+Kerberos 5 replay cache for display number \fBn\fP
+.SH "SEE ALSO"
+Protocols:
+.I "X Window System Protocol,"
+.I "NX Compression Protocol,"
+.I "The X Font Service Protocol,"
+.I "X Display Manager Control Protocol"
+.PP
+Fonts: \fIbdftopcf\fP(1), \fImkfontdir\fP(1), \fImkfontscale\fP(1),
+\fIxfs\fP(1), \fIxlsfonts\fP(1), \fIxfontsel\fP(1), \fIxfd\fP(1),
+.I "X Logical Font Description Conventions"
+.PP
+Security: \fIXsecurity\fP(__miscmansuffix__), \fIxauth\fP(1), \fIXau\fP(1),
+\fIxdm\fP(1), \fIxhost\fP(1), \fIxfwp\fP(1),
+.I "Security Extension Specification"
+.PP
+Starting the server: \fIxdm\fP(1), \fIxinit\fP(1)
+.PP
+Controlling the server once started: \fIxset\fP(1), \fIxsetroot\fP(1),
+\fIxhost\fP(1)
+.PP
+Server-specific man pages:
+\fIXdec\fP(1), \fIXmacII\fP(1), \fIXsun\fP(1), \fIXnest\fP(1),
+\fIXvfb\fP(1), \fIXFree86\fP(1), \fIXDarwin\fP(1).
+.PP
+Server internal documentation:
+.I "Definition of the Porting Layer for the X v11 Sample Server"
+.SH AUTHORS
+The first sample X server was originally written by Susan Angebranndt,
+Raymond Drewry, Philip Karlton, and Todd Newman, from Digital Equipment
+Corporation, with support from a large cast. It has since been
+extensively rewritten by Keith Packard and Bob Scheifler, from MIT. Dave
+Wiggins took over post-R5 and made substantial improvements.
+.PP
+The first implementation of nx-X11 (version 1.x up to 3.5.x) was written
+by NoMachine (maintained until 2011).
+.PP
+The current implementation of nx-X11 is maintained by various projects,
+amongst others The Arctica Project, TheQVD (Qindel Group) and X2Go.
+.PP
+This manual page was written by Per Hansen <spamhans@yahoo.de>, and
+modified by Marcelo Boveto Shima <marceloshima@gmail.com> and Mike
+Gabriel <mike.gabriel@das-netzwerkteam.de>. In 2016, the original
+Xserver.man page shipped with nx-X11 was merged into the \fBnxagent\fR
+man page and received a major update by Mike Gabriel
+<mike.gabriel@das-netzwerkteam.de>.
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
new file mode 100644
index 000000000..bcdaa2204
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -0,0 +1,49 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/* XPM */
+static char *nxagentIconData[] = {
+"16 16 5 1",
+" c None",
+"! c black",
+"# c #FF0000",
+"$ c #424242",
+"% c #750202",
+" ",
+"############### ",
+"# #$",
+"# #% #######% #$",
+"# #% #%%#%%#% #$",
+"# #% #% #% #% #$",
+"# #% #% #% #% #$",
+"# #% #% #% #% #$",
+"# %% #% #% #% #$",
+"# #% #% #% #$",
+"# #% #% #% #% #$",
+"# %% %% %% %% #$",
+"# #$",
+"###############$",
+" $$$$$$$$$$$$$$$",
+" "};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
new file mode 100644
index 000000000..3fb4362d1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -0,0 +1,56 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+static char *placeholderXpm[] = {
+/* columns rows colors chars-per-pixel */
+"14 16 10 1",
+" c #000000",
+". c #0000FF",
+"X c #008400",
+"o c #00FF00",
+"O c #00FFFF",
+"+ c #FF0000",
+"@ c #FF00FF",
+"# c #848484",
+"$ c #BDBDBD",
+"% c #FFFFFF",
+/* pixels */
+" #%%%",
+" %%%%%%%%%##%%",
+" %$$$$$$$$#%#%",
+" %$$$XX$$$#%%#",
+" %$$XoX $$ ",
+" %$$XXX $$$$% ",
+" %$$$ $$$$$% ",
+" %$$$$$$... % ",
+" %$+$$$$.O. % ",
+" %$@+$$$... % ",
+" %$@@+$$ $% ",
+" %$@@@+$$$$$% ",
+" %$ +$$$$% ",
+" %$$$$$$$$$$% ",
+" %%%%%%%%%%%% ",
+" "
+};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
new file mode 100644
index 000000000..a9ca85114
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -0,0 +1,711 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#define screensaver_width 256
+#define screensaver_height 256
+static unsigned char screensaver_bits[] = {
+ 0xa8, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x40, 0x55,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0xaa, 0x0a, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xaa, 0x2a, 0x80, 0x02, 0x80, 0xaa, 0xaa, 0x82, 0x0a, 0xa8, 0x28, 0x80,
+ 0x8a, 0x80, 0x2a, 0x80, 0x80, 0x8a, 0xa2, 0x82, 0x0a, 0xaa, 0x0a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0x02, 0x80, 0x82, 0x41, 0x40, 0x00, 0x50,
+ 0x55, 0x41, 0x00, 0x00, 0x04, 0x00, 0x54, 0x40, 0x10, 0x00, 0x40, 0x00,
+ 0x51, 0x55, 0x00, 0x15, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x8a, 0x02, 0x00, 0x02,
+ 0x00, 0x20, 0xa2, 0x00, 0x80, 0x00, 0x08, 0x00, 0xaa, 0x2a, 0x00, 0x2a,
+ 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80,
+ 0x01, 0x00, 0x01, 0x50, 0x45, 0x05, 0x00, 0x01, 0x10, 0x10, 0x40, 0x11,
+ 0x40, 0x00, 0x44, 0x00, 0x50, 0x15, 0x01, 0x15, 0x04, 0x00, 0x40, 0x00,
+ 0x05, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x50, 0x20, 0x00, 0x00, 0xa2,
+ 0xaa, 0x2a, 0x00, 0x00, 0x02, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0xa2, 0xaa, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x01, 0x40, 0x44, 0x15, 0x10, 0x01,
+ 0x10, 0x10, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x54, 0x55, 0x41, 0x45,
+ 0x04, 0x00, 0x40, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x54,
+ 0x20, 0x80, 0x00, 0x82, 0xaa, 0x0a, 0x00, 0x00, 0x22, 0x00, 0x80, 0x0a,
+ 0x00, 0x00, 0x82, 0x00, 0xa0, 0x8a, 0x22, 0x02, 0x00, 0x08, 0x20, 0x00,
+ 0xa8, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x2a, 0x10, 0x40, 0x00, 0x01,
+ 0x54, 0x45, 0x10, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00,
+ 0x50, 0x45, 0x05, 0x41, 0x00, 0x04, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x00, 0x28, 0x00, 0xaa, 0xaa, 0x0a, 0x0a, 0x00,
+ 0x20, 0x08, 0x00, 0x20, 0x00, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x22, 0x2a,
+ 0x00, 0x00, 0x0a, 0x00, 0xa8, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0a,
+ 0x50, 0x05, 0x00, 0x01, 0x55, 0x45, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x40, 0x55, 0x11, 0x00, 0x00, 0x54, 0x01, 0x00,
+ 0x44, 0x01, 0x00, 0x00, 0x05, 0x40, 0x00, 0x05, 0x00, 0x08, 0x00, 0x80,
+ 0xaa, 0xaa, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x80, 0x00,
+ 0x80, 0xaa, 0x28, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00,
+ 0x28, 0x00, 0x80, 0x02, 0x10, 0x10, 0x00, 0x01, 0x54, 0x45, 0x01, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x10, 0x55, 0x14, 0x00,
+ 0x00, 0x04, 0x04, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x40, 0x40, 0x01,
+ 0x08, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0xa0, 0xaa, 0x00, 0x80, 0x28, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x80, 0x02, 0x00, 0x00, 0x80, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x14, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x40, 0x00, 0x00, 0x08, 0x20, 0x80, 0x00, 0x08, 0x08, 0x80, 0x80,
+ 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x00,
+ 0x02, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,
+ 0x10, 0x10, 0x00, 0x01, 0x10, 0x45, 0x55, 0x01, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00,
+ 0x20, 0xa2, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x80, 0x00, 0x02, 0x04, 0x00, 0x40, 0x00, 0x04, 0x04, 0x40, 0x40,
+ 0x00, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00, 0x51, 0x45, 0x05,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x45, 0x01,
+ 0x2a, 0x80, 0xaa, 0xaa, 0x82, 0xaa, 0x2a, 0xa0, 0x02, 0x02, 0x80, 0xa8,
+ 0x00, 0x2a, 0xa0, 0x02, 0x80, 0xa2, 0x00, 0xa0, 0xa0, 0x0a, 0xa0, 0x00,
+ 0x00, 0x00, 0x80, 0x88, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x41, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0xaa, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa8, 0xaa,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x2a, 0x20, 0x00, 0x00, 0x41, 0x05, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+ 0x40, 0x10, 0x44, 0x15, 0x15, 0x00, 0x00, 0x50, 0x01, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x10, 0x50, 0x40,
+ 0x82, 0x08, 0x02, 0x08, 0x20, 0x08, 0x00, 0x22, 0xa0, 0x20, 0x88, 0x00,
+ 0x22, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x80, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x88, 0x20, 0x44, 0x10, 0x01, 0x04,
+ 0x50, 0x04, 0x00, 0x41, 0x10, 0x11, 0x44, 0x00, 0x41, 0x00, 0x00, 0x54,
+ 0x41, 0x00, 0x40, 0x55, 0x15, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x11, 0x04, 0x11, 0x80, 0x20, 0x02, 0x08, 0xa0, 0x08, 0x00, 0x02,
+ 0x88, 0x20, 0x88, 0x00, 0x82, 0x00, 0x00, 0x2a, 0x22, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x08, 0x20,
+ 0x40, 0x10, 0x01, 0x04, 0x50, 0x04, 0x00, 0x01, 0x04, 0x41, 0x44, 0x00,
+ 0x41, 0x00, 0x00, 0x15, 0x05, 0x14, 0x15, 0x50, 0x10, 0x05, 0x40, 0x41,
+ 0x41, 0x10, 0x45, 0x05, 0x50, 0x04, 0x04, 0x10, 0x80, 0x20, 0x02, 0x08,
+ 0xa0, 0x08, 0x00, 0x02, 0x08, 0x22, 0x82, 0x00, 0x82, 0x00, 0x00, 0x0a,
+ 0x2a, 0x22, 0x8a, 0x22, 0x22, 0x08, 0x80, 0x22, 0x22, 0x88, 0x88, 0x02,
+ 0x28, 0x02, 0x08, 0x20, 0x40, 0x10, 0x15, 0x54, 0x10, 0x05, 0x00, 0x14,
+ 0x04, 0x41, 0x44, 0x05, 0x41, 0x00, 0x00, 0x05, 0x50, 0x01, 0x41, 0x04,
+ 0x05, 0x11, 0x00, 0x05, 0x44, 0x44, 0x50, 0x00, 0x10, 0x05, 0x50, 0x10,
+ 0x80, 0x0a, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x20, 0xa8, 0x82, 0x82, 0x00,
+ 0x2a, 0x00, 0x80, 0x02, 0x22, 0x02, 0x82, 0x20, 0x20, 0x08, 0x20, 0x88,
+ 0x82, 0x88, 0x8a, 0x00, 0x88, 0x0a, 0x80, 0x20, 0x40, 0x04, 0x01, 0x04,
+ 0x10, 0x05, 0x00, 0x40, 0x04, 0x41, 0x41, 0x00, 0x11, 0x00, 0x40, 0x01,
+ 0x41, 0x41, 0x41, 0x14, 0x15, 0x11, 0x40, 0x44, 0x04, 0x44, 0x40, 0x00,
+ 0x44, 0x15, 0x00, 0x11, 0x80, 0x08, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x80,
+ 0x08, 0x82, 0x82, 0x00, 0x22, 0x00, 0xa0, 0x00, 0x22, 0x22, 0x82, 0x20,
+ 0x22, 0x0a, 0x20, 0x28, 0x82, 0x82, 0x88, 0x00, 0x88, 0x2a, 0x00, 0x22,
+ 0x44, 0x10, 0x01, 0x04, 0x10, 0x04, 0x00, 0x41, 0x04, 0x01, 0x41, 0x00,
+ 0x41, 0x00, 0x50, 0x01, 0x14, 0x14, 0x01, 0x55, 0x10, 0x15, 0x40, 0x45,
+ 0x05, 0x01, 0x45, 0x00, 0x04, 0x55, 0x04, 0x11, 0x82, 0x20, 0x02, 0x08,
+ 0x20, 0x08, 0x00, 0x22, 0x08, 0x82, 0x80, 0x00, 0x82, 0x00, 0xa8, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xaa, 0x88, 0x20, 0x41, 0x10, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+ 0x04, 0x01, 0x41, 0x15, 0x41, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x51, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa8, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x14, 0x40, 0x01, 0x41, 0x40, 0x01, 0x14, 0x10, 0x01, 0x00, 0x40,
+ 0x01, 0x04, 0x14, 0x14, 0x14, 0x10, 0x04, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x82, 0xa0, 0x20, 0x82,
+ 0xa2, 0x20, 0x02, 0x22, 0x28, 0x02, 0x00, 0x08, 0x8a, 0x22, 0x08, 0x08,
+ 0x22, 0x28, 0x0a, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x54,
+ 0x01, 0x00, 0x00, 0x40, 0x41, 0x40, 0x10, 0x04, 0x11, 0x11, 0x04, 0x41,
+ 0x10, 0x04, 0x00, 0x04, 0x04, 0x40, 0x10, 0x00, 0x41, 0x10, 0x11, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xaa, 0x02, 0x00, 0x00, 0xa0,
+ 0x82, 0x80, 0x08, 0x08, 0x02, 0x08, 0x88, 0x80, 0x08, 0x08, 0x00, 0x08,
+ 0x08, 0x20, 0x20, 0x80, 0x80, 0x20, 0x00, 0x00, 0x10, 0x50, 0x14, 0x14,
+ 0x45, 0x05, 0x40, 0x05, 0x41, 0x14, 0x15, 0x50, 0x41, 0x01, 0x04, 0x00,
+ 0x01, 0x04, 0x50, 0x00, 0x11, 0x04, 0x00, 0x14, 0x00, 0x40, 0x10, 0x44,
+ 0x00, 0x11, 0x00, 0x00, 0xa0, 0x88, 0x22, 0xa2, 0x88, 0x08, 0x00, 0x2a,
+ 0x82, 0x22, 0x22, 0xa8, 0x80, 0x0a, 0x08, 0x00, 0x02, 0xa8, 0x8a, 0xaa,
+ 0x08, 0x08, 0x00, 0xa8, 0x00, 0x2a, 0x20, 0x80, 0xaa, 0x20, 0x00, 0x00,
+ 0x00, 0x05, 0x04, 0x15, 0x55, 0x04, 0x40, 0x04, 0x50, 0x54, 0x01, 0x54,
+ 0x00, 0x54, 0x04, 0x00, 0x01, 0x04, 0x40, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x05, 0x41, 0x40, 0x40, 0x00, 0x10, 0x00, 0x00, 0x80, 0x08, 0x02, 0x82,
+ 0x80, 0x08, 0x80, 0x20, 0x02, 0x02, 0x02, 0x2a, 0x00, 0xa0, 0x08, 0x00,
+ 0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00, 0x8a, 0x20, 0x20, 0x82,
+ 0x00, 0x20, 0x00, 0x00, 0x10, 0x45, 0x04, 0x11, 0x51, 0x04, 0x50, 0x44,
+ 0x44, 0x44, 0x01, 0x15, 0x00, 0x40, 0x05, 0x00, 0x01, 0x04, 0x40, 0x00,
+ 0x10, 0x04, 0x00, 0x00, 0x54, 0x40, 0x40, 0x41, 0x00, 0x10, 0x00, 0x00,
+ 0xa0, 0x28, 0x02, 0x0a, 0x8a, 0x08, 0x20, 0x0a, 0x0a, 0x28, 0x02, 0x0a,
+ 0x00, 0x80, 0x08, 0x00, 0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00,
+ 0x88, 0x20, 0x80, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x05, 0x40, 0x00, 0x11, 0x00,
+ 0x01, 0x10, 0x10, 0x01, 0x11, 0x04, 0x00, 0x04, 0x50, 0x40, 0x41, 0x01,
+ 0x01, 0x11, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0x80, 0x02, 0x80, 0x80, 0x20, 0x02, 0x02, 0x20, 0x08, 0x82,
+ 0x08, 0x08, 0x00, 0x08, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x00, 0x00,
+ 0x00, 0x40, 0x01, 0x10, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x40, 0x01,
+ 0x40, 0x14, 0x40, 0x41, 0x05, 0x40, 0x01, 0x14, 0x14, 0x14, 0x00, 0x44,
+ 0x01, 0x45, 0x00, 0x00, 0x14, 0x54, 0x00, 0x00, 0x00, 0x80, 0x02, 0x08,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0xa8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01,
+ 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0xaa, 0x0a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x8a, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x05, 0x50, 0x00, 0x50, 0x40, 0x45, 0x11, 0x00, 0x50,
+ 0x40, 0x41, 0x01, 0x00, 0x14, 0x00, 0x51, 0x40, 0x40, 0x00, 0x05, 0x14,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a,
+ 0x88, 0x02, 0xaa, 0xa8, 0x80, 0x00, 0x00, 0xaa, 0xa8, 0xa2, 0x02, 0x00,
+ 0xa2, 0xa0, 0x22, 0xa8, 0xa0, 0xa0, 0x8a, 0x2a, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x04, 0x01, 0x45, 0x51,
+ 0x04, 0x40, 0x00, 0x45, 0x41, 0x51, 0x01, 0x00, 0x41, 0x50, 0x54, 0x50,
+ 0x50, 0x50, 0x14, 0x14, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xa2, 0xa0, 0x02, 0xa0, 0x88, 0x82,
+ 0xa0, 0x88, 0x02, 0x80, 0x82, 0x28, 0x28, 0xa0, 0x20, 0x28, 0x08, 0x8a,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x45, 0x54, 0x00,
+ 0x14, 0x40, 0x41, 0x50, 0x05, 0x51, 0x10, 0x41, 0x41, 0x41, 0x01, 0x00,
+ 0x05, 0x14, 0x10, 0x50, 0x40, 0x10, 0x14, 0x54, 0x04, 0x00, 0x41, 0x55,
+ 0x04, 0x45, 0x01, 0x04, 0x20, 0x02, 0x08, 0x00, 0x2a, 0xa0, 0x00, 0xa0,
+ 0x8a, 0x20, 0xa8, 0xa2, 0xa0, 0xa0, 0x00, 0x80, 0x0a, 0x28, 0x28, 0xa0,
+ 0x20, 0x28, 0x0a, 0x2a, 0x00, 0x00, 0x22, 0x0a, 0x80, 0x88, 0x02, 0x88,
+ 0x04, 0x50, 0x01, 0x00, 0x54, 0x40, 0x01, 0x50, 0x15, 0x10, 0x14, 0x51,
+ 0x40, 0x41, 0x01, 0x00, 0x15, 0x14, 0x14, 0x40, 0x11, 0x14, 0x05, 0x14,
+ 0x00, 0x40, 0x10, 0x00, 0x15, 0x45, 0x04, 0x01, 0x00, 0x00, 0x08, 0x00,
+ 0xa8, 0xa0, 0x00, 0x28, 0x8a, 0x08, 0x0a, 0x28, 0xa0, 0xa0, 0x00, 0x00,
+ 0x2a, 0x0a, 0x28, 0xa0, 0x08, 0x8a, 0x02, 0x0a, 0x00, 0x80, 0x00, 0x08,
+ 0x80, 0x00, 0x00, 0x82, 0x44, 0x11, 0x00, 0x00, 0x50, 0x50, 0x00, 0x10,
+ 0x05, 0x40, 0x15, 0x05, 0x50, 0x50, 0x00, 0x00, 0x14, 0x14, 0x14, 0x40,
+ 0x11, 0x54, 0x00, 0x05, 0x00, 0x00, 0x11, 0x00, 0x01, 0x40, 0x04, 0x44,
+ 0x80, 0x20, 0x0a, 0x00, 0xa0, 0xa0, 0x00, 0x88, 0x82, 0xa8, 0x0a, 0x00,
+ 0xa0, 0xa0, 0x00, 0x00, 0x28, 0x0a, 0x0a, 0xa0, 0x08, 0x0a, 0x00, 0x0a,
+ 0x00, 0x00, 0x22, 0x0a, 0xa2, 0x00, 0x00, 0x88, 0x01, 0x40, 0x15, 0x00,
+ 0x50, 0x51, 0x40, 0x00, 0x01, 0x51, 0x15, 0x00, 0x50, 0x50, 0x00, 0x00,
+ 0x54, 0x14, 0x54, 0x40, 0x05, 0x14, 0x00, 0x05, 0x00, 0x40, 0x41, 0x15,
+ 0x14, 0x45, 0x04, 0x05, 0x00, 0x00, 0x00, 0x80, 0xa0, 0xa0, 0x20, 0x88,
+ 0x80, 0xaa, 0x08, 0x82, 0x28, 0x28, 0x02, 0x20, 0x28, 0x0a, 0x2a, 0xa0,
+ 0x02, 0x0a, 0x88, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x40, 0x11, 0x44, 0x00, 0x55, 0x14, 0x44,
+ 0x50, 0x50, 0x01, 0x40, 0x10, 0x54, 0x15, 0x40, 0x01, 0x14, 0x04, 0x45,
+ 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x22, 0xa0, 0x0a, 0x00, 0x00, 0x0a, 0x2a, 0x20, 0x28, 0xa8, 0x00, 0xa0,
+ 0x08, 0xa8, 0x08, 0xa0, 0x00, 0xa8, 0x82, 0x82, 0x02, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00,
+ 0x00, 0x54, 0x55, 0x10, 0x50, 0x50, 0x00, 0x00, 0x05, 0x50, 0x04, 0x40,
+ 0x00, 0x50, 0x40, 0x05, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x80, 0xaa, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a,
+ 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01,
+ 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xaa,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x28,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x50, 0x15,
+ 0x55, 0x11, 0x55, 0x00, 0x15, 0x00, 0x54, 0x01, 0x00, 0x54, 0x01, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x00, 0x20, 0x82, 0x20, 0x08, 0x82, 0x00, 0x22, 0x80,
+ 0x08, 0x08, 0x28, 0xa2, 0x28, 0x20, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa2,
+ 0x00, 0x04, 0x41, 0x10, 0x04, 0x11, 0x00, 0x40, 0x10, 0x14, 0x10, 0x54,
+ 0x54, 0x11, 0x10, 0x00, 0x01, 0x00, 0x50, 0x14, 0x15, 0x05, 0x45, 0x01,
+ 0x50, 0x50, 0x44, 0x14, 0x05, 0x00, 0x04, 0x40, 0x20, 0x02, 0x22, 0x02,
+ 0x22, 0x08, 0x20, 0x20, 0x00, 0x08, 0x20, 0xa8, 0x28, 0x22, 0x08, 0x80,
+ 0x02, 0x00, 0x88, 0x22, 0xa2, 0x88, 0x28, 0x02, 0x88, 0x80, 0x22, 0xa2,
+ 0x08, 0x00, 0x08, 0x22, 0x00, 0x04, 0x41, 0x00, 0x04, 0x00, 0x01, 0x40,
+ 0x00, 0x10, 0x40, 0x04, 0x11, 0x10, 0x04, 0x10, 0x05, 0x00, 0x10, 0x04,
+ 0x01, 0x55, 0x45, 0x04, 0x10, 0x50, 0x44, 0x15, 0x01, 0x00, 0x14, 0x10,
+ 0x00, 0x2a, 0xa0, 0x02, 0x2a, 0x20, 0x22, 0x80, 0x02, 0x22, 0x20, 0x02,
+ 0x0a, 0xa0, 0x02, 0x08, 0x0a, 0x00, 0x20, 0x02, 0x82, 0x80, 0x20, 0x02,
+ 0x80, 0x88, 0x28, 0x82, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x44, 0x40, 0x01,
+ 0x14, 0x00, 0x04, 0x00, 0x05, 0x10, 0x40, 0x00, 0x11, 0x10, 0x05, 0x04,
+ 0x14, 0x00, 0x44, 0x44, 0x01, 0x51, 0x44, 0x04, 0x10, 0x45, 0x14, 0x11,
+ 0x01, 0x00, 0x50, 0x11, 0x00, 0x82, 0x20, 0x02, 0x22, 0x20, 0x28, 0x20,
+ 0x08, 0x2a, 0x80, 0x02, 0x02, 0x20, 0x08, 0x00, 0x00, 0x00, 0x28, 0x28,
+ 0x02, 0x8a, 0x22, 0x02, 0xa0, 0xa8, 0x08, 0x8a, 0x00, 0x00, 0x80, 0x22,
+ 0x00, 0x04, 0x41, 0x10, 0x04, 0x01, 0x10, 0x00, 0x10, 0x41, 0x40, 0x01,
+ 0x11, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51, 0x20, 0x82, 0x20, 0x00,
+ 0x02, 0x20, 0x28, 0x20, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x28, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x22, 0x10, 0x04, 0x45, 0x10, 0x04, 0x01, 0x10, 0x40,
+ 0x04, 0x40, 0x00, 0x00, 0x41, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41,
+ 0x8a, 0x0a, 0xaa, 0x8a, 0xaa, 0xa8, 0x20, 0xa0, 0x82, 0xa2, 0x80, 0x80,
+ 0xaa, 0xa8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x10, 0x50,
+ 0x41, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa0, 0x80, 0x02, 0xa8, 0x28,
+ 0x0a, 0xa0, 0x02, 0xa8, 0x00, 0x8a, 0x02, 0x28, 0x00, 0x00, 0x00, 0x0a,
+ 0x28, 0x80, 0x2a, 0x80, 0x22, 0x80, 0x0a, 0x00, 0xa8, 0x00, 0x28, 0x2a,
+ 0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0x55, 0x51, 0x14, 0x14, 0x54, 0x54,
+ 0x01, 0x54, 0x01, 0x50, 0x50, 0x05, 0x00, 0x05, 0x00, 0x50, 0x55, 0x40,
+ 0x51, 0x50, 0x15, 0x00, 0x54, 0x05, 0x14, 0x55, 0x00, 0x0a, 0x00, 0xa0,
+ 0x00, 0x80, 0xaa, 0x2a, 0x2a, 0x08, 0x2a, 0xa8, 0x02, 0xaa, 0x02, 0xa0,
+ 0xa0, 0x02, 0x00, 0x0a, 0x00, 0xa8, 0xaa, 0x80, 0x2a, 0xa8, 0x2a, 0x80,
+ 0xaa, 0x0a, 0xa8, 0xaa, 0x01, 0x05, 0x00, 0x50, 0x05, 0x40, 0x55, 0x55,
+ 0x14, 0x00, 0x14, 0x50, 0x05, 0x54, 0x01, 0x40, 0x51, 0x01, 0x00, 0x55,
+ 0x00, 0x54, 0x55, 0x41, 0x15, 0x54, 0x55, 0x40, 0x55, 0x15, 0x54, 0x55,
+ 0x02, 0x0a, 0x00, 0xa0, 0x0a, 0xa0, 0x02, 0x2a, 0x2a, 0x00, 0x0a, 0x88,
+ 0x0a, 0x2a, 0x00, 0x80, 0xaa, 0x00, 0x00, 0xaa, 0x00, 0xaa, 0xa0, 0xa2,
+ 0x0a, 0x2a, 0xa8, 0xa0, 0x0a, 0x0a, 0xaa, 0xa0, 0x01, 0x14, 0x01, 0x40,
+ 0x55, 0x50, 0x01, 0x14, 0x14, 0x00, 0x05, 0x04, 0x15, 0x15, 0x00, 0x00,
+ 0x51, 0x00, 0x00, 0x54, 0x05, 0x14, 0x40, 0x45, 0x05, 0x15, 0x50, 0x41,
+ 0x01, 0x14, 0x54, 0x40, 0x02, 0xa8, 0x00, 0x80, 0xaa, 0xa8, 0x00, 0x2a,
+ 0x28, 0x88, 0x02, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x0a, 0x0a, 0xa0, 0xa2, 0x82, 0x0a, 0xa0, 0xa0, 0x00, 0x28, 0x2a, 0xa0,
+ 0x01, 0x50, 0x00, 0x00, 0x55, 0x50, 0x00, 0x14, 0x54, 0x54, 0x05, 0x15,
+ 0x14, 0x15, 0x00, 0x00, 0x11, 0x00, 0x00, 0x50, 0x05, 0x15, 0x00, 0x40,
+ 0x01, 0x05, 0x40, 0x51, 0x00, 0x14, 0x14, 0x40, 0x00, 0xa8, 0x00, 0x00,
+ 0xa8, 0x28, 0x00, 0x28, 0x28, 0xa8, 0x02, 0x80, 0x0a, 0x0a, 0x00, 0x80,
+ 0x08, 0x00, 0x00, 0x80, 0x8a, 0x0a, 0x00, 0xa0, 0x80, 0xaa, 0xaa, 0xa8,
+ 0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x44, 0x01, 0x00, 0x50, 0x55, 0x00, 0x14,
+ 0x50, 0x14, 0x01, 0x00, 0x15, 0x05, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00,
+ 0x15, 0x05, 0x00, 0x50, 0x41, 0x55, 0x55, 0x51, 0x55, 0x15, 0x15, 0x40,
+ 0x00, 0x80, 0x02, 0x00, 0xa0, 0x28, 0x00, 0x0a, 0x28, 0x0a, 0x02, 0x00,
+ 0x8a, 0x0a, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x8a, 0x0a, 0x00, 0xa0,
+ 0x80, 0xaa, 0xaa, 0xa8, 0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x40, 0x01, 0x00,
+ 0x50, 0x55, 0x00, 0x14, 0x50, 0x05, 0x00, 0x00, 0x14, 0x05, 0x00, 0x50,
+ 0x50, 0x00, 0x00, 0x00, 0x15, 0x05, 0x00, 0x50, 0x40, 0x55, 0x55, 0x51,
+ 0x55, 0x15, 0x05, 0x50, 0x00, 0x80, 0x02, 0x2a, 0xa8, 0x28, 0x00, 0x0a,
+ 0xa8, 0x0a, 0x80, 0xaa, 0x82, 0x02, 0x00, 0x20, 0xa0, 0x00, 0xa0, 0x82,
+ 0x8a, 0x0a, 0x00, 0xa0, 0x80, 0x02, 0x00, 0x28, 0x00, 0x00, 0x0a, 0xa0,
+ 0x00, 0x00, 0x05, 0x14, 0x50, 0x54, 0x00, 0x15, 0x50, 0x05, 0x40, 0x55,
+ 0x01, 0x05, 0x00, 0x10, 0x40, 0x01, 0x40, 0x01, 0x05, 0x15, 0x50, 0x51,
+ 0x40, 0x01, 0x00, 0x50, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x0a, 0x2a,
+ 0xa8, 0xa8, 0x80, 0x0a, 0xa0, 0x02, 0x80, 0x0a, 0x80, 0x02, 0x00, 0x08,
+ 0x80, 0x02, 0xa0, 0x82, 0x0a, 0x2a, 0xa8, 0xa0, 0x80, 0x02, 0x2a, 0xa8,
+ 0x80, 0x8a, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x54, 0x55, 0x50, 0x55, 0x05,
+ 0x50, 0x01, 0x00, 0x00, 0x44, 0x05, 0x00, 0x04, 0x00, 0x05, 0x40, 0x55,
+ 0x05, 0x54, 0x55, 0x50, 0x00, 0x55, 0x15, 0x50, 0x55, 0x05, 0x05, 0x50,
+ 0x00, 0x00, 0x00, 0xa8, 0x2a, 0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x08, 0x00,
+ 0x8a, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x80, 0xaa, 0x02, 0xaa, 0x2a, 0x28,
+ 0x80, 0xaa, 0x0a, 0xa0, 0xaa, 0x82, 0x02, 0x28, 0x00, 0x00, 0x00, 0x50,
+ 0x15, 0x40, 0x55, 0x05, 0x40, 0x01, 0x10, 0x00, 0x55, 0x01, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x55, 0x01, 0x54, 0x15, 0x50, 0x00, 0x55, 0x05, 0x40,
+ 0x55, 0x01, 0x05, 0x50, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x0a,
+ 0xa0, 0x00, 0x00, 0xa0, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0xa0, 0x0a, 0x28, 0x00, 0xa8, 0x00, 0x80, 0x2a, 0x80, 0x02, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x55, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0xa0, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x50, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x0a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x45, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x22, 0xa0, 0x22, 0xa8, 0x0a, 0xa8, 0x00,
+ 0xa8, 0xa0, 0x28, 0x80, 0xaa, 0x22, 0x28, 0xa0, 0x02, 0x2a, 0x2a, 0xa0,
+ 0x02, 0x8a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x15, 0x50, 0x15, 0x54, 0x15, 0x54, 0x01, 0x55, 0x41, 0x55, 0x00,
+ 0x55, 0x11, 0x54, 0x50, 0x05, 0x54, 0x54, 0x54, 0x05, 0x54, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x08, 0x08,
+ 0x20, 0x08, 0x02, 0x82, 0x82, 0x82, 0x82, 0x00, 0xaa, 0x08, 0x20, 0x20,
+ 0x08, 0x08, 0x08, 0x0a, 0x0a, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0x04, 0x10, 0x10, 0x00, 0x01, 0x04,
+ 0x01, 0x01, 0x01, 0x01, 0x54, 0x14, 0x11, 0x00, 0x10, 0x10, 0x04, 0x04,
+ 0x04, 0x10, 0x00, 0x14, 0x51, 0x10, 0x44, 0x01, 0x50, 0x44, 0x44, 0x14,
+ 0xa0, 0x00, 0x02, 0x08, 0x08, 0x80, 0x00, 0x82, 0x00, 0x82, 0x80, 0x00,
+ 0xa8, 0x28, 0x00, 0xa0, 0x0a, 0x20, 0x08, 0x02, 0x08, 0x08, 0x00, 0x00,
+ 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x05, 0x04, 0x00,
+ 0x10, 0x00, 0x55, 0x45, 0x55, 0x41, 0x40, 0x00, 0x54, 0x54, 0x00, 0x50,
+ 0x05, 0x10, 0x04, 0x55, 0x05, 0x04, 0x00, 0x44, 0x10, 0x14, 0x45, 0x04,
+ 0x10, 0x54, 0x54, 0x04, 0x00, 0x0a, 0x02, 0x00, 0x08, 0x80, 0xaa, 0x82,
+ 0xaa, 0x82, 0x80, 0x00, 0x2a, 0xaa, 0x00, 0x08, 0x08, 0x20, 0x02, 0xaa,
+ 0x0a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x10, 0x14, 0x04, 0x00, 0x04, 0x00, 0x01, 0x40, 0x00, 0x40, 0x40, 0x00,
+ 0x15, 0x45, 0x15, 0x04, 0x04, 0x10, 0x01, 0x01, 0x00, 0x04, 0x00, 0x05,
+ 0x15, 0x10, 0x44, 0x04, 0x14, 0x14, 0x41, 0x04, 0x08, 0x08, 0x0a, 0x08,
+ 0x08, 0x80, 0x02, 0x82, 0x80, 0x20, 0x20, 0x80, 0x8a, 0x8a, 0x22, 0x02,
+ 0x02, 0xa0, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x05, 0x54, 0x15, 0x55, 0x01, 0x55, 0x01,
+ 0x55, 0x51, 0x51, 0x01, 0x45, 0x05, 0x00, 0x54, 0x15, 0x40, 0x00, 0x54,
+ 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0x02, 0xa8, 0x82, 0xaa, 0x00, 0xaa, 0x00, 0x2a, 0xa8, 0xa8, 0x80,
+ 0x82, 0x22, 0x20, 0xa8, 0x0a, 0x20, 0x00, 0xa8, 0x80, 0xaa, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x55, 0x55, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0xa8, 0xaa, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x54, 0x55, 0x01, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x50, 0x55, 0x05,
+ 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x0a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x0a, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+ 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x80, 0xaa, 0x2a,
+ 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0x02, 0x08, 0x00, 0x10, 0x50, 0x50, 0x50, 0x40, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x50, 0x00,
+ 0x50, 0x00, 0x05, 0x04, 0x01, 0x05, 0x50, 0x40, 0x54, 0x05, 0x04, 0x05,
+ 0x8a, 0x20, 0x20, 0x88, 0xa0, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+ 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x20, 0x00, 0x82, 0x82, 0x08, 0x8a,
+ 0x82, 0x08, 0x88, 0xa0, 0xa8, 0x0a, 0x22, 0x28, 0x00, 0x41, 0x00, 0x04,
+ 0x41, 0x44, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x10, 0x00, 0x01, 0x41, 0x10, 0x44, 0x44, 0x10, 0x04, 0x41,
+ 0x50, 0x15, 0x11, 0x10, 0x80, 0x80, 0x00, 0x02, 0x82, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0x00,
+ 0x02, 0x22, 0x20, 0x08, 0x20, 0x20, 0x02, 0x22, 0xa0, 0x2a, 0x22, 0x20,
+ 0x00, 0x41, 0x10, 0x01, 0x44, 0x00, 0x00, 0x40, 0x41, 0x51, 0x04, 0x14,
+ 0x15, 0x00, 0x11, 0x44, 0x50, 0x54, 0x40, 0x01, 0x05, 0x10, 0x00, 0x04,
+ 0x10, 0x40, 0x01, 0x44, 0x10, 0x15, 0x51, 0x00, 0xa8, 0x80, 0x00, 0xaa,
+ 0x82, 0x00, 0x00, 0x20, 0x22, 0x8a, 0xa2, 0x22, 0x22, 0x80, 0xa0, 0x88,
+ 0x88, 0x88, 0x88, 0x02, 0x2a, 0x20, 0x00, 0x08, 0xa0, 0x2a, 0xaa, 0x22,
+ 0x20, 0x8a, 0xa0, 0x02, 0x04, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x40,
+ 0x10, 0x10, 0x41, 0x54, 0x11, 0x00, 0x11, 0x40, 0x54, 0x05, 0x04, 0x05,
+ 0x50, 0x11, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40, 0x10, 0x45, 0x00, 0x15,
+ 0x82, 0x80, 0x08, 0x02, 0x80, 0x00, 0x00, 0x00, 0x22, 0x88, 0x02, 0x02,
+ 0x22, 0x00, 0x82, 0x08, 0x02, 0x08, 0x02, 0x0a, 0x80, 0x22, 0x00, 0x08,
+ 0x20, 0x00, 0x02, 0x20, 0x20, 0xa2, 0x00, 0x28, 0x01, 0x01, 0x05, 0x01,
+ 0x40, 0x00, 0x00, 0x40, 0x14, 0x51, 0x41, 0x44, 0x11, 0x40, 0x04, 0x11,
+ 0x04, 0x05, 0x01, 0x14, 0x00, 0x15, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40,
+ 0x10, 0x51, 0x01, 0x50, 0x82, 0x00, 0x02, 0x02, 0x80, 0x00, 0x00, 0x80,
+ 0xa2, 0x88, 0x2a, 0x28, 0x22, 0x80, 0x02, 0x28, 0x8a, 0x88, 0x00, 0x28,
+ 0x00, 0x22, 0x00, 0x08, 0x20, 0x00, 0x02, 0x20, 0xa0, 0xa8, 0x02, 0x20,
+ 0x01, 0x05, 0x05, 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x04,
+ 0x40, 0x40, 0x04, 0x44, 0x10, 0x51, 0x15, 0x40, 0x82, 0x00, 0x02, 0x08,
+ 0x82, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x00, 0x00, 0x02, 0x82, 0x08, 0x08, 0x80, 0x20, 0x08, 0x22,
+ 0xa0, 0xa0, 0x2a, 0x20, 0x14, 0x01, 0x00, 0x50, 0x50, 0x01, 0x00, 0x00,
+ 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x51, 0x00, 0x05, 0x15, 0x00, 0x05, 0x50, 0x50, 0x50, 0x40, 0x15, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa0, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x55, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xaa, 0x15, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
+ 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+ 0xa2, 0x00, 0x80, 0x02, 0x0a, 0xa2, 0x82, 0x02, 0x0a, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0xa8, 0xa0, 0x80, 0x82, 0xa0, 0x11, 0x01, 0x00, 0x04,
+ 0x11, 0x50, 0x41, 0x04, 0x11, 0x10, 0x00, 0x14, 0x44, 0x40, 0x00, 0x41,
+ 0x11, 0x00, 0x14, 0x00, 0x44, 0x05, 0x05, 0x04, 0x45, 0x00, 0x10, 0x44,
+ 0x11, 0x11, 0x04, 0x44, 0xa2, 0x02, 0x20, 0x80, 0x20, 0x28, 0x20, 0x08,
+ 0x02, 0x20, 0x80, 0x22, 0xa8, 0xa8, 0xa0, 0x82, 0x28, 0x00, 0x28, 0x80,
+ 0x22, 0x08, 0x82, 0x0a, 0x22, 0x80, 0x00, 0x82, 0x20, 0x00, 0x88, 0x8a,
+ 0x51, 0x05, 0x50, 0x00, 0x10, 0x11, 0x11, 0x10, 0x01, 0x50, 0x40, 0x10,
+ 0x54, 0x04, 0x11, 0x04, 0x41, 0x00, 0x50, 0x40, 0x10, 0x04, 0x44, 0x10,
+ 0x44, 0x40, 0x01, 0x01, 0x10, 0x10, 0x44, 0x14, 0xa2, 0x00, 0xa0, 0x00,
+ 0xa8, 0x02, 0xa0, 0x0a, 0x02, 0xa0, 0xa0, 0x00, 0x0a, 0x82, 0x08, 0x82,
+ 0x20, 0x00, 0xa0, 0x20, 0x20, 0x08, 0x22, 0x08, 0x02, 0x80, 0x02, 0x02,
+ 0x20, 0xa8, 0x8a, 0x82, 0x51, 0x01, 0x40, 0x01, 0x55, 0x01, 0x10, 0x00,
+ 0x01, 0x40, 0x41, 0x00, 0x04, 0x54, 0x50, 0x41, 0x40, 0x00, 0x40, 0x10,
+ 0x10, 0x04, 0x41, 0x05, 0x01, 0x00, 0x05, 0x01, 0x10, 0x10, 0x40, 0x50,
+ 0xa2, 0x08, 0x80, 0x82, 0xa0, 0x8a, 0x20, 0x00, 0x02, 0x80, 0x22, 0x00,
+ 0x02, 0x0a, 0x28, 0x80, 0x20, 0x00, 0x80, 0x20, 0x08, 0x88, 0xa0, 0x00,
+ 0x02, 0x00, 0x0a, 0x02, 0x20, 0x08, 0x80, 0xa0, 0x51, 0x01, 0x00, 0x44,
+ 0x50, 0x11, 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, 0x01, 0x04, 0x40,
+ 0x10, 0x00, 0x40, 0x11, 0x10, 0x10, 0x11, 0x00, 0x01, 0x00, 0x10, 0x01,
+ 0x10, 0x10, 0x40, 0x50, 0xa2, 0x08, 0x00, 0x88, 0x80, 0x08, 0x20, 0x00,
+ 0x02, 0x02, 0x22, 0x00, 0x02, 0x02, 0x08, 0x20, 0x20, 0x00, 0x80, 0x08,
+ 0x08, 0x88, 0x20, 0x80, 0x00, 0x00, 0x20, 0x02, 0x20, 0x28, 0x80, 0xa0,
+ 0x51, 0x11, 0x10, 0x44, 0x40, 0x50, 0x40, 0x10, 0x01, 0x00, 0x11, 0x00,
+ 0x01, 0x01, 0x04, 0x40, 0x10, 0x00, 0x01, 0x11, 0x04, 0x50, 0x10, 0x00,
+ 0x01, 0x40, 0x10, 0x04, 0x11, 0x50, 0x00, 0x01, 0xa2, 0x28, 0x20, 0x82,
+ 0x0a, 0x20, 0xa0, 0x0a, 0x02, 0x02, 0x22, 0x88, 0x00, 0x82, 0x08, 0x22,
+ 0x08, 0x80, 0x80, 0x28, 0x08, 0x28, 0x20, 0x88, 0x00, 0x80, 0x08, 0xaa,
+ 0x20, 0xa0, 0x82, 0xaa, 0x41, 0x50, 0x50, 0x01, 0x55, 0x00, 0x00, 0x05,
+ 0x05, 0x05, 0x51, 0x04, 0x01, 0x45, 0x14, 0x11, 0x50, 0x00, 0x41, 0x50,
+ 0x04, 0x10, 0x50, 0x44, 0x00, 0x40, 0x05, 0x50, 0x50, 0x40, 0x01, 0x14,
+ 0xaa, 0xaa, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0x82,
+ 0x00, 0x2a, 0xa8, 0x20, 0x28, 0x80, 0x2a, 0x20, 0x08, 0x08, 0xa0, 0x82,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x55, 0x01, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x40, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x55, 0x55, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x2a, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x45,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0xa2, 0x22, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x88, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x0a, 0x08,
+ 0x02, 0x22, 0xa0, 0x80, 0x08, 0x00, 0xa0, 0x00, 0x20, 0xa0, 0xa0, 0xa0,
+ 0x41, 0x01, 0x51, 0x45, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x55, 0x55, 0x14, 0x00, 0x11, 0x14, 0x05, 0x45, 0x10, 0x41,
+ 0x11, 0x00, 0x40, 0x01, 0x14, 0x41, 0x40, 0x10, 0x82, 0x28, 0xa2, 0xaa,
+ 0x80, 0xa2, 0xa2, 0xa0, 0xa8, 0x00, 0x28, 0x28, 0x08, 0xa2, 0x02, 0xaa,
+ 0xa8, 0x80, 0x20, 0x88, 0x88, 0x0a, 0x08, 0x82, 0x20, 0x00, 0x80, 0x0a,
+ 0x00, 0x82, 0x00, 0x08, 0x04, 0x51, 0x51, 0x55, 0x45, 0x44, 0x11, 0x11,
+ 0x11, 0x01, 0x50, 0x44, 0x04, 0x11, 0x05, 0x55, 0x41, 0x41, 0x40, 0x10,
+ 0x40, 0x55, 0x04, 0x44, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, 0x01, 0x04,
+ 0x88, 0xa8, 0xa8, 0x2a, 0x2a, 0x20, 0x08, 0x0a, 0x0a, 0x02, 0xa0, 0x80,
+ 0x88, 0x08, 0xa2, 0xaa, 0x02, 0x22, 0x00, 0x08, 0xa0, 0x8a, 0x02, 0x88,
+ 0x20, 0x00, 0x00, 0x20, 0x00, 0x82, 0x20, 0x02, 0x05, 0x55, 0x54, 0x55,
+ 0x44, 0x40, 0x50, 0x51, 0x11, 0x01, 0x04, 0x51, 0x10, 0x51, 0x41, 0x55,
+ 0x05, 0x44, 0x00, 0x10, 0x00, 0x50, 0x54, 0x45, 0x40, 0x00, 0x00, 0x40,
+ 0x50, 0x01, 0x01, 0x54, 0x80, 0x2a, 0xaa, 0x0a, 0x28, 0x28, 0x08, 0x08,
+ 0x08, 0x02, 0x88, 0x88, 0x80, 0x08, 0xa8, 0xaa, 0x0a, 0x28, 0x00, 0x08,
+ 0xa0, 0x02, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80, 0x08, 0x02, 0x02, 0x02,
+ 0x00, 0x15, 0x55, 0x15, 0x44, 0x44, 0x10, 0x11, 0x11, 0x01, 0x04, 0x45,
+ 0x50, 0x10, 0x51, 0x55, 0x15, 0x44, 0x00, 0x10, 0x00, 0x01, 0x04, 0x40,
+ 0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x11, 0x04, 0x80, 0x0a, 0xaa, 0x2a,
+ 0x82, 0x22, 0xa0, 0xa0, 0x08, 0x02, 0xa8, 0xa8, 0x20, 0xa0, 0xa8, 0xaa,
+ 0x0a, 0x28, 0x00, 0x08, 0x80, 0x00, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80,
+ 0x02, 0x02, 0x0a, 0x02, 0x00, 0x04, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x44, 0x00, 0x10,
+ 0x10, 0x00, 0x04, 0x40, 0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x04, 0x04,
+ 0x08, 0x02, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xaa, 0x28, 0x82, 0x00, 0x08, 0xa8, 0x80, 0x08, 0x88,
+ 0x20, 0x00, 0x20, 0x20, 0x02, 0x0a, 0x0a, 0x08, 0x44, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x51, 0x01, 0x11, 0x10, 0x54, 0x41, 0x10, 0x44, 0x40, 0x00, 0x40, 0x10,
+ 0x04, 0x01, 0x04, 0x10, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x00, 0x0a, 0x2a,
+ 0x2a, 0x0a, 0xa0, 0xa0, 0xa0, 0x00, 0x20, 0x0a, 0x28, 0x02, 0x00, 0xa0,
+ 0x50, 0x01, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/x2go.xpm b/nx-X11/programs/Xserver/hw/nxagent/x2go.xpm
new file mode 100644
index 000000000..46a74eab9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/x2go.xpm
@@ -0,0 +1,163 @@
+/**************************************************************************/
+/* */
+/* Copyright 2008 Heinz-M. Graesing <heinz-m.graesing@obviously-nice.de> */
+/* */
+/* NXAGENT, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+/* XPM */
+static char *x2goagentIconData[]={
+"128 128 17 1",
+". c None",
+"m c #323232",
+"l c #323232",
+"f c #323232",
+"e c #323232",
+"o c #323232",
+"# c #323232",
+"h c #323232",
+"i c #323232",
+"n c #323232",
+"d c #323232",
+"a c #323232",
+"g c #323232",
+"j c #323232",
+"b c #323232",
+"k c #323232",
+"c c #323232",
+".....#abccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbde.....",
+"...fbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccgf...",
+"..#ccccaheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeijccckf..",
+".ecccgl..................................................................................................................ejcckf.",
+".bccd.....................................................................................................................mdccg.",
+"#cca.......................................................................................................................mjcce",
+"gckm........................................................................................................................eccd",
+"ccn..........................................................................................................................jcb",
+"cce..........................................................................................................................icc",
+"ccm..........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc............................................meeee..........................................................................ecc",
+"cc.........eeeeeeeeoiiiiiiiinggggggggjccccccccccccc....#ggggggggggggggggggggggggggggf.............ggggggggggggggggggggggf....ecc",
+"cc....meeeeoiiiiiiiinggggggggjccccccccccccccccccccc....icccccccccccccccccccccccccccce.............cccccccccccccccccccccce....ecc",
+"cc....................................meeeeeeeeoiii....icccccccccccccccccccccccccccce.............cccccccccccccccccccccce....ecc",
+"cc.......................................................menbccccccccccccccccccbhe..................logccccccccccccghe.......ecc",
+"cc...........................................................iccccccccccccccccdm.......................#cccccccccke..........ecc",
+"cc..............................................lee...........#cccccccccccccckm.........................jccccccckm...........ecc",
+"cc........feeeeeeeeoiiiiiiiiiaggggggggjcccccccccccc............icccccccccccccd..........................icccccccf............ecc",
+"cc....meeeeeoiiiiiiiinggggggggjcccccccccccccccccccciiiiii#m.....jcccccccccccci..........................icccccci.............ecc",
+"cc......................................eeeeeeeeeiiiiiiiiigl....eccccccccccccd..........................dcccccj..............ecc",
+"cc...............................................................dcccccccccccj..........................bccccce..............ecc",
+"cc...............................................................lccccccccccccl........................lccccca...............ecc",
+"cc.............................................meeeeeeee#iiiie....dccccccccccch........................icccccl...............ecc",
+"cc.........meeeeeeeeoiiiiiiiinggggggggjccccccccccccccccccccccb....ecccccccccccb........................bccccn................ecc",
+"cc....meeeeiiiiiiiiiaggggggggbcccccccccccccccccccccccccccccccc#....gccccccccccco......................#cccckm................ecc",
+"cc....................................meeeeeeeeeiiiiiiiiiaggggd....#cccccccccccg......................bcccci.................ecc",
+"cc..................................................................bcccccccccccf....................#cccckm.................ecc",
+"cc..................................................................hcccccccccccd...................mkcccci..................ecc",
+"cc............................................meeeeeeeeoiiiiiiiil...mkcccccccccccl..................icccckm..................ecc",
+"cc.........eeeeeeeeoiiiiiiiinggggggggjccccccccccccccccccccccccccn....dccccccccccci.................mkcccci...................ecc",
+"cc....meeeeeiiiiiiiiiaggggggggbccccccccccccccccccccccccccccccccckm...lccccccccccck.................icccckm...................ecc",
+"cc.....................................leeeeeeeeoiiiiiiiiigggggggo....accccccccccc#...............mkcccch....................ecc",
+"cc....................................................................ecccccccccccb...............iccccb.....................ecc",
+"cc.....................................................................jccccccccccce.............mkcccc#.....................ecc",
+"cc.............................................meeeeeeeeehiiiiiiii#....#ccccccccccca.............nccccb......................ecc",
+"cc........feeeeeeee#iiiiiiiiigggggggggkccccccccccccccccccccccccccccl....kcccccccccccl...........lccccc#......................ecc",
+"cc....meeeeeoiiiiiiiiigggggggggkcccccccccccccccccccccccccccccccccccd....icccccccccccd...........dccccb.......................ecc",
+"cc......................................leeeeeeeeoiiiiiiiingggggggga....mccccccccccckm.........lccccc#.......................ecc",
+"cc.......................................................................dccccccccccch.........dccccb........................ecc",
+"cc.......................................................................lcccccccccccb........lccccc#........................ecc",
+"cc.............................................meeeeeeeeoiiiiiiiingggo....gccccccccccc#.......dccccg.........................ecc",
+"cc.........meeeeeeeeoiiiiiiiinggggggggjccccccccccccccccccccccccccccccg....occcccccccccg......lccccce.........................ecc",
+"cc....meeeeiiiiiiiiiaggggggggbcccccccccccccccccccccccccccccccccccccccce....bccccccccccce.....gccccg..........................ecc",
+"cc....................................meeeeeeeeeiiiiiiiiigggggggggkcccd....#cccccccccccd....eccccce..........................ecc",
+"cc.........................................................................mkcccccccccccl...gccccg...........................ecc",
+"cc..........................................................................nccccccccccci..eccccce...........................ecc",
+"cc............................................meeeeeeeeoiiiiiiiingggggggm...lccccccccccckm.gccccg............................ecc",
+"cc.........eeeeeeeeoiiiiiiiinggggggggjcccccccccccccccccccccccccccccccccc#....dccccccccccc#eccccce............................ecc",
+"cc....meeeeeiiiiiiiiiaggggggggkcccccccccccccccccccccccccccccccccccccccccb....ecccccccccccbgccccg.............................ecc",
+"cc.....................................leeeeeeeeoiiiiiiiiigggggggggkccccco....gccccccccccccccccl.............................ecc",
+"cc............................................................................#cccccccccccccccd..............................ecc",
+"cc.............................................................................bccccccccccccccl..............................ecc",
+"cc.............................................leeeeeeeeeiiiiiiiiiagggggggi....icccccccccccccd...............................ecc",
+"cc........feeeeeeee#iiiiiiiingggggggggkccccccccccccccccccccccccccccccccccckm...mkccccccccccccl...............................ecc",
+"cc....meeeeeoiiiiiiiiigggggggggkccccccccccccccccccccccccccccccccccccccccccci....dccccccccccca................................ecc",
+"cc......................................leeeeeeeeoiiiiiiiiigggggggggccccccck....lccccccccccckm...............................ecc",
+"cc...............................................................................accccccccccc#...............................ecc",
+"cc...............................................................................ecccccccccccb...............................ecc",
+"cc............................................leeeeeeeeeiiiiiiiiiaggggggggbcce....bccccccccccce..............................ecc",
+"cc.......feeeeeeee#iiiiiiiiigggggggggkcccccccccccccccccccccccccccccccccccccccd....#cccccccccccg..............................ecc",
+"cc....meeeeeeoiiiiiiiingggggggggccccccccccccccccccccccccccccccccccccccccccccccl....kcccccccccccl.............................ecc",
+"cc.......................................feeeeeeeehiiiiiiiidggggggggbccccccccci....ncccccccccccd.............................ecc",
+"cc...........................................................................mm....bccccccccccccm............................ecc",
+"cc................................................................................#ccccccccccccci............................ecc",
+"cc..........................................leeeeeeee#iiiiiiiidggggggggbcccccl....bccccccccccccck............................ecc",
+"cc......feeeeeeeehiiiiiiiiaggggggggkccccccccccccccccccccccccccccccccccccccccd....#ccccccccccccccc#...........................ecc",
+"cc....meeeeeee#iiiiiiiidggggggggjcccccccccccccccccccccccccccccccccccccccccccl....bcccccccccccccccb...........................ecc",
+"cc.......................................meeeeeeeeeiiiiiiiiigggggggggkcccccd....#cccccbccccccccccce..........................ecc",
+"cc..............................................................................bccccdhcccccccccccg..........................ecc",
+"cc.............................................................................#ccccclmkcccccccccccl.........................ecc",
+"cc..........................................meeeeeeeeeiiiiiiiiiaggggggggbkm....bccccd..ncccccccccccd.........................ecc",
+"cc.....leeeeeeeeoiiiiiiiiigggggggggkccccccccccccccccccccccccccccccccccccci....hcccckl..lccccccccccccm........................ecc",
+"cc....meeeeeeeehiiiiiiiidggggggggbcccccccccccccccccccccccccccccccccccccckm...mkcccci....dccccccccccci........................ecc",
+"cc........................................leeeeeeee#iiiiiiiinggggggggjcci....icccckm....eccccccccccck........................ecc",
+"cc..........................................................................mkcccci......gccccccccccc#.......................ecc",
+"cc..........................................................................icccckm......#cccccccccccb.......................ecc",
+"cc.........................................leeeeeeeeoiiiiiiiiigggggggga....mkcccci........bccccccccccce......................ecc",
+"cc....meeeeeeeeoiiiiiiiiigggggggggkccccccccccccccccccccccccccccccccccci....icccckm........hcccccccccccg......................ecc",
+"cc.....feeeeeeeehiiiiiiiiaggggggggkcccccccccccccccccccccccccccccccccckm...mkcccci.........mkcccccccccccl.....................ecc",
+"cc.........................................feeeeeeeehiiiiiiiiagggggggh....icccckm..........icccccccccccd.....................ecc",
+"cc.......................................................................mkcccci...........lccccccccccccm....................ecc",
+"cc.......................................................................icccckm............dccccccccccci....................ecc",
+"cc...........................................eeeeeeeeehiiiiiiiidggga....mkcccci.............fccccccccccck....................ecc",
+"cc......feeeeeeee#iiiiiiiingggggggggccccccccccccccccccccccccccccccci....iccccb...............gccccccccccc#...................ecc",
+"cc....meeeeeeeoiiiiiiiiigggggggggbcccccccccccccccccccccccccccccccckm...mkcccc#...............occcccccccccb...................ecc",
+"cc........................................meeeeeeeeeiiiiiiiiidgggg#....iccccb.................bccccccccccce..................ecc",
+"cc....................................................................mkcccc#.................#cccccccccccg..................ecc",
+"cc....................................................................iccccb..................mkcccccccccccl.................ecc",
+"cc..........................................eeeeeeeeeiiiiiiiiiaga....mkcccc#...................icccccccccccd.................ecc",
+"cc.....leeeeeeee#iiiiiiiinggggggggjccccccccccccccccccccccccccccci....iccccb....................lccccccccccccm................ecc",
+"cc....meeeeeeee#iiiiiiiiigggggggggkcccccccccccccccccccccccccccckm...mkcccc#.....................dccccccccccci................ecc",
+"cc.........................................leeeeeeeeoiiiiiiiiiah....iccccb......................lccccccccccck................ecc",
+"cc.................................................................mkcccc#.......................gccccccccccc#...............ecc",
+"cc.................................................................dccccj........................ecccccccccccj...............ecc",
+"cc..........................................leeeeeeeeeiiiiiiih....lccccce.........................bccccccccccce..............ecc",
+"cc....meeeeeeeeeiiiiiiiiidgggggggggcccccccccccccccccccccccccci....dccccg..........................#ccccccccccca..............ecc",
+"cc.....feeeeeeeeiiiiiiiinggggggggbcccccccccccccccccccccccccckm...lccccce...........................kcccccccccccl.............ecc",
+"cc........................................leeeeeeeehiiiiiiiih....dccccg............................ncccccccccccd.............ecc",
+"cc..............................................................lccccce............................fccccccccccccf............ecc",
+"cc..............................................................dccccb..............................jcccccccccccg............ecc",
+"cc.........................................meeeeeeeeoiiiiil....lcccccn..............................icccccccccccce...........ecc",
+"cc......feeeeeeeehiiiiiiiigggggggggccccccccccccccccjgggggo.....gccccc#..............................eccccccccccccbm..........ecc",
+"cc....meeeeeeeoiiiiiiiiidgggggggggccccccccccccccccc...........hcccccco...............................cccccccccccccn..........ecc",
+"cc.........................................leeeeeee..........ecccccccn..............................lcccccccccccccc#.........ecc",
+"cc..........................................................#kccccccckf.............................nccccccccccccccc#........ecc",
+"cc........................................................ldcccccccccck#m.........................lncccccccccccccccccdl......ecc",
+"cc.........................................feeeeeee....ogjcccccccccccccccggi..................oggbcccccccccccccccccccccja....ecc",
+"cc.....leeeeeeee#iiiiiiiidggggggggbcccccccccccccccc....icccccccccccccccccccg..................icccccccccccccccccccccccccc....ecc",
+"cc....meeeeeeeehiiiiiiiiaggggggggkccccccccccccccccc....icccccccccccccccccccg..................icccccccccccccccccccccccccc....ecc",
+"cc........................................feeeeeeee..........................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cc...........................................................................................................................ecc",
+"cce..........................................................................................................................hcc",
+"ccn..........................................................................................................................acb",
+"jcb.........................................................................................................................lcca",
+"hcci........................................................................................................................acc#",
+"mkcc#......................................................................................................................dccb.",
+".occci...................................................................................................................macccf.",
+"..#cccbne.............................................................................................................menkccc#..",
+"...okccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccbe...",
+"....mhjccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccg#....."};
diff --git a/nx-X11/programs/Xserver/include/.gitignore b/nx-X11/programs/Xserver/include/.gitignore
new file mode 100644
index 000000000..919ccf080
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/.gitignore
@@ -0,0 +1 @@
+osdep.h
diff --git a/nx-X11/programs/Xserver/include/Imakefile b/nx-X11/programs/Xserver/include/Imakefile
new file mode 100644
index 000000000..53f193ec8
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/Imakefile
@@ -0,0 +1,54 @@
+HEADERS = os.h misc.h
+
+#if defined(XorgVersion) \
+ || defined(BSDOSArchitecture)
+#endif
+
+LinkSourceFile(osdep.h,../os)
+#ifdef cygwinArchitecture
+LinkFile(xxwindow.h,window.h)
+#endif
+
+all::
+
+depend::
+
+InstallDriverSDKNonExecFile(XIstubs.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(bstore.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(bstorestr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(client.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(colormap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(colormapst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(cursor.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(cursorstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(dix.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(dixstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(exevents.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(extension.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(extnsionst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(gc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(gcstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(globals.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(input.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(inputstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(list.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(misc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(miscstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(opaque.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(os.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(pixmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(pixmapstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(property.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(propertyst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(region.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(regionstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(resource.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(screenint.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(scrnintstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(servermd.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(validate.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(window.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(windowstr.h,$(DRIVERSDKINCLUDEDIR))
+
+BuildIncludes($(HEADERS),nx-X11,..)
+InstallMultipleFlags($(HEADERS),$(INCDIR)/nx-X11,$(INSTINCFLAGS))
diff --git a/nx-X11/programs/Xserver/include/XIstubs.h b/nx-X11/programs/Xserver/include/XIstubs.h
new file mode 100644
index 000000000..45f6eb10c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/XIstubs.h
@@ -0,0 +1,75 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifndef XI_STUBS_H
+#define XI_STUBS_H 1
+
+int
+ChangeKeyboardDevice (
+ DeviceIntPtr /* old_dev */,
+ DeviceIntPtr /* new_dev */);
+
+int
+ChangePointerDevice (
+ DeviceIntPtr /* old_dev */,
+ DeviceIntPtr /* new_dev */,
+ unsigned char /* x */,
+ unsigned char /* y */);
+
+void
+CloseInputDevice (
+ DeviceIntPtr /* d */,
+ ClientPtr /* client */);
+
+void
+AddOtherInputDevices (void);
+
+void
+OpenInputDevice (
+ DeviceIntPtr /* dev */,
+ ClientPtr /* client */,
+ int * /* status */);
+
+int
+SetDeviceMode (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* mode */);
+
+int
+SetDeviceValuators (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int * /* valuators */,
+ int /* first_valuator */,
+ int /* num_valuators */);
+
+int
+ChangeDeviceControl (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ xDeviceCtl * /* control */);
+
+#endif /* XI_STUBS_H */
diff --git a/nx-X11/programs/Xserver/include/bstore.h b/nx-X11/programs/Xserver/include/bstore.h
new file mode 100644
index 000000000..843d6bb35
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/bstore.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of
+ * California makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ */
+
+/*
+ * Moved here from mi to allow wrapping of lower level backing store functions.
+ * -- 1997.10.27 Marc Aurele La France (tsi@xfree86.org)
+ */
+
+#ifndef _BSTORE_H_
+#define _BSTORE_H_
+
+#include "bstorestr.h"
+
+#endif /* _BSTORE_H_ */
diff --git a/nx-X11/programs/Xserver/include/bstorestr.h b/nx-X11/programs/Xserver/include/bstorestr.h
new file mode 100644
index 000000000..14e2fe1da
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/bstorestr.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of
+ * California makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ */
+
+/*
+ * Moved here from mi to allow wrapping of lower level backing store functions.
+ * -- 1997.10.27 Marc Aurele La France (tsi@xfree86.org)
+ */
+
+#ifndef _BSTORESTR_H_
+#define _BSTORESTR_H_
+
+#include "gc.h"
+#include "pixmap.h"
+#include "region.h"
+#include "window.h"
+
+typedef void (* BackingStoreSaveAreasProcPtr)(
+ PixmapPtr /*pBackingPixmap*/,
+ RegionPtr /*pObscured*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pWin*/);
+
+typedef void (* BackingStoreRestoreAreasProcPtr)(
+ PixmapPtr /*pBackingPixmap*/,
+ RegionPtr /*pExposed*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pWin*/);
+
+typedef void (* BackingStoreSetClipmaskRgnProcPtr)(
+ GCPtr /*pBackingGC*/,
+ RegionPtr /*pbackingCompositeClip*/);
+
+typedef PixmapPtr (* BackingStoreGetImagePixmapProcPtr)(void);
+
+typedef PixmapPtr (* BackingStoreGetSpansPixmapProcPtr)(void);
+
+typedef struct _BSFuncs {
+
+ BackingStoreSaveAreasProcPtr SaveAreas;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+ BackingStoreSetClipmaskRgnProcPtr SetClipmaskRgn;
+ BackingStoreGetImagePixmapProcPtr GetImagePixmap;
+ BackingStoreGetSpansPixmapProcPtr GetSpansPixmap;
+
+} BSFuncRec, *BSFuncPtr;
+
+#endif /* _BSTORESTR_H_ */
diff --git a/nx-X11/programs/Xserver/include/client.h b/nx-X11/programs/Xserver/include/client.h
new file mode 100644
index 000000000..87f2b1172
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/client.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All
+ * rights reserved.
+ *
+ * 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 THE
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+/* Author: Rami Ylimäki <rami.ylimaki@vincit.fi> */
+
+#ifndef CLIENT_H
+#define CLIENT_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif /* HAVE_DIX_CONFIG_H */
+#include <X11/Xfuncproto.h>
+#include <sys/types.h>
+
+/* Client IDs. Use GetClientPid, GetClientCmdName and GetClientCmdArgs
+ * instead of accessing the fields directly. */
+typedef struct {
+ pid_t pid; /* process ID, -1 if not available */
+ const char *cmdname; /* process name, NULL if not available */
+ const char *cmdargs; /* process arguments, NULL if not available */
+} ClientIdRec, *ClientIdPtr;
+
+struct _Client;
+
+/* Initialize and clean up. */
+void ReserveClientIds(struct _Client *client);
+void ReleaseClientIds(struct _Client *client);
+
+/* Determine client IDs for caching. Exported on purpose for
+ * extensions such as SELinux. */
+extern _X_EXPORT pid_t DetermineClientPid(struct _Client *client);
+extern _X_EXPORT void DetermineClientCmd(pid_t, const char **cmdname,
+ const char **cmdargs);
+
+/* Query cached client IDs. Exported on purpose for drivers. */
+extern _X_EXPORT pid_t GetClientPid(struct _Client *client);
+extern _X_EXPORT const char *GetClientCmdName(struct _Client *client);
+extern _X_EXPORT const char *GetClientCmdArgs(struct _Client *client);
+
+#endif /* CLIENT_H */
diff --git a/nx-X11/programs/Xserver/include/closestr.h b/nx-X11/programs/Xserver/include/closestr.h
new file mode 100644
index 000000000..b19108d94
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/closestr.h
@@ -0,0 +1,156 @@
+/*
+
+Copyright 1991, 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.
+
+*/
+
+
+#ifndef CLOSESTR_H
+#define CLOSESTR_H
+
+#include <nx-X11/Xproto.h>
+#include "closure.h"
+#include "dix.h"
+#include "misc.h"
+#include "gcstruct.h"
+
+/* closure structures */
+
+/* OpenFont */
+
+typedef struct _OFclosure {
+ ClientPtr client;
+ short current_fpe;
+ short num_fpes;
+ FontPathElementPtr *fpe_list;
+ Mask flags;
+ Bool slept;
+
+/* XXX -- get these from request buffer instead? */
+ char *origFontName;
+ int origFontNameLen;
+ XID fontid;
+ char *fontname;
+ int fnamelen;
+ FontPtr non_cachable_font;
+} OFclosureRec;
+
+/* ListFontsWithInfo */
+
+#define XLFDMAXFONTNAMELEN 256
+typedef struct _LFWIstate {
+ char pattern[XLFDMAXFONTNAMELEN];
+ int patlen;
+ int current_fpe;
+ int max_names;
+ Bool list_started;
+ void * private;
+} LFWIstateRec, *LFWIstatePtr;
+
+typedef struct _LFWIclosure {
+ ClientPtr client;
+ int num_fpes;
+ FontPathElementPtr *fpe_list;
+ xListFontsWithInfoReply *reply;
+ int length;
+ LFWIstateRec current;
+ LFWIstateRec saved;
+ int savedNumFonts;
+ Bool haveSaved;
+ Bool slept;
+ char *savedName;
+} LFWIclosureRec;
+
+/* ListFonts */
+
+typedef struct _LFclosure {
+ ClientPtr client;
+ int num_fpes;
+ FontPathElementPtr *fpe_list;
+ FontNamesPtr names;
+ LFWIstateRec current;
+ LFWIstateRec saved;
+ Bool haveSaved;
+ Bool slept;
+ char *savedName;
+ int savedNameLen;
+} LFclosureRec;
+
+/* PolyText */
+
+typedef
+ int (* PolyTextPtr)(
+ DrawablePtr /* pDraw */,
+ GCPtr /* pGC */,
+ int /* x */,
+ int /* y */,
+ int /* count */,
+ void * /* chars or shorts */
+ );
+
+typedef struct _PTclosure {
+ ClientPtr client;
+ DrawablePtr pDraw;
+ GC *pGC;
+ unsigned char *pElt;
+ unsigned char *endReq;
+ unsigned char *data;
+ int xorg;
+ int yorg;
+ CARD8 reqType;
+ PolyTextPtr polyText;
+ int itemSize;
+ XID did;
+ int err;
+ Bool slept;
+} PTclosureRec;
+
+/* ImageText */
+
+typedef
+ void (* ImageTextPtr)(
+ DrawablePtr /* pDraw */,
+ GCPtr /* pGC */,
+ int /* x */,
+ int /* y */,
+ int /* count */,
+ void * /* chars or shorts */
+ );
+
+typedef struct _ITclosure {
+ ClientPtr client;
+ DrawablePtr pDraw;
+ GC *pGC;
+ BYTE nChars;
+ unsigned char *data;
+ int xorg;
+ int yorg;
+ CARD8 reqType;
+ ImageTextPtr imageText;
+ int itemSize;
+ XID did;
+ Bool slept;
+} ITclosureRec;
+#endif /* CLOSESTR_H */
diff --git a/nx-X11/programs/Xserver/include/closure.h b/nx-X11/programs/Xserver/include/closure.h
new file mode 100644
index 000000000..b261f5e0d
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/closure.h
@@ -0,0 +1,57 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef CLOSURE_H
+#define CLOSURE_H 1
+
+typedef struct _LFclosure *LFclosurePtr;
+typedef struct _LFWIclosure *LFWIclosurePtr;
+typedef struct _OFclosure *OFclosurePtr;
+typedef struct _PTclosure *PTclosurePtr;
+typedef struct _ITclosure *ITclosurePtr;
+
+#endif /* CLOSURE_H */
diff --git a/nx-X11/programs/Xserver/include/colormap.h b/nx-X11/programs/Xserver/include/colormap.h
new file mode 100644
index 000000000..be3803848
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/colormap.h
@@ -0,0 +1,186 @@
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+#ifndef CMAP_H
+#define CMAP_H 1
+
+#include <nx-X11/Xproto.h>
+#include "screenint.h"
+#include "window.h"
+
+/* these follow X.h's AllocNone and AllocAll */
+#define CM_PSCREEN 2
+#define CM_PWIN 3
+/* Passed internally in colormap.c */
+#define REDMAP 0
+#define GREENMAP 1
+#define BLUEMAP 2
+#define PSEUDOMAP 3
+#define AllocPrivate (-1)
+#define AllocTemporary (-2)
+#define DynamicClass 1
+
+/* Values for the flags field of a colormap. These should have 1 bit set
+ * and not overlap */
+#define IsDefault 1
+#define AllAllocated 2
+#define BeingCreated 4
+
+
+typedef CARD32 Pixel;
+typedef struct _CMEntry *EntryPtr;
+/* moved to screenint.h: typedef struct _ColormapRec *ColormapPtr */
+typedef struct _colorResource *colorResourcePtr;
+
+extern int CreateColormap(
+ Colormap /*mid*/,
+ ScreenPtr /*pScreen*/,
+ VisualPtr /*pVisual*/,
+ ColormapPtr* /*ppcmap*/,
+ int /*alloc*/,
+ int /*client*/);
+
+extern int FreeColormap(
+ void * /*pmap*/,
+ XID /*mid*/);
+
+extern int TellLostMap(
+ WindowPtr /*pwin*/,
+ void * /* Colormap *pmid */);
+
+extern int TellGainedMap(
+ WindowPtr /*pwin*/,
+ void * /* Colormap *pmid */);
+
+extern int CopyColormapAndFree(
+ Colormap /*mid*/,
+ ColormapPtr /*pSrc*/,
+ int /*client*/);
+
+extern int AllocColor(
+ ColormapPtr /*pmap*/,
+ unsigned short* /*pred*/,
+ unsigned short* /*pgreen*/,
+ unsigned short* /*pblue*/,
+ Pixel* /*pPix*/,
+ int /*client*/);
+
+extern void FakeAllocColor(
+ ColormapPtr /*pmap*/,
+ xColorItem * /*item*/);
+
+extern void FakeFreeColor(
+ ColormapPtr /*pmap*/,
+ Pixel /*pixel*/);
+
+typedef int (*ColorCompareProcPtr)(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/);
+
+extern int FindColor(
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb* /*prgb*/,
+ Pixel* /*pPixel*/,
+ int /*channel*/,
+ int /*client*/,
+ ColorCompareProcPtr /*comp*/);
+
+extern int QueryColors(
+ ColormapPtr /*pmap*/,
+ int /*count*/,
+ Pixel* /*ppixIn*/,
+ xrgb* /*prgbList*/);
+
+extern int FreeClientPixels(
+ void * /*pcr*/,
+ XID /*fakeid*/);
+
+extern int AllocColorCells(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*colors*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel* /*ppix*/,
+ Pixel* /*masks*/);
+
+extern int AllocColorPlanes(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*colors*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel* /*pixels*/,
+ Pixel* /*prmask*/,
+ Pixel* /*pgmask*/,
+ Pixel* /*pbmask*/);
+
+extern int FreeColors(
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*count*/,
+ Pixel* /*pixels*/,
+ Pixel /*mask*/);
+
+extern int StoreColors(
+ ColormapPtr /*pmap*/,
+ int /*count*/,
+ xColorItem* /*defs*/);
+
+extern int IsMapInstalled(
+ Colormap /*map*/,
+ WindowPtr /*pWin*/);
+
+extern Bool ResizeVisualArray(ScreenPtr /* pScreen */ ,
+ int /* new_vis_count */ ,
+ DepthPtr /* depth */ );
+
+#endif /* CMAP_H */
diff --git a/nx-X11/programs/Xserver/include/colormapst.h b/nx-X11/programs/Xserver/include/colormapst.h
new file mode 100644
index 000000000..a8fa055de
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/colormapst.h
@@ -0,0 +1,120 @@
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+*/
+
+#ifndef CMAPSTRUCT_H
+#define CMAPSTRUCT_H 1
+
+#include "colormap.h"
+#include "screenint.h"
+
+/* Shared color -- the color is used by AllocColorPlanes */
+typedef struct
+{
+ unsigned short color;
+ short refcnt;
+} SHAREDCOLOR;
+
+/* LOCO -- a local color for a PseudoColor cell. DirectColor maps always
+ * use the first value (called red) in the structure. What channel they
+ * are really talking about depends on which map they are in. */
+typedef struct
+{
+ unsigned short red, green, blue;
+} LOCO;
+
+/* SHCO -- a shared color for a PseudoColor cell. Used with AllocColorPlanes.
+ * DirectColor maps always use the first value (called red) in the structure.
+ * What channel they are really talking about depends on which map they
+ * are in. */
+typedef struct
+{
+ SHAREDCOLOR *red, *green, *blue;
+} SHCO;
+
+
+/* color map entry */
+typedef struct _CMEntry
+{
+ union
+ {
+ LOCO local;
+ SHCO shco;
+ } co;
+ short refcnt;
+ Bool fShared;
+} Entry;
+
+/* COLORMAPs can be used for either Direct or Pseudo color. PseudoColor
+ * only needs one cell table, we arbitrarily pick red. We keep track
+ * of that table with freeRed, numPixelsRed, and clientPixelsRed */
+
+typedef struct _ColormapRec
+{
+ VisualPtr pVisual;
+ short class; /* PseudoColor or DirectColor */
+ long mid; /* client's name for colormap */
+ ScreenPtr pScreen; /* screen map is associated with */
+ short flags; /* 1 = IsDefault
+ * 2 = AllAllocated */
+ int freeRed;
+ int freeGreen;
+ int freeBlue;
+ int *numPixelsRed;
+ int *numPixelsGreen;
+ int *numPixelsBlue;
+ Pixel **clientPixelsRed;
+ Pixel **clientPixelsGreen;
+ Pixel **clientPixelsBlue;
+ Entry *red;
+ Entry *green;
+ Entry *blue;
+ void * devPriv;
+ DevUnion *devPrivates; /* dynamic devPrivates added after devPriv
+ already existed - must keep devPriv */
+} ColormapRec;
+
+#endif /* COLORMAP_H */
diff --git a/nx-X11/programs/Xserver/include/cursor.h b/nx-X11/programs/Xserver/include/cursor.h
new file mode 100644
index 000000000..4b9444888
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/cursor.h
@@ -0,0 +1,146 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef CURSOR_H
+#define CURSOR_H
+
+#include "misc.h"
+#include "screenint.h"
+#include "window.h"
+
+#define NullCursor ((CursorPtr)NULL)
+
+/* Provide support for alpha composited cursors */
+#ifdef RENDER
+#define ARGB_CURSOR
+#endif
+
+typedef struct _Cursor *CursorPtr;
+typedef struct _CursorMetric *CursorMetricPtr;
+
+extern CursorPtr rootCursor;
+
+extern int FreeCursor(
+ void * /*pCurs*/,
+ XID /*cid*/);
+
+/* Quartz support on Mac OS X pulls in the QuickDraw
+ framework whose AllocCursor function conflicts here. */
+#ifdef __DARWIN__
+#define AllocCursor Darwin_X_AllocCursor
+#endif
+extern CursorPtr AllocCursor(
+ unsigned char* /*psrcbits*/,
+ unsigned char* /*pmaskbits*/,
+ CursorMetricPtr /*cm*/,
+ unsigned /*foreRed*/,
+ unsigned /*foreGreen*/,
+ unsigned /*foreBlue*/,
+ unsigned /*backRed*/,
+ unsigned /*backGreen*/,
+ unsigned /*backBlue*/);
+
+extern CursorPtr AllocCursorARGB(
+ unsigned char* /*psrcbits*/,
+ unsigned char* /*pmaskbits*/,
+ CARD32* /*argb*/,
+ CursorMetricPtr /*cm*/,
+ unsigned /*foreRed*/,
+ unsigned /*foreGreen*/,
+ unsigned /*foreBlue*/,
+ unsigned /*backRed*/,
+ unsigned /*backGreen*/,
+ unsigned /*backBlue*/);
+
+extern int AllocGlyphCursor(
+ Font /*source*/,
+ unsigned int /*sourceChar*/,
+ Font /*mask*/,
+ unsigned int /*maskChar*/,
+ unsigned /*foreRed*/,
+ unsigned /*foreGreen*/,
+ unsigned /*foreBlue*/,
+ unsigned /*backRed*/,
+ unsigned /*backGreen*/,
+ unsigned /*backBlue*/,
+ CursorPtr* /*ppCurs*/,
+ ClientPtr /*client*/);
+
+extern CursorPtr CreateRootCursor(
+ char* /*pfilename*/,
+ unsigned int /*glyph*/);
+
+extern int ServerBitsFromGlyph(
+ FontPtr /*pfont*/,
+ unsigned int /*ch*/,
+ register CursorMetricPtr /*cm*/,
+ unsigned char ** /*ppbits*/);
+
+extern Bool CursorMetricsFromGlyph(
+ FontPtr /*pfont*/,
+ unsigned /*ch*/,
+ CursorMetricPtr /*cm*/);
+
+extern void CheckCursorConfinement(
+ WindowPtr /*pWin*/);
+
+extern void NewCurrentScreen(
+ ScreenPtr /*newScreen*/,
+ int /*x*/,
+ int /*y*/);
+
+extern Bool PointerConfinedToScreen(void);
+
+extern void GetSpritePosition(
+ int * /*px*/,
+ int * /*py*/);
+
+#ifdef PANORAMIX
+extern int XineramaGetCursorScreen(void);
+#endif /* PANORAMIX */
+
+#endif /* CURSOR_H */
diff --git a/nx-X11/programs/Xserver/include/cursorstr.h b/nx-X11/programs/Xserver/include/cursorstr.h
new file mode 100644
index 000000000..bc7d24c04
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/cursorstr.h
@@ -0,0 +1,93 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef CURSORSTRUCT_H
+#define CURSORSTRUCT_H
+
+#include "cursor.h"
+/*
+ * device-independent cursor storage
+ */
+
+/*
+ * source and mask point directly to the bits, which are in the server-defined
+ * bitmap format.
+ */
+typedef struct _CursorBits {
+ unsigned char *source; /* points to bits */
+ unsigned char *mask; /* points to bits */
+ Bool emptyMask; /* all zeros mask */
+ unsigned short width, height, xhot, yhot; /* metrics */
+ int refcnt; /* can be shared */
+ void * devPriv[MAXSCREENS]; /* set by pScr->RealizeCursor*/
+#ifdef ARGB_CURSOR
+ CARD32 *argb; /* full-color alpha blended */
+#endif
+} CursorBits, *CursorBitsPtr;
+
+typedef struct _Cursor {
+ CursorBitsPtr bits;
+ unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */
+ unsigned short backRed, backGreen, backBlue; /* device-independent color */
+ int refcnt;
+ void * devPriv[MAXSCREENS]; /* set by pScr->RealizeCursor*/
+#ifdef XFIXES
+ CARD32 serialNumber;
+ Atom name;
+#endif
+} CursorRec;
+
+typedef struct _CursorMetric {
+ unsigned short width, height, xhot, yhot;
+} CursorMetricRec;
+
+typedef struct {
+ int x, y;
+ ScreenPtr pScreen;
+} HotSpot;
+
+#endif /* CURSORSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/dix.h b/nx-X11/programs/Xserver/include/dix.h
new file mode 100644
index 000000000..4a57f724d
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dix.h
@@ -0,0 +1,786 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef DIX_H
+#define DIX_H
+
+#include <stdint.h>
+
+#include "gc.h"
+#include "window.h"
+#include "input.h"
+
+#define EARLIER -1
+#define SAMETIME 0
+#define LATER 1
+
+#define NullClient ((ClientPtr) 0)
+#define REQUEST(type) \
+ register type *stuff = (type *)client->requestBuffer
+
+
+#define REQUEST_SIZE_MATCH(req)\
+ if ((sizeof(req) >> 2) != client->req_len)\
+ return(BadLength)
+
+#define REQUEST_AT_LEAST_SIZE(req) \
+ if ((sizeof(req) >> 2) > client->req_len )\
+ return(BadLength)
+
+#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \
+ if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \
+ return(BadLength)
+
+#define REQUEST_FIXED_SIZE(req, n)\
+ if (((sizeof(req) >> 2) > client->req_len) || \
+ ((n >> 2) >= client->req_len) || \
+ ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \
+ return(BadLength)
+
+#define LEGAL_NEW_RESOURCE(id,client)\
+ if (!LegalNewID(id,client)) \
+ {\
+ client->errorValue = id;\
+ return(BadIDChoice);\
+ }
+
+/* XXX if you are using this macro, you are probably not generating Match
+ * errors where appropriate */
+#define LOOKUP_DRAWABLE(did, client)\
+ ((DrawablePtr)LookupDrawable(did, client))
+
+#ifdef XCSECURITY
+
+#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\
+ {\
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
+ RC_DRAWABLE, mode);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ if (pDraw->type == UNDRAWABLE_WINDOW)\
+ return BadMatch;\
+ }
+
+#define SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, mode)\
+ {\
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
+ RC_DRAWABLE, mode);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ }
+
+#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
+ pGC = (GC *) SecurityLookupIDByType(client, rid, RT_GC, mode);\
+ if (!pGC)\
+ {\
+ client->errorValue = rid;\
+ return (BadGC);\
+ }
+
+#define VERIFY_DRAWABLE(pDraw, did, client)\
+ SECURITY_VERIFY_DRAWABLE(pDraw, did, client, DixUnknownAccess)
+
+#define VERIFY_GEOMETRABLE(pDraw, did, client)\
+ SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, DixUnknownAccess)
+
+#define VERIFY_GC(pGC, rid, client)\
+ SECURITY_VERIFY_GC(pGC, rid, client, DixUnknownAccess)
+
+#else /* not XCSECURITY */
+
+#define VERIFY_DRAWABLE(pDraw, did, client)\
+ {\
+ pDraw = (DrawablePtr) LookupIDByClass(did, RC_DRAWABLE);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ if (pDraw->type == UNDRAWABLE_WINDOW)\
+ return BadMatch;\
+ }
+
+#define VERIFY_GEOMETRABLE(pDraw, did, client)\
+ {\
+ pDraw = (DrawablePtr) LookupIDByClass(did, RC_DRAWABLE);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ }
+
+#define VERIFY_GC(pGC, rid, client)\
+ pGC = (GC *)LookupIDByType(rid, RT_GC);\
+ if (!pGC)\
+ {\
+ client->errorValue = rid;\
+ return (BadGC);\
+ }
+
+#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\
+ VERIFY_DRAWABLE(pDraw, did, client)
+
+#define SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, mode)\
+ VERIFY_GEOMETRABLE(pDraw, did, client)
+
+#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
+ VERIFY_GC(pGC, rid, client)
+
+#endif /* XCSECURITY */
+
+/*
+ * We think that most hardware implementations of DBE will want
+ * LookupID*(dbe_back_buffer_id) to return the window structure that the
+ * id is a back buffer for. Since both front and back buffers will
+ * return the same structure, you need to be able to distinguish
+ * somewhere what kind of buffer (front/back) was being asked for, so
+ * that ddx can render to the right place. That's the problem that the
+ * following code solves. Note: we couldn't embed this in the LookupID*
+ * functions because the VALIDATE_DRAWABLE_AND_GC macro often circumvents
+ * those functions by checking a one-element cache. That's why we're
+ * mucking with VALIDATE_DRAWABLE_AND_GC.
+ *
+ * If you put -DNEED_DBE_BUF_BITS into PervasiveDBEDefines, the window
+ * structure will have two additional bits defined, srcBuffer and
+ * dstBuffer, and their values will be maintained via the macros
+ * SET_DBE_DSTBUF and SET_DBE_SRCBUF (below). If you also
+ * put -DNEED_DBE_BUF_VALIDATE into PervasiveDBEDefines, the function
+ * DbeValidateBuffer will be called any time the bits change to give you
+ * a chance to do some setup. See the DBE code for more details on this
+ * function. We put in these levels of conditionality so that you can do
+ * just what you need to do, and no more. If neither of these defines
+ * are used, the bits won't be there, and VALIDATE_DRAWABLE_AND_GC will
+ * be unchanged. dpw
+ */
+
+#if defined(NEED_DBE_BUF_BITS)
+#define SET_DBE_DSTBUF(_pDraw, _drawID) \
+ SET_DBE_BUF(_pDraw, _drawID, dstBuffer, TRUE)
+#define SET_DBE_SRCBUF(_pDraw, _drawID) \
+ SET_DBE_BUF(_pDraw, _drawID, srcBuffer, FALSE)
+#if defined (NEED_DBE_BUF_VALIDATE)
+#define SET_DBE_BUF(_pDraw, _drawID, _whichBuffer, _dstbuf) \
+ if (_pDraw->type == DRAWABLE_WINDOW)\
+ {\
+ int thisbuf = (_pDraw->id == _drawID);\
+ if (thisbuf != ((WindowPtr)_pDraw)->_whichBuffer)\
+ {\
+ ((WindowPtr)_pDraw)->_whichBuffer = thisbuf;\
+ DbeValidateBuffer((WindowPtr)_pDraw, _drawID, _dstbuf);\
+ }\
+ }
+#else /* want buffer bits, but don't need to call DbeValidateBuffer */
+#define SET_DBE_BUF(_pDraw, _drawID, _whichBuffer, _dstbuf) \
+ if (_pDraw->type == DRAWABLE_WINDOW)\
+ {\
+ ((WindowPtr)_pDraw)->_whichBuffer = (_pDraw->id == _drawID);\
+ }
+#endif /* NEED_DBE_BUF_VALIDATE */
+#else /* don't want buffer bits in window */
+#define SET_DBE_DSTBUF(_pDraw, _drawID) /**/
+#define SET_DBE_SRCBUF(_pDraw, _drawID) /**/
+#endif /* NEED_DBE_BUF_BITS */
+
+#define VALIDATE_DRAWABLE_AND_GC(drawID, pDraw, pGC, client)\
+ {\
+ SECURITY_VERIFY_GEOMETRABLE(pDraw, drawID, client, DixWriteAccess);\
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, DixReadAccess);\
+ if ((pGC->depth != pDraw->depth) ||\
+ (pGC->pScreen != pDraw->pScreen))\
+ return (BadMatch);\
+ }\
+ SET_DBE_DSTBUF(pDraw, drawID);\
+ if (pGC->serialNumber != pDraw->serialNumber)\
+ ValidateGC(pDraw, pGC);
+
+
+#define WriteReplyToClient(pClient, size, pReply) { \
+ if ((pClient)->swapped) \
+ (*ReplySwapVector[((xReq *)(pClient)->requestBuffer)->reqType]) \
+ (pClient, (int)(size), pReply); \
+ else WriteToClient(pClient, (int)(size), (pReply)); }
+
+#define WriteSwappedDataToClient(pClient, size, pbuf) \
+ if ((pClient)->swapped) \
+ (*(pClient)->pSwapReplyFunc)(pClient, (int)(size), pbuf); \
+ else WriteToClient (pClient, (int)(size), (pbuf));
+
+typedef struct _TimeStamp *TimeStampPtr;
+
+#ifndef _XTYPEDEF_CLIENTPTR
+typedef struct _Client *ClientPtr; /* also in misc.h */
+#define _XTYPEDEF_CLIENTPTR
+#endif
+
+typedef struct _WorkQueue *WorkQueuePtr;
+
+extern ClientPtr requestingClient;
+extern ClientPtr *clients;
+extern ClientPtr serverClient;
+extern int currentMaxClients;
+
+typedef int HWEventQueueType;
+typedef HWEventQueueType* HWEventQueuePtr;
+
+extern HWEventQueuePtr checkForInput[2];
+
+typedef struct _TimeStamp {
+ CARD32 months; /* really ~49.7 days */
+ CARD32 milliseconds;
+} TimeStamp;
+
+/* dispatch.c */
+
+extern void SetInputCheck(
+ HWEventQueuePtr /*c0*/,
+ HWEventQueuePtr /*c1*/);
+
+extern void CloseDownClient(
+ ClientPtr /*client*/);
+
+extern void UpdateCurrentTime(void);
+
+extern void UpdateCurrentTimeIf(void);
+
+extern void InitSelections(void);
+
+extern int dixDestroyPixmap(
+ void * /*value*/,
+ XID /*pid*/);
+
+extern void CloseDownRetainedResources(void);
+
+extern void InitClient(
+ ClientPtr /*client*/,
+ int /*i*/,
+ void * /*ospriv*/);
+
+extern ClientPtr NextAvailableClient(
+ void * /*ospriv*/);
+
+extern void SendErrorToClient(
+ ClientPtr /*client*/,
+ unsigned int /*majorCode*/,
+ unsigned int /*minorCode*/,
+ XID /*resId*/,
+ int /*errorCode*/);
+
+extern void DeleteWindowFromAnySelections(
+ WindowPtr /*pWin*/);
+
+extern void MarkClientException(
+ ClientPtr /*client*/);
+
+extern int GetGeometry(
+ ClientPtr /*client*/,
+ xGetGeometryReply* /* wa */);
+
+extern int SendConnSetup(
+ ClientPtr /*client*/,
+ char* /*reason*/);
+
+extern int DoGetImage(
+ ClientPtr /*client*/,
+ int /*format*/,
+ Drawable /*drawable*/,
+ int /*x*/,
+ int /*y*/,
+ int /*width*/,
+ int /*height*/,
+ Mask /*planemask*/,
+ xGetImageReply ** /*im_return*/);
+
+#if defined(DDXBEFORERESET)
+extern void ddxBeforeReset (void);
+#endif
+
+/* dixutils.c */
+
+extern void CopyISOLatin1Lowered(
+ char * /*dest*/,
+ const char * /*source*/,
+ int /*length*/);
+
+extern int CompareISOLatin1Lowered(
+ unsigned char * /*a*/,
+ int alen,
+ unsigned char * /*b*/,
+ int blen);
+
+#ifdef XCSECURITY
+
+extern WindowPtr SecurityLookupWindow(
+ XID /*rid*/,
+ ClientPtr /*client*/,
+ Mask /*access_mode*/);
+
+extern void * SecurityLookupDrawable(
+ XID /*rid*/,
+ ClientPtr /*client*/,
+ Mask /*access_mode*/);
+
+extern WindowPtr LookupWindow(
+ XID /*rid*/,
+ ClientPtr /*client*/);
+
+extern void * LookupDrawable(
+ XID /*rid*/,
+ ClientPtr /*client*/);
+
+#else
+
+extern WindowPtr LookupWindow(
+ XID /*rid*/,
+ ClientPtr /*client*/);
+
+extern void * LookupDrawable(
+ XID /*rid*/,
+ ClientPtr /*client*/);
+
+#define SecurityLookupWindow(rid, client, access_mode) \
+ LookupWindow(rid, client)
+
+#define SecurityLookupDrawable(rid, client, access_mode) \
+ LookupDrawable(rid, client)
+
+#endif /* XCSECURITY */
+
+extern ClientPtr LookupClient(
+ XID /*rid*/,
+ ClientPtr /*client*/);
+
+extern void NoopDDA(void);
+
+extern int AlterSaveSetForClient(
+ ClientPtr /*client*/,
+ WindowPtr /*pWin*/,
+ unsigned /*mode*/,
+ Bool /*toRoot*/,
+ Bool /*remap*/);
+
+extern void DeleteWindowFromAnySaveSet(
+ WindowPtr /*pWin*/);
+
+extern void BlockHandler(
+ void * /*pTimeout*/,
+ void * /*pReadmask*/);
+
+extern void WakeupHandler(
+ int /*result*/,
+ void * /*pReadmask*/);
+
+typedef void (* WakeupHandlerProcPtr)(
+ void * /* blockData */,
+ int /* result */,
+ void * /* pReadmask */);
+
+extern Bool RegisterBlockAndWakeupHandlers(
+ BlockHandlerProcPtr /*blockHandler*/,
+ WakeupHandlerProcPtr /*wakeupHandler*/,
+ void * /*blockData*/);
+
+extern void RemoveBlockAndWakeupHandlers(
+ BlockHandlerProcPtr /*blockHandler*/,
+ WakeupHandlerProcPtr /*wakeupHandler*/,
+ void * /*blockData*/);
+
+extern void InitBlockAndWakeupHandlers(void);
+
+extern void ProcessWorkQueue(void);
+
+extern void ProcessWorkQueueZombies(void);
+
+extern Bool QueueWorkProc(
+ Bool (* /*function*/)(
+ ClientPtr /*clientUnused*/,
+ void * /*closure*/),
+ ClientPtr /*client*/,
+ void * /*closure*/
+);
+
+typedef Bool (* ClientSleepProcPtr)(
+ ClientPtr /*client*/,
+ void * /*closure*/);
+
+extern Bool ClientSleep(
+ ClientPtr /*client*/,
+ ClientSleepProcPtr /* function */,
+ void * /*closure*/);
+
+#ifndef ___CLIENTSIGNAL_DEFINED___
+#define ___CLIENTSIGNAL_DEFINED___
+extern Bool ClientSignal(
+ ClientPtr /*client*/);
+#endif /* ___CLIENTSIGNAL_DEFINED___ */
+
+extern void ClientWakeup(
+ ClientPtr /*client*/);
+
+extern Bool ClientIsAsleep(
+ ClientPtr /*client*/);
+
+/* atom.c */
+
+extern Atom MakeAtom(
+ const char * /*string*/,
+ unsigned /*len*/,
+ Bool /*makeit*/);
+
+extern Bool ValidAtom(
+ Atom /*atom*/);
+
+extern const char *NameForAtom(
+ Atom /*atom*/);
+
+extern void AtomError(void);
+
+extern void FreeAllAtoms(void);
+
+extern void InitAtoms(void);
+
+/* events.c */
+
+extern void SetMaskForEvent(
+ Mask /* mask */,
+ int /* event */);
+
+
+extern Bool IsParent(
+ WindowPtr /* maybeparent */,
+ WindowPtr /* child */);
+
+extern WindowPtr GetCurrentRootWindow(void);
+
+extern WindowPtr GetSpriteWindow(void);
+
+
+extern void NoticeEventTime(xEventPtr /* xE */);
+
+extern void EnqueueEvent(
+ xEventPtr /* xE */,
+ DeviceIntPtr /* device */,
+ int /* count */);
+
+extern void ComputeFreezes(void);
+
+extern void CheckGrabForSyncs(
+ DeviceIntPtr /* dev */,
+ Bool /* thisMode */,
+ Bool /* otherMode */);
+
+extern void ActivatePointerGrab(
+ DeviceIntPtr /* mouse */,
+ GrabPtr /* grab */,
+ TimeStamp /* time */,
+ Bool /* autoGrab */);
+
+extern void DeactivatePointerGrab(
+ DeviceIntPtr /* mouse */);
+
+extern void ActivateKeyboardGrab(
+ DeviceIntPtr /* keybd */,
+ GrabPtr /* grab */,
+ TimeStamp /* time */,
+ Bool /* passive */);
+
+extern void DeactivateKeyboardGrab(
+ DeviceIntPtr /* keybd */);
+
+extern void AllowSome(
+ ClientPtr /* client */,
+ TimeStamp /* time */,
+ DeviceIntPtr /* thisDev */,
+ int /* newState */);
+
+extern void ReleaseActiveGrabs(
+ ClientPtr client);
+
+extern int DeliverEventsToWindow(
+ WindowPtr /* pWin */,
+ xEventPtr /* pEvents */,
+ int /* count */,
+ Mask /* filter */,
+ GrabPtr /* grab */,
+ int /* mskidx */);
+
+extern int DeliverDeviceEvents(
+ WindowPtr /* pWin */,
+ xEventPtr /* xE */,
+ GrabPtr /* grab */,
+ WindowPtr /* stopAt */,
+ DeviceIntPtr /* dev */,
+ int /* count */);
+
+extern void DefineInitialRootWindow(
+ WindowPtr /* win */);
+
+extern void WindowHasNewCursor(
+ WindowPtr /* pWin */);
+
+extern Bool CheckDeviceGrabs(
+ DeviceIntPtr /* device */,
+ xEventPtr /* xE */,
+ int /* checkFirst */,
+ int /* count */);
+
+extern void DeliverFocusedEvent(
+ DeviceIntPtr /* keybd */,
+ xEventPtr /* xE */,
+ WindowPtr /* window */,
+ int /* count */);
+
+extern void DeliverGrabbedEvent(
+ xEventPtr /* xE */,
+ DeviceIntPtr /* thisDev */,
+ Bool /* deactivateGrab */,
+ int /* count */);
+
+#ifdef XKB
+extern void FixKeyState(
+ xEvent * /* xE */,
+ DeviceIntPtr /* keybd */);
+#endif /* XKB */
+
+extern void RecalculateDeliverableEvents(
+ WindowPtr /* pWin */);
+
+extern int OtherClientGone(
+ void * /* value */,
+ XID /* id */);
+
+extern void DoFocusEvents(
+ DeviceIntPtr /* dev */,
+ WindowPtr /* fromWin */,
+ WindowPtr /* toWin */,
+ int /* mode */);
+
+extern int SetInputFocus(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ Window /* focusID */,
+ CARD8 /* revertTo */,
+ Time /* ctime */,
+ Bool /* followOK */);
+
+extern int GrabDevice(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned /* this_mode */,
+ unsigned /* other_mode */,
+ Window /* grabWindow */,
+ unsigned /* ownerEvents */,
+ Time /* ctime */,
+ Mask /* mask */,
+ CARD8 * /* status */);
+
+extern void InitEvents(void);
+
+extern void CloseDownEvents(void);
+
+extern void DeleteWindowFromAnyEvents(
+ WindowPtr /* pWin */,
+ Bool /* freeResources */);
+
+
+extern Mask EventMaskForClient(
+ WindowPtr /* pWin */,
+ ClientPtr /* client */);
+
+
+
+extern int DeliverEvents(
+ WindowPtr /*pWin*/,
+ xEventPtr /*xE*/,
+ int /*count*/,
+ WindowPtr /*otherParent*/);
+
+
+extern void WriteEventsToClient(
+ ClientPtr /*pClient*/,
+ int /*count*/,
+ xEventPtr /*events*/);
+
+extern int TryClientEvents(
+ ClientPtr /*client*/,
+ xEventPtr /*pEvents*/,
+ int /*count*/,
+ Mask /*mask*/,
+ Mask /*filter*/,
+ GrabPtr /*grab*/);
+
+extern void WindowsRestructured(void);
+
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen);
+#endif
+
+extern void ResetClientPrivates(void);
+
+extern int AllocateClientPrivateIndex(void);
+
+extern Bool AllocateClientPrivate(
+ int /*index*/,
+ unsigned /*amount*/);
+
+/*
+ * callback manager stuff
+ */
+
+#ifndef _XTYPEDEF_CALLBACKLISTPTR
+typedef struct _CallbackList *CallbackListPtr; /* also in misc.h */
+#define _XTYPEDEF_CALLBACKLISTPTR
+#endif
+
+typedef void (*CallbackProcPtr) (
+ CallbackListPtr *, void *, void *);
+
+typedef Bool (*AddCallbackProcPtr) (
+ CallbackListPtr *, CallbackProcPtr, void *);
+
+typedef Bool (*DeleteCallbackProcPtr) (
+ CallbackListPtr *, CallbackProcPtr, void *);
+
+typedef void (*CallCallbacksProcPtr) (
+ CallbackListPtr *, void *);
+
+typedef void (*DeleteCallbackListProcPtr) (
+ CallbackListPtr *);
+
+typedef struct _CallbackProcs {
+ AddCallbackProcPtr AddCallback;
+ DeleteCallbackProcPtr DeleteCallback;
+ CallCallbacksProcPtr CallCallbacks;
+ DeleteCallbackListProcPtr DeleteCallbackList;
+} CallbackFuncsRec, *CallbackFuncsPtr;
+
+extern Bool CreateCallbackList(
+ CallbackListPtr * /*pcbl*/,
+ CallbackFuncsPtr /*cbfuncs*/);
+
+extern Bool AddCallback(
+ CallbackListPtr * /*pcbl*/,
+ CallbackProcPtr /*callback*/,
+ void * /*data*/);
+
+extern Bool DeleteCallback(
+ CallbackListPtr * /*pcbl*/,
+ CallbackProcPtr /*callback*/,
+ void * /*data*/);
+
+extern void CallCallbacks(
+ CallbackListPtr * /*pcbl*/,
+ void * /*call_data*/);
+
+extern void DeleteCallbackList(
+ CallbackListPtr * /*pcbl*/);
+
+extern void InitCallbackManager(void);
+
+/*
+ * ServerGrabCallback stuff
+ */
+
+extern CallbackListPtr ServerGrabCallback;
+
+typedef enum {SERVER_GRABBED, SERVER_UNGRABBED,
+ CLIENT_PERVIOUS, CLIENT_IMPERVIOUS } ServerGrabState;
+
+typedef struct {
+ ClientPtr client;
+ ServerGrabState grabstate;
+} ServerGrabInfoRec;
+
+/*
+ * EventCallback stuff
+ */
+
+extern CallbackListPtr EventCallback;
+
+typedef struct {
+ ClientPtr client;
+ xEventPtr events;
+ int count;
+} EventInfoRec;
+
+/*
+ * DeviceEventCallback stuff
+ */
+
+extern CallbackListPtr DeviceEventCallback;
+
+typedef struct {
+ xEventPtr events;
+ int count;
+} DeviceEventInfoRec;
+
+/*
+ * SelectionCallback stuff
+ */
+
+extern CallbackListPtr SelectionCallback;
+
+typedef enum {
+ SelectionSetOwner,
+ SelectionWindowDestroy,
+ SelectionClientClose
+} SelectionCallbackKind;
+
+typedef struct {
+ struct _Selection *selection;
+ SelectionCallbackKind kind;
+} SelectionInfoRec;
+
+#endif /* DIX_H */
diff --git a/nx-X11/programs/Xserver/include/dixevents.h b/nx-X11/programs/Xserver/include/dixevents.h
new file mode 100644
index 000000000..2a9458f08
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dixevents.h
@@ -0,0 +1,105 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifndef DIXEVENTS_H
+#define DIXEVENTS_H
+
+extern void SetCriticalEvent(int /* event */);
+
+extern CursorPtr GetSpriteCursor(void);
+
+extern int ProcAllowEvents(ClientPtr /* client */);
+
+extern int MaybeDeliverEventsToClient(
+ WindowPtr /* pWin */,
+ xEvent * /* pEvents */,
+ int /* count */,
+ Mask /* filter */,
+ ClientPtr /* dontClient */);
+
+extern int ProcWarpPointer(ClientPtr /* client */);
+
+#if 0
+extern void
+#ifdef XKB
+CoreProcessKeyboardEvent (
+#else
+ProcessKeyboardEvent (
+#endif
+ xEvent * /* xE */,
+ DeviceIntPtr /* keybd */,
+ int /* count */);
+
+extern void
+#ifdef XKB
+CoreProcessPointerEvent (
+#else
+ProcessPointerEvent (
+#endif
+ xEvent * /* xE */,
+ DeviceIntPtr /* mouse */,
+ int /* count */);
+#endif
+
+extern int EventSelectForWindow(
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */);
+
+extern int EventSuppressForWindow(
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ Bool * /* checkOptional */);
+
+extern int ProcSetInputFocus(ClientPtr /* client */);
+
+extern int ProcGetInputFocus(ClientPtr /* client */);
+
+extern int ProcGrabPointer(ClientPtr /* client */);
+
+extern int ProcChangeActivePointerGrab(ClientPtr /* client */);
+
+extern int ProcUngrabPointer(ClientPtr /* client */);
+
+extern int ProcGrabKeyboard(ClientPtr /* client */);
+
+extern int ProcUngrabKeyboard(ClientPtr /* client */);
+
+extern int ProcQueryPointer(ClientPtr /* client */);
+
+extern int ProcSendEvent(ClientPtr /* client */);
+
+extern int ProcUngrabKey(ClientPtr /* client */);
+
+extern int ProcGrabKey(ClientPtr /* client */);
+
+extern int ProcGrabButton(ClientPtr /* client */);
+
+extern int ProcUngrabButton(ClientPtr /* client */);
+
+extern int ProcRecolorCursor(ClientPtr /* client */);
+
+#endif /* DIXEVENTS_H */
diff --git a/nx-X11/programs/Xserver/include/dixfont.h b/nx-X11/programs/Xserver/include/dixfont.h
new file mode 100644
index 000000000..21d917fe5
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dixfont.h
@@ -0,0 +1,174 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef DIXFONT_H
+#define DIXFONT_H 1
+
+#include "dix.h"
+#include <X11/fonts/font.h>
+#include "closure.h"
+#include <X11/fonts/fontstruct.h>
+
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS XFONT2 */
+
+#define NullDIXFontProp ((DIXFontPropPtr)0)
+
+typedef struct _DIXFontProp *DIXFontPropPtr;
+
+#ifdef HAS_XFONT2
+xfont2_fpe_funcs_rec const **fpe_functions;
+#else
+extern FPEFunctions *fpe_functions;
+#endif /* HAS_XFONT2 */
+
+extern int FontToXError(int /*err*/);
+
+extern Bool SetDefaultFont(char * /*defaultfontname*/);
+
+extern void QueueFontWakeup(FontPathElementPtr /*fpe*/);
+
+extern void RemoveFontWakeup(FontPathElementPtr /*fpe*/);
+
+extern void FontWakeup(void * /*data*/,
+ int /*count*/,
+ void * /*LastSelectMask*/);
+
+extern int OpenFont(ClientPtr /*client*/,
+ XID /*fid*/,
+ Mask /*flags*/,
+ unsigned /*lenfname*/,
+ char * /*pfontname*/);
+
+extern int CloseFont(void * /*pfont*/,
+ XID /*fid*/);
+
+typedef struct _xQueryFontReply *xQueryFontReplyPtr;
+
+extern void QueryFont(FontPtr /*pFont*/,
+ xQueryFontReplyPtr /*pReply*/,
+ int /*nProtoCCIStructs*/);
+
+extern int ListFonts(ClientPtr /*client*/,
+ unsigned char * /*pattern*/,
+ unsigned int /*length*/,
+ unsigned int /*max_names*/);
+
+int
+doListFontsWithInfo(ClientPtr /*client*/,
+ LFWIclosurePtr /*c*/);
+
+extern int doPolyText(ClientPtr /*client*/,
+ PTclosurePtr /*c*/
+);
+
+extern int PolyText(ClientPtr /*client*/,
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ unsigned char * /*pElt*/,
+ unsigned char * /*endReq*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ int /*reqType*/,
+ XID /*did*/);
+
+extern int doImageText(ClientPtr /*client*/,
+ ITclosurePtr /*c*/);
+
+extern int ImageText(ClientPtr /*client*/,
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nChars*/,
+ unsigned char * /*data*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ int /*reqType*/,
+ XID /*did*/);
+
+extern int SetFontPath(ClientPtr /*client*/,
+ int /*npaths*/,
+ unsigned char * /*paths*/);
+
+extern int SetDefaultFontPath(char * /*path*/);
+
+extern unsigned char *GetFontPath(int * /*count*/,
+ int * /*length*/);
+
+extern int LoadGlyphs(ClientPtr /*client*/,
+ FontPtr /*pfont*/,
+ unsigned /*nchars*/,
+ int /*item_size*/,
+ unsigned char * /*data*/);
+
+extern void DeleteClientFontStuff(ClientPtr /*client*/);
+
+/* Quartz support on Mac OS X pulls in the QuickDraw
+ framework whose InitFonts function conflicts here. */
+#ifdef __DARWIN__
+#define InitFonts Darwin_X_InitFonts
+#endif
+extern void InitFonts(void);
+
+extern void FreeFonts(void);
+
+#ifdef HAS_XFONT2
+extern void GetGlyphs(FontPtr /*font */ ,
+ unsigned long /*count */ ,
+ unsigned char * /*chars */ ,
+ FontEncoding /*fontEncoding */ ,
+ unsigned long * /*glyphcount */ ,
+ CharInfoPtr * /*glyphs */ );
+#else
+extern FontPtr find_old_font(XID /*id*/);
+
+#define GetGlyphs dixGetGlyphs
+extern void dixGetGlyphs(FontPtr /*font*/,
+ unsigned long /*count*/,
+ unsigned char * /*chars*/,
+ FontEncoding /*fontEncoding*/,
+ unsigned long * /*glyphcount*/,
+ CharInfoPtr * /*glyphs*/);
+
+extern void register_fpe_functions(void);
+
+extern void QueryGlyphExtents(FontPtr /*pFont*/,
+ CharInfoPtr * /*charinfo*/,
+ unsigned long /*count*/,
+ ExtentInfoPtr /*info*/);
+
+extern Bool QueryTextExtents(FontPtr /*pFont*/,
+ unsigned long /*count*/,
+ unsigned char * /*chars*/,
+ ExtentInfoPtr /*info*/);
+#endif /* HAS_XFONT2 */
+
+extern Bool ParseGlyphCachingMode(char * /*str*/);
+
+extern void InitGlyphCaching(void);
+
+extern void SetGlyphCachingMode(int /*newmode*/);
+
+#endif /* DIXFONT_H */
diff --git a/nx-X11/programs/Xserver/include/dixfontstr.h b/nx-X11/programs/Xserver/include/dixfontstr.h
new file mode 100644
index 000000000..3e76f9e6a
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dixfontstr.h
@@ -0,0 +1,96 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef DIXFONTSTRUCT_H
+#define DIXFONTSTRUCT_H
+
+#include "servermd.h"
+#include "dixfont.h"
+#include <X11/fonts/fontstruct.h>
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#endif /* HAS_XFONT2 */
+#include "closure.h"
+#include <nx-X11/Xproto.h> /* for xQueryFontReply */
+
+#define FONTCHARSET(font) (font)
+#define FONTMAXBOUNDS(font,field) (font)->info.maxbounds.field
+#define FONTMINBOUNDS(font,field) (font)->info.minbounds.field
+#define TERMINALFONT(font) (font)->info.terminalFont
+#define FONTASCENT(font) (font)->info.fontAscent
+#define FONTDESCENT(font) (font)->info.fontDescent
+#define FONTGLYPHS(font) 0
+#define FONTCONSTMETRICS(font) (font)->info.constantMetrics
+#define FONTCONSTWIDTH(font) (font)->info.constantWidth
+#define FONTALLEXIST(font) (font)->info.allExist
+#define FONTFIRSTCOL(font) (font)->info.firstCol
+#define FONTLASTCOL(font) (font)->info.lastCol
+#define FONTFIRSTROW(font) (font)->info.firstRow
+#define FONTLASTROW(font) (font)->info.lastRow
+#define FONTDEFAULTCH(font) (font)->info.defaultCh
+#define FONTINKMIN(font) (&((font)->info.ink_minbounds))
+#define FONTINKMAX(font) (&((font)->info.ink_maxbounds))
+#define FONTPROPS(font) (font)->info.props
+#define FONTGLYPHBITS(base,pci) ((unsigned char *) (pci)->bits)
+#define FONTINFONPROPS(font) (font)->info.nprops
+
+/* some things haven't changed names, but we'll be careful anyway */
+
+#define FONTREFCNT(font) (font)->refcnt
+
+/*
+ * for linear char sets
+ */
+#define N1dChars(pfont) (FONTLASTCOL(pfont) - FONTFIRSTCOL(pfont) + 1)
+
+/*
+ * for 2D char sets
+ */
+#define N2dChars(pfont) (N1dChars(pfont) * \
+ (FONTLASTROW(pfont) - FONTFIRSTROW(pfont) + 1))
+
+#ifndef GLYPHPADBYTES
+#define GLYPHPADBYTES -1
+#endif
+
+#if GLYPHPADBYTES == 0 || GLYPHPADBYTES == 1
+#define GLYPHWIDTHBYTESPADDED(pci) (GLYPHWIDTHBYTES(pci))
+#define PADGLYPHWIDTHBYTES(w) (((w)+7)>>3)
+#endif
+
+#if GLYPHPADBYTES == 2
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+1) & ~0x1)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+1) & ~0x1)
+#endif
+
+#if GLYPHPADBYTES == 4
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+3) & ~0x3)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+3) & ~0x3)
+#endif
+
+#if GLYPHPADBYTES == 8 /* for a cray? */
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+7) & ~0x7)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+7) & ~0x7)
+#endif
+
+#endif /* DIXFONTSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/dixgrabs.h b/nx-X11/programs/Xserver/include/dixgrabs.h
new file mode 100644
index 000000000..f1f7c2cb5
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dixgrabs.h
@@ -0,0 +1,58 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifndef DIXGRABS_H
+#define DIXGRABS_H 1
+
+extern GrabPtr CreateGrab(
+ int /* client */,
+ DeviceIntPtr /* device */,
+ WindowPtr /* window */,
+ Mask /* eventMask */,
+ Bool /* ownerEvents */,
+ Bool /* keyboardMode */,
+ Bool /* pointerMode */,
+ DeviceIntPtr /* modDevice */,
+ unsigned short /* modifiers */,
+ int /* type */,
+ KeyCode /* keybut */,
+ WindowPtr /* confineTo */,
+ CursorPtr /* cursor */);
+
+extern int DeletePassiveGrab(
+ void * /* value */,
+ XID /* id */);
+
+extern Bool GrabMatchesSecond(
+ GrabPtr /* pFirstGrab */,
+ GrabPtr /* pSecondGrab */);
+
+extern int AddPassiveGrabToList(
+ GrabPtr /* pGrab */);
+
+extern Bool DeletePassiveGrabFromList(
+ GrabPtr /* pMinuendGrab */);
+
+#endif /* DIXGRABS_H */
diff --git a/nx-X11/programs/Xserver/include/dixstruct.h b/nx-X11/programs/Xserver/include/dixstruct.h
new file mode 100644
index 000000000..cdd2543a6
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/dixstruct.h
@@ -0,0 +1,220 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef DIXSTRUCT_H
+#define DIXSTRUCT_H
+
+#include "client.h"
+#include "dix.h"
+#include "resource.h"
+#include "cursor.h"
+#include "gc.h"
+#include "pixmap.h"
+#include <nx-X11/Xmd.h>
+
+/*
+ * direct-mapped hash table, used by resource manager to store
+ * translation from client ids to server addresses.
+ */
+
+#ifdef DEBUG
+#define MAX_REQUEST_LOG 100
+#endif
+
+extern CallbackListPtr ClientStateCallback;
+
+typedef struct {
+ ClientPtr client;
+ xConnSetupPrefix *prefix;
+ xConnSetup *setup;
+} NewClientInfoRec;
+
+typedef void (*ReplySwapPtr) (
+ ClientPtr /* pClient */,
+ int /* size */,
+ void * /* pbuf */);
+
+extern void ReplyNotSwappd (
+ ClientPtr /* pClient */,
+ int /* size */,
+ void * /* pbuf */);
+
+typedef enum {ClientStateInitial,
+ ClientStateAuthenticating,
+ ClientStateRunning,
+ ClientStateRetained,
+ ClientStateGone,
+ ClientStateCheckingSecurity,
+ ClientStateCheckedSecurity} ClientState;
+
+#ifdef XFIXES
+typedef struct _saveSet {
+ struct _Window *windowPtr;
+ Bool toRoot;
+ Bool remap;
+} SaveSetElt;
+#define SaveSetWindow(ss) ((ss).windowPtr)
+#define SaveSetToRoot(ss) ((ss).toRoot)
+#define SaveSetRemap(ss) ((ss).remap)
+#define SaveSetAssignWindow(ss,w) ((ss).windowPtr = (w))
+#define SaveSetAssignToRoot(ss,tr) ((ss).toRoot = (tr))
+#define SaveSetAssignRemap(ss,rm) ((ss).remap = (rm))
+#else
+typedef struct _Window *SaveSetElt;
+#define SaveSetWindow(ss) (ss)
+#define SaveSetToRoot(ss) FALSE
+#define SaveSetRemap(ss) TRUE
+#define SaveSetAssignWindow(ss,w) ((ss) = (w))
+#define SaveSetAssignToRoot(ss,tr)
+#define SaveSetAssignRemap(ss,rm)
+#endif
+
+typedef struct _Client {
+ int index;
+ Mask clientAsMask;
+ void *requestBuffer;
+ void *osPrivate; /* for OS layer, including scheduler */
+ Bool swapped;
+ Bool local;
+ ReplySwapPtr pSwapReplyFunc;
+ XID errorValue;
+ int sequence;
+ int closeDownMode;
+ int clientGone;
+ int noClientException; /* this client died or needs to be
+ * killed */
+ SaveSetElt *saveSet;
+ int numSaved;
+ void *screenPrivate[MAXSCREENS];
+ int (**requestVector) (
+ ClientPtr /* pClient */);
+ CARD32 req_len; /* length of current request */
+ Bool big_requests; /* supports large requests */
+ int priority;
+ ClientState clientState;
+ DevUnion *devPrivates;
+#ifdef XKB
+ unsigned short xkbClientFlags;
+ unsigned short mapNotifyMask;
+ unsigned short newKeyboardNotifyMask;
+ unsigned short vMajor,vMinor;
+ KeyCode minKC,maxKC;
+#endif
+
+#ifdef DEBUG
+ unsigned char requestLog[MAX_REQUEST_LOG];
+ int requestLogIndex;
+#endif
+ unsigned long replyBytesRemaining;
+#ifdef XCSECURITY
+ XID authId;
+ unsigned int trustLevel;
+ void * (* CheckAccess)(
+ ClientPtr /*pClient*/,
+ XID /*id*/,
+ RESTYPE /*classes*/,
+ Mask /*access_mode*/,
+ void * /*resourceval*/);
+#endif
+ struct _FontResolution * (*fontResFunc) ( /* no need for font.h */
+ ClientPtr /* pClient */,
+ int * /* num */);
+ int smart_priority;
+ long smart_start_tick;
+ long smart_stop_tick;
+ long smart_check_tick;
+
+ ClientIdPtr clientIds;
+} ClientRec;
+
+/*
+ * Scheduling interface
+ */
+extern long SmartScheduleTime;
+extern long SmartScheduleInterval;
+extern long SmartScheduleSlice;
+extern long SmartScheduleMaxSlice;
+#ifdef HAVE_SETITIMER
+#if HAVE_SETITIMER
+extern Bool SmartScheduleSignalEnable;
+#else
+#define SmartScheduleSignalEnable FALSE
+#endif
+#endif
+extern void SmartScheduleStartTimer(void);
+extern void SmartScheduleStopTimer(void);
+#define SMART_MAX_PRIORITY (20)
+#define SMART_MIN_PRIORITY (-20)
+
+extern void SmartScheduleInit(void);
+
+/* This prototype is used pervasively in Xext, dix */
+#define DISPATCH_PROC(func) int func(ClientPtr /* client */)
+
+typedef struct _WorkQueue {
+ struct _WorkQueue *next;
+ Bool (*function) (
+ ClientPtr /* pClient */,
+ void * /* closure */
+);
+ ClientPtr client;
+ void *closure;
+} WorkQueueRec;
+
+extern TimeStamp currentTime;
+extern TimeStamp lastDeviceEventTime;
+
+extern int CompareTimeStamps(
+ TimeStamp /*a*/,
+ TimeStamp /*b*/);
+
+extern TimeStamp ClientTimeToServerTime(CARD32 /*c*/);
+
+typedef struct _CallbackRec {
+ CallbackProcPtr proc;
+ void * data;
+ Bool deleted;
+ struct _CallbackRec *next;
+} CallbackRec, *CallbackPtr;
+
+typedef struct _CallbackList {
+ CallbackFuncsRec funcs;
+ int inCallback;
+ Bool deleted;
+ int numDeleted;
+ CallbackPtr list;
+} CallbackListRec;
+
+/* proc vectors */
+
+extern int (* InitialVector[3]) (ClientPtr /*client*/);
+
+extern int (* ProcVector[256]) (ClientPtr /*client*/);
+
+extern int (* SwappedProcVector[256]) (ClientPtr /*client*/);
+
+extern ReplySwapPtr ReplySwapVector[256];
+
+extern int ProcBadRequest(ClientPtr /*client*/);
+
+#endif /* DIXSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/exevents.h b/nx-X11/programs/Xserver/include/exevents.h
new file mode 100644
index 000000000..1169a6c4e
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/exevents.h
@@ -0,0 +1,182 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/********************************************************************
+ * Interface of 'exevents.c'
+ */
+
+#ifndef EXEVENTS_H
+#define EXEVENTS_H
+
+extern void RegisterOtherDevice (
+ DeviceIntPtr /* device */);
+
+extern void ProcessOtherEvent (
+ xEventPtr /* FIXME deviceKeyButtonPointer * xE */,
+ DeviceIntPtr /* other */,
+ int /* count */);
+
+extern int InitProximityClassDeviceStruct(
+ DeviceIntPtr /* dev */);
+
+extern void InitValuatorAxisStruct(
+ DeviceIntPtr /* dev */,
+ int /* axnum */,
+ int /* minval */,
+ int /* maxval */,
+ int /* resolution */,
+ int /* min_res */,
+ int /* max_res */);
+
+extern void DeviceFocusEvent(
+ DeviceIntPtr /* dev */,
+ int /* type */,
+ int /* mode */,
+ int /* detail */,
+ WindowPtr /* pWin */);
+
+extern int GrabButton(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ BYTE /* this_device_mode */,
+ BYTE /* other_devices_mode */,
+ CARD16 /* modifiers */,
+ DeviceIntPtr /* modifier_device */,
+ CARD8 /* button */,
+ Window /* grabWindow */,
+ BOOL /* ownerEvents */,
+ Cursor /* rcursor */,
+ Window /* rconfineTo */,
+ Mask /* eventMask */);
+
+extern int GrabKey(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ BYTE /* this_device_mode */,
+ BYTE /* other_devices_mode */,
+ CARD16 /* modifiers */,
+ DeviceIntPtr /* modifier_device */,
+ CARD8 /* key */,
+ Window /* grabWindow */,
+ BOOL /* ownerEvents */,
+ Mask /* mask */);
+
+extern int SelectForWindow(
+ DeviceIntPtr /* dev */,
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ Mask /* exclusivemasks */,
+ Mask /* validmasks */);
+
+extern int AddExtensionClient (
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ int /* mskidx */);
+
+extern void RecalculateDeviceDeliverableEvents(
+ WindowPtr /* pWin */);
+
+extern int InputClientGone(
+ WindowPtr /* pWin */,
+ XID /* id */);
+
+extern int SendEvent (
+ ClientPtr /* client */,
+ DeviceIntPtr /* d */,
+ Window /* dest */,
+ Bool /* propagate */,
+ xEvent * /* ev */,
+ Mask /* mask */,
+ int /* count */);
+
+extern int SetButtonMapping (
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* nElts */,
+ BYTE * /* map */);
+
+extern int SetModifierMapping(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* len */,
+ int /* rlen */,
+ int /* numKeyPerModifier */,
+ KeyCode * /* inputMap */,
+ KeyClassPtr * /* k */);
+
+extern void SendDeviceMappingNotify(
+ CARD8 /* request, */,
+ KeyCode /* firstKeyCode */,
+ CARD8 /* count */,
+ DeviceIntPtr /* dev */);
+
+extern int ChangeKeyMapping(
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned /* len */,
+ int /* type */,
+ KeyCode /* firstKeyCode */,
+ CARD8 /* keyCodes */,
+ CARD8 /* keySymsPerKeyCode */,
+ KeySym * /* map */);
+
+extern void DeleteWindowFromAnyExtEvents(
+ WindowPtr /* pWin */,
+ Bool /* freeResources */);
+
+extern void DeleteDeviceFromAnyExtEvents(
+ WindowPtr /* pWin */,
+ DeviceIntPtr /* dev */);
+
+extern int MaybeSendDeviceMotionNotifyHint (
+ deviceKeyButtonPointer * /* pEvents */,
+ Mask /* mask */);
+
+extern void CheckDeviceGrabAndHintWindow (
+ WindowPtr /* pWin */,
+ int /* type */,
+ deviceKeyButtonPointer * /* xE */,
+ GrabPtr /* grab */,
+ ClientPtr /* client */,
+ Mask /* deliveryMask */);
+
+extern Mask DeviceEventMaskForClient(
+ DeviceIntPtr /* dev */,
+ WindowPtr /* pWin */,
+ ClientPtr /* client */);
+
+extern void MaybeStopDeviceHint(
+ DeviceIntPtr /* dev */,
+ ClientPtr /* client */);
+
+extern int DeviceEventSuppressForWindow(
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ int /* maskndx */);
+
+#endif /* EXEVENTS_H */
diff --git a/nx-X11/programs/Xserver/include/extension.h b/nx-X11/programs/Xserver/include/extension.h
new file mode 100644
index 000000000..f9e74e82c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/extension.h
@@ -0,0 +1,65 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef EXTENSION_H
+#define EXTENSION_H
+
+_XFUNCPROTOBEGIN
+
+extern unsigned short StandardMinorOpcode(ClientPtr /*client*/);
+
+extern unsigned short MinorOpcodeOfRequest(ClientPtr /*client*/);
+
+extern void InitExtensions(int argc, char **argv);
+
+extern void InitVisualWrap(void);
+
+extern void CloseDownExtensions(void);
+
+_XFUNCPROTOEND
+
+#endif /* EXTENSION_H */
diff --git a/nx-X11/programs/Xserver/include/extinit.h b/nx-X11/programs/Xserver/include/extinit.h
new file mode 100644
index 000000000..b1a0f215d
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/extinit.h
@@ -0,0 +1,165 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/********************************************************************
+ * Interface of extinit.c
+ */
+
+#ifndef EXTINIT_H
+#define EXTINIT_H
+
+#include "extnsionst.h"
+
+void
+XInputExtensionInit(
+ void
+ );
+
+
+int
+ProcIDispatch (
+ ClientPtr /* client */
+ );
+
+int
+SProcIDispatch(
+ ClientPtr /* client */
+ );
+
+void
+SReplyIDispatch (
+ ClientPtr /* client */,
+ int /* len */,
+ xGrabDeviceReply * /* rep */
+ );
+
+void
+SEventIDispatch (
+ xEvent * /* from */,
+ xEvent * /* to */
+ );
+
+void
+SEventDeviceValuator (
+ deviceValuator * /* from */,
+ deviceValuator * /* to */
+ );
+
+void
+SEventFocus (
+ deviceFocus * /* from */,
+ deviceFocus * /* to */
+ );
+
+void
+SDeviceStateNotifyEvent (
+ deviceStateNotify * /* from */,
+ deviceStateNotify * /* to */
+ );
+
+void
+SDeviceKeyStateNotifyEvent (
+ deviceKeyStateNotify * /* from */,
+ deviceKeyStateNotify * /* to */
+ );
+
+void
+SDeviceButtonStateNotifyEvent (
+ deviceButtonStateNotify * /* from */,
+ deviceButtonStateNotify * /* to */
+ );
+
+void
+SChangeDeviceNotifyEvent (
+ changeDeviceNotify * /* from */,
+ changeDeviceNotify * /* to */
+ );
+
+void
+SDeviceMappingNotifyEvent (
+ deviceMappingNotify * /* from */,
+ deviceMappingNotify * /* to */
+ );
+
+void
+FixExtensionEvents (
+ ExtensionEntry * /* extEntry */
+ );
+
+void
+RestoreExtensionEvents (
+ void
+ );
+
+void
+IResetProc(
+ ExtensionEntry * /* unused */
+ );
+
+void
+AssignTypeAndName (
+ DeviceIntPtr /* dev */,
+ Atom /* type */,
+ char * /* name */
+ );
+
+void
+MakeDeviceTypeAtoms (
+ void
+);
+
+DeviceIntPtr
+LookupDeviceIntRec (
+ CARD8 /* id */
+ );
+
+void
+SetExclusiveAccess (
+ Mask /* mask */
+ );
+
+void
+AllowPropagateSuppress (
+ Mask /* mask */
+ );
+
+Mask
+GetNextExtEventMask (
+ void
+);
+
+void
+SetMaskForExtEvent(
+ Mask /* mask */,
+ int /* event */
+ );
+
+void
+SetEventInfo(
+ Mask /* mask */,
+ int /* constant */
+ );
+
+#endif /* EXTINIT_H */
diff --git a/nx-X11/programs/Xserver/include/extnsionst.h b/nx-X11/programs/Xserver/include/extnsionst.h
new file mode 100644
index 000000000..da4cee57c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/extnsionst.h
@@ -0,0 +1,150 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef EXTENSIONSTRUCT_H
+#define EXTENSIONSTRUCT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include "extension.h"
+#include "gc.h"
+
+typedef struct _ExtensionEntry {
+ int index;
+ void (* CloseDown)( /* called at server shutdown */
+ struct _ExtensionEntry * /* extension */);
+ char *name; /* extension name */
+ int base; /* base request number */
+ int eventBase;
+ int eventLast;
+ int errorBase;
+ int errorLast;
+ int num_aliases;
+ char **aliases;
+ void * extPrivate;
+ unsigned short (* MinorOpcode)( /* called for errors */
+ ClientPtr /* client */);
+#ifdef XCSECURITY
+ Bool secure; /* extension visible to untrusted clients? */
+#endif
+} ExtensionEntry;
+
+/*
+ * The arguments may be different for extension event swapping functions.
+ * Deal with this by casting when initializing the event's EventSwapVector[]
+ * entries.
+ */
+typedef void (*EventSwapPtr) (xEvent *, xEvent *);
+
+extern EventSwapPtr EventSwapVector[128];
+
+extern void NotImplemented ( /* FIXME: this may move to another file... */
+ xEvent *,
+ xEvent *);
+
+typedef void (* ExtensionLookupProc)(
+#ifdef EXTENSION_PROC_ARGS
+ EXTENSION_PROC_ARGS
+#else
+ /* args no longer indeterminate */
+ char *name,
+ GCPtr pGC
+#endif
+);
+
+typedef struct _ProcEntry {
+ char *name;
+ ExtensionLookupProc proc;
+} ProcEntryRec, *ProcEntryPtr;
+
+typedef struct _ScreenProcEntry {
+ int num;
+ ProcEntryPtr procList;
+} ScreenProcEntry;
+
+#define SetGCVector(pGC, VectorElement, NewRoutineAddress, Atom) \
+ pGC->VectorElement = NewRoutineAddress;
+
+#define GetGCValue(pGC, GCElement) (pGC->GCElement)
+
+
+extern ExtensionEntry *AddExtension(
+ char* /*name*/,
+ int /*NumEvents*/,
+ int /*NumErrors*/,
+ int (* /*MainProc*/)(ClientPtr /*client*/),
+ int (* /*SwappedMainProc*/)(ClientPtr /*client*/),
+ void (* /*CloseDownProc*/)(ExtensionEntry * /*extension*/),
+ unsigned short (* /*MinorOpcodeProc*/)(ClientPtr /*client*/)
+);
+
+extern Bool AddExtensionAlias(
+ char* /*alias*/,
+ ExtensionEntry * /*extension*/);
+
+extern ExtensionEntry *CheckExtension(const char *extname);
+
+extern ExtensionLookupProc LookupProc(
+ char* /*name*/,
+ GCPtr /*pGC*/);
+
+extern Bool RegisterProc(
+ char* /*name*/,
+ GCPtr /*pGC*/,
+ ExtensionLookupProc /*proc*/);
+
+extern Bool RegisterScreenProc(
+ char* /*name*/,
+ ScreenPtr /*pScreen*/,
+ ExtensionLookupProc /*proc*/);
+
+extern void DeclareExtensionSecurity(
+ char * /*extname*/,
+ Bool /*secure*/);
+
+#endif /* EXTENSIONSTRUCT_H */
+
diff --git a/nx-X11/programs/Xserver/include/gc.h b/nx-X11/programs/Xserver/include/gc.h
new file mode 100644
index 000000000..75a38617e
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/gc.h
@@ -0,0 +1,190 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef GC_H
+#define GC_H
+
+#include <nx-X11/X.h> /* for GContext, Mask */
+
+#ifndef _XTYPEDEF_POINTER
+/* Don't let Xdefs.h define 'pointer' */
+#define _XTYPEDEF_POINTER 1
+#endif /* _XTYPEDEF_POINTER */
+
+/* FIXME: for building this code against Xlib versions older than apprx. 04/2014
+ * we still have to define the pointer type via Xdefs.h.
+ *
+ * The nx-libs code itself does not require the pointer definition.
+ */
+#undef _XTYPEDEF_POINTER
+
+#include <nx-X11/Xdefs.h> /* for Bool */
+
+#include <nx-X11/Xproto.h>
+#include "screenint.h" /* for ScreenPtr */
+#include "pixmap.h" /* for DrawablePtr */
+
+/* clientClipType field in GC */
+#define CT_NONE 0
+#define CT_PIXMAP 1
+#define CT_REGION 2
+#define CT_UNSORTED 6
+#define CT_YSORTED 10
+#define CT_YXSORTED 14
+#define CT_YXBANDED 18
+
+#define GCQREASON_VALIDATE 1
+#define GCQREASON_CHANGE 2
+#define GCQREASON_COPY_SRC 3
+#define GCQREASON_COPY_DST 4
+#define GCQREASON_DESTROY 5
+
+#define GC_CHANGE_SERIAL_BIT (((unsigned long)1)<<31)
+#define GC_CALL_VALIDATE_BIT (1L<<30)
+#define GCExtensionInterest (1L<<29)
+
+#define DRAWABLE_SERIAL_BITS (~(GC_CHANGE_SERIAL_BIT))
+
+#define MAX_SERIAL_NUM (1L<<28)
+
+#define NEXT_SERIAL_NUMBER ((++globalSerialNumber) > MAX_SERIAL_NUM ? \
+ (globalSerialNumber = 1): globalSerialNumber)
+
+typedef struct _GCInterest *GCInterestPtr;
+typedef struct _GC *GCPtr;
+typedef struct _GCOps *GCOpsPtr;
+
+extern void ValidateGC(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/);
+
+extern int ChangeGC(
+ GCPtr/*pGC*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/);
+
+extern int DoChangeGC(
+ GCPtr/*pGC*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/,
+ int /*fPointer*/);
+
+typedef union {
+ CARD32 val;
+ void * ptr;
+} ChangeGCVal, *ChangeGCValPtr;
+
+extern int dixChangeGC(
+ ClientPtr /*client*/,
+ GCPtr /*pGC*/,
+ BITS32 /*mask*/,
+ CARD32 * /*pval*/,
+ ChangeGCValPtr /*pCGCV*/);
+
+extern GCPtr CreateGC(
+ DrawablePtr /*pDrawable*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/,
+ int* /*pStatus*/);
+
+extern int CopyGC(
+ GCPtr/*pgcSrc*/,
+ GCPtr/*pgcDst*/,
+ BITS32 /*mask*/);
+
+extern int FreeGC(
+ void * /*pGC*/,
+ XID /*gid*/);
+
+extern void SetGCMask(
+ GCPtr /*pGC*/,
+ Mask /*selectMask*/,
+ Mask /*newDataMask*/);
+
+extern GCPtr CreateScratchGC(
+ ScreenPtr /*pScreen*/,
+ unsigned /*depth*/);
+
+extern void FreeGCperDepth(
+ int /*screenNum*/);
+
+extern Bool CreateGCperDepth(
+ int /*screenNum*/);
+
+extern Bool CreateDefaultStipple(
+ int /*screenNum*/);
+
+extern void FreeDefaultStipple(
+ int /*screenNum*/);
+
+extern int SetDashes(
+ GCPtr /*pGC*/,
+ unsigned /*offset*/,
+ unsigned /*ndash*/,
+ unsigned char* /*pdash*/);
+
+extern int VerifyRectOrder(
+ int /*nrects*/,
+ xRectangle* /*prects*/,
+ int /*ordering*/);
+
+extern int SetClipRects(
+ GCPtr /*pGC*/,
+ int /*xOrigin*/,
+ int /*yOrigin*/,
+ int /*nrects*/,
+ xRectangle* /*prects*/,
+ int /*ordering*/);
+
+extern GCPtr GetScratchGC(
+ unsigned /*depth*/,
+ ScreenPtr /*pScreen*/);
+
+extern void FreeScratchGC(
+ GCPtr /*pGC*/);
+
+#endif /* GC_H */
diff --git a/nx-X11/programs/Xserver/include/gcstruct.h b/nx-X11/programs/Xserver/include/gcstruct.h
new file mode 100644
index 000000000..9a8169cab
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/gcstruct.h
@@ -0,0 +1,326 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+
+#ifndef GCSTRUCT_H
+#define GCSTRUCT_H
+
+#include "gc.h"
+
+#include "regionstr.h"
+#include "region.h"
+#include "pixmap.h"
+#include "screenint.h"
+#include <nx-X11/Xprotostr.h>
+
+/*
+ * functions which modify the state of the GC
+ */
+
+typedef struct _GCFuncs {
+ void (* ValidateGC)(
+ GCPtr /*pGC*/,
+ unsigned long /*stateChanges*/,
+ DrawablePtr /*pDrawable*/);
+
+ void (* ChangeGC)(
+ GCPtr /*pGC*/,
+ unsigned long /*mask*/);
+
+ void (* CopyGC)(
+ GCPtr /*pGCSrc*/,
+ unsigned long /*mask*/,
+ GCPtr /*pGCDst*/);
+
+ void (* DestroyGC)(
+ GCPtr /*pGC*/);
+
+ void (* ChangeClip)(
+ GCPtr /*pGC*/,
+ int /*type*/,
+ void * /*pvalue*/,
+ int /*nrects*/);
+
+ void (* DestroyClip)(
+ GCPtr /*pGC*/);
+
+ void (* CopyClip)(
+ GCPtr /*pgcDst*/,
+ GCPtr /*pgcSrc*/);
+ DevUnion devPrivate;
+} GCFuncs;
+
+/*
+ * graphics operations invoked through a GC
+ */
+
+typedef struct _GCOps {
+ void (* FillSpans)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/);
+
+ void (* SetSpans)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/);
+
+ void (* PutImage)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pBits*/);
+
+ RegionPtr (* CopyArea)(
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/);
+
+ RegionPtr (* CopyPlane)(
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/);
+ void (* PolyPoint)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/);
+
+ void (* Polylines)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/);
+
+ void (* PolySegment)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/);
+
+ void (* PolyRectangle)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/);
+
+ void (* PolyArc)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/);
+
+ void (* FillPolygon)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/);
+
+ void (* PolyFillRect)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/);
+
+ void (* PolyFillArc)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/);
+
+ int (* PolyText8)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/);
+
+ int (* PolyText16)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/);
+
+ void (* ImageText8)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/);
+
+ void (* ImageText16)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/);
+
+ void (* ImageGlyphBlt)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ void * /*pglyphBase*/);
+
+ void (* PolyGlyphBlt)(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ void * /*pglyphBase*/);
+
+ void (* PushPixels)(
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDst*/,
+ int /*w*/,
+ int /*h*/,
+ int /*x*/,
+ int /*y*/);
+
+#ifdef NEED_LINEHELPER
+ void (* LineHelper)();
+#endif
+
+ DevUnion devPrivate;
+} GCOps;
+
+/* there is padding in the bit fields because the Sun compiler doesn't
+ * force alignment to 32-bit boundaries. losers.
+ */
+typedef struct _GC {
+ ScreenPtr pScreen;
+ unsigned char depth;
+ unsigned char alu;
+ unsigned short lineWidth;
+ unsigned short dashOffset;
+ unsigned short numInDashList;
+ unsigned char *dash;
+ unsigned int lineStyle : 2;
+ unsigned int capStyle : 2;
+ unsigned int joinStyle : 2;
+ unsigned int fillStyle : 2;
+ unsigned int fillRule : 1;
+ unsigned int arcMode : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int clientClipType : 2; /* CT_<kind> */
+ unsigned int miTranslate:1; /* should mi things translate? */
+ unsigned int tileIsPixel:1; /* tile is solid pixel */
+ unsigned int fExpose:1; /* Call exposure handling */
+ unsigned int freeCompClip:1; /* Free composite clip */
+ unsigned int unused:14; /* see comment above */
+ unsigned long planemask;
+ unsigned long fgPixel;
+ unsigned long bgPixel;
+ /*
+ * alas -- both tile and stipple must be here as they
+ * are independently specifiable
+ */
+ PixUnion tile;
+ PixmapPtr stipple;
+ DDXPointRec patOrg; /* origin for (tile, stipple) */
+ struct _Font *font;
+ DDXPointRec clipOrg;
+ DDXPointRec lastWinOrg; /* position of window last validated */
+ void * clientClip;
+ unsigned long stateChanges; /* masked with GC_<kind> */
+ unsigned long serialNumber;
+ GCFuncs *funcs;
+ GCOps *ops;
+ DevUnion *devPrivates;
+ /*
+ * The following were moved here from private storage to allow device-
+ * independent access to them from screen wrappers.
+ * --- 1997.11.03 Marc Aurele La France (tsi@xfree86.org)
+ */
+ PixmapPtr pRotatedPixmap; /* tile/stipple rotated for alignment */
+ RegionPtr pCompositeClip;
+ /* fExpose & freeCompClip defined above */
+} GC;
+
+#endif /* GCSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/globals.h b/nx-X11/programs/Xserver/include/globals.h
new file mode 100644
index 000000000..1c4d73e64
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/globals.h
@@ -0,0 +1,147 @@
+
+#ifndef _XSERV_GLOBAL_H_
+#define _XSERV_GLOBAL_H_
+
+#include "window.h" /* for WindowPtr */
+
+/* Global X server variables that are visible to mi, dix, os, and ddx */
+
+extern CARD32 defaultScreenSaverTime;
+extern CARD32 defaultScreenSaverInterval;
+extern CARD32 ScreenSaverTime;
+extern CARD32 ScreenSaverInterval;
+
+extern char *defaultFontPath;
+extern int monitorResolution;
+extern Bool loadableFonts;
+extern int defaultColorVisualClass;
+
+extern Bool Must_have_memory;
+extern int GrabInProgress;
+extern char *ConnectionInfo;
+extern Bool noTestExtensions;
+
+extern DDXPointRec dixScreenOrigins[MAXSCREENS];
+
+#ifdef DPMSExtension
+extern CARD32 defaultDPMSStandbyTime;
+extern CARD32 defaultDPMSSuspendTime;
+extern CARD32 defaultDPMSOffTime;
+extern CARD32 DPMSStandbyTime;
+extern CARD32 DPMSSuspendTime;
+extern CARD32 DPMSOffTime;
+extern CARD16 DPMSPowerLevel;
+extern Bool defaultDPMSEnabled;
+extern Bool DPMSEnabled;
+extern Bool DPMSEnabledSwitch;
+extern Bool DPMSDisabledSwitch;
+extern Bool DPMSCapableFlag;
+#endif
+
+#ifdef PANORAMIX
+extern Bool PanoramiXMapped;
+extern Bool PanoramiXVisibilityNotifySent;
+extern Bool PanoramiXWindowExposureSent;
+extern Bool PanoramiXOneExposeRequest;
+extern Bool PanoramiXExtensionDisabledHack;
+#endif
+
+#ifdef BIGREQS
+extern Bool noBigReqExtension;
+#endif
+
+#ifdef COMPOSITE
+extern Bool noCompositeExtension;
+#endif
+
+#ifdef DAMAGE
+extern Bool noDamageExtension;
+#endif
+
+#ifdef DBE
+extern Bool noDbeExtension;
+#endif
+
+#ifdef DPSEXT
+extern Bool noDPSExtension;
+#endif
+
+#ifdef DPMSExtension
+extern Bool noDPMSExtension;
+#endif
+
+#ifdef GLXEXT
+extern Bool noGlxExtension;
+#endif
+
+#ifdef SCREENSAVER
+extern Bool noScreenSaverExtension;
+#endif
+
+#ifdef MITSHM
+extern Bool noMITShmExtension;
+#endif
+
+#ifdef RANDR
+extern Bool noRRExtension;
+extern Bool noRRXineramaExtension;
+#endif
+
+#ifdef RENDER
+extern Bool noRenderExtension;
+#endif
+
+#ifdef SHAPE
+extern Bool noShapeExtension;
+#endif
+
+#ifdef XCSECURITY
+extern Bool noSecurityExtension;
+#endif
+
+#ifdef XSYNC
+extern Bool noSyncExtension;
+#endif
+
+#ifdef RES
+extern Bool noResExtension;
+#endif
+
+#ifdef XCMISC
+extern Bool noXCMiscExtension;
+#endif
+
+#ifdef XF86BIGFONT
+extern Bool noXFree86BigfontExtension;
+#endif
+
+#ifdef XF86DRI
+extern Bool noXFree86DRIExtension;
+#endif
+
+#ifdef XFIXES
+extern Bool noXFixesExtension;
+#endif
+
+#ifdef XKB
+/* |noXkbExtension| is defined in xc/programs/Xserver/xkb/xkbInit.c */
+extern Bool noXkbExtension;
+#endif
+
+#ifdef PANORAMIX
+extern Bool noPanoramiXExtension;
+#endif
+
+#ifdef XINPUT
+extern Bool noXInputExtension;
+#endif
+
+#ifdef XIDLE
+extern Bool noXIdleExtension;
+#endif
+
+#ifdef XV
+extern Bool noXvExtension;
+#endif
+
+#endif /* !_XSERV_GLOBAL_H_ */
diff --git a/nx-X11/programs/Xserver/include/input.h b/nx-X11/programs/Xserver/include/input.h
new file mode 100644
index 000000000..7cfbf32a7
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/input.h
@@ -0,0 +1,389 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "window.h" /* for WindowPtr */
+
+#define DEVICE_INIT 0
+#define DEVICE_ON 1
+#define DEVICE_OFF 2
+#define DEVICE_CLOSE 3
+
+#define MAP_LENGTH 256
+#define DOWN_LENGTH 32 /* 256/8 => number of bytes to hold 256 bits */
+#define NullGrab ((GrabPtr)NULL)
+#define PointerRootWin ((WindowPtr)PointerRoot)
+#define NoneWin ((WindowPtr)None)
+#define NullDevice ((DevicePtr)NULL)
+
+#ifndef FollowKeyboard
+#define FollowKeyboard 3
+#endif
+#ifndef FollowKeyboardWin
+#define FollowKeyboardWin ((WindowPtr) FollowKeyboard)
+#endif
+#ifndef RevertToFollowKeyboard
+#define RevertToFollowKeyboard 3
+#endif
+
+typedef unsigned long Leds;
+typedef struct _OtherClients *OtherClientsPtr;
+typedef struct _InputClients *InputClientsPtr;
+typedef struct _DeviceIntRec *DeviceIntPtr;
+
+typedef int (*DeviceProc)(
+ DeviceIntPtr /*device*/,
+ int /*what*/);
+
+typedef void (*ProcessInputProc)(
+ xEventPtr /*events*/,
+ DeviceIntPtr /*device*/,
+ int /*count*/);
+
+typedef Bool (*DeviceHandleProc)(
+ DeviceIntPtr /*device*/,
+ void* /*data*/
+ );
+
+typedef void (*DeviceUnwrapProc)(
+ DeviceIntPtr /*device*/,
+ DeviceHandleProc /*proc*/,
+ void* /*data*/
+ );
+
+typedef struct _DeviceRec {
+ void * devicePrivate;
+ ProcessInputProc processInputProc; /* current */
+ ProcessInputProc realInputProc; /* deliver */
+ ProcessInputProc enqueueInputProc; /* enqueue */
+ Bool on; /* used by DDX to keep state */
+} DeviceRec, *DevicePtr;
+
+typedef struct {
+ int click, bell, bell_pitch, bell_duration;
+ Bool autoRepeat;
+ unsigned char autoRepeats[32];
+ Leds leds;
+ unsigned char id;
+} KeybdCtrl;
+
+typedef struct {
+ KeySym *map;
+ KeyCode minKeyCode,
+ maxKeyCode;
+ int mapWidth;
+} KeySymsRec, *KeySymsPtr;
+
+typedef struct {
+ int num, den, threshold;
+ unsigned char id;
+} PtrCtrl;
+
+typedef struct {
+ int resolution, min_value, max_value;
+ int integer_displayed;
+ unsigned char id;
+} IntegerCtrl;
+
+typedef struct {
+ int max_symbols, num_symbols_supported;
+ int num_symbols_displayed;
+ KeySym *symbols_supported;
+ KeySym *symbols_displayed;
+ unsigned char id;
+} StringCtrl;
+
+typedef struct {
+ int percent, pitch, duration;
+ unsigned char id;
+} BellCtrl;
+
+typedef struct {
+ Leds led_values;
+ Mask led_mask;
+ unsigned char id;
+} LedCtrl;
+
+extern int AllocateDevicePrivateIndex(void);
+extern Bool AllocateDevicePrivate(DeviceIntPtr device, int index);
+extern void ResetDevicePrivateIndex(void);
+
+extern KeybdCtrl defaultKeyboardControl;
+extern PtrCtrl defaultPointerControl;
+
+#undef AddInputDevice
+extern DevicePtr AddInputDevice(
+ DeviceProc /*deviceProc*/,
+ Bool /*autoStart*/);
+
+#define AddInputDevice(deviceProc, autoStart) \
+ _AddInputDevice(deviceProc, autoStart)
+
+extern DeviceIntPtr _AddInputDevice(
+ DeviceProc /*deviceProc*/,
+ Bool /*autoStart*/);
+
+extern Bool EnableDevice(
+ DeviceIntPtr /*device*/);
+
+extern Bool DisableDevice(
+ DeviceIntPtr /*device*/);
+
+extern int InitAndStartDevices(void);
+
+extern void CloseDownDevices(void);
+
+extern void RemoveDevice(
+ DeviceIntPtr /*dev*/);
+
+extern int NumMotionEvents(void);
+
+#undef RegisterPointerDevice
+extern void RegisterPointerDevice(
+ DevicePtr /*device*/);
+
+#define RegisterPointerDevice(device) \
+ _RegisterPointerDevice(device)
+
+extern void _RegisterPointerDevice(
+ DeviceIntPtr /*device*/);
+
+#undef RegisterKeyboardDevice
+extern void RegisterKeyboardDevice(
+ DevicePtr /*device*/);
+
+#define RegisterKeyboardDevice(device) \
+ _RegisterKeyboardDevice(device)
+
+extern void _RegisterKeyboardDevice(
+ DeviceIntPtr /*device*/);
+
+extern DevicePtr LookupKeyboardDevice(void);
+
+extern DevicePtr LookupPointerDevice(void);
+
+extern DevicePtr LookupDevice(
+ int /* id */);
+
+extern void QueryMinMaxKeyCodes(
+ KeyCode* /*minCode*/,
+ KeyCode* /*maxCode*/);
+
+extern Bool SetKeySymsMap(
+ KeySymsPtr /*dst*/,
+ KeySymsPtr /*src*/);
+
+extern Bool InitKeyClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ KeySymsPtr /*pKeySyms*/,
+ CARD8 /*pModifiers*/[]);
+
+extern Bool InitButtonClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ int /*numButtons*/,
+ CARD8* /*map*/);
+
+typedef int (*ValuatorMotionProcPtr)(
+ DeviceIntPtr /*pdevice*/,
+ xTimecoord * /*coords*/,
+ unsigned long /*start*/,
+ unsigned long /*stop*/,
+ ScreenPtr /*pScreen*/);
+
+extern Bool InitValuatorClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ int /*numAxes*/,
+ ValuatorMotionProcPtr /* motionProc */,
+ int /*numMotionEvents*/,
+ int /*mode*/);
+
+extern Bool InitFocusClassDeviceStruct(
+ DeviceIntPtr /*device*/);
+
+typedef void (*BellProcPtr)(
+ int /*percent*/,
+ DeviceIntPtr /*device*/,
+ void * /*ctrl*/,
+ int);
+
+typedef void (*KbdCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ KeybdCtrl * /*ctrl*/);
+
+extern Bool InitKbdFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ BellProcPtr /*bellProc*/,
+ KbdCtrlProcPtr /*controlProc*/);
+
+typedef void (*PtrCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ PtrCtrl * /*ctrl*/);
+
+extern Bool InitPtrFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ PtrCtrlProcPtr /*controlProc*/);
+
+typedef void (*StringCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ StringCtrl * /*ctrl*/);
+
+extern Bool InitStringFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ StringCtrlProcPtr /*controlProc*/,
+ int /*max_symbols*/,
+ int /*num_symbols_supported*/,
+ KeySym* /*symbols*/);
+
+typedef void (*BellCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ BellCtrl * /*ctrl*/);
+
+extern Bool InitBellFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ BellProcPtr /*bellProc*/,
+ BellCtrlProcPtr /*controlProc*/);
+
+typedef void (*LedCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ LedCtrl * /*ctrl*/);
+
+extern Bool InitLedFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ LedCtrlProcPtr /*controlProc*/);
+
+typedef void (*IntegerCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ IntegerCtrl * /*ctrl*/);
+
+
+extern Bool InitIntegerFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ IntegerCtrlProcPtr /*controlProc*/);
+
+extern Bool InitPointerDeviceStruct(
+ DevicePtr /*device*/,
+ CARD8* /*map*/,
+ int /*numButtons*/,
+ ValuatorMotionProcPtr /*motionProc*/,
+ PtrCtrlProcPtr /*controlProc*/,
+ int /*numMotionEvents*/);
+
+extern Bool InitKeyboardDeviceStruct(
+ DevicePtr /*device*/,
+ KeySymsPtr /*pKeySyms*/,
+ CARD8 /*pModifiers*/[],
+ BellProcPtr /*bellProc*/,
+ KbdCtrlProcPtr /*controlProc*/);
+
+extern void SendMappingNotify(
+ unsigned int /*request*/,
+ unsigned int /*firstKeyCode*/,
+ unsigned int /*count*/,
+ ClientPtr /* client */);
+
+extern Bool BadDeviceMap(
+ BYTE* /*buff*/,
+ int /*length*/,
+ unsigned /*low*/,
+ unsigned /*high*/,
+ XID* /*errval*/);
+
+extern Bool AllModifierKeysAreUp(
+ DeviceIntPtr /*device*/,
+ CARD8* /*map1*/,
+ int /*per1*/,
+ CARD8* /*map2*/,
+ int /*per2*/);
+
+extern void NoteLedState(
+ DeviceIntPtr /*keybd*/,
+ int /*led*/,
+ Bool /*on*/);
+
+extern void MaybeStopHint(
+ DeviceIntPtr /*device*/,
+ ClientPtr /*client*/);
+
+extern void ProcessPointerEvent(
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*mouse*/,
+ int /*count*/);
+
+extern void ProcessKeyboardEvent(
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*keybd*/,
+ int /*count*/);
+
+#ifdef XKB
+extern void CoreProcessPointerEvent(
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*mouse*/,
+ int /*count*/);
+
+extern void CoreProcessKeyboardEvent(
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*keybd*/,
+ int /*count*/);
+#endif
+
+extern Bool LegalModifier(
+ unsigned int /*key*/,
+ DevicePtr /*pDev*/);
+
+extern void ProcessInputEvents(void);
+
+extern void InitInput(
+ int /*argc*/,
+ char ** /*argv*/);
+
+#endif /* INPUT_H */
diff --git a/nx-X11/programs/Xserver/include/inputstr.h b/nx-X11/programs/Xserver/include/inputstr.h
new file mode 100644
index 000000000..5e2e26968
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/inputstr.h
@@ -0,0 +1,312 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+
+#ifndef INPUTSTRUCT_H
+#define INPUTSTRUCT_H
+
+#include "input.h"
+#include "window.h"
+#include "dixstruct.h"
+
+#define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
+
+#define SameClient(obj,client) \
+ (CLIENT_BITS((obj)->resource) == (client)->clientAsMask)
+
+#define MAX_DEVICES 20
+
+#define EMASKSIZE MAX_DEVICES
+
+/* Kludge: OtherClients and InputClients must be compatible, see code */
+
+typedef struct _OtherClients {
+ OtherClientsPtr next;
+ XID resource; /* id for putting into resource manager */
+ Mask mask;
+} OtherClients;
+
+typedef struct _InputClients {
+ InputClientsPtr next;
+ XID resource; /* id for putting into resource manager */
+ Mask mask[EMASKSIZE];
+} InputClients;
+
+typedef struct _OtherInputMasks {
+ Mask deliverableEvents[EMASKSIZE];
+ Mask inputEvents[EMASKSIZE];
+ Mask dontPropagateMask[EMASKSIZE];
+ InputClientsPtr inputClients;
+} OtherInputMasks;
+
+/*
+ * The following structure gets used for both active and passive grabs. For
+ * active grabs some of the fields (e.g. modifiers) are not used. However,
+ * that is not much waste since there aren't many active grabs (one per
+ * keyboard/pointer device) going at once in the server.
+ */
+
+#define MasksPerDetailMask 8 /* 256 keycodes and 256 possible
+ modifier combinations, but only
+ 3 buttons. */
+
+ typedef struct _DetailRec { /* Grab details may be bit masks */
+ unsigned short exact;
+ Mask *pMask;
+ } DetailRec;
+
+ typedef struct _GrabRec {
+ GrabPtr next; /* for chain of passive grabs */
+ XID resource;
+ DeviceIntPtr device;
+ WindowPtr window;
+ unsigned ownerEvents:1;
+ unsigned keyboardMode:1;
+ unsigned pointerMode:1;
+ unsigned coreGrab:1; /* grab is on core device */
+ unsigned coreMods:1; /* modifiers are on core keyboard */
+ CARD8 type; /* event type */
+ DetailRec modifiersDetail;
+ DeviceIntPtr modifierDevice;
+ DetailRec detail; /* key or button */
+ WindowPtr confineTo; /* always NULL for keyboards */
+ CursorPtr cursor; /* always NULL for keyboards */
+ Mask eventMask;
+} GrabRec;
+
+typedef struct _KeyClassRec {
+ CARD8 down[DOWN_LENGTH];
+ KeyCode *modifierKeyMap;
+ KeySymsRec curKeySyms;
+ int modifierKeyCount[8];
+ CARD8 modifierMap[MAP_LENGTH];
+ CARD8 maxKeysPerModifier;
+ unsigned short state;
+ unsigned short prev_state;
+#ifdef XKB
+ struct _XkbSrvInfo *xkbInfo;
+#endif
+} KeyClassRec, *KeyClassPtr;
+
+typedef struct _AxisInfo {
+ int resolution;
+ int min_resolution;
+ int max_resolution;
+ int min_value;
+ int max_value;
+} AxisInfo, *AxisInfoPtr;
+
+typedef struct _ValuatorClassRec {
+ ValuatorMotionProcPtr GetMotionProc;
+ int numMotionEvents;
+ WindowPtr motionHintWindow;
+ AxisInfoPtr axes;
+ unsigned short numAxes;
+ int *axisVal;
+ CARD8 mode;
+} ValuatorClassRec, *ValuatorClassPtr;
+
+typedef struct _ButtonClassRec {
+ CARD8 numButtons;
+ CARD8 buttonsDown; /* number of buttons currently down */
+ unsigned short state;
+ Mask motionMask;
+ CARD8 down[DOWN_LENGTH];
+ CARD8 map[MAP_LENGTH];
+#ifdef XKB
+ union _XkbAction * xkb_acts;
+#endif
+} ButtonClassRec, *ButtonClassPtr;
+
+typedef struct _FocusClassRec {
+ WindowPtr win;
+ int revert;
+ TimeStamp time;
+ WindowPtr *trace;
+ int traceSize;
+ int traceGood;
+} FocusClassRec, *FocusClassPtr;
+
+typedef struct _ProximityClassRec {
+ char pad;
+} ProximityClassRec, *ProximityClassPtr;
+
+typedef struct _KbdFeedbackClassRec *KbdFeedbackPtr;
+typedef struct _PtrFeedbackClassRec *PtrFeedbackPtr;
+typedef struct _IntegerFeedbackClassRec *IntegerFeedbackPtr;
+typedef struct _StringFeedbackClassRec *StringFeedbackPtr;
+typedef struct _BellFeedbackClassRec *BellFeedbackPtr;
+typedef struct _LedFeedbackClassRec *LedFeedbackPtr;
+
+typedef struct _KbdFeedbackClassRec {
+ BellProcPtr BellProc;
+ KbdCtrlProcPtr CtrlProc;
+ KeybdCtrl ctrl;
+ KbdFeedbackPtr next;
+#ifdef XKB
+ struct _XkbSrvLedInfo *xkb_sli;
+#endif
+} KbdFeedbackClassRec;
+
+typedef struct _PtrFeedbackClassRec {
+ PtrCtrlProcPtr CtrlProc;
+ PtrCtrl ctrl;
+ PtrFeedbackPtr next;
+} PtrFeedbackClassRec;
+
+typedef struct _IntegerFeedbackClassRec {
+ IntegerCtrlProcPtr CtrlProc;
+ IntegerCtrl ctrl;
+ IntegerFeedbackPtr next;
+} IntegerFeedbackClassRec;
+
+typedef struct _StringFeedbackClassRec {
+ StringCtrlProcPtr CtrlProc;
+ StringCtrl ctrl;
+ StringFeedbackPtr next;
+} StringFeedbackClassRec;
+
+typedef struct _BellFeedbackClassRec {
+ BellProcPtr BellProc;
+ BellCtrlProcPtr CtrlProc;
+ BellCtrl ctrl;
+ BellFeedbackPtr next;
+} BellFeedbackClassRec;
+
+typedef struct _LedFeedbackClassRec {
+ LedCtrlProcPtr CtrlProc;
+ LedCtrl ctrl;
+ LedFeedbackPtr next;
+#ifdef XKB
+ struct _XkbSrvLedInfo *xkb_sli;
+#endif
+} LedFeedbackClassRec;
+
+/* states for devices */
+
+#define NOT_GRABBED 0
+#define THAWED 1
+#define THAWED_BOTH 2 /* not a real state */
+#define FREEZE_NEXT_EVENT 3
+#define FREEZE_BOTH_NEXT_EVENT 4
+#define FROZEN 5 /* any state >= has device frozen */
+#define FROZEN_NO_EVENT 5
+#define FROZEN_WITH_EVENT 6
+#define THAW_OTHERS 7
+
+typedef struct _DeviceIntRec {
+ DeviceRec public;
+ DeviceIntPtr next;
+ TimeStamp grabTime;
+ Bool startup; /* true if needs to be turned on at
+ server intialization time */
+ DeviceProc deviceProc; /* proc(DevicePtr, DEVICE_xx). It is
+ used to initialize, turn on, or
+ turn off the device */
+ Bool inited; /* TRUE if INIT returns Success */
+ GrabPtr grab; /* the grabber - used by DIX */
+ struct {
+ Bool frozen;
+ int state;
+ GrabPtr other; /* if other grab has this frozen */
+ xEvent *event; /* saved to be replayed */
+ int evcount;
+ } sync;
+ Atom type;
+ char *name;
+ CARD8 id;
+ CARD8 activatingKey;
+ Bool fromPassiveGrab;
+ GrabRec activeGrab;
+ void (*ActivateGrab) (
+ DeviceIntPtr /*device*/,
+ GrabPtr /*grab*/,
+ TimeStamp /*time*/,
+ Bool /*autoGrab*/);
+ void (*DeactivateGrab)(
+ DeviceIntPtr /*device*/);
+ KeyClassPtr key;
+ ValuatorClassPtr valuator;
+ ButtonClassPtr button;
+ FocusClassPtr focus;
+ ProximityClassPtr proximity;
+ KbdFeedbackPtr kbdfeed;
+ PtrFeedbackPtr ptrfeed;
+ IntegerFeedbackPtr intfeed;
+ StringFeedbackPtr stringfeed;
+ BellFeedbackPtr bell;
+ LedFeedbackPtr leds;
+#ifdef XKB
+ struct _XkbInterest * xkb_interest;
+#endif
+ DevUnion *devPrivates;
+ int nPrivates;
+ DeviceUnwrapProc unwrapProc;
+} DeviceIntRec;
+
+typedef struct {
+ int numDevices; /* total number of devices */
+ DeviceIntPtr devices; /* all devices turned on */
+ DeviceIntPtr off_devices; /* all devices turned off */
+ DeviceIntPtr keyboard; /* the main one for the server */
+ DeviceIntPtr pointer;
+} InputInfo;
+
+extern InputInfo inputInfo;
+
+/* for keeping the events for devices grabbed synchronously */
+typedef struct _QdEvent *QdEventPtr;
+typedef struct _QdEvent {
+ QdEventPtr next;
+ DeviceIntPtr device;
+ ScreenPtr pScreen; /* what screen the pointer was on */
+ unsigned long months; /* milliseconds is in the event */
+ xEvent *event;
+ int evcount;
+} QdEventRec;
+
+#endif /* INPUTSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/list.h b/nx-X11/programs/Xserver/include/list.h
new file mode 100644
index 000000000..3f0574d43
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/list.h
@@ -0,0 +1,494 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ */
+
+#ifndef _XORG_LIST_H_
+#define _XORG_LIST_H_
+
+#include <stddef.h> /* offsetof() */
+
+/**
+ * @file Classic doubly-link circular list implementation.
+ * For real usage examples of the linked list, see the file test/list.c
+ *
+ * Example:
+ * We need to keep a list of struct foo in the parent struct bar, i.e. what
+ * we want is something like this.
+ *
+ * struct bar {
+ * ...
+ * struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
+ * ...
+ * }
+ *
+ * We need one list head in bar and a list element in all list_of_foos (both are of
+ * data type 'struct xorg_list').
+ *
+ * struct bar {
+ * ...
+ * struct xorg_list list_of_foos;
+ * ...
+ * }
+ *
+ * struct foo {
+ * ...
+ * struct xorg_list entry;
+ * ...
+ * }
+ *
+ * Now we initialize the list head:
+ *
+ * struct bar bar;
+ * ...
+ * xorg_list_init(&bar.list_of_foos);
+ *
+ * Then we create the first element and add it to this list:
+ *
+ * struct foo *foo = malloc(...);
+ * ....
+ * xorg_list_add(&foo->entry, &bar.list_of_foos);
+ *
+ * Repeat the above for each element you want to add to the list. Deleting
+ * works with the element itself.
+ * xorg_list_del(&foo->entry);
+ * free(foo);
+ *
+ * Note: calling xorg_list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
+ * list again.
+ *
+ * Looping through the list requires a 'struct foo' as iterator and the
+ * name of the field the subnodes use.
+ *
+ * struct foo *iterator;
+ * xorg_list_for_each_entry(iterator, &bar.list_of_foos, entry) {
+ * if (iterator->something == ...)
+ * ...
+ * }
+ *
+ * Note: You must not call xorg_list_del() on the iterator if you continue the
+ * loop. You need to run the safe for-each loop instead:
+ *
+ * struct foo *iterator, *next;
+ * xorg_list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
+ * if (...)
+ * xorg_list_del(&iterator->entry);
+ * }
+ *
+ */
+
+/**
+ * The linkage struct for list nodes. This struct must be part of your
+ * to-be-linked struct. struct xorg_list is required for both the head of the
+ * list and for each list node.
+ *
+ * Position and name of the struct xorg_list field is irrelevant.
+ * There are no requirements that elements of a list are of the same type.
+ * There are no requirements for a list head, any struct xorg_list can be a list
+ * head.
+ */
+struct xorg_list {
+ struct xorg_list *next, *prev;
+};
+
+/**
+ * Initialize the list as an empty list.
+ *
+ * Example:
+ * xorg_list_init(&bar->list_of_foos);
+ *
+ * @param list The list to initialize
+ */
+static inline void
+xorg_list_init(struct xorg_list *list)
+{
+ list->next = list->prev = list;
+}
+
+static inline void
+__xorg_list_add(struct xorg_list *entry,
+ struct xorg_list *prev, struct xorg_list *next)
+{
+ next->prev = entry;
+ entry->next = next;
+ entry->prev = prev;
+ prev->next = entry;
+}
+
+/**
+ * Insert a new element after the given list head. The new element does not
+ * need to be initialised as empty list.
+ * The list changes from:
+ * head → some element → ...
+ * to
+ * head → new element → older element → ...
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * xorg_list_add(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+xorg_list_add(struct xorg_list *entry, struct xorg_list *head)
+{
+ __xorg_list_add(entry, head, head->next);
+}
+
+/**
+ * Append a new element to the end of the list given with this list head.
+ *
+ * The list changes from:
+ * head → some element → ... → lastelement
+ * to
+ * head → some element → ... → lastelement → new element
+ *
+ * Example:
+ * struct foo *newfoo = malloc(...);
+ * xorg_list_append(&newfoo->entry, &bar->list_of_foos);
+ *
+ * @param entry The new element to prepend to the list.
+ * @param head The existing list.
+ */
+static inline void
+xorg_list_append(struct xorg_list *entry, struct xorg_list *head)
+{
+ __xorg_list_add(entry, head->prev, head);
+}
+
+static inline void
+__xorg_list_del(struct xorg_list *prev, struct xorg_list *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * Remove the element from the list it is in. Using this function will reset
+ * the pointers to/from this element so it is removed from the list. It does
+ * NOT free the element itself or manipulate it otherwise.
+ *
+ * Using xorg_list_del on a pure list head (like in the example at the top of
+ * this file) will NOT remove the first element from
+ * the list but rather reset the list as empty list.
+ *
+ * Example:
+ * xorg_list_del(&foo->entry);
+ *
+ * @param entry The element to remove.
+ */
+static inline void
+xorg_list_del(struct xorg_list *entry)
+{
+ __xorg_list_del(entry->prev, entry->next);
+ xorg_list_init(entry);
+}
+
+/**
+ * Check if the list is empty.
+ *
+ * Example:
+ * xorg_list_is_empty(&bar->list_of_foos);
+ *
+ * @return True if the list contains one or more elements or False otherwise.
+ */
+static inline int
+xorg_list_is_empty(struct xorg_list *head)
+{
+ return head->next == head;
+}
+
+/**
+ * Returns a pointer to the container of this list element.
+ *
+ * Example:
+ * struct foo* f;
+ * f = container_of(&foo->entry, struct foo, entry);
+ * assert(f == foo);
+ *
+ * @param ptr Pointer to the struct xorg_list.
+ * @param type Data type of the list element.
+ * @param member Member name of the struct xorg_list field in the list element.
+ * @return A pointer to the data struct containing the list head.
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) \
+ (type *)((char *)(ptr) - offsetof(type, member))
+#endif
+
+/**
+ * Alias of container_of
+ */
+#define xorg_list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * Retrieve the first list entry for the given list pointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = xorg_list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct xorg_list field in the list element.
+ * @return A pointer to the first list element.
+ */
+#define xorg_list_first_entry(ptr, type, member) \
+ xorg_list_entry((ptr)->next, type, member)
+
+/**
+ * Retrieve the last list entry for the given listpointer.
+ *
+ * Example:
+ * struct foo *first;
+ * first = xorg_list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
+ *
+ * @param ptr The list head
+ * @param type Data type of the list element to retrieve
+ * @param member Member name of the struct xorg_list field in the list element.
+ * @return A pointer to the last list element.
+ */
+#define xorg_list_last_entry(ptr, type, member) \
+ xorg_list_entry((ptr)->prev, type, member)
+
+#ifdef HAVE_TYPEOF
+#define __container_of(ptr, sample, member) \
+ container_of(ptr, typeof(*sample), member)
+#else
+/* This implementation of __container_of has undefined behavior according
+ * to the C standard, but it works in many cases. If your compiler doesn't
+ * support typeof() and fails with this implementation, please try a newer
+ * compiler.
+ */
+#define __container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) \
+ - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
+/**
+ * Loop through the list given by head and set pos to struct in the list.
+ *
+ * Example:
+ * struct foo *iterator;
+ * xorg_list_for_each_entry(iterator, &bar->list_of_foos, entry) {
+ * [modify iterator]
+ * }
+ *
+ * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe
+ * instead.
+ *
+ * @param pos Iterator variable of the type of the list elements.
+ * @param head List head
+ * @param member Member name of the struct xorg_list in the list elements.
+ *
+ */
+#define xorg_list_for_each_entry(pos, head, member) \
+ for (pos = NULL, \
+ pos = __container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+/**
+ * Loop through the list, keeping a backup pointer to the element. This
+ * macro allows for the deletion of a list element while looping through the
+ * list.
+ *
+ * See xorg_list_for_each_entry for more details.
+ */
+#define xorg_list_for_each_entry_safe(pos, tmp, head, member) \
+ for (pos = NULL, \
+ pos = __container_of((head)->next, pos, member), \
+ tmp = __container_of(pos->member.next, pos, member); \
+ &pos->member != (head); \
+ pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
+
+/* NULL-Terminated List Interface
+ *
+ * The interface below does _not_ use the struct xorg_list as described above.
+ * It is mainly for legacy structures that cannot easily be switched to
+ * struct xorg_list.
+ *
+ * This interface is for structs like
+ * struct foo {
+ * [...]
+ * struct foo *next;
+ * [...]
+ * };
+ *
+ * The position and field name of "next" are arbitrary.
+ */
+
+/**
+ * Init the element as null-terminated list.
+ *
+ * Example:
+ * struct foo *list = malloc();
+ * nt_list_init(list, next);
+ *
+ * @param list The list element that will be the start of the list
+ * @param member Member name of the field pointing to next struct
+ */
+#define nt_list_init(_list, _member) \
+ (_list)->_member = NULL
+
+/**
+ * Returns the next element in the list or NULL on termination.
+ *
+ * Example:
+ * struct foo *element = list;
+ * while ((element = nt_list_next(element, next)) { }
+ *
+ * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe
+ * instead.
+ *
+ * @param list The list or current element.
+ * @param member Member name of the field pointing to next struct.
+ */
+#define nt_list_next(_list, _member) \
+ (_list)->_member
+
+/**
+ * Iterate through each element in the list.
+ *
+ * Example:
+ * struct foo *iterator;
+ * nt_list_for_each_entry(iterator, list, next) {
+ * [modify iterator]
+ * }
+ *
+ * @param entry Assigned to the current list element
+ * @param list The list to iterate through.
+ * @param member Member name of the field pointing to next struct.
+ */
+#define nt_list_for_each_entry(_entry, _list, _member) \
+ for (_entry = _list; _entry; _entry = (_entry)->_member)
+
+/**
+ * Iterate through each element in the list, keeping a backup pointer to the
+ * element. This macro allows for the deletion of a list element while
+ * looping through the list.
+ *
+ * See nt_list_for_each_entry for more details.
+ *
+ * @param entry Assigned to the current list element
+ * @param tmp The pointer to the next element
+ * @param list The list to iterate through.
+ * @param member Member name of the field pointing to next struct.
+ */
+#define nt_list_for_each_entry_safe(_entry, _tmp, _list, _member) \
+ for (_entry = _list, _tmp = (_entry) ? (_entry)->_member : NULL;\
+ _entry; \
+ _entry = _tmp, _tmp = (_tmp) ? (_tmp)->_member: NULL)
+
+/**
+ * Append the element to the end of the list. This macro may be used to
+ * merge two lists.
+ *
+ * Example:
+ * struct foo *elem = malloc(...);
+ * nt_list_init(elem, next)
+ * nt_list_append(elem, list, struct foo, next);
+ *
+ * Resulting list order:
+ * list_item_0 -> list_item_1 -> ... -> elem_item_0 -> elem_item_1 ...
+ *
+ * @param entry An entry (or list) to append to the list
+ * @param list The list to append to. This list must be a valid list, not
+ * NULL.
+ * @param type The list type
+ * @param member Member name of the field pointing to next struct
+ */
+#define nt_list_append(_entry, _list, _type, _member) \
+ do { \
+ _type *__iterator = _list; \
+ while (__iterator->_member) { __iterator = __iterator->_member;}\
+ __iterator->_member = _entry; \
+ } while (0)
+
+/**
+ * Insert the element at the next position in the list. This macro may be
+ * used to insert a list into a list.
+ *
+ * struct foo *elem = malloc(...);
+ * nt_list_init(elem, next)
+ * nt_list_insert(elem, list, struct foo, next);
+ *
+ * Resulting list order:
+ * list_item_0 -> elem_item_0 -> elem_item_1 ... -> list_item_1 -> ...
+ *
+ * @param entry An entry (or list) to append to the list
+ * @param list The list to insert to. This list must be a valid list, not
+ * NULL.
+ * @param type The list type
+ * @param member Member name of the field pointing to next struct
+ */
+#define nt_list_insert(_entry, _list, _type, _member) \
+ do { \
+ nt_list_append((_list)->_member, _entry, _type, _member); \
+ (_list)->_member = _entry; \
+ } while (0)
+
+/**
+ * Delete the entry from the list by iterating through the list and
+ * removing any reference from the list to the entry.
+ *
+ * Example:
+ * struct foo *elem = <assign to right element>
+ * nt_list_del(elem, list, struct foo, next);
+ *
+ * @param entry The entry to delete from the list. entry is always
+ * re-initialized as a null-terminated list.
+ * @param list The list containing the entry, set to the new list without
+ * the removed entry.
+ * @param type The list type
+ * @param member Member name of the field pointing to the next entry
+ */
+#define nt_list_del(_entry, _list, _type, _member) \
+ do { \
+ _type *__e = _entry; \
+ if (__e == NULL || _list == NULL) break; \
+ if ((_list) == __e) { \
+ _list = __e->_member; \
+ } else { \
+ _type *__prev = _list; \
+ while (__prev->_member && __prev->_member != __e) \
+ __prev = nt_list_next(__prev, _member); \
+ if (__prev->_member) \
+ __prev->_member = __e->_member; \
+ } \
+ nt_list_init(__e, _member); \
+ } while(0)
+
+/**
+ * DO NOT USE THIS.
+ * This is a remainder of the xfree86 DDX attempt of having a set of generic
+ * list functions. Unfortunately, the xf86OptionRec uses it and we can't
+ * easily get rid of it. Do not use for new code.
+ */
+typedef struct generic_list_rec {
+ void *next;
+} GenericListRec, *GenericListPtr, *glp;
+
+#endif
diff --git a/nx-X11/programs/Xserver/include/misc.h b/nx-X11/programs/Xserver/include/misc.h
new file mode 100644
index 000000000..27137cd50
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/misc.h
@@ -0,0 +1,400 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+Copyright 1992, 1993 Data General Corporation;
+Copyright 1992, 1993 OMRON Corporation
+
+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, and that
+neither the name OMRON or DATA GENERAL be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission of the party whose name is to be used. Neither OMRON or
+DATA GENERAL make any representation about the suitability of this software
+for any purpose. It is provided "as is" without express or implied warranty.
+
+OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL OMRON OR DATA GENERAL 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.
+
+******************************************************************/
+#ifndef MISC_H
+#define MISC_H 1
+/*
+ * X internal definitions
+ *
+ */
+
+extern unsigned long globalSerialNumber;
+extern unsigned long serverGeneration;
+
+#include <nx-X11/Xosdefs.h>
+#include <nx-X11/Xfuncproto.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/X.h>
+#include <stdint.h>
+
+#ifndef _XTYPEDEF_POINTER
+/* Don't let Xdefs.h define 'pointer' */
+#define _XTYPEDEF_POINTER 1
+#endif /* _XTYPEDEF_POINTER */
+
+/* FIXME: for building this code against Xlib versions older than apprx. 04/2014
+ * we still have to define the pointer type via Xdefs.h.
+ *
+ * The nx-libs code itself does not require the pointer definition.
+ *
+ */
+#undef _XTYPEDEF_POINTER
+
+#include <nx-X11/Xdefs.h>
+
+#ifndef NULL
+#include <stddef.h>
+#endif
+
+#ifndef MAXSCREENS
+#define MAXSCREENS 16
+#endif
+#define MAXCLIENTS 256
+#define MAXDITS 1
+#define MAXEXTENSIONS 128
+#define MAXFORMATS 8
+#define MAXVISUALS_PER_SCREEN 50
+
+typedef unsigned long PIXEL;
+typedef unsigned long ATOM;
+
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef _XTYPEDEF_CALLBACKLISTPTR
+typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */
+#define _XTYPEDEF_CALLBACKLISTPTR
+#endif
+
+typedef struct _xReq *xReqPtr;
+
+#include "os.h" /* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */
+#include <nx-X11/Xfuncs.h> /* for bcopy, bzero, and bcmp */
+
+#define NullBox ((BoxPtr)0)
+#define MILLI_PER_MIN (1000 * 60)
+#define MILLI_PER_SECOND (1000)
+
+ /* this next is used with None and ParentRelative to tell
+ PaintWin() what to use to paint the background. Also used
+ in the macro IS_VALID_PIXMAP */
+
+#define USE_BACKGROUND_PIXEL 3
+#define USE_BORDER_PIXEL 3
+
+
+/* byte swap a 32-bit literal */
+#define lswapl(x) ((((x) & 0xff) << 24) |\
+ (((x) & 0xff00) << 8) |\
+ (((x) & 0xff0000) >> 8) |\
+ (((x) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
+
+#undef min
+#undef max
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+/* abs() is a function, not a macro; include the file declaring
+ * it in case we haven't done that yet.
+ */
+#include <stdlib.h>
+#ifndef Fabs
+#define Fabs(a) ((a) > 0.0 ? (a) : -(a)) /* floating absolute value */
+#endif
+#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
+/* this assumes b > 0 */
+#define modulus(a, b, d) if (((d) = (a) % (b)) < 0) (d) += (b)
+/*
+ * return the least significant bit in x which is set
+ *
+ * This works on 1's complement and 2's complement machines.
+ * If you care about the extra instruction on 2's complement
+ * machines, change to ((x) & (-(x)))
+ */
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/* XXX Not for modules */
+#include <limits.h>
+#if !defined(MAXSHORT) || !defined(MINSHORT) || \
+ !defined(MAXINT) || !defined(MININT)
+/*
+ * Some implementations #define these through <math.h>, so preclude
+ * #include'ing it later.
+ */
+
+#include <math.h>
+#endif
+#undef MAXSHORT
+#define MAXSHORT SHRT_MAX
+#undef MINSHORT
+#define MINSHORT SHRT_MIN
+#undef MAXINT
+#define MAXINT INT_MAX
+#undef MININT
+#define MININT INT_MIN
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h> /* for fopen, etc... */
+
+/**
+ * Calculate the number of bytes needed to hold bits.
+ * @param bits The minimum number of bits needed.
+ * @return The number of bytes needed to hold bits.
+ */
+static __inline__ int
+bits_to_bytes(const int bits) {
+ return ((bits + 7) >> 3);
+}
+/**
+ * Calculate the number of 4-byte units needed to hold the given number of
+ * bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The number of 4-byte units needed to hold bytes.
+ */
+static __inline__ int
+bytes_to_int32(const int bytes) {
+ return (((bytes) + 3) >> 2);
+}
+
+/**
+ * Calculate the number of bytes (in multiples of 4) needed to hold bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The closest multiple of 4 that is equal or higher than bytes.
+ */
+static __inline__ int
+pad_to_int32(const int bytes) {
+ return (((bytes) + 3) & ~3);
+}
+
+/**
+ * Compare the two version numbers comprising of major.minor.
+ *
+ * @return A value less than 0 if a is less than b, 0 if a is equal to b,
+ * or a value greater than 0
+ */
+static inline int
+version_compare(uint32_t a_major, uint32_t a_minor,
+ uint32_t b_major, uint32_t b_minor)
+{
+ if (a_major > b_major)
+ return 1;
+ if (a_major < b_major)
+ return -1;
+ if (a_minor > b_minor)
+ return 1;
+ if (a_minor < b_minor)
+ return -1;
+
+ return 0;
+}
+
+/* some macros to help swap requests, replies, and events */
+
+#define LengthRestB(stuff) \
+ ((client->req_len << 2) - sizeof(*stuff))
+
+#define LengthRestS(stuff) \
+ ((client->req_len << 1) - (sizeof(*stuff) >> 1))
+
+#define LengthRestL(stuff) \
+ (client->req_len - (sizeof(*stuff) >> 2))
+
+#define SwapRestS(stuff) \
+ SwapShorts((short *)(stuff + 1), LengthRestS(stuff))
+
+#define SwapRestL(stuff) \
+ SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff))
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+void __attribute__ ((error("wrong sized variable passed to swap")))
+wrong_size(void);
+#else
+static inline void
+wrong_size(void)
+{
+}
+#endif
+
+#if !(defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)))
+static inline int
+__builtin_constant_p(int x)
+{
+ return 0;
+}
+#endif
+
+/* byte swap a 64-bit value */
+static inline void
+swap_uint64(uint64_t *x)
+{
+ char n;
+
+ n = ((char *) x)[0];
+ ((char *) x)[0] = ((char *) x)[7];
+ ((char *) x)[7] = n;
+
+ n = ((char *) x)[1];
+ ((char *) x)[1] = ((char *) x)[6];
+ ((char *) x)[6] = n;
+
+ n = ((char *) x)[2];
+ ((char *) x)[2] = ((char *) x)[5];
+ ((char *) x)[5] = n;
+
+ n = ((char *) x)[3];
+ ((char *) x)[3] = ((char *) x)[4];
+ ((char *) x)[4] = n;
+}
+
+#define swapll(x) do { \
+ if (sizeof(*(x)) != 8) \
+ wrong_size(); \
+ swap_uint64((uint64_t *)(x)); \
+ } while (0)
+
+/* byte swap a 32-bit value */
+static inline void
+swap_uint32(uint32_t * x)
+{
+ char n = ((char *) x)[0];
+
+ ((char *) x)[0] = ((char *) x)[3];
+ ((char *) x)[3] = n;
+ n = ((char *) x)[1];
+ ((char *) x)[1] = ((char *) x)[2];
+ ((char *) x)[2] = n;
+}
+
+#define swapl(x) do { \
+ if (sizeof(*(x)) != 4) \
+ wrong_size(); \
+ if (__builtin_constant_p((uintptr_t)(x) & 3) && ((uintptr_t)(x) & 3) == 0) \
+ *(x) = lswapl(*(x)); \
+ else \
+ swap_uint32((uint32_t *)(x)); \
+ } while (0)
+
+/* byte swap a 16-bit value */
+static inline void
+swap_uint16(uint16_t * x)
+{
+ char n = ((char *) x)[0];
+
+ ((char *) x)[0] = ((char *) x)[1];
+ ((char *) x)[1] = n;
+}
+
+#define swaps(x) do { \
+ if (sizeof(*(x)) != 2) \
+ wrong_size(); \
+ if (__builtin_constant_p((uintptr_t)(x) & 1) && ((uintptr_t)(x) & 1) == 0) \
+ *(x) = lswaps(*(x)); \
+ else \
+ swap_uint16((uint16_t *)(x)); \
+ } while (0)
+
+/* copy 32-bit value from src to dst byteswapping on the way */
+#define cpswapl(src, dst) do { \
+ if (sizeof((src)) != 4 || sizeof((dst)) != 4) \
+ wrong_size(); \
+ (dst) = lswapl((src)); \
+ } while (0)
+
+/* copy short from src to dst byteswapping on the way */
+#define cpswaps(src, dst) do { \
+ if (sizeof((src)) != 2 || sizeof((dst)) != 2) \
+ wrong_size(); \
+ (dst) = lswaps((src)); \
+ } while (0)
+
+extern void SwapLongs(
+ CARD32 *list,
+ unsigned long count);
+
+extern void SwapShorts(
+ short *list,
+ unsigned long count);
+
+extern void MakePredeclaredAtoms(void);
+
+extern int Ones(
+ unsigned long /*mask*/);
+
+typedef struct _xPoint *DDXPointPtr;
+typedef struct pixman_box16 *BoxPtr;
+typedef struct _xEvent *xEventPtr;
+typedef struct _xRectangle *xRectanglePtr;
+typedef struct _GrabRec *GrabPtr;
+
+/* typedefs from other places - duplicated here to minimize the amount
+ * of unnecessary junk that one would normally have to include to get
+ * these symbols defined
+ */
+
+#ifndef _XTYPEDEF_CHARINFOPTR
+typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */
+#define _XTYPEDEF_CHARINFOPTR
+#endif
+
+#endif /* MISC_H */
diff --git a/nx-X11/programs/Xserver/include/miscstruct.h b/nx-X11/programs/Xserver/include/miscstruct.h
new file mode 100644
index 000000000..f3cd47614
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/miscstruct.h
@@ -0,0 +1,78 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef MISCSTRUCT_H
+#define MISCSTRUCT_H 1
+
+#include <pixman.h>
+
+#include "misc.h"
+#include <nx-X11/Xprotostr.h>
+#include "gc.h"
+
+typedef xPoint DDXPointRec;
+
+typedef struct pixman_box16 BoxRec;
+
+typedef union _DevUnion {
+ void * ptr;
+ long val;
+ unsigned long uval;
+ RegionPtr (*fptr)(
+ DrawablePtr /* pSrcDrawable */,
+ DrawablePtr /* pDstDrawable */,
+ GCPtr /* pGC */,
+ int /* srcx */,
+ int /* srcy */,
+ int /* width */,
+ int /* height */,
+ int /* dstx */,
+ int /* dsty */,
+ unsigned long /* bitPlane */);
+} DevUnion;
+
+#endif /* MISCSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/opaque.h b/nx-X11/programs/Xserver/include/opaque.h
new file mode 100644
index 000000000..8312b4a21
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/opaque.h
@@ -0,0 +1,83 @@
+/*
+
+Copyright 1987, 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.
+
+*/
+
+#ifndef OPAQUE_H
+#define OPAQUE_H
+
+#include <nx-X11/Xmd.h>
+
+#include "globals.h"
+
+extern char *defaultTextFont;
+extern char *defaultCursorFont;
+extern int MaxClients;
+extern volatile char isItTimeToYield;
+extern volatile char dispatchException;
+
+/* bit values for dispatchException */
+#define DE_RESET 1
+#define DE_TERMINATE 2
+#define DE_PRIORITYCHANGE 4 /* set when a client's priority changes */
+
+extern CARD32 TimeOutValue;
+extern int ScreenSaverBlanking;
+extern int ScreenSaverAllowExposures;
+extern int defaultScreenSaverBlanking;
+extern int defaultScreenSaverAllowExposures;
+extern int argcGlobal;
+extern char **argvGlobal;
+extern char *display;
+extern int displayfd;
+extern Bool explicit_display;
+
+extern int defaultBackingStore;
+extern Bool disableBackingStore;
+extern Bool enableBackingStore;
+extern Bool disableSaveUnders;
+extern Bool PartialNetwork;
+#ifndef NOLOGOHACK
+extern int logoScreenSaver;
+#endif
+#ifdef RLIMIT_DATA
+extern int limitDataSpace;
+#endif
+#ifdef RLIMIT_STACK
+extern int limitStackSpace;
+#endif
+#ifdef RLIMIT_NOFILE
+extern int limitNoFile;
+#endif
+extern Bool permitOldBugs;
+extern Bool defeatAccessControl;
+extern long maxBigRequestSize;
+extern Bool blackRoot;
+
+extern Bool CoreDump;
+extern Bool NoListenAll;
+
+#endif /* OPAQUE_H */
diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h
new file mode 100644
index 000000000..0c7ce6a6f
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/os.h
@@ -0,0 +1,555 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifndef OS_H
+#define OS_H
+
+#include "misc.h"
+#include <stdarg.h>
+
+#define NullFID ((FID) 0)
+
+#define SCREEN_SAVER_ON 0
+#define SCREEN_SAVER_OFF 1
+#define SCREEN_SAVER_FORCER 2
+#define SCREEN_SAVER_CYCLE 3
+
+#ifndef MAX_REQUEST_SIZE
+#define MAX_REQUEST_SIZE 65535
+#endif
+#ifndef MAX_BIG_REQUEST_SIZE
+#define MAX_BIG_REQUEST_SIZE 4194303
+#endif
+
+typedef void * FID;
+typedef struct _FontPathRec *FontPathPtr;
+typedef struct _NewClientRec *NewClientPtr;
+
+#ifndef xnfalloc
+#define xnfalloc(size) XNFalloc((unsigned long)(size))
+#define xnfcalloc(_num, _size) XNFcalloc((unsigned long)(_num)*(unsigned long)(_size))
+#define xnfrealloc(ptr, size) XNFrealloc((void *)(ptr), (unsigned long)(size))
+
+#define xstrdup(s) Xstrdup(s)
+#define xnfstrdup(s) XNFstrdup(s)
+
+#define xallocarray(num, size) reallocarray(NULL, (num), (size))
+#endif
+
+#ifdef __SCO__
+#include <stdio.h>
+#endif
+#include <string.h>
+
+/* have to put $(SIGNAL_DEFINES) in DEFINES in Imakefile to get this right */
+#ifdef SIGNALRETURNSINT
+#define SIGVAL int
+#else
+#define SIGVAL void
+#endif
+
+extern void (*OsVendorVErrorFProc)(const char *, va_list args);
+
+extern int WaitForSomething(
+ int* /*pClientsReady*/
+);
+
+extern int ReadRequestFromClient(ClientPtr /*client*/);
+
+extern Bool InsertFakeRequest(
+ ClientPtr /*client*/,
+ char* /*data*/,
+ int /*count*/);
+
+extern void ResetCurrentRequest(ClientPtr /*client*/);
+
+extern void FlushAllOutput(void);
+
+extern void FlushIfCriticalOutputPending(void);
+
+extern void SetCriticalOutputPending(void);
+
+extern int WriteToClient(ClientPtr /*who*/, int /*count*/, const void* /*__buf*/);
+
+extern void ResetOsBuffers(void);
+
+extern void InitConnectionLimits(void);
+
+extern void NotifyParentProcess(void);
+
+extern void CreateWellKnownSockets(void);
+
+extern void ResetWellKnownSockets(void);
+
+extern void CloseWellKnownConnections(void);
+
+extern XID AuthorizationIDOfClient(ClientPtr /*client*/);
+
+extern char *ClientAuthorized(
+ ClientPtr /*client*/,
+ unsigned int /*proto_n*/,
+ char* /*auth_proto*/,
+ unsigned int /*string_n*/,
+ char* /*auth_string*/);
+
+extern void CheckConnections(void);
+
+extern void CloseDownConnection(ClientPtr /*client*/);
+
+typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data);
+
+#define X_NOTIFY_NONE 0
+#define X_NOTIFY_READ 1
+#define X_NOTIFY_WRITE 2
+
+extern Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
+
+static inline void RemoveNotifyFd(int fd)
+{
+ (void) SetNotifyFd(fd, NULL, X_NOTIFY_NONE, NULL);
+}
+
+extern void OnlyListenToOneClient(ClientPtr /*client*/);
+
+extern void ListenToAllClients(void);
+
+extern void IgnoreClient(ClientPtr /*client*/);
+
+extern void AttendClient(ClientPtr /*client*/);
+
+extern void MakeClientGrabImpervious(ClientPtr /*client*/);
+
+extern void MakeClientGrabPervious(ClientPtr /*client*/);
+
+extern void AvailableClientInput(ClientPtr /* client */);
+
+extern CARD32 GetTimeInMillis(void);
+
+extern void AdjustWaitForDelay(
+ void * /*waitTime*/,
+ unsigned long /*newdelay*/);
+
+typedef struct _OsTimerRec *OsTimerPtr;
+
+typedef CARD32 (*OsTimerCallback)(
+ OsTimerPtr /* timer */,
+ CARD32 /* time */,
+ void * /* arg */);
+
+extern void TimerInit(void);
+
+extern Bool TimerForce(OsTimerPtr /* timer */);
+
+#define TimerAbsolute (1<<0)
+#define TimerForceOld (1<<1)
+
+extern OsTimerPtr TimerSet(
+ OsTimerPtr /* timer */,
+ int /* flags */,
+ CARD32 /* millis */,
+ OsTimerCallback /* func */,
+ void * /* arg */);
+
+extern void TimerCheck(void);
+extern void TimerCancel(OsTimerPtr /* pTimer */);
+extern void TimerFree(OsTimerPtr /* pTimer */);
+
+extern void SetScreenSaverTimer(void);
+extern void FreeScreenSaverTimer(void);
+
+#ifdef DPMSExtension
+extern void SetDPMSTimers(void);
+extern void FreeDPMSTimers(void);
+#endif
+
+extern SIGVAL AutoResetServer(int /*sig*/);
+
+extern SIGVAL GiveUp(int /*sig*/);
+
+extern void UseMsg(void);
+
+extern void InitGlobals(void);
+
+extern void ProcessCommandLine(int /*argc*/, char* /*argv*/[]);
+
+extern int set_font_authorizations(
+ char ** /* authorizations */,
+ int * /*authlen */,
+ void * /* client */);
+
+extern void * XNFalloc(unsigned long /*amount*/);
+extern void * XNFcalloc(unsigned long /*amount*/);
+extern void * XNFrealloc(void * /*ptr*/, unsigned long /*amount*/);
+
+extern void OsInitAllocator(void);
+
+extern char *Xstrdup(const char *s);
+extern char *XNFstrdup(const char *s);
+extern char *Xprintf(const char *fmt, ...);
+extern char *Xvprintf(const char *fmt, va_list va);
+extern char *XNFprintf(const char *fmt, ...);
+extern char *XNFvprintf(const char *fmt, va_list va);
+
+typedef SIGVAL (*OsSigHandlerPtr)(int /* sig */);
+
+extern OsSigHandlerPtr OsSignal(int /* sig */, OsSigHandlerPtr /* handler */);
+
+extern int auditTrailLevel;
+
+#ifdef SERVER_LOCK
+extern void LockServer(void);
+extern void UnlockServer(void);
+#endif
+
+extern int OsLookupColor(
+ int /*screen*/,
+ char * /*name*/,
+ unsigned /*len*/,
+ unsigned short * /*pred*/,
+ unsigned short * /*pgreen*/,
+ unsigned short * /*pblue*/);
+
+extern void OsInit(void);
+
+extern void OsCleanup(Bool);
+
+extern void OsVendorFatalError(void);
+
+extern void OsVendorInit(void);
+
+extern int OsInitColors(void);
+
+void OsBlockSignals (void);
+
+void OsReleaseSignals (void);
+
+#if !defined(WIN32)
+extern int System(char *);
+extern void * Popen(char *, char *);
+extern int Pclose(void *);
+extern void * Fopen(char *, char *);
+extern int Fclose(void *);
+#else
+#define System(a) system(a)
+#define Popen(a,b) popen(a,b)
+#define Pclose(a) pclose(a)
+#define Fopen(a,b) fopen(a,b)
+#define Fclose(a) fclose(a)
+#endif
+
+extern void CheckUserParameters(int argc, char **argv, char **envp);
+extern void CheckUserAuthorization(void);
+
+extern int AddHost(
+ ClientPtr /*client*/,
+ int /*family*/,
+ unsigned /*length*/,
+ void * /*pAddr*/);
+
+extern Bool ForEachHostInFamily (
+ int /*family*/,
+ Bool (* /*func*/ )(
+ unsigned char * /* addr */,
+ short /* len */,
+ void * /* closure */),
+ void * /*closure*/);
+
+extern int RemoveHost(
+ ClientPtr /*client*/,
+ int /*family*/,
+ unsigned /*length*/,
+ void * /*pAddr*/);
+
+extern int GetHosts(
+ void ** /*data*/,
+ int * /*pnHosts*/,
+ int * /*pLen*/,
+ BOOL * /*pEnabled*/);
+
+typedef struct sockaddr * sockaddrPtr;
+
+extern int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client);
+
+extern int LocalClientCred(ClientPtr, int *, int *);
+
+#define LCC_UID_SET (1 << 0)
+#define LCC_GID_SET (1 << 1)
+#define LCC_PID_SET (1 << 2)
+#define LCC_ZID_SET (1 << 3)
+
+typedef struct {
+ int fieldsSet; /* Bit mask of fields set */
+ int euid; /* Effective uid */
+ int egid; /* Primary effective group id */
+ int nSuppGids; /* Number of supplementary group ids */
+ int *pSuppGids; /* Array of supplementary group ids */
+ int pid; /* Process id */
+ int zoneid; /* Only set on Solaris 10 & later */
+} LocalClientCredRec;
+
+extern int GetLocalClientCreds(ClientPtr, LocalClientCredRec **);
+extern void FreeLocalClientCreds(LocalClientCredRec *);
+
+extern int ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
+
+extern int GetAccessControl(void);
+
+
+extern void AddLocalHosts(void);
+
+extern void ResetHosts(char *display);
+
+extern void EnableLocalHost(void);
+
+extern void DisableLocalHost(void);
+
+extern void AccessUsingXdmcp(void);
+
+extern void DefineSelf(int /*fd*/);
+
+extern void AugmentSelf(void * /*from*/, int /*len*/);
+
+extern void InitAuthorization(char * /*filename*/);
+
+/* extern int LoadAuthorization(void); */
+
+extern void RegisterAuthorizations(void);
+
+extern XID AuthorizationToID (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data);
+
+extern int AuthorizationFromID (
+ XID id,
+ unsigned short *name_lenp,
+ char **namep,
+ unsigned short *data_lenp,
+ char **datap);
+
+extern XID CheckAuthorization(
+ unsigned int /*namelength*/,
+ char * /*name*/,
+ unsigned int /*datalength*/,
+ char * /*data*/,
+ ClientPtr /*client*/,
+ char ** /*reason*/
+);
+
+extern void ResetAuthorization(void);
+
+extern int RemoveAuthorization (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data);
+
+extern int AddAuthorization(
+ unsigned int /*name_length*/,
+ char * /*name*/,
+ unsigned int /*data_length*/,
+ char * /*data*/);
+
+extern XID GenerateAuthorization(
+ unsigned int /* name_length */,
+ char * /* name */,
+ unsigned int /* data_length */,
+ char * /* data */,
+ unsigned int * /* data_length_return */,
+ char ** /* data_return */);
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+extern void ExpandCommandLine(int * /*pargc*/, char *** /*pargv*/);
+#endif
+
+extern void ddxInitGlobals(void);
+
+extern int ddxProcessArgument(int /*argc*/, char * /*argv*/ [], int /*i*/);
+
+extern void ddxUseMsg(void);
+
+/*
+ * idiom processing stuff
+ */
+
+extern xReqPtr PeekNextRequest(xReqPtr req, ClientPtr client, Bool readmore);
+
+extern void SkipRequests(xReqPtr req, ClientPtr client, int numskipped);
+
+/* int ReqLen(xReq *req, ClientPtr client)
+ * Given a pointer to a *complete* request, return its length in bytes.
+ * Note that if the request is a big request (as defined in the Big
+ * Requests extension), the macro lies by returning 4 less than the
+ * length that it actually occupies in the request buffer. This is so you
+ * can blindly compare the length with the various sz_<request> constants
+ * in Xproto.h without having to know/care about big requests.
+ */
+#define ReqLen(_pxReq, _client) \
+ ((_pxReq->length ? \
+ (_client->swapped ? lswaps(_pxReq->length) : _pxReq->length) \
+ : ((_client->swapped ? \
+ lswapl(((CARD32*)_pxReq)[1]) : ((CARD32*)_pxReq)[1])-1) \
+ ) << 2)
+
+/* otherReqTypePtr CastxReq(xReq *req, otherReqTypePtr)
+ * Cast the given request to one of type otherReqTypePtr to access
+ * fields beyond the length field.
+ */
+#define CastxReq(_pxReq, otherReqTypePtr) \
+ (_pxReq->length ? (otherReqTypePtr)_pxReq \
+ : (otherReqTypePtr)(((CARD32*)_pxReq)+1))
+
+/* stuff for SkippedRequestsCallback */
+extern CallbackListPtr SkippedRequestsCallback;
+typedef struct {
+ xReqPtr req;
+ ClientPtr client;
+ int numskipped;
+} SkippedRequestInfoRec;
+
+/* stuff for ReplyCallback */
+extern CallbackListPtr ReplyCallback;
+typedef struct {
+ ClientPtr client;
+ const void * replyData;
+ unsigned long dataLenBytes;
+ unsigned long bytesRemaining;
+ Bool startOfReply;
+} ReplyInfoRec;
+
+/* stuff for FlushCallback */
+extern CallbackListPtr FlushCallback;
+
+extern void AbortDDX(void);
+extern void ddxGiveUp(void);
+extern int TimeSinceLastInputEvent(void);
+
+#ifndef HAVE_REALLOCARRAY
+#define reallocarray xreallocarray
+extern _X_EXPORT void *
+reallocarray(void *optr, size_t nmemb, size_t size);
+#endif
+
+#ifndef HAVE_STRLCPY
+extern _X_EXPORT size_t
+strlcpy(char *dst, const char *src, size_t siz);
+extern _X_EXPORT size_t
+strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+#ifndef HAVE_TIMINGSAFE_MEMCMP
+extern _X_EXPORT int
+timingsafe_memcmp(const void *b1, const void *b2, size_t len);
+#endif
+
+/* Logging. */
+typedef enum _LogParameter {
+ XLOG_FLUSH,
+ XLOG_SYNC,
+ XLOG_VERBOSITY,
+ XLOG_FILE_VERBOSITY
+} LogParameter;
+
+/* Flags for log messages. */
+typedef enum {
+ X_PROBED, /* Value was probed */
+ X_CONFIG, /* Value was given in the config file */
+ X_DEFAULT, /* Value is a default */
+ X_CMDLINE, /* Value was given on the command line */
+ X_NOTICE, /* Notice */
+ X_ERROR, /* Error message */
+ X_WARNING, /* Warning message */
+ X_INFO, /* Informational message */
+ X_NONE, /* No prefix */
+ X_NOT_IMPLEMENTED, /* Not implemented */
+ X_UNKNOWN = -1 /* unknown -- this must always be last */
+} MessageType;
+
+/* XXX Need to check which GCC versions have the format(printf) attribute. */
+#if defined(__GNUC__) && \
+ ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ > 4)))
+#define _printf_attribute(a,b) __attribute((format(__printf__,a,b)))
+#else
+#define _printf_attribute(a,b) /**/
+#endif
+
+extern const char *LogInit(const char *fname, const char *backup);
+extern void LogSetDisplay(void);
+extern void LogClose(void);
+extern Bool LogSetParameter(LogParameter param, int value);
+extern void LogVWrite(int verb, const char *f, va_list args);
+extern void LogWrite(int verb, const char *f, ...) _printf_attribute(2,3);
+extern void LogVMessageVerb(MessageType type, int verb, const char *format,
+ va_list args);
+extern void LogMessageVerb(MessageType type, int verb, const char *format,
+ ...) _printf_attribute(3,4);
+extern void LogMessage(MessageType type, const char *format, ...)
+ _printf_attribute(2,3);
+extern void FreeAuditTimer(void);
+extern void AuditF(const char *f, ...) _printf_attribute(1,2);
+extern void VAuditF(const char *f, va_list args);
+extern void FatalError(const char *f, ...) _printf_attribute(1,2)
+#if defined(__GNUC__) && \
+ ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ > 4)))
+__attribute((noreturn))
+#endif
+;
+
+extern void VErrorF(const char *f, va_list args);
+extern void ErrorF(const char *f, ...) _printf_attribute(1,2);
+extern void Error(char *str);
+extern void LogPrintMarkers(void);
+
+#if defined(NEED_SNPRINTF)
+extern int snprintf(char *str, size_t size, const char *format, ...)
+ _printf_attribute(3,4);
+extern int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+#endif
+
+#endif /* OS_H */
diff --git a/nx-X11/programs/Xserver/include/pixmap.h b/nx-X11/programs/Xserver/include/pixmap.h
new file mode 100644
index 000000000..7d893d57c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/pixmap.h
@@ -0,0 +1,108 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef PIXMAP_H
+#define PIXMAP_H
+
+#include "misc.h"
+#include "screenint.h"
+
+/* types for Drawable */
+#define DRAWABLE_WINDOW 0
+#define DRAWABLE_PIXMAP 1
+#define UNDRAWABLE_WINDOW 2
+#define DRAWABLE_BUFFER 3
+
+/* flags to PaintWindow() */
+#define PW_BACKGROUND 0
+#define PW_BORDER 1
+
+#define NullPixmap ((PixmapPtr)0)
+
+typedef struct _Drawable *DrawablePtr;
+typedef struct _Pixmap *PixmapPtr;
+
+typedef union _PixUnion {
+ PixmapPtr pixmap;
+ unsigned long pixel;
+} PixUnion;
+
+#define SamePixUnion(a,b,isPixel)\
+ ((isPixel) ? (a).pixel == (b).pixel : (a).pixmap == (b).pixmap)
+
+#define EqualPixUnion(as, a, bs, b) \
+ ((as) == (bs) && (SamePixUnion (a, b, as)))
+
+#define OnScreenDrawable(type) \
+ ((type == DRAWABLE_WINDOW) || (type == DRAWABLE_BUFFER))
+
+#define WindowDrawable(type) \
+ ((type == DRAWABLE_WINDOW) || (type == UNDRAWABLE_WINDOW))
+
+extern PixmapPtr GetScratchPixmapHeader(
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ void * /*pPixData*/);
+
+extern void FreeScratchPixmapHeader(
+ PixmapPtr /*pPixmap*/);
+
+extern Bool CreateScratchPixmapsForScreen(
+ int /*scrnum*/);
+
+extern void FreeScratchPixmapsForScreen(
+ int /*scrnum*/);
+
+extern PixmapPtr AllocatePixmap(
+ ScreenPtr /*pScreen*/,
+ int /*pixDataSize*/);
+
+#endif /* PIXMAP_H */
diff --git a/nx-X11/programs/Xserver/include/pixmapstr.h b/nx-X11/programs/Xserver/include/pixmapstr.h
new file mode 100644
index 000000000..5d38c1c3b
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/pixmapstr.h
@@ -0,0 +1,87 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef PIXMAPSTRUCT_H
+#define PIXMAPSTRUCT_H
+#include "pixmap.h"
+#include "screenint.h"
+#include "regionstr.h"
+
+typedef struct _Drawable {
+ unsigned char type; /* DRAWABLE_<type> */
+ unsigned char class; /* specific to type */
+ unsigned char depth;
+ unsigned char bitsPerPixel;
+ unsigned long id; /* resource id */
+ short x; /* window: screen absolute, pixmap: 0 */
+ short y; /* window: screen absolute, pixmap: 0 */
+ unsigned short width;
+ unsigned short height;
+ ScreenPtr pScreen;
+ unsigned long serialNumber;
+} DrawableRec;
+
+/*
+ * PIXMAP -- device dependent
+ */
+
+typedef struct _Pixmap {
+ DrawableRec drawable;
+ int refcnt;
+ int devKind;
+ DevUnion devPrivate;
+#ifdef PIXPRIV
+ DevUnion *devPrivates; /* real devPrivates like gcs & windows */
+#endif
+#ifdef COMPOSITE
+ short screen_x;
+ short screen_y;
+#endif
+ unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */
+} PixmapRec;
+
+#endif /* PIXMAPSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/property.h b/nx-X11/programs/Xserver/include/property.h
new file mode 100644
index 000000000..79aa1679c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/property.h
@@ -0,0 +1,72 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef PROPERTY_H
+#define PROPERTY_H
+
+#include "window.h"
+
+typedef struct _Property *PropertyPtr;
+
+extern int ChangeWindowProperty(
+ WindowPtr /*pWin*/,
+ Atom /*property*/,
+ Atom /*type*/,
+ int /*format*/,
+ int /*mode*/,
+ unsigned long /*len*/,
+ void * /*value*/,
+ Bool /*sendevent*/);
+
+extern int DeleteProperty(
+ WindowPtr /*pWin*/,
+ Atom /*propName*/);
+
+extern void DeleteAllWindowProperties(
+ WindowPtr /*pWin*/);
+
+#endif /* PROPERTY_H */
diff --git a/nx-X11/programs/Xserver/include/propertyst.h b/nx-X11/programs/Xserver/include/propertyst.h
new file mode 100644
index 000000000..493d6595e
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/propertyst.h
@@ -0,0 +1,66 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef PROPERTYSTRUCT_H
+#define PROPERTYSTRUCT_H
+#include "misc.h"
+#include "property.h"
+/*
+ * PROPERTY -- property element
+ */
+
+typedef struct _Property {
+ struct _Property *next;
+ ATOM propertyName;
+ ATOM type; /* ignored by server */
+ short format; /* format of data for swapping - 8,16,32 */
+ long size; /* size of data in (format/8) bytes */
+ void *data; /* private to client */
+} PropertyRec;
+
+#endif /* PROPERTYSTRUCT_H */
+
diff --git a/nx-X11/programs/Xserver/include/protocol-versions.h b/nx-X11/programs/Xserver/include/protocol-versions.h
new file mode 100644
index 000000000..9b9319fd2
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/protocol-versions.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ */
+
+/**
+ * This file specifies the server-supported protocol versions.
+ */
+#ifndef PROTOCOL_VERSIONS_H
+#define PROTOCOL_VERSIONS_H
+
+#ifdef NXAGENT_SERVER
+# define XTRANS_SEND_FDS 0
+#endif
+
+/* Composite */
+#define SERVER_COMPOSITE_MAJOR_VERSION 0
+#define SERVER_COMPOSITE_MINOR_VERSION 4
+
+/* Damage */
+#define SERVER_DAMAGE_MAJOR_VERSION 1
+#ifndef NXAGENT_SERVER
+#define SERVER_DAMAGE_MINOR_VERSION 1
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_DAMAGE_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+#ifndef NXAGENT_SERVER
+/* DRI3 */
+#define SERVER_DRI3_MAJOR_VERSION 1
+#define SERVER_DRI3_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+#ifndef NXAGENT_SERVER
+/* DMX */
+#define SERVER_DMX_MAJOR_VERSION 2
+#define SERVER_DMX_MINOR_VERSION 2
+#define SERVER_DMX_PATCH_VERSION 20040604
+#endif /* !defined(NXAGENT_SERVER) */
+
+#ifndef NXAGENT_SERVER
+/* Generic event extension */
+#define SERVER_GE_MAJOR_VERSION 1
+#define SERVER_GE_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* GLX */
+#define SERVER_GLX_MAJOR_VERSION 1
+#ifndef NXAGENT_SERVER
+#define SERVER_GLX_MINOR_VERSION 4
+#else
+#define SERVER_GLX_MINOR_VERSION 2
+#endif
+
+/* Xinerama */
+#define SERVER_PANORAMIX_MAJOR_VERSION 1
+#define SERVER_PANORAMIX_MINOR_VERSION 1
+
+#ifndef NXAGENT_SERVER
+/* Present */
+#define SERVER_PRESENT_MAJOR_VERSION 1
+#define SERVER_PRESENT_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* RandR */
+#define SERVER_RANDR_MAJOR_VERSION 1
+#define SERVER_RANDR_MINOR_VERSION 5
+
+/* Record */
+#define SERVER_RECORD_MAJOR_VERSION 1
+#define SERVER_RECORD_MINOR_VERSION 13
+
+/* Render */
+#define SERVER_RENDER_MAJOR_VERSION 0
+#ifndef NXAGENT_SERVER
+#define SERVER_RENDER_MINOR_VERSION 11
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_RENDER_MINOR_VERSION 10
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* RandR Xinerama */
+#define SERVER_RRXINERAMA_MAJOR_VERSION 1
+#define SERVER_RRXINERAMA_MINOR_VERSION 1
+
+/* Screensaver */
+#define SERVER_SAVER_MAJOR_VERSION 1
+#define SERVER_SAVER_MINOR_VERSION 1
+
+/* Security */
+#define SERVER_SECURITY_MAJOR_VERSION 1
+#define SERVER_SECURITY_MINOR_VERSION 0
+
+/* Shape */
+#define SERVER_SHAPE_MAJOR_VERSION 1
+#define SERVER_SHAPE_MINOR_VERSION 1
+
+/* SHM */
+#define SERVER_SHM_MAJOR_VERSION 1
+#ifndef NXAGENT_SERVER
+#if XTRANS_SEND_FDS
+#define SERVER_SHM_MINOR_VERSION 2
+#else
+#define SERVER_SHM_MINOR_VERSION 1
+#endif
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_SHM_MINOR_VERSION 1
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* Sync */
+#define SERVER_SYNC_MAJOR_VERSION 3
+#ifndef NXAGENT_SERVER
+#define SERVER_SYNC_MINOR_VERSION 1
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_SYNC_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* Big Font */
+#define SERVER_XF86BIGFONT_MAJOR_VERSION 1
+#define SERVER_XF86BIGFONT_MINOR_VERSION 1
+
+#ifndef NXAGENT_SERVER
+/* Vidmode */
+#define SERVER_XF86VIDMODE_MAJOR_VERSION 2
+#define SERVER_XF86VIDMODE_MINOR_VERSION 2
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* Fixes */
+#ifndef NXAGENT_SERVER
+#define SERVER_XFIXES_MAJOR_VERSION 5
+#define SERVER_XFIXES_MINOR_VERSION 0
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_XFIXES_MAJOR_VERSION 3
+#define SERVER_XFIXES_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* X Input */
+#ifndef NXAGENT_SERVER
+#define SERVER_XI_MAJOR_VERSION 2
+#define SERVER_XI_MINOR_VERSION 3
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_XI_MAJOR_VERSION 1
+#define SERVER_XI_MINOR_VERSION 3
+#endif /* !defined(NXAGENT_SERVER) */
+
+/* XKB */
+#define SERVER_XKB_MAJOR_VERSION 1
+#define SERVER_XKB_MINOR_VERSION 0
+
+/* Resource */
+#define SERVER_XRES_MAJOR_VERSION 1
+#ifndef NXAGENT_SERVER
+#define SERVER_XRES_MINOR_VERSION 2
+#else /* !defined(NXAGENT_SERVER) */
+#define SERVER_XRES_MINOR_VERSION 0
+#endif /* !defined(NXAGENT_SERVER) */
+
+#ifndef NXAGENT_SERVER
+/* XvMC */
+#define SERVER_XVMC_MAJOR_VERSION 1
+#define SERVER_XVMC_MINOR_VERSION 1
+#endif /* !defined(NXAGENT_SERVER) */
+
+#endif /* PROTOCOL_VERSIONS_H */
diff --git a/nx-X11/programs/Xserver/include/region.h b/nx-X11/programs/Xserver/include/region.h
new file mode 100644
index 000000000..e9d7e778c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/region.h
@@ -0,0 +1,53 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef REGION_H
+#define REGION_H
+
+#include "regionstr.h"
+
+#endif /* REGION_H */
diff --git a/nx-X11/programs/Xserver/include/regionstr.h b/nx-X11/programs/Xserver/include/regionstr.h
new file mode 100644
index 000000000..959b9c423
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/regionstr.h
@@ -0,0 +1,411 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef REGIONSTRUCT_H
+#define REGIONSTRUCT_H
+
+#include <pixman.h>
+
+typedef struct pixman_region16 RegionRec, *RegionPtr;
+
+#include <stddef.h>
+#include <limits.h>
+
+#include "miscstruct.h"
+
+/* Return values from RectIn() */
+
+#define rgnOUT 0
+#define rgnIN 1
+#define rgnPART 2
+
+#define NullRegion ((RegionPtr)0)
+
+/*
+ * clip region
+ */
+
+typedef struct pixman_region16_data RegDataRec, *RegDataPtr;
+
+extern BoxRec RegionEmptyBox;
+extern RegDataRec RegionEmptyData;
+extern RegDataRec RegionBrokenData;
+
+static inline Bool RegionNil(RegionPtr reg) {
+ return ((reg)->data && !(reg)->data->numRects);
+}
+
+static inline Bool RegionNar(RegionPtr reg) {
+ return ((reg)->data == &RegionBrokenData);
+}
+
+static inline int RegionNumRects(RegionPtr reg) {
+ return ((reg)->data ? (reg)->data->numRects : 1);
+}
+
+static inline int RegionSize(RegionPtr reg) {
+ return ((reg)->data ? (reg)->data->size : 0);
+}
+
+static inline BoxPtr RegionRects(RegionPtr reg) {
+ return ((reg)->data ? (BoxPtr)((reg)->data + 1) : &(reg)->extents);
+}
+
+static inline BoxPtr RegionBoxptr(RegionPtr reg) {
+ return ((BoxPtr)((reg)->data + 1));
+}
+
+static inline BoxPtr RegionBox(RegionPtr reg, int i) {
+ return (&RegionBoxptr(reg)[i]);
+}
+
+static inline BoxPtr RegionTop(RegionPtr reg) {
+ return RegionBox(reg, (reg)->data->numRects);
+}
+
+static inline BoxPtr RegionEnd(RegionPtr reg) {
+ return RegionBox(reg, (reg)->data->numRects - 1);
+}
+
+static inline size_t RegionSizeof(int n) {
+ return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)));
+}
+
+static inline void RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size)
+{
+ if ((_rect) != NULL)
+ {
+ (_pReg)->extents = *(_rect);
+ (_pReg)->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ (_pReg)->extents = RegionEmptyBox;
+ if (((_size) > 1) && ((_pReg)->data =
+ (RegDataPtr)malloc(RegionSizeof(_size))))
+ {
+ (_pReg)->data->size = (_size);
+ (_pReg)->data->numRects = 0;
+ }
+ else
+ (_pReg)->data = &RegionEmptyData;
+ }
+}
+
+static inline void RegionUninit(RegionPtr _pReg)
+{
+ if ((_pReg)->data && (_pReg)->data->size) {
+ free((_pReg)->data);
+ (_pReg)->data = NULL;
+ }
+}
+
+static inline void RegionReset(RegionPtr _pReg, BoxPtr _pBox)
+{
+ (_pReg)->extents = *(_pBox);
+ RegionUninit(_pReg);
+ (_pReg)->data = (RegDataPtr)NULL;
+}
+
+static inline Bool RegionNotEmpty(RegionPtr _pReg) {
+ return !RegionNil(_pReg);
+}
+
+static inline Bool RegionBroken(RegionPtr _pReg) {
+ return RegionNar(_pReg);
+}
+
+static inline void RegionEmpty(RegionPtr _pReg)
+{
+ RegionUninit(_pReg);
+ (_pReg)->extents.x2 = (_pReg)->extents.x1;
+ (_pReg)->extents.y2 = (_pReg)->extents.y1;
+ (_pReg)->data = &RegionEmptyData;
+}
+
+static inline BoxPtr RegionExtents(RegionPtr _pReg)
+{
+ return (&(_pReg)->extents);
+}
+
+static inline void RegionNull(RegionPtr _pReg)
+{
+ (_pReg)->extents = RegionEmptyBox;
+ (_pReg)->data = &RegionEmptyData;
+}
+
+static inline Bool
+RegionCopy(RegionPtr dst, RegionPtr src)
+{
+ return pixman_region_copy (dst, src);
+}
+
+static inline Bool
+RegionIntersect(
+ RegionPtr newReg, /* destination Region */
+ RegionPtr reg1,
+ RegionPtr reg2 /* source regions */
+ )
+{
+ return pixman_region_intersect (newReg, reg1, reg2);
+}
+
+static inline Bool
+RegionUnion(
+ RegionPtr newReg, /* destination Region */
+ RegionPtr reg1,
+ RegionPtr reg2 /* source regions */
+ )
+{
+ return pixman_region_union (newReg, reg1, reg2);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * Subtract --
+ * Subtract regS from regM and leave the result in regD.
+ * S stands for subtrahend, M for minuend and D for difference.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * regD is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline Bool
+RegionSubtract(RegionPtr regD, RegionPtr regM, RegionPtr regS)
+{
+ return pixman_region_subtract (regD, regM, regS);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * Inverse --
+ * Take a region and a box and return a region that is everything
+ * in the box but not in the region. The careful reader will note
+ * that this is the same as subtracting the region from the box...
+ *
+ * Results:
+ * TRUE.
+ *
+ * Side Effects:
+ * newReg is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline Bool
+RegionInverse(
+ RegionPtr newReg, /* Destination region */
+ RegionPtr reg1, /* Region to invert */
+ BoxPtr invRect /* Bounding box for inversion */
+ )
+{
+ return pixman_region_inverse (newReg, reg1, invRect);
+}
+
+static inline int
+RegionContainsRect(RegionPtr region, BoxPtr prect)
+{
+ return pixman_region_contains_rectangle (region, prect);
+}
+
+/* TranslateRegion(pReg, x, y)
+ * translates in place
+ */
+
+static inline void
+RegionTranslate(RegionPtr pReg, int x, int y)
+{
+ pixman_region_translate (pReg, x, y);
+}
+
+static inline Bool
+RegionContainsPoint(
+ RegionPtr pReg,
+ int x,
+ int y,
+ BoxPtr box /* "return" value */
+ )
+{
+ return pixman_region_contains_point (pReg, x, y, box);
+}
+
+static inline Bool
+RegionEqual(RegionPtr reg1, RegionPtr reg2)
+{
+ return pixman_region_equal (reg1, reg2);
+}
+
+extern RegionPtr RegionCreate(
+ BoxPtr /*rect*/,
+ int /*size*/);
+
+extern void RegionInit(
+ RegionPtr /*pReg*/,
+ BoxPtr /*rect*/,
+ int /*size*/);
+
+extern void RegionDestroy(
+ RegionPtr /*pReg*/);
+
+extern void RegionUninit(
+ RegionPtr /*pReg*/);
+
+extern Bool RegionCopy(
+ RegionPtr /*dst*/,
+ RegionPtr /*src*/);
+
+extern Bool RegionIntersect(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/);
+
+extern Bool RegionUnion(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/);
+
+extern Bool RegionAppend(
+ RegionPtr /*dstrgn*/,
+ RegionPtr /*rgn*/);
+
+extern Bool RegionValidate(
+ RegionPtr /*badreg*/,
+ Bool * /*pOverlap*/);
+
+extern RegionPtr RegionFromRects(
+ int /*nrects*/,
+ xRectanglePtr /*prect*/,
+ int /*ctype*/);
+
+extern Bool RegionSubtract(
+ RegionPtr /*regD*/,
+ RegionPtr /*regM*/,
+ RegionPtr /*regS*/);
+
+extern Bool RegionInverse(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ BoxPtr /*invRect*/);
+
+extern int RegionContainsRect(
+ RegionPtr /*region*/,
+ BoxPtr /*prect*/);
+
+extern void RegionTranslate(
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/);
+
+extern void RegionReset(
+ RegionPtr /*pReg*/,
+ BoxPtr /*pBox*/);
+
+extern Bool RegionBreak(
+ RegionPtr /*pReg*/);
+
+extern Bool RegionContainsPoint(
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/);
+
+extern Bool RegionEqual(
+ RegionPtr /*pReg1*/,
+ RegionPtr /*pReg2*/);
+
+extern Bool RegionNotEmpty(
+ RegionPtr /*pReg*/);
+
+extern void RegionEmpty(
+ RegionPtr /*pReg*/);
+
+extern BoxPtr RegionExtents(
+ RegionPtr /*pReg*/);
+
+#define INCLUDE_LEGACY_REGION_DEFINES
+#ifdef INCLUDE_LEGACY_REGION_DEFINES
+
+#define REGION_NIL RegionNil
+#define REGION_NAR RegionNar
+#define REGION_NUM_RECTS RegionNumRects
+#define REGION_SIZE RegionSize
+#define REGION_RECTS RegionRects
+#define REGION_BOXPTR RegionBoxptr
+#define REGION_BOX RegionBox
+#define REGION_TOP RegionTop
+#define REGION_END RegionEnd
+#define REGION_SZOF RegionSizeof
+#define BitmapToRegion BitmapToRegion
+#define REGION_CREATE(pScreen, r, s) RegionCreate(r,s)
+#define REGION_COPY(pScreen, d, r) RegionCopy(d, r)
+#define REGION_DESTROY(pScreen, r) RegionDestroy(r)
+#define REGION_INTERSECT(pScreen, res, r1, r2) RegionIntersect(res, r1, r2)
+#define REGION_UNION(pScreen, res, r1, r2) RegionUnion(res, r1, r2)
+#define REGION_SUBTRACT(pScreen, res, r1, r2) RegionSubtract(res, r1, r2)
+#define REGION_INVERSE(pScreen, n, r, b) RegionInverse(n, r, b)
+#define REGION_TRANSLATE(pScreen, r, x, y) RegionTranslate(r, x, y)
+#define RECT_IN_REGION(pScreen, r, b) RegionContainsRect(r, b)
+#define POINT_IN_REGION(pScreen, r, x, y, b) RegionContainsPoint(r, x, y, b)
+#define REGION_EQUAL(pScreen, r1, r2) RegionEqual(r1, r2)
+#define REGION_APPEND(pScreen, d, r) RegionAppend(d, r)
+#define REGION_VALIDATE(pScreen, r, o) RegionValidate(r, o)
+#define RECTS_TO_REGION(pScreen, n, r, c) RegionFromRects(n, r, c)
+#define REGION_BREAK(pScreen, r) RegionBreak(r)
+#define REGION_INIT(pScreen, r, b, s) RegionInit(r, b, s)
+#define REGION_UNINIT(pScreen, r) RegionUninit(r)
+#define REGION_RESET(pScreen, r, b) RegionReset(r, b)
+#define REGION_NOTEMPTY(pScreen, r) RegionNotEmpty(r)
+#define REGION_BROKEN(pScreen, r) RegionBroken(r)
+#define REGION_EMPTY(pScreen, r) RegionEmpty(r)
+#define REGION_EXTENTS(pScreen, r) RegionExtents(r)
+#define REGION_NULL(pScreen, r) RegionNull(r)
+
+#endif /* INCLUDE_LEGACY_REGION_DEFINES */
+#endif /* REGIONSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/resource.h b/nx-X11/programs/Xserver/include/resource.h
new file mode 100644
index 000000000..30ae624fb
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/resource.h
@@ -0,0 +1,272 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef RESOURCE_H
+#define RESOURCE_H 1
+#include "misc.h"
+
+/*****************************************************************
+ * STUFF FOR RESOURCES
+ *****************************************************************/
+
+/* classes for Resource routines */
+
+typedef unsigned long RESTYPE;
+
+#define RC_VANILLA ((RESTYPE)0)
+#define RC_CACHED ((RESTYPE)1<<31)
+#define RC_DRAWABLE ((RESTYPE)1<<30)
+/* Use class RC_NEVERRETAIN for resources that should not be retained
+ * regardless of the close down mode when the client dies. (A client's
+ * event selections on objects that it doesn't own are good candidates.)
+ * Extensions can use this too!
+ */
+#define RC_NEVERRETAIN ((RESTYPE)1<<29)
+#define RC_LASTPREDEF RC_NEVERRETAIN
+#define RC_ANY (~(RESTYPE)0)
+
+/* types for Resource routines */
+
+#define RT_WINDOW ((RESTYPE)1|RC_DRAWABLE)
+#define RT_PIXMAP ((RESTYPE)2|RC_DRAWABLE)
+#define RT_GC ((RESTYPE)3)
+#undef RT_FONT
+#undef RT_CURSOR
+#define RT_FONT ((RESTYPE)4)
+#define RT_CURSOR ((RESTYPE)5)
+#define RT_COLORMAP ((RESTYPE)6)
+#define RT_CMAPENTRY ((RESTYPE)7)
+#define RT_OTHERCLIENT ((RESTYPE)8|RC_NEVERRETAIN)
+#define RT_PASSIVEGRAB ((RESTYPE)9|RC_NEVERRETAIN)
+#define RT_LASTPREDEF ((RESTYPE)9)
+#define RT_NONE ((RESTYPE)0)
+
+/* bits and fields within a resource id */
+#define RESOURCE_AND_CLIENT_COUNT 29 /* 29 bits for XIDs */
+#if MAXCLIENTS == 64
+#define RESOURCE_CLIENT_BITS 6
+#endif
+#if MAXCLIENTS == 128
+#define RESOURCE_CLIENT_BITS 7
+#endif
+#if MAXCLIENTS == 256
+#define RESOURCE_CLIENT_BITS 8
+#endif
+#if MAXCLIENTS == 512
+#define RESOURCE_CLIENT_BITS 9
+#endif
+/* client field offset */
+#define CLIENTOFFSET (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS)
+/* resource field */
+#define RESOURCE_ID_MASK ((1 << CLIENTOFFSET) - 1)
+/* client field */
+#define RESOURCE_CLIENT_MASK (((1 << RESOURCE_CLIENT_BITS) - 1) << CLIENTOFFSET)
+/* extract the client mask from an XID */
+#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
+/* extract the client id from an XID */
+#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
+#define SERVER_BIT (Mask)0x40000000 /* use illegal bit */
+
+#ifdef INVALID
+#undef INVALID /* needed on HP/UX */
+#endif
+
+/* Invalid resource id */
+#define INVALID (0)
+
+#define BAD_RESOURCE 0xe0000000
+
+typedef int (*DeleteType)(
+ void * /*value*/,
+ XID /*id*/);
+
+typedef void (*FindResType)(
+ void * /*value*/,
+ XID /*id*/,
+ void * /*cdata*/);
+
+typedef void (*FindAllRes)(
+ void * /*value*/,
+ XID /*id*/,
+ RESTYPE /*type*/,
+ void * /*cdata*/);
+
+typedef Bool (*FindComplexResType)(
+ void * /*value*/,
+ XID /*id*/,
+ void * /*cdata*/);
+
+extern RESTYPE CreateNewResourceType(
+ DeleteType /*deleteFunc*/);
+
+extern RESTYPE CreateNewResourceClass(void);
+
+extern Bool InitClientResources(
+ ClientPtr /*client*/);
+
+extern XID FakeClientID(
+ int /*client*/);
+
+/* Quartz support on Mac OS X uses the CarbonCore
+ framework whose AddResource function conflicts here. */
+#ifdef __DARWIN__
+#define AddResource Darwin_X_AddResource
+#endif
+extern Bool AddResource(
+ XID /*id*/,
+ RESTYPE /*type*/,
+ void * /*value*/);
+
+extern void FreeResource(
+ XID /*id*/,
+ RESTYPE /*skipDeleteFuncType*/);
+
+extern void FreeResourceByType(
+ XID /*id*/,
+ RESTYPE /*type*/,
+ Bool /*skipFree*/);
+
+extern Bool ChangeResourceValue(
+ XID /*id*/,
+ RESTYPE /*rtype*/,
+ void * /*value*/);
+
+extern void FindClientResourcesByType(
+ ClientPtr /*client*/,
+ RESTYPE /*type*/,
+ FindResType /*func*/,
+ void * /*cdata*/);
+
+extern void FindAllClientResources(
+ ClientPtr /*client*/,
+ FindAllRes /*func*/,
+ void * /*cdata*/);
+
+extern void FreeClientNeverRetainResources(
+ ClientPtr /*client*/);
+
+extern void FreeClientResources(
+ ClientPtr /*client*/);
+
+extern void FreeAllResources(void);
+
+extern Bool LegalNewID(
+ XID /*id*/,
+ ClientPtr /*client*/);
+
+extern void * LookupIDByType(
+ XID /*id*/,
+ RESTYPE /*rtype*/);
+
+extern void * LookupIDByClass(
+ XID /*id*/,
+ RESTYPE /*classes*/);
+
+extern void * LookupClientResourceComplex(
+ ClientPtr client,
+ RESTYPE type,
+ FindComplexResType func,
+ void * cdata);
+
+/* These are the access modes that can be passed in the last parameter
+ * to SecurityLookupIDByType/Class. The Security extension doesn't
+ * currently make much use of these; they're mainly provided as an
+ * example of what you might need for discretionary access control.
+ * You can or these values together to indicate multiple modes
+ * simultaneously.
+ */
+
+#define DixUnknownAccess 0 /* don't know intentions */
+#define DixReadAccess (1<<0) /* inspecting the object */
+#define DixWriteAccess (1<<1) /* changing the object */
+#define DixDestroyAccess (1<<2) /* destroying the object */
+
+#ifdef XCSECURITY
+
+extern void * SecurityLookupIDByType(
+ ClientPtr /*client*/,
+ XID /*id*/,
+ RESTYPE /*rtype*/,
+ Mask /*access_mode*/);
+
+extern void * SecurityLookupIDByClass(
+ ClientPtr /*client*/,
+ XID /*id*/,
+ RESTYPE /*classes*/,
+ Mask /*access_mode*/);
+
+#else /* not XCSECURITY */
+
+#define SecurityLookupIDByType(client, id, rtype, access_mode) \
+ LookupIDByType(id, rtype)
+
+#define SecurityLookupIDByClass(client, id, classes, access_mode) \
+ LookupIDByClass(id, classes)
+
+#endif /* XCSECURITY */
+
+extern void GetXIDRange(
+ int /*client*/,
+ Bool /*server*/,
+ XID * /*minp*/,
+ XID * /*maxp*/);
+
+extern unsigned int GetXIDList(
+ ClientPtr /*client*/,
+ unsigned int /*count*/,
+ XID * /*pids*/);
+
+extern RESTYPE lastResourceType;
+extern RESTYPE TypeMask;
+
+#ifdef XResExtension
+extern Atom *ResourceNames;
+void RegisterResourceName(RESTYPE type, char* name);
+#endif
+
+#endif /* RESOURCE_H */
+
diff --git a/nx-X11/programs/Xserver/include/rgb.h b/nx-X11/programs/Xserver/include/rgb.h
new file mode 100644
index 000000000..3e768b615
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/rgb.h
@@ -0,0 +1,53 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef RGB_H
+#define RGB_H
+typedef struct _RGB {
+ unsigned short red, green, blue;
+ } RGB;
+#endif /* RGB_H */
diff --git a/nx-X11/programs/Xserver/include/screenint.h b/nx-X11/programs/Xserver/include/screenint.h
new file mode 100644
index 000000000..abaa6f85b
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/screenint.h
@@ -0,0 +1,110 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef SCREENINT_H
+#define SCREENINT_H
+
+#include "misc.h"
+
+typedef struct _PixmapFormat *PixmapFormatPtr;
+typedef struct _Visual *VisualPtr;
+typedef struct _Depth *DepthPtr;
+typedef struct _Screen *ScreenPtr;
+
+extern void ResetScreenPrivates(void);
+
+extern int AllocateScreenPrivateIndex(void);
+
+extern void ResetWindowPrivates(void);
+
+extern int AllocateWindowPrivateIndex(void);
+
+extern Bool AllocateWindowPrivate(
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */);
+
+extern void ResetGCPrivates(void);
+
+extern int AllocateGCPrivateIndex(void);
+
+extern Bool AllocateGCPrivate(
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */);
+
+extern int AddScreen(
+ Bool (* /*pfnInit*/)(
+ ScreenPtr /*pScreen*/,
+ int /*argc*/,
+ char ** /*argv*/),
+ int /*argc*/,
+ char** /*argv*/);
+
+#ifdef PIXPRIV
+
+extern void ResetPixmapPrivates(void);
+
+extern int AllocatePixmapPrivateIndex(void);
+
+extern Bool AllocatePixmapPrivate(
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */);
+
+#endif /* PIXPRIV */
+
+extern void ResetColormapPrivates(void);
+
+
+typedef struct _ColormapRec *ColormapPtr;
+typedef int (*InitCmapPrivFunc)(ColormapPtr, int);
+
+extern int AllocateColormapPrivateIndex(
+ InitCmapPrivFunc /* initPrivFunc */);
+
+#endif /* SCREENINT_H */
diff --git a/nx-X11/programs/Xserver/include/scrnintstr.h b/nx-X11/programs/Xserver/include/scrnintstr.h
new file mode 100644
index 000000000..5a3f32309
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/scrnintstr.h
@@ -0,0 +1,756 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef SCREENINTSTRUCT_H
+#define SCREENINTSTRUCT_H
+
+#include "screenint.h"
+#include "regionstr.h"
+#include "bstore.h"
+#include "colormap.h"
+#include "cursor.h"
+#include "validate.h"
+#include <nx-X11/Xproto.h>
+#include "dix.h"
+
+typedef struct _PixmapFormat {
+ unsigned char depth;
+ unsigned char bitsPerPixel;
+ unsigned char scanlinePad;
+ } PixmapFormatRec;
+
+typedef struct _Visual {
+ VisualID vid;
+ short class;
+ short bitsPerRGBValue;
+ short ColormapEntries;
+ short nplanes;/* = log2 (ColormapEntries). This does not
+ * imply that the screen has this many planes.
+ * it may have more or fewer */
+ unsigned long redMask, greenMask, blueMask;
+ int offsetRed, offsetGreen, offsetBlue;
+ } VisualRec;
+
+typedef struct _Depth {
+ unsigned char depth;
+ short numVids;
+ VisualID *vids; /* block of visual ids for this depth */
+ } DepthRec;
+
+
+/*
+ * There is a typedef for each screen function void * so that code that
+ * needs to declare a screen function void * (e.g. in a screen private
+ * or as a local variable) can easily do so and retain full type checking.
+ */
+
+typedef Bool (* CloseScreenProcPtr)(
+ ScreenPtr /*pScreen*/);
+
+typedef void (* QueryBestSizeProcPtr)(
+ int /*class*/,
+ unsigned short * /*pwidth*/,
+ unsigned short * /*pheight*/,
+ ScreenPtr /*pScreen*/);
+
+typedef Bool (* SaveScreenProcPtr)(
+ ScreenPtr /*pScreen*/,
+ int /*on*/);
+
+typedef void (* GetImageProcPtr)(
+ DrawablePtr /*pDrawable*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/);
+
+typedef void (* GetSpansProcPtr)(
+ DrawablePtr /*pDrawable*/,
+ int /*wMax*/,
+ DDXPointPtr /*ppt*/,
+ int* /*pwidth*/,
+ int /*nspans*/,
+ char * /*pdstStart*/);
+
+typedef void (* PointerNonInterestBoxProcPtr)(
+ ScreenPtr /*pScreen*/,
+ BoxPtr /*pBox*/);
+
+typedef void (* SourceValidateProcPtr)(
+ DrawablePtr /*pDrawable*/,
+ int /*x*/,
+ int /*y*/,
+ int /*width*/,
+ int /*height*/);
+
+typedef Bool (* CreateWindowProcPtr)(
+ WindowPtr /*pWindow*/);
+
+typedef Bool (* DestroyWindowProcPtr)(
+ WindowPtr /*pWindow*/);
+
+typedef Bool (* PositionWindowProcPtr)(
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/);
+
+typedef Bool (* ChangeWindowAttributesProcPtr)(
+ WindowPtr /*pWindow*/,
+ unsigned long /*mask*/);
+
+typedef Bool (* RealizeWindowProcPtr)(
+ WindowPtr /*pWindow*/);
+
+typedef Bool (* UnrealizeWindowProcPtr)(
+ WindowPtr /*pWindow*/);
+
+typedef void (* RestackWindowProcPtr)(
+ WindowPtr /*pWindow*/,
+ WindowPtr /*pOldNextSib*/);
+
+typedef int (* ValidateTreeProcPtr)(
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/);
+
+typedef void (* PostValidateTreeProcPtr)(
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/);
+
+typedef void (* WindowExposuresProcPtr)(
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgn*/,
+ RegionPtr /*other_exposed*/);
+
+typedef void (* PaintWindowProcPtr)(
+ WindowPtr /*pWindow*/,
+ RegionPtr /*pRegion*/,
+ int /*what*/);
+
+typedef PaintWindowProcPtr PaintWindowBackgroundProcPtr;
+typedef PaintWindowProcPtr PaintWindowBorderProcPtr;
+
+typedef void (* CopyWindowProcPtr)(
+ WindowPtr /*pWindow*/,
+ DDXPointRec /*ptOldOrg*/,
+ RegionPtr /*prgnSrc*/);
+
+typedef void (* ClearToBackgroundProcPtr)(
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/);
+
+typedef void (* ClipNotifyProcPtr)(
+ WindowPtr /*pWindow*/,
+ int /*dx*/,
+ int /*dy*/);
+
+/* pixmap will exist only for the duration of the current rendering operation */
+#define CREATE_PIXMAP_USAGE_SCRATCH 1
+/* pixmap will be the backing pixmap for a redirected window */
+#define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2
+/* pixmap will contain a glyph */
+#define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3
+
+typedef PixmapPtr (* CreatePixmapProcPtr)(
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ unsigned /*usage_hint*/);
+
+typedef Bool (* DestroyPixmapProcPtr)(
+ PixmapPtr /*pPixmap*/);
+
+typedef void (* SaveDoomedAreasProcPtr)(
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgnSave*/,
+ int /*xorg*/,
+ int /*yorg*/);
+
+typedef RegionPtr (* RestoreAreasProcPtr)(
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgnRestore*/);
+
+typedef void (* ExposeCopyProcPtr)(
+ WindowPtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ RegionPtr /*prgnExposed*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/);
+
+typedef RegionPtr (* TranslateBackingStoreProcPtr)(
+ WindowPtr /*pWindow*/,
+ int /*windx*/,
+ int /*windy*/,
+ RegionPtr /*oldClip*/,
+ int /*oldx*/,
+ int /*oldy*/);
+
+typedef RegionPtr (* ClearBackingStoreProcPtr)(
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/);
+
+typedef void (* DrawGuaranteeProcPtr)(
+ WindowPtr /*pWindow*/,
+ GCPtr /*pGC*/,
+ int /*guarantee*/);
+
+typedef Bool (* RealizeFontProcPtr)(
+ ScreenPtr /*pScreen*/,
+ FontPtr /*pFont*/);
+
+typedef Bool (* UnrealizeFontProcPtr)(
+ ScreenPtr /*pScreen*/,
+ FontPtr /*pFont*/);
+
+typedef void (* ConstrainCursorProcPtr)(
+ ScreenPtr /*pScreen*/,
+ BoxPtr /*pBox*/);
+
+typedef void (* CursorLimitsProcPtr)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ BoxPtr /*pHotBox*/,
+ BoxPtr /*pTopLeftBox*/);
+
+typedef Bool (* DisplayCursorProcPtr)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/);
+
+typedef Bool (* RealizeCursorProcPtr)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/);
+
+typedef Bool (* UnrealizeCursorProcPtr)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/);
+
+typedef void (* RecolorCursorProcPtr)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ Bool /*displayed*/);
+
+typedef Bool (* SetCursorPositionProcPtr)(
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ Bool /*generateEvent*/);
+
+typedef Bool (* CreateGCProcPtr)(
+ GCPtr /*pGC*/);
+
+typedef Bool (* CreateColormapProcPtr)(
+ ColormapPtr /*pColormap*/);
+
+typedef void (* DestroyColormapProcPtr)(
+ ColormapPtr /*pColormap*/);
+
+typedef void (* InstallColormapProcPtr)(
+ ColormapPtr /*pColormap*/);
+
+typedef void (* UninstallColormapProcPtr)(
+ ColormapPtr /*pColormap*/);
+
+typedef int (* ListInstalledColormapsProcPtr) (
+ ScreenPtr /*pScreen*/,
+ XID* /*pmaps */);
+
+typedef void (* StoreColorsProcPtr)(
+ ColormapPtr /*pColormap*/,
+ int /*ndef*/,
+ xColorItem * /*pdef*/);
+
+typedef void (* ResolveColorProcPtr)(
+ unsigned short* /*pred*/,
+ unsigned short* /*pgreen*/,
+ unsigned short* /*pblue*/,
+ VisualPtr /*pVisual*/);
+
+#ifdef NEED_SCREEN_REGIONS
+
+typedef RegionPtr (* RegionCreateProcPtr)(
+ BoxPtr /*rect*/,
+ int /*size*/);
+
+typedef void (* RegionInitProcPtr)(
+ RegionPtr /*pReg*/,
+ BoxPtr /*rect*/,
+ int /*size*/);
+
+typedef Bool (* RegionCopyProcPtr)(
+ RegionPtr /*dst*/,
+ RegionPtr /*src*/);
+
+typedef void (* RegionDestroyProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef void (* RegionUninitProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef Bool (* IntersectProcPtr)(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/);
+
+typedef Bool (* UnionProcPtr)(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/);
+
+typedef Bool (* SubtractProcPtr)(
+ RegionPtr /*regD*/,
+ RegionPtr /*regM*/,
+ RegionPtr /*regS*/);
+
+typedef Bool (* InverseProcPtr)(
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ BoxPtr /*invRect*/);
+
+typedef void (* RegionResetProcPtr)(
+ RegionPtr /*pReg*/,
+ BoxPtr /*pBox*/);
+
+typedef void (* TranslateRegionProcPtr)(
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/);
+
+typedef int (* RectInProcPtr)(
+ RegionPtr /*region*/,
+ BoxPtr /*prect*/);
+
+typedef Bool (* PointInRegionProcPtr)(
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/);
+
+typedef Bool (* RegionNotEmptyProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef Bool (* RegionEqualProcPtr)(
+ RegionPtr /*pReg1*/,
+ RegionPtr /*pReg2*/);
+
+typedef Bool (* RegionBrokenProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef Bool (* RegionBreakProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef void (* RegionEmptyProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef BoxPtr (* RegionExtentsProcPtr)(
+ RegionPtr /*pReg*/);
+
+typedef Bool (* RegionAppendProcPtr)(
+ RegionPtr /*dstrgn*/,
+ RegionPtr /*rgn*/);
+
+typedef Bool (* RegionValidateProcPtr)(
+ RegionPtr /*badreg*/,
+ Bool* /*pOverlap*/);
+
+#endif /* NEED_SCREEN_REGIONS */
+
+typedef RegionPtr (* BitmapToRegionProcPtr)(
+ PixmapPtr /*pPix*/);
+
+#ifdef NEED_SCREEN_REGIONS
+
+typedef RegionPtr (* RectsToRegionProcPtr)(
+ int /*nrects*/,
+ xRectangle* /*prect*/,
+ int /*ctype*/);
+
+#endif /* NEED_SCREEN_REGIONS */
+
+typedef void (* SendGraphicsExposeProcPtr)(
+ ClientPtr /*client*/,
+ RegionPtr /*pRgn*/,
+ XID /*drawable*/,
+ int /*major*/,
+ int /*minor*/);
+
+typedef void (* ScreenBlockHandlerProcPtr)(
+ int /*screenNum*/,
+ void * /*blockData*/,
+ void * /*pTimeout*/,
+ void * /*pReadmask*/);
+
+typedef void (* ScreenWakeupHandlerProcPtr)(
+ int /*screenNum*/,
+ void * /*wakeupData*/,
+ unsigned long /*result*/,
+ void * /*pReadMask*/);
+
+typedef Bool (* CreateScreenResourcesProcPtr)(
+ ScreenPtr /*pScreen*/);
+
+typedef Bool (* ModifyPixmapHeaderProcPtr)(
+ PixmapPtr /*pPixmap*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ void * /*pPixData*/);
+
+typedef PixmapPtr (* GetWindowPixmapProcPtr)(
+ WindowPtr /*pWin*/);
+
+typedef void (* SetWindowPixmapProcPtr)(
+ WindowPtr /*pWin*/,
+ PixmapPtr /*pPix*/);
+
+typedef PixmapPtr (* GetScreenPixmapProcPtr)(
+ ScreenPtr /*pScreen*/);
+
+typedef void (* SetScreenPixmapProcPtr)(
+ PixmapPtr /*pPix*/);
+
+typedef void (* MarkWindowProcPtr)(
+ WindowPtr /*pWin*/);
+
+typedef Bool (* MarkOverlappedWindowsProcPtr)(
+ WindowPtr /*parent*/,
+ WindowPtr /*firstChild*/,
+ WindowPtr * /*pLayerWin*/);
+
+typedef Bool (* ChangeSaveUnderProcPtr)(
+ WindowPtr /*pLayerWin*/,
+ WindowPtr /*firstChild*/);
+
+typedef void (* PostChangeSaveUnderProcPtr)(
+ WindowPtr /*pLayerWin*/,
+ WindowPtr /*firstChild*/);
+
+typedef void (* MoveWindowProcPtr)(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pSib*/,
+ VTKind /*kind*/);
+
+typedef void (* ResizeWindowProcPtr)(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ WindowPtr /*pSib*/
+);
+
+typedef WindowPtr (* GetLayerWindowProcPtr)(
+ WindowPtr /*pWin*/
+);
+
+typedef void (* HandleExposuresProcPtr)(
+ WindowPtr /*pWin*/);
+
+typedef void (* ReparentWindowProcPtr)(
+ WindowPtr /*pWin*/,
+ WindowPtr /*pPriorParent*/);
+
+#ifdef SHAPE
+typedef void (* SetShapeProcPtr)(
+ WindowPtr /*pWin*/);
+#endif /* SHAPE */
+
+typedef void (* ChangeBorderWidthProcPtr)(
+ WindowPtr /*pWin*/,
+ unsigned int /*width*/);
+
+typedef void (* MarkUnrealizedWindowProcPtr)(
+ WindowPtr /*pChild*/,
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/);
+
+typedef void (*ConstrainCursorHarderProcPtr)(
+ ScreenPtr, /*pScreen*/
+ int, /*mode*/
+ int *, /*x*/
+ int * /*y*/);
+
+typedef Bool (*ReplaceScanoutPixmapProcPtr)(
+ DrawablePtr, /*pDrawable*/
+ PixmapPtr, /*pPixmap*/
+ Bool /*enable*/);
+
+typedef struct _Screen {
+ int myNum; /* index of this instance in Screens[] */
+ ATOM id;
+ short width, height;
+ short mmWidth, mmHeight;
+ short numDepths;
+ unsigned char rootDepth;
+ DepthPtr allowedDepths;
+ unsigned long rootVisual;
+ unsigned long defColormap;
+ short minInstalledCmaps, maxInstalledCmaps;
+ char backingStoreSupport, saveUnderSupport;
+ unsigned long whitePixel, blackPixel;
+ unsigned long rgf; /* array of flags; she's -- HUNGARIAN */
+ GCPtr GCperDepth[MAXFORMATS+1];
+ /* next field is a stipple to use as default in
+ a GC. we don't build default tiles of all depths
+ because they are likely to be of a color
+ different from the default fg pixel, so
+ we don't win anything by building
+ a standard one.
+ */
+ PixmapPtr PixmapPerDepth[1];
+ void * devPrivate;
+ short numVisuals;
+ VisualPtr visuals;
+ WindowPtr root;
+ int WindowPrivateLen;
+ unsigned *WindowPrivateSizes;
+ unsigned totalWindowSize;
+ int GCPrivateLen;
+ unsigned *GCPrivateSizes;
+ unsigned totalGCSize;
+
+ /* Random screen procedures */
+
+ CloseScreenProcPtr CloseScreen;
+ QueryBestSizeProcPtr QueryBestSize;
+ SaveScreenProcPtr SaveScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PointerNonInterestBoxProcPtr PointerNonInterestBox;
+ SourceValidateProcPtr SourceValidate;
+
+ /* Window Procedures */
+
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ PositionWindowProcPtr PositionWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ValidateTreeProcPtr ValidateTree;
+ PostValidateTreeProcPtr PostValidateTree;
+ WindowExposuresProcPtr WindowExposures;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ ClipNotifyProcPtr ClipNotify;
+ RestackWindowProcPtr RestackWindow;
+
+ /* Pixmap procedures */
+
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+
+ /* Backing store procedures */
+
+ SaveDoomedAreasProcPtr SaveDoomedAreas;
+ RestoreAreasProcPtr RestoreAreas;
+ ExposeCopyProcPtr ExposeCopy;
+ TranslateBackingStoreProcPtr TranslateBackingStore;
+ ClearBackingStoreProcPtr ClearBackingStore;
+ DrawGuaranteeProcPtr DrawGuarantee;
+ /*
+ * A read/write copy of the lower level backing store vector is needed now
+ * that the functions can be wrapped.
+ */
+ BSFuncRec BackingStoreFuncs;
+
+ /* Font procedures */
+
+ RealizeFontProcPtr RealizeFont;
+ UnrealizeFontProcPtr UnrealizeFont;
+
+ /* Cursor Procedures */
+
+ ConstrainCursorProcPtr ConstrainCursor;
+ ConstrainCursorHarderProcPtr ConstrainCursorHarder;
+ CursorLimitsProcPtr CursorLimits;
+ DisplayCursorProcPtr DisplayCursor;
+ RealizeCursorProcPtr RealizeCursor;
+ UnrealizeCursorProcPtr UnrealizeCursor;
+ RecolorCursorProcPtr RecolorCursor;
+ SetCursorPositionProcPtr SetCursorPosition;
+
+ /* GC procedures */
+
+ CreateGCProcPtr CreateGC;
+
+ /* Colormap procedures */
+
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ UninstallColormapProcPtr UninstallColormap;
+ ListInstalledColormapsProcPtr ListInstalledColormaps;
+ StoreColorsProcPtr StoreColors;
+ ResolveColorProcPtr ResolveColor;
+
+ /* Region procedures */
+
+#ifdef NEED_SCREEN_REGIONS
+ RegionCreateProcPtr RegionCreate;
+ RegionInitProcPtr RegionInit;
+ RegionCopyProcPtr RegionCopy;
+ RegionDestroyProcPtr RegionDestroy;
+ RegionUninitProcPtr RegionUninit;
+ IntersectProcPtr Intersect;
+ UnionProcPtr Union;
+ SubtractProcPtr Subtract;
+ InverseProcPtr Inverse;
+ RegionResetProcPtr RegionReset;
+ TranslateRegionProcPtr TranslateRegion;
+ RectInProcPtr RectIn;
+ PointInRegionProcPtr PointInRegion;
+ RegionNotEmptyProcPtr RegionNotEmpty;
+ RegionEqualProcPtr RegionEqual;
+ RegionBrokenProcPtr RegionBroken;
+ RegionBreakProcPtr RegionBreak;
+ RegionEmptyProcPtr RegionEmpty;
+ RegionExtentsProcPtr RegionExtents;
+ RegionAppendProcPtr RegionAppend;
+ RegionValidateProcPtr RegionValidate;
+#endif /* NEED_SCREEN_REGIONS */
+ BitmapToRegionProcPtr BitmapToRegion;
+#ifdef NEED_SCREEN_REGIONS
+ RectsToRegionProcPtr RectsToRegion;
+#endif /* NEED_SCREEN_REGIONS */
+ SendGraphicsExposeProcPtr SendGraphicsExpose;
+
+ /* os layer procedures */
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+ ScreenWakeupHandlerProcPtr WakeupHandler;
+
+ void * blockData;
+ void * wakeupData;
+
+ /* anybody can get a piece of this array */
+ DevUnion *devPrivates;
+
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
+
+ GetWindowPixmapProcPtr GetWindowPixmap;
+ SetWindowPixmapProcPtr SetWindowPixmap;
+ GetScreenPixmapProcPtr GetScreenPixmap;
+ SetScreenPixmapProcPtr SetScreenPixmap;
+
+ PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */
+
+#ifdef PIXPRIV
+ int PixmapPrivateLen;
+ unsigned int *PixmapPrivateSizes;
+ unsigned int totalPixmapSize;
+#endif
+
+ MarkWindowProcPtr MarkWindow;
+ MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
+ ChangeSaveUnderProcPtr ChangeSaveUnder;
+ PostChangeSaveUnderProcPtr PostChangeSaveUnder;
+ MoveWindowProcPtr MoveWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ GetLayerWindowProcPtr GetLayerWindow;
+ HandleExposuresProcPtr HandleExposures;
+ ReparentWindowProcPtr ReparentWindow;
+
+#ifdef SHAPE
+ SetShapeProcPtr SetShape;
+#endif /* SHAPE */
+
+ ChangeBorderWidthProcPtr ChangeBorderWidth;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+ ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
+} ScreenRec;
+
+static inline RegionPtr BitmapToRegion(ScreenPtr _pScreen, PixmapPtr pPix) {
+ return (*(_pScreen)->BitmapToRegion)(pPix); /* no mi version?! */
+}
+
+typedef struct _ScreenInfo {
+ int imageByteOrder;
+ int bitmapScanlineUnit;
+ int bitmapScanlinePad;
+ int bitmapBitOrder;
+ int numPixmapFormats;
+ PixmapFormatRec
+ formats[MAXFORMATS];
+ int arraySize;
+ int numScreens;
+ ScreenPtr screens[MAXSCREENS];
+ int numVideoScreens;
+} ScreenInfo;
+
+extern ScreenInfo screenInfo;
+
+extern void InitOutput(
+ ScreenInfo * /*pScreenInfo*/,
+ int /*argc*/,
+ char ** /*argv*/);
+
+#endif /* SCREENINTSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/selection.h b/nx-X11/programs/Xserver/include/selection.h
new file mode 100644
index 000000000..fbe7cfca6
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/selection.h
@@ -0,0 +1,68 @@
+
+#ifndef SELECTION_H
+#define SELECTION_H 1
+
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#include "dixstruct.h"
+/*
+ *
+ * Selection data structures
+ */
+
+typedef struct _Selection {
+ Atom selection;
+ TimeStamp lastTimeChanged;
+ Window window;
+ WindowPtr pWin;
+ ClientPtr client;
+} Selection;
+
+#endif /* SELECTION_H */
+
+
diff --git a/nx-X11/programs/Xserver/include/servermd.h b/nx-X11/programs/Xserver/include/servermd.h
new file mode 100644
index 000000000..04cd97bb8
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/servermd.h
@@ -0,0 +1,415 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef SERVERMD_H
+#define SERVERMD_H 1
+
+/*
+ * Note: much of this is vestigial from mfb/cfb times. This should
+ * really be simplified even further.
+ */
+
+/*
+ * Machine dependent values:
+ * GLYPHPADBYTES should be chosen with consideration for the space-time
+ * trade-off. Padding to 0 bytes means that there is no wasted space
+ * in the font bitmaps (both on disk and in memory), but that access of
+ * the bitmaps will cause odd-address memory references. Padding to
+ * 2 bytes would ensure even address memory references and would
+ * be suitable for a 68010-class machine, but at the expense of wasted
+ * space in the font bitmaps. Padding to 4 bytes would be good
+ * for real 32 bit machines, etc. Be sure that you tell the font
+ * compiler what kind of padding you want because its defines are
+ * kept separate from this. See server/include/font.h for how
+ * GLYPHPADBYTES is used.
+ *
+ */
+
+#ifdef vax
+
+#define IMAGE_BYTE_ORDER LSBFirst /* Values for the VAX only */
+#define BITMAP_BIT_ORDER LSBFirst
+#define GLYPHPADBYTES 1
+
+#endif /* vax */
+
+#ifdef __arm32__
+
+#define IMAGE_BYTE_ORDER LSBFirst
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+#define GLYPHPADBYTES 4
+
+#endif /* __arm32__ */
+
+#ifdef __aarch64__
+
+#ifdef __AARCH64EL__
+#define IMAGE_BYTE_ORDER LSBFirst
+#define BITMAP_BIT_ORDER LSBFirst
+#endif
+#ifdef __AARCH64EB__
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+#define GLYPHPADBYTES 4
+
+#endif /* __aarch64__ */
+
+#if defined(__powerpc__) || defined(__ppc__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#endif /* PowerPC */
+
+#if defined(__sh__)
+
+#if defined(__BIG_ENDIAN__)
+# define IMAGE_BYTE_ORDER MSBFirst
+# define BITMAP_BIT_ORDER MSBFirst
+# define GLYPHPADBYTES 4
+#else
+# define IMAGE_BYTE_ORDER LSBFirst
+# define BITMAP_BIT_ORDER LSBFirst
+# define GLYPHPADBYTES 4
+#endif
+
+#endif /* SuperH */
+
+
+#if (defined(sun) && (defined(__sparc) || defined(sparc))) || \
+ (defined(__uxp__) && (defined(sparc) || defined(mc68000))) || \
+ defined(__sparc__) || defined(__mc68000__)
+
+#if defined(__sparc) || defined(__sparc__)
+# if !defined(sparc)
+# define sparc 1
+# endif
+#endif
+
+#if defined(sun386) || defined(sun5)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the SUN only */
+# define BITMAP_BIT_ORDER LSBFirst
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the SUN only */
+# define BITMAP_BIT_ORDER MSBFirst
+#endif
+
+#define GLYPHPADBYTES 4
+
+#endif /* sun && !(i386 && SVR4) */
+
+#if defined(ibm032) || defined (ibm)
+
+#ifdef i386
+# define IMAGE_BYTE_ORDER LSBFirst /* Value for PS/2 only */
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the RT only*/
+#endif
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 1
+/* ibm pcc doesn't understand pragmas. */
+
+#ifdef i386
+#define BITMAP_SCANLINE_UNIT 8
+#endif
+
+#endif /* ibm */
+
+#if defined (M4310) || defined(M4315) || defined(M4317) || defined(M4319) || defined(M4330)
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for Pegasus only */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#endif /* tektronix */
+
+#ifdef macII
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the MacII only */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#endif /* macII */
+
+#if (defined(mips) || defined(__mips))
+
+#if defined(MIPSEL) || defined(__MIPSEL__)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the PMAX only */
+# define BITMAP_BIT_ORDER LSBFirst
+# define GLYPHPADBYTES 4
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the MIPS only */
+# define BITMAP_BIT_ORDER MSBFirst
+# define GLYPHPADBYTES 4
+#endif
+
+#endif /* mips */
+
+#if defined(__alpha) || defined(__alpha__) || defined(__alphaCross)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the Alpha only */
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+# define GLYPHPADBYTES 4
+
+#endif /* alpha */
+
+#if defined (linux) && defined (__s390__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#define BITMAP_SCANLINE_UNIT 8
+
+#endif /* linux/s390 */
+
+#if defined (linux) && defined (__s390x__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#define BITMAP_SCANLINE_UNIT 8
+
+#endif /* linux/s390x */
+
+
+#if defined(__ia64__) || defined(ia64)
+# define IMAGE_BYTE_ORDER LSBFirst
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+# define GLYPHPADBYTES 4
+
+#endif /* ia64 */
+
+#if defined(__amd64__) || defined(amd64) || defined(__amd64)
+# define IMAGE_BYTE_ORDER LSBFirst
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+# define GLYPHPADBYTES 4
+/* ???? */
+#endif /* AMD64 */
+
+#ifdef stellar
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the stellar only*/
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define IMAGE_BUFSIZE (64*1024)
+/*
+ * Use SysV random number generator.
+ */
+#define random rand
+
+#endif /* stellar */
+
+#ifdef luna
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the OMRON only*/
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#ifndef mc68000
+#endif
+
+#endif /* luna */
+
+#if (defined(SVR4) && defined(i386)) || \
+ defined(__alpha__) || defined(__alpha) || \
+ defined(__i386__) || defined(__i386) || \
+ defined(__s390x__) || defined(__s390__)
+
+#ifndef IMAGE_BYTE_ORDER
+#define IMAGE_BYTE_ORDER LSBFirst
+#endif
+
+#ifndef BITMAP_BIT_ORDER
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+#endif
+
+#ifndef BITMAP_SCANLINE_UNIT
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+#endif
+
+#ifndef GLYPHPADBYTES
+#define GLYPHPADBYTES 4
+#endif
+
+#ifdef XSVGA
+#define AVOID_GLYPHBLT
+#define NO_ONE_RECT
+#endif
+
+#endif /* SVR4 / BSD / i386 */
+
+#if defined (linux) && defined (__mc68000__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+
+#endif /* linux/m68k */
+
+/* linux on the Compaq Itsy */
+#if defined(linux) && defined(__arm__)
+#define IMAGE_BYTE_ORDER LSBFirst
+#define BITMAP_BIT_ORDER LSBFirst
+#define GLYPHPADBYTES 4
+#endif
+
+/* size of buffer to use with GetImage, measured in bytes. There's obviously
+ * a trade-off between the amount of stack (or whatever ALLOCATE_LOCAL gives
+ * you) used and the number of times the ddx routine has to be called.
+ */
+#ifndef IMAGE_BUFSIZE
+#define IMAGE_BUFSIZE (64*1024)
+#endif
+
+/* pad scanline to a longword */
+#ifndef BITMAP_SCANLINE_UNIT
+#define BITMAP_SCANLINE_UNIT 32
+#endif
+
+#ifndef BITMAP_SCANLINE_PAD
+#define BITMAP_SCANLINE_PAD 32
+#define LOG2_BITMAP_PAD 5
+#define LOG2_BYTES_PER_SCANLINE_PAD 2
+#endif
+
+/*
+ * This returns the number of padding units, for depth d and width w.
+ * For bitmaps this can be calculated with the macros above.
+ * Other depths require either grovelling over the formats field of the
+ * screenInfo or hardwired constants.
+ */
+
+typedef struct _PaddingInfo {
+ int padRoundUp; /* pixels per pad unit - 1 */
+ int padPixelsLog2; /* log 2 (pixels per pad unit) */
+ int padBytesLog2; /* log 2 (bytes per pad unit) */
+ int notPower2; /* bitsPerPixel not a power of 2 */
+ int bytesPerPixel; /* only set when notPower2 is TRUE */
+ int bitsPerPixel; /* bits per pixel */
+} PaddingInfo;
+extern PaddingInfo PixmapWidthPaddingInfo[];
+
+/* The only portable way to get the bpp from the depth is to look it up */
+#define BitsPerPixel(d) (PixmapWidthPaddingInfo[d].bitsPerPixel)
+
+#define PixmapWidthInPadUnits(w, d) \
+ (PixmapWidthPaddingInfo[d].notPower2 ? \
+ (((int)(w) * PixmapWidthPaddingInfo[d].bytesPerPixel + \
+ PixmapWidthPaddingInfo[d].bytesPerPixel) >> \
+ PixmapWidthPaddingInfo[d].padBytesLog2) : \
+ ((int)((w) + PixmapWidthPaddingInfo[d].padRoundUp) >> \
+ PixmapWidthPaddingInfo[d].padPixelsLog2))
+
+/*
+ * Return the number of bytes to which a scanline of the given
+ * depth and width will be padded.
+ */
+#define PixmapBytePad(w, d) \
+ (PixmapWidthInPadUnits(w, d) << PixmapWidthPaddingInfo[d].padBytesLog2)
+
+#define BitmapBytePad(w) \
+ (((int)((w) + BITMAP_SCANLINE_PAD - 1) >> LOG2_BITMAP_PAD) << LOG2_BYTES_PER_SCANLINE_PAD)
+
+#define PixmapWidthInPadUnitsProto(w, d) PixmapWidthInPadUnits(w, d)
+#define PixmapBytePadProto(w, d) PixmapBytePad(w, d)
+#define BitmapBytePadProto(w) BitmapBytePad(w)
+
+#endif /* SERVERMD_H */
diff --git a/nx-X11/programs/Xserver/include/site.h b/nx-X11/programs/Xserver/include/site.h
new file mode 100644
index 000000000..c8dfe69a6
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/site.h
@@ -0,0 +1,133 @@
+/************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+********************************************************/
+
+#ifndef SITE_H
+#define SITE_H
+/*
+ * The vendor string identifies the vendor responsible for the
+ * server executable.
+ */
+#ifndef VENDOR_STRING
+#define VENDOR_STRING "The X.Org Group"
+#endif
+
+/*
+ * The vendor release number identifies, for the purpose of submitting
+ * traceable bug reports, the release number of software produced
+ * by the vendor.
+ */
+#ifndef VENDOR_RELEASE
+#define VENDOR_RELEASE 6600
+#endif
+
+/*
+ * The following constant is provided solely as a last line of defense. The
+ * normal build ALWAYS overrides it using a special rule given in
+ * server/dix/Imakefile. If you want to change this constant, you should set
+ * the DefaultFontPath configuration parameter.
+ * DO NOT CHANGE THESE VALUES OR THE DIX IMAKEFILE!
+ */
+#ifndef COMPILEDDEFAULTFONTPATH
+#define COMPILEDDEFAULTFONTPATH "/usr/lib/X11/fonts/misc/"
+#endif
+
+/*
+ * The following constants contain default values for all of the variables
+ * that can be initialized on the server command line or in the environment.
+ */
+#define COMPILEDDEFAULTFONT "fixed"
+#define COMPILEDCURSORFONT "cursor"
+#ifndef COMPILEDDISPLAYCLASS
+#define COMPILEDDISPLAYCLASS "MIT-unspecified"
+#endif
+#define DEFAULT_TIMEOUT 60 /* seconds */
+#define DEFAULT_KEYBOARD_CLICK 0
+#define DEFAULT_BELL 50
+#define DEFAULT_BELL_PITCH 400
+#define DEFAULT_BELL_DURATION 100
+#ifdef XKB
+#define DEFAULT_AUTOREPEAT TRUE
+#else
+#define DEFAULT_AUTOREPEAT FALSE
+#endif
+#define DEFAULT_AUTOREPEATS {\
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+#define DEFAULT_LEDS 0x0 /* all off */
+#define DEFAULT_LEDS_MASK 0xffffffff /* 32 */
+#define DEFAULT_INT_RESOLUTION 1000
+#define DEFAULT_INT_MIN_VALUE 0
+#define DEFAULT_INT_MAX_VALUE 100
+#define DEFAULT_INT_DISPLAYED 0
+
+#define DEFAULT_PTR_NUMERATOR 2
+#define DEFAULT_PTR_DENOMINATOR 1
+#define DEFAULT_PTR_THRESHOLD 4
+
+#define DEFAULT_SCREEN_SAVER_TIME (10 * (60 * 1000))
+#define DEFAULT_SCREEN_SAVER_INTERVAL (10 * (60 * 1000))
+#define DEFAULT_SCREEN_SAVER_BLANKING PreferBlanking
+#define DEFAULT_SCREEN_SAVER_EXPOSURES AllowExposures
+#ifndef NOLOGOHACK
+#define DEFAULT_LOGO_SCREEN_SAVER 1
+#endif
+#ifndef DEFAULT_ACCESS_CONTROL
+#define DEFAULT_ACCESS_CONTROL TRUE
+#endif
+
+/* Default logging parameters. */
+#ifndef DEFAULT_LOG_VERBOSITY
+#define DEFAULT_LOG_VERBOSITY 0
+#endif
+#ifndef DEFAULT_LOG_FILE_VERBOSITY
+#define DEFAULT_LOG_FILE_VERBOSITY 3
+#endif
+
+#endif /* SITE_H */
diff --git a/nx-X11/programs/Xserver/include/swaprep.h b/nx-X11/programs/Xserver/include/swaprep.h
new file mode 100644
index 000000000..8a9dcf036
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/swaprep.h
@@ -0,0 +1,310 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifndef SWAPREP_H
+#define SWAPREP_H 1
+
+extern void Swap32Write(
+ ClientPtr /* pClient */,
+ int /* size */,
+ CARD32 * /* pbuf */);
+
+extern void CopySwap32Write(
+ ClientPtr /* pClient */,
+ int /* size */,
+ CARD32 * /* pbuf */);
+
+extern void CopySwap16Write(
+ ClientPtr /* pClient */,
+ int /* size */,
+ short * /* pbuf */);
+
+extern void SGenericReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGenericReply * /* pRep */);
+
+extern void SGetWindowAttributesReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetWindowAttributesReply * /* pRep */);
+
+extern void SGetGeometryReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetGeometryReply * /* pRep */);
+
+extern void SQueryTreeReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryTreeReply * /* pRep */);
+
+extern void SInternAtomReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xInternAtomReply * /* pRep */);
+
+extern void SGetAtomNameReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetAtomNameReply * /* pRep */);
+
+extern void SGetPropertyReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPropertyReply * /* pRep */);
+
+extern void SListPropertiesReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListPropertiesReply * /* pRep */);
+
+extern void SGetSelectionOwnerReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetSelectionOwnerReply * /* pRep */);
+
+extern void SQueryPointerReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryPointerReply * /* pRep */);
+
+extern void SwapTimecoord(
+ xTimecoord * /* pCoord */);
+
+extern void SwapTimeCoordWrite(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xTimecoord * /* pRep */);
+
+extern void SGetMotionEventsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetMotionEventsReply * /* pRep */);
+
+extern void STranslateCoordsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xTranslateCoordsReply * /* pRep */);
+
+extern void SGetInputFocusReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetInputFocusReply * /* pRep */);
+
+extern void SQueryKeymapReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryKeymapReply * /* pRep */);
+
+extern void SQueryFontReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryFontReply * /* pRep */);
+
+extern void SQueryTextExtentsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryTextExtentsReply * /* pRep */);
+
+extern void SListFontsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListFontsReply * /* pRep */);
+
+extern void SListFontsWithInfoReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListFontsWithInfoReply * /* pRep */);
+
+extern void SGetFontPathReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetFontPathReply * /* pRep */);
+
+extern void SGetImageReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetImageReply * /* pRep */);
+
+extern void SListInstalledColormapsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListInstalledColormapsReply * /* pRep */);
+
+extern void SAllocColorReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorReply * /* pRep */);
+
+extern void SAllocNamedColorReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocNamedColorReply * /* pRep */);
+
+extern void SAllocColorCellsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorCellsReply * /* pRep */);
+
+extern void SAllocColorPlanesReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorPlanesReply * /* pRep */);
+
+extern void SwapRGB(
+ xrgb * /* prgb */);
+
+extern void SQColorsExtend(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xrgb * /* prgb */);
+
+extern void SQueryColorsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryColorsReply * /* pRep */);
+
+extern void SLookupColorReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xLookupColorReply * /* pRep */);
+
+extern void SQueryBestSizeReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryBestSizeReply * /* pRep */);
+
+extern void SListExtensionsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListExtensionsReply * /* pRep */);
+
+extern void SGetKeyboardMappingReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetKeyboardMappingReply * /* pRep */);
+
+extern void SGetPointerMappingReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPointerMappingReply * /* pRep */);
+
+extern void SGetModifierMappingReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetModifierMappingReply * /* pRep */);
+
+extern void SGetKeyboardControlReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetKeyboardControlReply * /* pRep */);
+
+extern void SGetPointerControlReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPointerControlReply * /* pRep */);
+
+extern void SGetScreenSaverReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetScreenSaverReply * /* pRep */);
+
+extern void SLHostsExtend(
+ ClientPtr /* pClient */,
+ int /* size */,
+ char * /* buf */);
+
+extern void SListHostsReply(
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListHostsReply * /* pRep */);
+
+extern void SErrorEvent(
+ xError * /* from */,
+ xError * /* to */);
+
+extern void SwapConnSetupInfo(
+ char * /* pInfo */,
+ char * /* pInfoTBase */);
+
+extern void WriteSConnectionInfo(
+ ClientPtr /* pClient */,
+ unsigned long /* size */,
+ char * /* pInfo */);
+
+extern void SwapConnSetup(
+ xConnSetup * /* pConnSetup */,
+ xConnSetup * /* pConnSetupT */);
+
+extern void SwapWinRoot(
+ xWindowRoot * /* pRoot */,
+ xWindowRoot * /* pRootT */);
+
+extern void SwapVisual(
+ xVisualType * /* pVis */,
+ xVisualType * /* pVisT */);
+
+extern void SwapConnSetupPrefix(
+ xConnSetupPrefix * /* pcspFrom */,
+ xConnSetupPrefix * /* pcspTo */);
+
+extern void WriteSConnSetupPrefix(
+ ClientPtr /* pClient */,
+ xConnSetupPrefix * /* pcsp */);
+
+#undef SWAPREP_PROC
+#define SWAPREP_PROC(func) void func(xEvent * /* from */, xEvent * /* to */)
+
+SWAPREP_PROC(SCirculateEvent);
+SWAPREP_PROC(SClientMessageEvent);
+SWAPREP_PROC(SColormapEvent);
+SWAPREP_PROC(SConfigureNotifyEvent);
+SWAPREP_PROC(SConfigureRequestEvent);
+SWAPREP_PROC(SCreateNotifyEvent);
+SWAPREP_PROC(SDestroyNotifyEvent);
+SWAPREP_PROC(SEnterLeaveEvent);
+SWAPREP_PROC(SExposeEvent);
+SWAPREP_PROC(SFocusEvent);
+SWAPREP_PROC(SGraphicsExposureEvent);
+SWAPREP_PROC(SGravityEvent);
+SWAPREP_PROC(SKeyButtonPtrEvent);
+SWAPREP_PROC(SKeymapNotifyEvent);
+SWAPREP_PROC(SMapNotifyEvent);
+SWAPREP_PROC(SMapRequestEvent);
+SWAPREP_PROC(SMappingEvent);
+SWAPREP_PROC(SNoExposureEvent);
+SWAPREP_PROC(SPropertyEvent);
+SWAPREP_PROC(SReparentEvent);
+SWAPREP_PROC(SResizeRequestEvent);
+SWAPREP_PROC(SSelectionClearEvent);
+SWAPREP_PROC(SSelectionNotifyEvent);
+SWAPREP_PROC(SSelectionRequestEvent);
+SWAPREP_PROC(SUnmapNotifyEvent);
+SWAPREP_PROC(SVisibilityEvent);
+
+#undef SWAPREP_PROC
+
+#endif /* SWAPREP_H */
diff --git a/nx-X11/programs/Xserver/include/swapreq.h b/nx-X11/programs/Xserver/include/swapreq.h
new file mode 100644
index 000000000..9c785fe62
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/swapreq.h
@@ -0,0 +1,119 @@
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ 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 name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+#ifndef SWAPREQ_H
+#define SWAPREQ_H 1
+
+/* The first two are in misc.h */
+#if 0
+extern void SwapLongs (
+ CARD32 * /* list */,
+ unsigned long /* count */);
+
+extern void SwapShorts (
+ short * /* list */,
+ unsigned long /* count */);
+#endif
+
+extern void SwapColorItem(
+ xColorItem * /* pItem */);
+
+extern void SwapConnClientPrefix(
+ xConnClientPrefix * /* pCCP */);
+
+#undef SWAPREQ_PROC
+
+#define SWAPREQ_PROC(func) int func(ClientPtr /* client */)
+
+SWAPREQ_PROC(SProcAllocColor);
+SWAPREQ_PROC(SProcAllocColorCells);
+SWAPREQ_PROC(SProcAllocColorPlanes);
+SWAPREQ_PROC(SProcAllocNamedColor);
+SWAPREQ_PROC(SProcChangeActivePointerGrab);
+SWAPREQ_PROC(SProcChangeGC);
+SWAPREQ_PROC(SProcChangeHosts);
+SWAPREQ_PROC(SProcChangeKeyboardControl);
+SWAPREQ_PROC(SProcChangeKeyboardMapping);
+SWAPREQ_PROC(SProcChangePointerControl);
+SWAPREQ_PROC(SProcChangeProperty);
+SWAPREQ_PROC(SProcChangeWindowAttributes);
+SWAPREQ_PROC(SProcClearToBackground);
+SWAPREQ_PROC(SProcConfigureWindow);
+SWAPREQ_PROC(SProcConvertSelection);
+SWAPREQ_PROC(SProcCopyArea);
+SWAPREQ_PROC(SProcCopyColormapAndFree);
+SWAPREQ_PROC(SProcCopyGC);
+SWAPREQ_PROC(SProcCopyPlane);
+SWAPREQ_PROC(SProcCreateColormap);
+SWAPREQ_PROC(SProcCreateCursor);
+SWAPREQ_PROC(SProcCreateGC);
+SWAPREQ_PROC(SProcCreateGlyphCursor);
+SWAPREQ_PROC(SProcCreatePixmap);
+SWAPREQ_PROC(SProcCreateWindow);
+SWAPREQ_PROC(SProcDeleteProperty);
+SWAPREQ_PROC(SProcFillPoly);
+SWAPREQ_PROC(SProcFreeColors);
+SWAPREQ_PROC(SProcGetImage);
+SWAPREQ_PROC(SProcGetMotionEvents);
+SWAPREQ_PROC(SProcGetProperty);
+SWAPREQ_PROC(SProcGrabButton);
+SWAPREQ_PROC(SProcGrabKey);
+SWAPREQ_PROC(SProcGrabKeyboard);
+SWAPREQ_PROC(SProcGrabPointer);
+SWAPREQ_PROC(SProcImageText);
+SWAPREQ_PROC(SProcInternAtom);
+SWAPREQ_PROC(SProcListFonts);
+SWAPREQ_PROC(SProcListFontsWithInfo);
+SWAPREQ_PROC(SProcLookupColor);
+SWAPREQ_PROC(SProcNoOperation);
+SWAPREQ_PROC(SProcOpenFont);
+SWAPREQ_PROC(SProcPoly);
+SWAPREQ_PROC(SProcPolyText);
+SWAPREQ_PROC(SProcPutImage);
+SWAPREQ_PROC(SProcQueryBestSize);
+SWAPREQ_PROC(SProcQueryColors);
+SWAPREQ_PROC(SProcQueryExtension);
+SWAPREQ_PROC(SProcRecolorCursor);
+SWAPREQ_PROC(SProcReparentWindow);
+SWAPREQ_PROC(SProcResourceReq);
+SWAPREQ_PROC(SProcRotateProperties);
+SWAPREQ_PROC(SProcSendEvent);
+SWAPREQ_PROC(SProcSetClipRectangles);
+SWAPREQ_PROC(SProcSetDashes);
+SWAPREQ_PROC(SProcSetFontPath);
+SWAPREQ_PROC(SProcSetInputFocus);
+SWAPREQ_PROC(SProcSetScreenSaver);
+SWAPREQ_PROC(SProcSetSelectionOwner);
+SWAPREQ_PROC(SProcSimpleReq);
+SWAPREQ_PROC(SProcStoreColors);
+SWAPREQ_PROC(SProcStoreNamedColor);
+SWAPREQ_PROC(SProcTranslateCoords);
+SWAPREQ_PROC(SProcUngrabButton);
+SWAPREQ_PROC(SProcUngrabKey);
+SWAPREQ_PROC(SProcWarpPointer);
+
+#undef SWAPREQ_PROC
+
+#endif /* SWAPREQ_H */
diff --git a/nx-X11/programs/Xserver/include/validate.h b/nx-X11/programs/Xserver/include/validate.h
new file mode 100644
index 000000000..e88fb41a2
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/validate.h
@@ -0,0 +1,40 @@
+
+/*
+
+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.
+*/
+
+#ifndef VALIDATE_H
+#define VALIDATE_H
+
+#include "miscstruct.h"
+#include "regionstr.h"
+
+typedef enum { VTOther, VTStack, VTMove, VTUnmap, VTMap, VTBroken } VTKind;
+
+/* union _Validate is now device dependent; see mivalidate.h for an example */
+typedef union _Validate *ValidatePtr;
+
+#define UnmapValData ((ValidatePtr)1)
+
+#endif /* VALIDATE_H */
diff --git a/nx-X11/programs/Xserver/include/window.h b/nx-X11/programs/Xserver/include/window.h
new file mode 100644
index 000000000..a8c78f569
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/window.h
@@ -0,0 +1,267 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include "misc.h"
+#include "region.h"
+#include "screenint.h"
+#include <nx-X11/Xproto.h>
+
+#define TOTALLY_OBSCURED 0
+#define UNOBSCURED 1
+#define OBSCURED 2
+
+#define VisibilityNotViewable 3
+
+/* return values for tree-walking callback procedures */
+#define WT_STOPWALKING 0
+#define WT_WALKCHILDREN 1
+#define WT_DONTWALKCHILDREN 2
+#define WT_NOMATCH 3
+#define NullWindow ((WindowPtr) 0)
+
+typedef struct _BackingStore *BackingStorePtr;
+typedef struct _Window *WindowPtr;
+
+typedef int (*VisitWindowProcPtr)(
+ WindowPtr /*pWin*/,
+ void * /*data*/);
+
+extern int TraverseTree(
+ WindowPtr /*pWin*/,
+ VisitWindowProcPtr /*func*/,
+ void * /*data*/);
+
+extern int WalkTree(
+ ScreenPtr /*pScreen*/,
+ VisitWindowProcPtr /*func*/,
+ void * /*data*/);
+
+extern WindowPtr AllocateWindow(
+ ScreenPtr /*pScreen*/);
+
+extern Bool CreateRootWindow(
+ ScreenPtr /*pScreen*/);
+
+extern void InitRootWindow(
+ WindowPtr /*pWin*/);
+
+extern void ClippedRegionFromBox(
+ WindowPtr /*pWin*/,
+ RegionPtr /*Rgn*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/);
+
+typedef WindowPtr (* RealChildHeadProc) (WindowPtr pWin);
+
+void RegisterRealChildHeadProc (RealChildHeadProc proc);
+
+extern WindowPtr RealChildHead(
+ WindowPtr /*pWin*/);
+
+extern WindowPtr CreateWindow(
+ Window /*wid*/,
+ WindowPtr /*pParent*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ unsigned int /*bw*/,
+ unsigned int /*class*/,
+ Mask /*vmask*/,
+ XID* /*vlist*/,
+ int /*depth*/,
+ ClientPtr /*client*/,
+ VisualID /*visual*/,
+ int* /*error*/);
+
+extern int DeleteWindow(
+ void * /*pWin*/,
+ XID /*wid*/);
+
+extern void DestroySubwindows(
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/);
+
+/* Quartz support on Mac OS X uses the HIToolbox
+ framework whose ChangeWindowAttributes function conflicts here. */
+#ifdef __DARWIN__
+#define ChangeWindowAttributes Darwin_X_ChangeWindowAttributes
+#endif
+extern int ChangeWindowAttributes(
+ WindowPtr /*pWin*/,
+ Mask /*vmask*/,
+ XID* /*vlist*/,
+ ClientPtr /*client*/);
+
+/* Quartz support on Mac OS X uses the HIToolbox
+ framework whose GetWindowAttributes function conflicts here. */
+#ifdef __DARWIN__
+#define GetWindowAttributes(w,c,x) Darwin_X_GetWindowAttributes(w,c,x)
+extern void Darwin_X_GetWindowAttributes(
+#else
+extern void GetWindowAttributes(
+#endif
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/,
+ xGetWindowAttributesReply* /* wa */);
+
+extern RegionPtr CreateUnclippedWinSize(
+ WindowPtr /*pWin*/);
+
+extern void GravityTranslate(
+ int /*x*/,
+ int /*y*/,
+ int /*oldx*/,
+ int /*oldy*/,
+ int /*dw*/,
+ int /*dh*/,
+ unsigned /*gravity*/,
+ int* /*destx*/,
+ int* /*desty*/);
+
+extern int ConfigureWindow(
+ WindowPtr /*pWin*/,
+ Mask /*mask*/,
+ XID* /*vlist*/,
+ ClientPtr /*client*/);
+
+extern int CirculateWindow(
+ WindowPtr /*pParent*/,
+ int /*direction*/,
+ ClientPtr /*client*/);
+
+extern int ReparentWindow(
+ WindowPtr /*pWin*/,
+ WindowPtr /*pParent*/,
+ int /*x*/,
+ int /*y*/,
+ ClientPtr /*client*/);
+
+extern int MapWindow(
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/);
+
+extern void MapSubwindows(
+ WindowPtr /*pParent*/,
+ ClientPtr /*client*/);
+
+extern int UnmapWindow(
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/);
+
+extern void UnmapSubwindows(
+ WindowPtr /*pWin*/);
+
+extern void HandleSaveSet(
+ ClientPtr /*client*/);
+
+extern Bool VisibleBoundingBoxFromPoint(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/);
+
+extern Bool PointInWindowIsVisible(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/);
+
+extern RegionPtr NotClippedByChildren(
+ WindowPtr /*pWin*/);
+
+extern void SendVisibilityNotify(
+ WindowPtr /*pWin*/);
+
+extern void SaveScreens(
+ int /*on*/,
+ int /*mode*/);
+
+extern WindowPtr FindWindowWithOptional(
+ WindowPtr /*w*/);
+
+extern void CheckWindowOptionalNeed(
+ WindowPtr /*w*/);
+
+extern Bool MakeWindowOptional(
+ WindowPtr /*pWin*/);
+
+extern void DisposeWindowOptional(
+ WindowPtr /*pWin*/);
+
+extern WindowPtr MoveWindowInStack(
+ WindowPtr /*pWin*/,
+ WindowPtr /*pNextSib*/);
+
+void SetWinSize(
+ WindowPtr /*pWin*/);
+
+void SetBorderSize(
+ WindowPtr /*pWin*/);
+
+void ResizeChildrenWinSize(
+ WindowPtr /*pWin*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*dw*/,
+ int /*dh*/);
+
+extern void SendShapeNotify(
+ WindowPtr /* pWin */,
+ int /* which */ );
+
+extern RegionPtr CreateBoundingShape(
+ WindowPtr /* pWin */ );
+
+extern RegionPtr CreateClipShape(
+ WindowPtr /* pWin */ );
+
+#endif /* WINDOW_H */
diff --git a/nx-X11/programs/Xserver/include/windowstr.h b/nx-X11/programs/Xserver/include/windowstr.h
new file mode 100644
index 000000000..36d598c6e
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/windowstr.h
@@ -0,0 +1,255 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef WINDOWSTRUCT_H
+#define WINDOWSTRUCT_H
+
+#include "window.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "cursor.h"
+#include "property.h"
+#include "resource.h" /* for ROOT_WINDOW_ID_BASE */
+#include "dix.h"
+#include "miscstruct.h"
+#include <nx-X11/Xprotostr.h>
+#include "opaque.h"
+
+#define GuaranteeNothing 0
+#define GuaranteeVisBack 1
+
+#define SameBackground(as, a, bs, b) \
+ ((as) == (bs) && ((as) == None || \
+ (as) == ParentRelative || \
+ SamePixUnion(a,b,as == BackgroundPixel)))
+
+#define SameBorder(as, a, bs, b) \
+ EqualPixUnion(as, a, bs, b)
+
+typedef struct _WindowOpt {
+ VisualID visual; /* default: same as parent */
+ CursorPtr cursor; /* default: window.cursorNone */
+ Colormap colormap; /* default: same as parent */
+ Mask dontPropagateMask; /* default: window.dontPropagate */
+ Mask otherEventMasks; /* default: 0 */
+ struct _OtherClients *otherClients; /* default: NULL */
+ struct _GrabRec *passiveGrabs; /* default: NULL */
+ PropertyPtr userProps; /* default: NULL */
+ unsigned long backingBitPlanes; /* default: ~0L */
+ unsigned long backingPixel; /* default: 0 */
+#ifdef SHAPE
+ RegionPtr boundingShape; /* default: NULL */
+ RegionPtr clipShape; /* default: NULL */
+ RegionPtr inputShape; /* default: NULL */
+#endif
+#ifdef XINPUT
+ struct _OtherInputMasks *inputMasks; /* default: NULL */
+#endif
+} WindowOptRec, *WindowOptPtr;
+
+#define BackgroundPixel 2L
+#define BackgroundPixmap 3L
+
+/*
+ * The redirectDraw field can have one of three values:
+ *
+ * RedirectDrawNone
+ * A normal window; painted into the same pixmap as the parent
+ * and clipping parent and siblings to its geometry. These
+ * windows get a clip list equal to the intersection of their
+ * geometry with the parent geometry, minus the geometry
+ * of overlapping None and Clipped siblings.
+ * RedirectDrawAutomatic
+ * A redirected window which clips parent and sibling drawing.
+ * Contents for these windows are manage inside the server.
+ * These windows get an internal clip list equal to their
+ * geometry.
+ * RedirectDrawManual
+ * A redirected window which does not clip parent and sibling
+ * drawing; the window must be represented within the parent
+ * geometry by the client performing the redirection management.
+ * Contents for these windows are managed outside the server.
+ * These windows get an internal clip list equal to their
+ * geometry.
+ */
+
+#define RedirectDrawNone 0
+#define RedirectDrawAutomatic 1
+#define RedirectDrawManual 2
+
+typedef struct _Window {
+ DrawableRec drawable;
+ WindowPtr parent; /* ancestor chain */
+ WindowPtr nextSib; /* next lower sibling */
+ WindowPtr prevSib; /* next higher sibling */
+ WindowPtr firstChild; /* top-most child */
+ WindowPtr lastChild; /* bottom-most child */
+ RegionRec clipList; /* clipping rectangle for output */
+ RegionRec borderClip; /* NotClippedByChildren + border */
+ union _Validate *valdata;
+ RegionRec winSize;
+ RegionRec borderSize;
+ DDXPointRec origin; /* position relative to parent */
+ unsigned short borderWidth;
+ unsigned short deliverableEvents;
+ Mask eventMask;
+ PixUnion background;
+ PixUnion border;
+ void * backStorage; /* null when BS disabled */
+ WindowOptPtr optional;
+ unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */
+ unsigned borderIsPixel:1;
+ unsigned cursorIsNone:1; /* else real cursor (might inherit) */
+ unsigned backingStore:2;
+ unsigned saveUnder:1;
+ unsigned DIXsaveUnder:1;
+ unsigned bitGravity:4;
+ unsigned winGravity:4;
+ unsigned overrideRedirect:1;
+ unsigned visibility:2;
+ unsigned mapped:1;
+ unsigned realized:1; /* ancestors are all mapped */
+ unsigned viewable:1; /* realized && InputOutput */
+ unsigned dontPropagate:3;/* index into DontPropagateMasks */
+ unsigned forcedBS:1; /* system-supplied backingStore */
+#ifdef NEED_DBE_BUF_BITS
+#define DBE_FRONT_BUFFER 1
+#define DBE_BACK_BUFFER 0
+ unsigned dstBuffer:1; /* destination buffer for rendering */
+ unsigned srcBuffer:1; /* source buffer for rendering */
+#endif
+#ifdef COMPOSITE
+ unsigned redirectDraw:2; /* rendering is redirected from here */
+#endif
+ DevUnion *devPrivates;
+} WindowRec;
+
+/*
+ * Ok, a bunch of macros for accessing the optional record
+ * fields (or filling the appropriate default value)
+ */
+
+extern Mask DontPropagateMasks[];
+
+#define wTrackParent(w,field) ((w)->optional ? \
+ (w)->optional->field \
+ : FindWindowWithOptional(w)->optional->field)
+#define wUseDefault(w,field,def) ((w)->optional ? \
+ (w)->optional->field \
+ : def)
+
+#define wVisual(w) wTrackParent(w, visual)
+#define wCursor(w) ((w)->cursorIsNone ? None : wTrackParent(w, cursor))
+#define wColormap(w) ((w)->drawable.class == InputOnly ? None : wTrackParent(w, colormap))
+#define wDontPropagateMask(w) wUseDefault(w, dontPropagateMask, DontPropagateMasks[(w)->dontPropagate])
+#define wOtherEventMasks(w) wUseDefault(w, otherEventMasks, 0)
+#define wOtherClients(w) wUseDefault(w, otherClients, NULL)
+#ifdef XINPUT
+#define wOtherInputMasks(w) wUseDefault(w, inputMasks, NULL)
+#else
+#define wOtherInputMasks(w) NULL
+#endif
+#define wPassiveGrabs(w) wUseDefault(w, passiveGrabs, NULL)
+#define wUserProps(w) wUseDefault(w, userProps, NULL)
+#define wBackingBitPlanes(w) wUseDefault(w, backingBitPlanes, ~0L)
+#define wBackingPixel(w) wUseDefault(w, backingPixel, 0)
+#ifdef SHAPE
+#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL)
+#define wClipShape(w) wUseDefault(w, clipShape, NULL)
+#define wInputShape(w) wUseDefault(w, inputShape, NULL)
+#endif
+#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)])
+#define wBorderWidth(w) ((int) (w)->borderWidth)
+
+/* true when w needs a border drawn. */
+
+#ifdef SHAPE
+#define HasBorder(w) ((w)->borderWidth || wClipShape(w))
+#else
+#define HasBorder(w) ((w)->borderWidth)
+#endif
+
+typedef struct _ScreenSaverStuff {
+ WindowPtr pWindow;
+ XID wid;
+ char blanked;
+ Bool (*ExternalScreenSaver)(
+ ScreenPtr /*pScreen*/,
+ int /*xstate*/,
+ Bool /*force*/);
+} ScreenSaverStuffRec, *ScreenSaverStuffPtr;
+
+#define SCREEN_IS_BLANKED 0
+#define SCREEN_ISNT_SAVED 1
+#define SCREEN_IS_TILED 2
+#define SCREEN_IS_BLACK 3
+
+#define HasSaverWindow(i) (savedScreenInfo[i].pWindow != NullWindow)
+
+extern int screenIsSaved;
+extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+/*
+ * this is the configuration parameter "NO_BACK_SAVE"
+ * it means that any existant backing store should not
+ * be used to implement save unders.
+ */
+
+#ifndef NO_BACK_SAVE
+#define DO_SAVE_UNDERS(pWin) ((pWin)->drawable.pScreen->saveUnderSupport ==\
+ USE_DIX_SAVE_UNDERS)
+/*
+ * saveUnderSupport is set to this magic value when using DIXsaveUnders
+ */
+
+#define USE_DIX_SAVE_UNDERS 0x40
+#endif
+
+extern int numSaveUndersViewable;
+extern int deltaSaveUndersViewable;
+
+#endif /* WINDOWSTRUCT_H */
diff --git a/nx-X11/programs/Xserver/include/xkbfile.h b/nx-X11/programs/Xserver/include/xkbfile.h
new file mode 100644
index 000000000..e99de6c9c
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/xkbfile.h
@@ -0,0 +1,479 @@
+
+#ifndef _XKBFILE_H_
+#define _XKBFILE_H_ 1
+
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+/***====================================================================***/
+
+#define XkbXKMFile 0
+#define XkbCFile 1
+#define XkbXKBFile 2
+#define XkbMessage 3
+
+#define XkbMapDefined (1<<0)
+#define XkbStateDefined (1<<1)
+
+typedef struct _XkbFileInfo {
+ unsigned type;
+ unsigned defined;
+ XkbDescPtr xkb;
+} XkbFileInfo,*XkbFileInfoPtr;
+
+typedef void (*XkbFileAddOnFunc)(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ int /* fileSection */,
+ void * /* priv */
+);
+
+/***====================================================================***/
+
+#define _XkbSuccess 0
+#define _XkbErrMissingNames 1
+#define _XkbErrMissingTypes 2
+#define _XkbErrMissingReqTypes 3
+#define _XkbErrMissingSymbols 4
+#define _XkbErrMissingVMods 5
+#define _XkbErrMissingIndicators 6
+#define _XkbErrMissingCompatMap 7
+#define _XkbErrMissingSymInterps 8
+#define _XkbErrMissingGeometry 9
+#define _XkbErrIllegalDoodad 10
+#define _XkbErrIllegalTOCType 11
+#define _XkbErrIllegalContents 12
+#define _XkbErrEmptyFile 13
+#define _XkbErrFileNotFound 14
+#define _XkbErrFileCannotOpen 15
+#define _XkbErrBadValue 16
+#define _XkbErrBadMatch 17
+#define _XkbErrBadTypeName 18
+#define _XkbErrBadTypeWidth 19
+#define _XkbErrBadFileType 20
+#define _XkbErrBadFileVersion 21
+#define _XkbErrBadFileFormat 22
+#define _XkbErrBadAlloc 23
+#define _XkbErrBadLength 24
+#define _XkbErrXReqFailure 25
+#define _XkbErrBadImplementation 26
+
+extern char * _XkbErrMessages[];
+extern unsigned _XkbErrCode;
+extern char * _XkbErrLocation;
+extern unsigned _XkbErrData;
+
+/***====================================================================***/
+
+_XFUNCPROTOBEGIN
+
+extern char * XkbIndentText(
+ unsigned /* size */
+);
+
+extern char * XkbAtomText(
+ Display * /* dpy */,
+ Atom /* atm */,
+ unsigned /* format */
+);
+
+extern char * XkbKeysymText(
+ KeySym /* sym */,
+ unsigned /* format */
+);
+
+extern char * XkbStringText(
+ char * /* str */,
+ unsigned /* format */
+);
+
+extern char * XkbKeyNameText(
+ char * /* name */,
+ unsigned /* format */
+);
+
+extern char *
+XkbModIndexText(
+ unsigned /* ndx */,
+ unsigned /* format */
+);
+
+extern char *
+XkbModMaskText(
+ unsigned /* mask */,
+ unsigned /* format */
+);
+
+extern char * XkbVModIndexText(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ unsigned /* ndx */,
+ unsigned /* format */
+);
+
+extern char * XkbVModMaskText(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ unsigned /* modMask */,
+ unsigned /* mask */,
+ unsigned /* format */
+);
+
+extern char * XkbConfigText(
+ unsigned /* config */,
+ unsigned /* format */
+);
+
+extern char * XkbSIMatchText(
+ unsigned /* type */,
+ unsigned /* format */
+);
+
+extern char * XkbIMWhichStateMaskText(
+ unsigned /* use_which */,
+ unsigned /* format */
+);
+
+extern char * XkbAccessXDetailText(
+ unsigned /* state */,
+ unsigned /* format */
+);
+
+extern char * XkbNKNDetailMaskText(
+ unsigned /* detail */,
+ unsigned /* format */
+);
+
+extern char * XkbControlsMaskText(
+ unsigned /* ctrls */,
+ unsigned /* format */
+);
+
+extern char * XkbGeomFPText(
+ int /* val */,
+ unsigned /* format */
+);
+
+extern char * XkbDoodadTypeText(
+ unsigned /* type */,
+ unsigned /* format */
+);
+
+extern char * XkbActionTypeText(
+ unsigned /* type */,
+ unsigned /* format */
+);
+
+extern char * XkbActionText(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ XkbAction * /* action */,
+ unsigned /* format */
+);
+
+extern char * XkbBehaviorText(
+ XkbDescPtr /* xkb */,
+ XkbBehavior * /* behavior */,
+ unsigned /* format */
+);
+
+/***====================================================================***/
+
+#define _XkbKSLower (1<<0)
+#define _XkbKSUpper (1<<1)
+
+#define XkbKSIsLower(k) (_XkbKSCheckCase(k)&_XkbKSLower)
+#define XkbKSIsUpper(k) (_XkbKSCheckCase(k)&_XkbKSUpper)
+#define XkbKSIsKeypad(k) (((k)>=XK_KP_Space)&&((k)<=XK_KP_Equal))
+#define XkbKSIsDeadKey(k) \
+ (((k)>=XK_dead_grave)&&((k)<=XK_dead_semivoiced_sound))
+
+extern unsigned _XkbKSCheckCase(
+ KeySym /* sym */
+);
+
+extern int XkbFindKeycodeByName(
+ XkbDescPtr /* xkb */,
+ char * /* name */,
+ Bool /* use_aliases */
+);
+
+extern Bool XkbLookupGroupAndLevel(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int * /* mods_inout */,
+ int * /* grp_inout */,
+ int * /* lvl_rtrn */
+);
+
+/***====================================================================***/
+
+
+/***====================================================================***/
+
+extern Atom XkbInternAtom(
+ Display * /* dpy */,
+ char * /* name */,
+ Bool /* onlyIfExists */
+);
+
+extern Status XkbChangeKbdDisplay(
+ Display * /* newDpy */,
+ XkbFileInfo * /* result */
+);
+
+extern Atom XkbChangeAtomDisplay(
+ Display * /* oldDpy */,
+ Display * /* newDpy */,
+ Atom /* atm */
+);
+
+extern void XkbInitAtoms(
+ Display * /* dpy */
+);
+
+/***====================================================================***/
+
+#ifdef _XKBGEOM_H_
+
+#define XkbDW_Unknown 0
+#define XkbDW_Doodad 1
+#define XkbDW_Section 2
+typedef struct _XkbDrawable {
+ int type;
+ int priority;
+ union {
+ XkbDoodadPtr doodad;
+ XkbSectionPtr section;
+ } u;
+ struct _XkbDrawable * next;
+} XkbDrawableRec,*XkbDrawablePtr;
+
+extern XkbDrawablePtr
+XkbGetOrderedDrawables(
+ XkbGeometryPtr /* geom */,
+ XkbSectionPtr /* section */
+);
+
+extern void
+XkbFreeOrderedDrawables(
+ XkbDrawablePtr /* draw */
+);
+
+#endif
+
+/***====================================================================***/
+
+extern unsigned XkbConvertGetByNameComponents(
+ Bool /* toXkm */,
+ unsigned /* orig */
+);
+
+extern unsigned XkbConvertXkbComponents(
+ Bool /* toXkm */,
+ unsigned /* orig */
+);
+
+extern Bool XkbDetermineFileType(
+ XkbFileInfo * /* xkb */,
+ int /* format */,
+ int * /* opts_missing */
+);
+
+extern Bool XkbNameMatchesPattern(
+ char * /* name */,
+ char * /* pattern */
+);
+
+/***====================================================================***/
+
+extern Bool XkbWriteXKBKeycodes(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBKeyTypes(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBCompatMap(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBSymbols(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBGeometry(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBSemantics(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBLayout(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBKeymap(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteXKBFile(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+);
+
+extern Bool XkbWriteCFile(
+ FILE * /* file */,
+ char * /* name */,
+ XkbFileInfo * /* info */
+);
+
+extern Bool XkbWriteXKMFile(
+ FILE * /* file */,
+ XkbFileInfo * /* result */
+);
+
+extern Bool XkbWriteToServer(
+ XkbFileInfo * /* result */
+);
+
+extern void XkbEnsureSafeMapName(
+ char * /* name */
+);
+
+extern Bool XkbWriteXKBKeymapForNames(
+ FILE * /* file */,
+ XkbComponentNamesPtr /* names */,
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ unsigned /* want */,
+ unsigned /* need */
+);
+
+extern Status XkbMergeFile(
+ XkbDescPtr /* xkb */,
+ XkbFileInfo /* finfo */
+);
+
+/***====================================================================***/
+
+extern Bool XkmProbe(
+ FILE * /* file */
+);
+
+extern unsigned XkbReadFromServer(
+ Display * /* dpy */,
+ unsigned /* need */,
+ unsigned /* want */,
+ XkbFileInfo * /* result */
+);
+
+extern unsigned XkmReadFile(
+ FILE * /* file */,
+ unsigned /* need */,
+ unsigned /* want */,
+ XkbFileInfo * /* result */
+);
+
+#ifdef _XKMFORMAT_H_
+
+extern Bool XkmReadTOC(
+ FILE * /* file */,
+ xkmFileInfo * /* file_info */,
+ int /* max_toc */,
+ xkmSectionInfo * /* toc */
+);
+
+extern xkmSectionInfo *XkmFindTOCEntry(
+ xkmFileInfo * /* finfo */,
+ xkmSectionInfo * /* toc */,
+ unsigned /* type */
+);
+
+extern Bool XkmReadFileSection(
+ FILE * /* file */,
+ xkmSectionInfo * /* toc */,
+ XkbFileInfo * /* result */,
+ unsigned * /* loaded_rtrn */
+);
+
+extern char * XkmReadFileSectionName(
+ FILE * /* file */,
+ xkmSectionInfo * /* toc */
+);
+
+#endif /* _XKMFORMAT_H */
+
+_XFUNCPROTOEND
+
+#endif /* _XKBFILE_H_ */
diff --git a/nx-X11/programs/Xserver/include/xkbrules.h b/nx-X11/programs/Xserver/include/xkbrules.h
new file mode 100644
index 000000000..021e1021f
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/xkbrules.h
@@ -0,0 +1,184 @@
+#ifndef _XKBRULES_H_
+#define _XKBRULES_H_ 1
+
+/************************************************************
+ Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+/***====================================================================***/
+
+typedef struct _XkbRF_VarDefs {
+ char * model;
+ char * layout;
+ char * variant;
+ char * options;
+ unsigned short sz_extra;
+ unsigned short num_extra;
+ char * extra_names;
+ char ** extra_values;
+} XkbRF_VarDefsRec,*XkbRF_VarDefsPtr;
+
+typedef struct _XkbRF_VarDesc {
+ char * name;
+ char * desc;
+} XkbRF_VarDescRec, *XkbRF_VarDescPtr;
+
+typedef struct _XkbRF_DescribeVars {
+ int sz_desc;
+ int num_desc;
+ XkbRF_VarDescPtr desc;
+} XkbRF_DescribeVarsRec,*XkbRF_DescribeVarsPtr;
+
+typedef struct _XkbRF_Rule {
+ int number;
+ int layout_num;
+ int variant_num;
+ char * model;
+ char * layout;
+ char * variant;
+ char * option;
+ /* yields */
+ char * keycodes;
+ char * symbols;
+ char * types;
+ char * compat;
+ char * geometry;
+ char * keymap;
+ unsigned flags;
+} XkbRF_RuleRec,*XkbRF_RulePtr;
+
+typedef struct _XkbRF_Group {
+ int number;
+ char * name;
+ char * words;
+} XkbRF_GroupRec, *XkbRF_GroupPtr;
+
+#define XkbRF_PendingMatch (1L<<1)
+#define XkbRF_Option (1L<<2)
+#define XkbRF_Append (1L<<3)
+#define XkbRF_Normal (1L<<4)
+#define XkbRF_Invalid (1L<<5)
+
+typedef struct _XkbRF_Rules {
+ XkbRF_DescribeVarsRec models;
+ XkbRF_DescribeVarsRec layouts;
+ XkbRF_DescribeVarsRec variants;
+ XkbRF_DescribeVarsRec options;
+ unsigned short sz_extra;
+ unsigned short num_extra;
+ char ** extra_names;
+ XkbRF_DescribeVarsPtr extra;
+
+ unsigned short sz_rules;
+ unsigned short num_rules;
+ XkbRF_RulePtr rules;
+ unsigned short sz_groups;
+ unsigned short num_groups;
+ XkbRF_GroupPtr groups;
+} XkbRF_RulesRec, *XkbRF_RulesPtr;
+
+/***====================================================================***/
+
+_XFUNCPROTOBEGIN
+
+extern Bool XkbRF_GetComponents(
+ XkbRF_RulesPtr /* rules */,
+ XkbRF_VarDefsPtr /* var_defs */,
+ XkbComponentNamesPtr /* names */
+);
+
+extern XkbRF_RulePtr XkbRF_AddRule(
+ XkbRF_RulesPtr /* rules */
+);
+
+extern XkbRF_GroupPtr XkbRF_AddGroup(XkbRF_RulesPtr rules);
+
+extern Bool XkbRF_LoadRules(
+ FILE * /* file */,
+ XkbRF_RulesPtr /* rules */
+);
+
+extern Bool XkbRF_LoadRulesByName(
+ char * /* base */,
+ char * /* locale */,
+ XkbRF_RulesPtr /* rules */
+);
+
+/***====================================================================***/
+
+extern XkbRF_VarDescPtr XkbRF_AddVarDesc(
+ XkbRF_DescribeVarsPtr /* vars */
+);
+
+extern XkbRF_VarDescPtr XkbRF_AddVarDescCopy(
+ XkbRF_DescribeVarsPtr /* vars */,
+ XkbRF_VarDescPtr /* copy_from */
+);
+
+extern XkbRF_DescribeVarsPtr XkbRF_AddVarToDescribe(
+ XkbRF_RulesPtr /* rules */,
+ char * /* name */
+);
+
+extern Bool XkbRF_LoadDescriptions(
+ FILE * /* file */,
+ XkbRF_RulesPtr /* rules */
+);
+
+extern Bool XkbRF_LoadDescriptionsByName(
+ char * /* base */,
+ char * /* locale */,
+ XkbRF_RulesPtr /* rules */
+);
+
+extern XkbRF_RulesPtr XkbRF_Load(
+ char * /* base */,
+ char * /* locale */,
+ Bool /* wantDesc */,
+ Bool /* wantRules */
+);
+
+extern XkbRF_RulesPtr XkbRF_Create(
+ int /* sz_rules */,
+ int /* sz_extra */
+);
+
+/***====================================================================***/
+
+extern void XkbRF_Free(
+ XkbRF_RulesPtr /* rules */,
+ Bool /* freeRules */
+);
+
+
+/***====================================================================***/
+
+#define _XKB_RF_NAMES_PROP_ATOM "_XKB_RULES_NAMES"
+#define _XKB_RF_NAMES_PROP_MAXLEN 1024
+
+
+_XFUNCPROTOEND
+
+#endif /* _XKBRULES_H_ */
diff --git a/nx-X11/programs/Xserver/include/xkbsrv.h b/nx-X11/programs/Xserver/include/xkbsrv.h
new file mode 100644
index 000000000..533a30930
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/xkbsrv.h
@@ -0,0 +1,1181 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifndef _XKBSRV_H_
+#define _XKBSRV_H_
+
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbAddKeyType SrvXkbAddKeyType
+#define XkbCopyKeyType SrvXkbCopyKeyType
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbInitCanonicalKeyTypes SrvXkbInitCanonicalKeyTypes
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbUpdateMapFromCore SrvXkbUpdateMapFromCore
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeControls SrvXkbFreeControls
+#define XkbFreeIndicatorMaps SrvXkbFreeIndicatorMaps
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbAddDeviceLedInfo SrvXkbAddDeviceLedInfo
+#define XkbAllocDeviceInfo SrvXkbAllocDeviceInfo
+#define XkbFreeDeviceInfo SrvXkbFreeDeviceInfo
+#define XkbResizeDeviceButtonActions SrvXkbResizeDeviceButtonActions
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+#define XkbUpdateActionVirtualMods SrvXkbUpdateActionVirtualMods
+#define XkbUpdateKeyTypeVirtualMods SrvXkbUpdateKeyTypeVirtualMods
+
+#include <nx-X11/extensions/XKBproto.h>
+#include "xkbstr.h"
+#include "inputstr.h"
+
+#ifdef NXAGENT_SERVER
+extern char *_NXGetXkbBasePath(const char *path);
+extern char *_NXGetXkbCompPath(const char *path);
+#endif
+
+typedef struct _XkbInterest {
+ DeviceIntPtr dev;
+ ClientPtr client;
+ XID resource;
+ struct _XkbInterest * next;
+ CARD16 extDevNotifyMask;
+ CARD16 stateNotifyMask;
+ CARD16 namesNotifyMask;
+ CARD32 ctrlsNotifyMask;
+ CARD8 compatNotifyMask;
+ BOOL bellNotifyMask;
+ BOOL actionMessageMask;
+ CARD16 accessXNotifyMask;
+ CARD32 iStateNotifyMask;
+ CARD32 iMapNotifyMask;
+ CARD16 altSymsNotifyMask;
+ CARD32 autoCtrls;
+ CARD32 autoCtrlValues;
+} XkbInterestRec,*XkbInterestPtr;
+
+typedef struct _XkbRadioGroup {
+ CARD8 flags;
+ CARD8 nMembers;
+ CARD8 dfltDown;
+ CARD8 currentDown;
+ CARD8 members[XkbRGMaxMembers];
+} XkbRadioGroupRec, *XkbRadioGroupPtr;
+
+typedef struct _XkbEventCause {
+ CARD8 kc;
+ CARD8 event;
+ CARD8 mjr;
+ CARD8 mnr;
+ ClientPtr client;
+} XkbEventCauseRec,*XkbEventCausePtr;
+#define XkbSetCauseKey(c,k,e) { (c)->kc= (k),(c)->event= (e),\
+ (c)->mjr= (c)->mnr= 0; \
+ (c)->client= NULL; }
+#define XkbSetCauseReq(c,j,n,cl) { (c)->kc= (c)->event= 0,\
+ (c)->mjr= (j),(c)->mnr= (n);\
+ (c)->client= (cl); }
+#define XkbSetCauseCoreReq(c,e,cl) XkbSetCauseReq(c,e,0,cl)
+#define XkbSetCauseXkbReq(c,e,cl) XkbSetCauseReq(c,XkbReqCode,e,cl)
+#define XkbSetCauseUnknown(c) XkbSetCauseKey(c,0,0)
+
+#define _OFF_TIMER 0
+#define _KRG_WARN_TIMER 1
+#define _KRG_TIMER 2
+#define _SK_TIMEOUT_TIMER 3
+#define _ALL_TIMEOUT_TIMER 4
+
+#define _BEEP_NONE 0
+#define _BEEP_FEATURE_ON 1
+#define _BEEP_FEATURE_OFF 2
+#define _BEEP_FEATURE_CHANGE 3
+#define _BEEP_SLOW_WARN 4
+#define _BEEP_SLOW_PRESS 5
+#define _BEEP_SLOW_ACCEPT 6
+#define _BEEP_SLOW_REJECT 7
+#define _BEEP_SLOW_RELEASE 8
+#define _BEEP_STICKY_LATCH 9
+#define _BEEP_STICKY_LOCK 10
+#define _BEEP_STICKY_UNLOCK 11
+#define _BEEP_LED_ON 12
+#define _BEEP_LED_OFF 13
+#define _BEEP_LED_CHANGE 14
+#define _BEEP_BOUNCE_REJECT 15
+
+typedef struct _XkbSrvInfo {
+ XkbStateRec prev_state;
+ XkbStateRec state;
+ XkbDescPtr desc;
+
+ DeviceIntPtr device;
+ KbdCtrlProcPtr kbdProc;
+
+ XkbRadioGroupPtr radioGroups;
+ CARD8 nRadioGroups;
+ CARD8 clearMods;
+ CARD8 setMods;
+ INT16 groupChange;
+
+ CARD16 dfltPtrDelta;
+
+ double mouseKeysCurve;
+ double mouseKeysCurveFactor;
+ INT16 mouseKeysDX;
+ INT16 mouseKeysDY;
+ CARD8 mouseKeysFlags;
+ Bool mouseKeysAccel;
+ CARD8 mouseKeysCounter;
+
+ CARD8 lockedPtrButtons;
+ CARD8 shiftKeyCount;
+ KeyCode mouseKey;
+ KeyCode inactiveKey;
+ KeyCode slowKey;
+ KeyCode repeatKey;
+ CARD8 krgTimerActive;
+ CARD8 beepType;
+ CARD8 beepCount;
+
+ CARD32 flags;
+ CARD32 lastPtrEventTime;
+ CARD32 lastShiftEventTime;
+ OsTimerPtr beepTimer;
+ OsTimerPtr mouseKeyTimer;
+ OsTimerPtr slowKeysTimer;
+ OsTimerPtr bounceKeysTimer;
+ OsTimerPtr repeatKeyTimer;
+ OsTimerPtr krgTimer;
+} XkbSrvInfoRec, *XkbSrvInfoPtr;
+
+#define XkbSLI_IsDefault (1L<<0)
+#define XkbSLI_HasOwnState (1L<<1)
+
+typedef struct _XkbSrvLedInfo {
+ CARD16 flags;
+ CARD16 class;
+ CARD16 id;
+ union {
+ KbdFeedbackPtr kf;
+ LedFeedbackPtr lf;
+ } fb;
+
+ CARD32 physIndicators;
+ CARD32 autoState;
+ CARD32 explicitState;
+ CARD32 effectiveState;
+
+ CARD32 mapsPresent;
+ CARD32 namesPresent;
+ XkbIndicatorMapPtr maps;
+ Atom * names;
+
+ CARD32 usesBase;
+ CARD32 usesLatched;
+ CARD32 usesLocked;
+ CARD32 usesEffective;
+ CARD32 usesCompat;
+ CARD32 usesControls;
+
+ CARD32 usedComponents;
+} XkbSrvLedInfoRec, *XkbSrvLedInfoPtr;
+
+/*
+ * Settings for xkbClientFlags field (used by DIX)
+ * These flags _must_ not overlap with XkbPCF_*
+ */
+#define _XkbClientInitialized (1<<15)
+
+#define _XkbWantsDetectableAutoRepeat(c)\
+ ((c)->xkbClientFlags&XkbPCF_DetectableAutoRepeatMask)
+
+/*
+ * Settings for flags field
+ */
+#define _XkbStateNotifyInProgress (1<<0)
+
+typedef struct
+{
+ ProcessInputProc processInputProc;
+ ProcessInputProc realInputProc;
+ DeviceUnwrapProc unwrapProc;
+} xkbDeviceInfoRec, *xkbDeviceInfoPtr;
+
+#define WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \
+ device->public.processInputProc = proc; \
+ oldprocs->processInputProc = \
+ oldprocs->realInputProc = device->public.realInputProc; \
+ device->public.realInputProc = proc; \
+ oldprocs->unwrapProc = device->unwrapProc; \
+ device->unwrapProc = unwrapproc;
+
+#define COND_WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \
+ if (device->public.processInputProc == device->public.realInputProc)\
+ device->public.processInputProc = proc; \
+ oldprocs->processInputProc = \
+ oldprocs->realInputProc = device->public.realInputProc; \
+ device->public.realInputProc = proc; \
+ oldprocs->unwrapProc = device->unwrapProc; \
+ device->unwrapProc = unwrapproc;
+
+#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs) \
+ device->public.processInputProc = oldprocs->processInputProc; \
+ device->public.realInputProc = oldprocs->realInputProc; \
+ device->unwrapProc = oldprocs->unwrapProc;
+
+#define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr) (dev)->devPrivates[xkbDevicePrivateIndex].ptr)
+
+/***====================================================================***/
+
+
+/***====================================================================***/
+
+#define XkbAX_KRGMask (XkbSlowKeysMask|XkbBounceKeysMask)
+#define XkbAllFilteredEventsMask \
+ (XkbAccessXKeysMask|XkbRepeatKeysMask|XkbMouseKeysAccelMask|XkbAX_KRGMask)
+
+/***====================================================================***/
+
+extern int XkbReqCode;
+extern int XkbEventBase;
+extern int XkbKeyboardErrorCode;
+extern int XkbDisableLockActions;
+extern char * XkbBaseDirectory;
+extern char * XkbBinDirectory;
+extern char * XkbInitialMap;
+extern int _XkbClientMajor;
+extern int _XkbClientMinor;
+extern unsigned int XkbXIUnsupported;
+
+extern char * XkbModelUsed,*XkbLayoutUsed,*XkbVariantUsed,*XkbOptionsUsed;
+extern Bool noXkbExtension;
+extern Bool XkbWantRulesProp;
+
+extern void * XkbLastRepeatEvent;
+
+extern CARD32 xkbDebugFlags;
+extern CARD32 xkbDebugCtrls;
+
+
+#define _XkbAlloc(s) malloc((s))
+#define _XkbCalloc(n,s) calloc((n), (s))
+#define _XkbRealloc(o,s) realloc((o),(s))
+#define _XkbTypedAlloc(t) ((t *)malloc(sizeof(t)))
+#define _XkbTypedCalloc(n,t) ((t *)calloc((n), sizeof(t)))
+#define _XkbTypedRealloc(o,n,t) \
+ ((o)?(t *)realloc((o),(n)*sizeof(t)):_XkbTypedCalloc(n,t))
+#define _XkbClearElems(a,f,l,t) bzero(&(a)[f],((l)-(f)+1)*sizeof(t))
+#define _XkbFree(p) free(p)
+
+
+#define _XkbLibError(c,l,d) \
+ { _XkbErrCode= (c); _XkbErrLocation= (l); _XkbErrData= (d); }
+#define _XkbErrCode2(a,b) ((XID)((((unsigned int)(a))<<24)|((b)&0xffffff)))
+#define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c))
+#define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d)))
+
+extern int DeviceKeyPress,DeviceKeyRelease;
+extern int DeviceButtonPress,DeviceButtonRelease;
+
+#ifdef XINPUT
+#define _XkbIsPressEvent(t) (((t)==KeyPress)||((t)==DeviceKeyPress))
+#define _XkbIsReleaseEvent(t) (((t)==KeyRelease)||((t)==DeviceKeyRelease))
+#else
+#define _XkbIsPressEvent(t) ((t)==KeyPress)
+#define _XkbIsReleaseEvent(t) ((t)==KeyRelease)
+#endif
+
+#define _XkbCoreKeycodeInRange(c,k) (((k)>=(c)->curKeySyms.minKeyCode)&&\
+ ((k)<=(c)->curKeySyms.maxKeyCode))
+#define _XkbCoreNumKeys(c) ((c)->curKeySyms.maxKeyCode-\
+ (c)->curKeySyms.minKeyCode+1)
+
+#define XConvertCase(s,l,u) XkbConvertCase(s,l,u)
+#undef IsKeypadKey
+#define IsKeypadKey(s) XkbKSIsKeypad(s)
+
+#define Status int
+#define XPointer void *
+#define Display struct _XDisplay
+
+#ifndef True
+#define True 1
+#define False 0
+#endif
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+_XFUNCPROTOBEGIN
+
+extern void XkbUseMsg(
+ void
+);
+
+extern int XkbProcessArguments(
+ int /* argc */,
+ char ** /* argv */,
+ int /* i */
+);
+
+extern void XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc);
+
+extern void XkbFreeCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern void XkbFreeNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern DeviceIntPtr _XkbLookupAnyDevice(
+ int /* id */,
+ int * /* why_rtrn */
+);
+
+extern DeviceIntPtr _XkbLookupKeyboard(
+ int /* id */,
+ int * /* why_rtrn */
+);
+
+extern DeviceIntPtr _XkbLookupBellDevice(
+ int /* id */,
+ int * /* why_rtrn */
+);
+
+extern DeviceIntPtr _XkbLookupLedDevice(
+ int /* id */,
+ int * /* why_rtrn */
+);
+
+extern DeviceIntPtr _XkbLookupButtonDevice(
+ int /* id */,
+ int * /* why_rtrn */
+);
+
+extern XkbDescPtr XkbAllocKeyboard(
+ void
+);
+
+extern Status XkbAllocClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nTypes */
+);
+
+extern Status XkbAllocServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nNewActions */
+);
+
+extern void XkbFreeClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern void XkbFreeServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern Status XkbAllocIndicatorMaps(
+ XkbDescPtr /* xkb */
+);
+
+extern Status XkbAllocCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nInterpret */
+);
+
+extern Status XkbAllocNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ int /* nTotalRG */,
+ int /* nTotalAliases */
+);
+
+extern Status XkbAllocControls(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which*/
+);
+
+extern Status XkbCopyKeyType(
+ XkbKeyTypePtr /* from */,
+ XkbKeyTypePtr /* into */
+);
+
+extern Status XkbCopyKeyTypes(
+ XkbKeyTypePtr /* from */,
+ XkbKeyTypePtr /* into */,
+ int /* num_types */
+);
+
+extern Status XkbResizeKeyType(
+ XkbDescPtr /* xkb */,
+ int /* type_ndx */,
+ int /* map_count */,
+ Bool /* want_preserve */,
+ int /* new_num_lvls */
+);
+
+extern void XkbFreeKeyboard(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeDesc */
+);
+
+extern void XkbSetActionKeyMods(
+ XkbDescPtr /* xkb */,
+ XkbAction * /* act */,
+ unsigned int /* mods */
+);
+
+extern Bool XkbCheckActionVMods(
+ XkbDescPtr /* xkb */,
+ XkbAction * /* act */,
+ unsigned int /* changed */
+);
+
+extern Bool XkbApplyVModChanges(
+ XkbSrvInfoPtr /* xkbi */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* pChanges */,
+ unsigned int * /* needChecksRtrn */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbApplyVModChangesToAllDevices(
+ DeviceIntPtr /* dev */,
+ XkbDescPtr /* xkb */,
+ unsigned int /* changed */,
+ XkbEventCausePtr /* cause */
+);
+
+extern unsigned int XkbMaskForVMask(
+ XkbDescPtr /* xkb */,
+ unsigned int /* vmask */
+);
+
+extern Bool XkbVirtualModsToReal(
+ XkbDescPtr /* xkb */,
+ unsigned int /* virtua_mask */,
+ unsigned int * /* mask_rtrn */
+);
+
+extern unsigned int XkbAdjustGroup(
+ int /* group */,
+ XkbControlsPtr /* ctrls */
+);
+
+extern KeySym *XkbResizeKeySyms(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* needed */
+);
+
+extern XkbAction *XkbResizeKeyActions(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* needed */
+);
+
+extern void XkbUpdateKeyTypesFromCore(
+ DeviceIntPtr /* pXDev */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* pChanges */
+);
+
+extern void XkbUpdateDescActions(
+ XkbDescPtr /* xkb */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* changes */
+);
+
+extern void XkbUpdateActions(
+ DeviceIntPtr /* pXDev */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* pChanges */,
+ unsigned int * /* needChecksRtrn */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbUpdateCoreDescription(
+ DeviceIntPtr /* keybd */,
+ Bool /* resize */
+);
+
+extern void XkbApplyMappingChange(
+ DeviceIntPtr /* pXDev */,
+ CARD8 /* request */,
+ KeyCode /* firstKey */,
+ CARD8 /* num */,
+ ClientPtr /* client */
+);
+
+extern void XkbSetIndicators(
+ DeviceIntPtr /* pXDev */,
+ CARD32 /* affect */,
+ CARD32 /* values */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbUpdateIndicators(
+ DeviceIntPtr /* keybd */,
+ CARD32 /* changed */,
+ Bool /* check_edevs */,
+ XkbChangesPtr /* pChanges */,
+ XkbEventCausePtr /* cause */
+);
+
+extern XkbSrvLedInfoPtr XkbAllocSrvLedInfo(
+ DeviceIntPtr /* dev */,
+ KbdFeedbackPtr /* kf */,
+ LedFeedbackPtr /* lf */,
+ unsigned int /* needed_parts */
+);
+
+extern XkbSrvLedInfoPtr XkbFindSrvLedInfo(
+ DeviceIntPtr /* dev */,
+ unsigned int /* class */,
+ unsigned int /* id */,
+ unsigned int /* needed_parts */
+);
+
+extern void XkbApplyLedNameChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_names */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbApplyLedMapChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_maps */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbApplyLedStateChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_leds */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbUpdateLedAutoState(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* maps_to_check */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbFlushLedEvents(
+ DeviceIntPtr /* dev */,
+ DeviceIntPtr /* kbd */,
+ XkbSrvLedInfoPtr /* sli */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbUpdateAllDeviceIndicators(
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern unsigned int XkbIndicatorsToUpdate(
+ DeviceIntPtr /* dev */,
+ unsigned long /* state_changes */,
+ Bool /* enabled_ctrl_changes */
+);
+
+extern void XkbComputeDerivedState(
+ XkbSrvInfoPtr /* xkbi */
+);
+
+extern void XkbCheckSecondaryEffects(
+ XkbSrvInfoPtr /* xkbi */,
+ unsigned int /* which */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbCheckIndicatorMaps(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* which */
+);
+
+extern unsigned int XkbStateChangedFlags(
+ XkbStatePtr /* old */,
+ XkbStatePtr /* new */
+);
+
+extern void XkbSendStateNotify(
+ DeviceIntPtr /* kbd */,
+ xkbStateNotify * /* pSN */
+);
+
+extern void XkbSendMapNotify(
+ DeviceIntPtr /* kbd */,
+ xkbMapNotify * /* ev */
+);
+
+extern int XkbComputeControlsNotify(
+ DeviceIntPtr /* kbd */,
+ XkbControlsPtr /* old */,
+ XkbControlsPtr /* new */,
+ xkbControlsNotify * /* pCN */,
+ Bool /* forceCtrlProc */
+);
+
+extern void XkbSendControlsNotify(
+ DeviceIntPtr /* kbd */,
+ xkbControlsNotify * /* ev */
+);
+
+extern void XkbSendCompatMapNotify(
+ DeviceIntPtr /* kbd */,
+ xkbCompatMapNotify * /* ev */
+);
+
+extern void XkbSendIndicatorNotify(
+ DeviceIntPtr /* kbd */,
+ int /* xkbType */,
+ xkbIndicatorNotify * /* ev */
+);
+
+extern void XkbHandleBell(
+ BOOL /* force */,
+ BOOL /* eventOnly */,
+ DeviceIntPtr /* kbd */,
+ CARD8 /* percent */,
+ void * /* ctrl */,
+ CARD8 /* class */,
+ Atom /* name */,
+ WindowPtr /* pWin */,
+ ClientPtr /* pClient */
+);
+
+extern void XkbSendAccessXNotify(
+ DeviceIntPtr /* kbd */,
+ xkbAccessXNotify * /* pEv */
+);
+
+extern void XkbSendNamesNotify(
+ DeviceIntPtr /* kbd */,
+ xkbNamesNotify * /* ev */
+);
+
+extern void XkbSendCompatNotify(
+ DeviceIntPtr /* kbd */,
+ xkbCompatMapNotify * /* ev */
+);
+
+extern void XkbSendActionMessage(
+ DeviceIntPtr /* kbd */,
+ xkbActionMessage * /* ev */
+);
+
+extern void XkbSendExtensionDeviceNotify(
+ DeviceIntPtr /* kbd */,
+ ClientPtr /* client */,
+ xkbExtensionDeviceNotify * /* ev */
+);
+
+extern void XkbSendNotification(
+ DeviceIntPtr /* kbd */,
+ XkbChangesPtr /* pChanges */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbProcessKeyboardEvent(
+ struct _xEvent * /* xE */,
+ DeviceIntPtr /* keybd */,
+ int /* count */
+);
+
+extern void XkbProcessOtherEvent(
+ struct _xEvent * /* xE */,
+ DeviceIntPtr /* keybd */,
+ int /* count */
+);
+
+extern void XkbHandleActions(
+ DeviceIntPtr /* dev */,
+ DeviceIntPtr /* kbd */,
+ struct _xEvent * /* xE */,
+ int /* count */
+);
+
+extern Bool XkbEnableDisableControls(
+ XkbSrvInfoPtr /* xkbi */,
+ unsigned long /* change */,
+ unsigned long /* newValues */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void AccessXInit(
+ DeviceIntPtr /* dev */
+);
+
+extern Bool AccessXFilterPressEvent(
+ register struct _xEvent * /* xE */,
+ register DeviceIntPtr /* keybd */,
+ int /* count */
+);
+
+extern Bool AccessXFilterReleaseEvent(
+ register struct _xEvent * /* xE */,
+ register DeviceIntPtr /* keybd */,
+ int /* count */
+);
+
+extern void AccessXCancelRepeatKey(
+ XkbSrvInfoPtr /* xkbi */,
+ KeyCode /* key */
+);
+
+extern void AccessXComputeCurveFactor(
+ XkbSrvInfoPtr /* xkbi */,
+ XkbControlsPtr /* ctrls */
+);
+
+extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* ledClass */,
+ unsigned int /* ledId */
+);
+
+extern XkbDeviceInfoPtr XkbAllocDeviceInfo(
+ unsigned int /* deviceSpec */,
+ unsigned int /* nButtons */,
+ unsigned int /* szLeds */
+);
+
+extern void XkbFreeDeviceInfo(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* which */,
+ Bool /* freeDevI */
+);
+
+extern Status XkbResizeDeviceButtonActions(
+ XkbDeviceInfoPtr /* devi */,
+ unsigned int /* newTotal */
+);
+
+extern XkbInterestPtr XkbFindClientResource(
+ DevicePtr /* inDev */,
+ ClientPtr /* client */
+);
+
+extern XkbInterestPtr XkbAddClientResource(
+ DevicePtr /* inDev */,
+ ClientPtr /* client */,
+ XID /* id */
+);
+
+extern int XkbRemoveClient(
+ DevicePtr /* inDev */,
+ ClientPtr /* client */
+);
+
+extern int XkbRemoveResourceClient(
+ DevicePtr /* inDev */,
+ XID /* id */
+);
+
+extern int XkbDDXInitDevice(
+ DeviceIntPtr /* dev */
+);
+
+extern int XkbDDXAccessXBeep(
+ DeviceIntPtr /* dev */,
+ unsigned int /* what */,
+ unsigned int /* which */
+);
+
+extern void XkbDDXKeyClick(
+ DeviceIntPtr /* dev */,
+ int /* keycode */,
+ int /* synthetic */
+);
+
+extern int XkbDDXUsesSoftRepeat(
+ DeviceIntPtr /* dev */
+);
+
+extern void XkbDDXKeybdCtrlProc(
+ DeviceIntPtr /* dev */,
+ KeybdCtrl * /* ctrl */
+);
+
+extern void XkbDDXChangeControls(
+ DeviceIntPtr /* dev */,
+ XkbControlsPtr /* old */,
+ XkbControlsPtr /* new */
+);
+
+extern void XkbDDXUpdateIndicators(
+ DeviceIntPtr /* keybd */,
+ CARD32 /* newState */
+);
+
+extern void XkbDDXUpdateDeviceIndicators(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ CARD32 /* newState */
+);
+
+extern void XkbDDXFakePointerButton(
+ int /* event */,
+ int /* button */
+);
+
+extern void XkbDDXFakePointerMotion(
+ unsigned int /* flags */,
+ int /* x */,
+ int /* y */
+);
+
+extern void XkbDDXFakeDeviceButton(
+ DeviceIntPtr /* dev */,
+ Bool /* press */,
+ int /* button */
+);
+
+extern int XkbDDXTerminateServer(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern int XkbDDXSwitchScreen(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern int XkbDDXPrivate(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern void XkbDisableComputedAutoRepeats(
+ DeviceIntPtr /* pXDev */,
+ unsigned int /* key */
+);
+
+extern void XkbSetRepeatKeys(
+ DeviceIntPtr /* pXDev */,
+ int /* key */,
+ int /* onoff */
+);
+
+extern int XkbLatchModifiers(
+ DeviceIntPtr /* pXDev */,
+ CARD8 /* mask */,
+ CARD8 /* latches */
+);
+
+extern int XkbLatchGroup(
+ DeviceIntPtr /* pXDev */,
+ int /* group */
+);
+
+extern void XkbClearAllLatchesAndLocks(
+ DeviceIntPtr /* dev */,
+ XkbSrvInfoPtr /* xkbi */,
+ Bool /* genEv */,
+ XkbEventCausePtr /* cause */
+);
+
+extern void XkbSetRulesDflts(
+ char * /* rulesFile */,
+ char * /* model */,
+ char * /* layout */,
+ char * /* variant */,
+ char * /* options */
+);
+
+extern void XkbInitDevice(
+ DeviceIntPtr /* pXDev */
+);
+
+extern Bool XkbInitKeyboardDeviceStruct(
+ DeviceIntPtr /* pXDev */,
+ XkbComponentNamesPtr /* pNames */,
+ KeySymsPtr /* pSyms */,
+ CARD8 /* pMods */[],
+ BellProcPtr /* bellProc */,
+ KbdCtrlProcPtr /* ctrlProc */
+);
+
+extern int SProcXkbDispatch(
+ ClientPtr /* client */
+);
+
+extern XkbGeometryPtr XkbLookupNamedGeometry(
+ DeviceIntPtr /* dev */,
+ Atom /* name */,
+ Bool * /* shouldFree */
+);
+
+extern void XkbConvertCase(
+ KeySym /* sym */,
+ KeySym * /* lower */,
+ KeySym * /* upper */
+);
+
+extern Status XkbChangeKeycodeRange(
+ XkbDescPtr /* xkb */,
+ int /* minKC */,
+ int /* maxKC */,
+ XkbChangesPtr /* changes */
+);
+
+extern int XkbFinishDeviceInit(
+ DeviceIntPtr /* pXDev */
+);
+
+extern void XkbFreeSrvLedInfo(
+ XkbSrvLedInfoPtr /* sli */
+);
+
+extern void XkbFreeInfo(
+ XkbSrvInfoPtr /* xkbi */
+);
+
+extern Status XkbChangeTypesOfKey(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* nGroups */,
+ unsigned int /* groups */,
+ int * /* newTypesIn */,
+ XkbMapChangesPtr /* changes */
+);
+
+extern XkbKeyTypePtr XkbAddKeyType(
+ XkbDescPtr /* xkb */,
+ Atom /* name */,
+ int /* map_count */,
+ Bool /* want_preserve */,
+ int /* num_lvls */
+);
+
+extern Status XkbInitCanonicalKeyTypes(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ int /* keypadVMod */
+);
+
+extern int XkbKeyTypesForCoreSymbols(
+ XkbDescPtr /* xkb */,
+ int /* map_width */,
+ KeySym * /* core_syms */,
+ unsigned int /* protected */,
+ int * /* types_inout */,
+ KeySym * /* xkb_syms_rtrn */
+);
+
+extern Bool XkbApplyCompatMapToKey(
+ XkbDescPtr /* xkb */,
+ KeyCode /* key */,
+ XkbChangesPtr /* changes */
+);
+
+extern Bool XkbUpdateMapFromCore(
+ XkbDescPtr /* xkb */,
+ KeyCode /* first_key */,
+ int /* num_keys */,
+ int /* map_width */,
+ KeySym * /* core_keysyms */,
+ XkbChangesPtr /* changes */
+);
+
+extern void XkbFreeControls(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern void XkbFreeIndicatorMaps(
+ XkbDescPtr /* xkb */
+);
+
+extern Bool XkbApplyVirtualModChanges(
+ XkbDescPtr /* xkb */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* changes */
+);
+
+extern Bool XkbUpdateActionVirtualMods(
+ XkbDescPtr /* xkb */,
+ XkbAction * /* act */,
+ unsigned int /* changed */
+);
+
+extern void XkbUpdateKeyTypeVirtualMods(
+ XkbDescPtr /* xkb */,
+ XkbKeyTypePtr /* type */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* changes */
+);
+
+extern void XkbSendNewKeyboardNotify(
+ DeviceIntPtr /* kbd */,
+ xkbNewKeyboardNotify * /* pNKN */
+);
+
+
+#include <nx-X11/extensions/XKMformat.h>
+#include "xkbfile.h"
+#include "xkbrules.h"
+
+#define _XkbListKeymaps 0
+#define _XkbListKeycodes 1
+#define _XkbListTypes 2
+#define _XkbListCompat 3
+#define _XkbListSymbols 4
+#define _XkbListGeometry 5
+#define _XkbListNumComponents 6
+
+typedef struct _XkbSrvListInfo {
+ int szPool;
+ int nPool;
+ char * pool;
+
+ int maxRtrn;
+ int nTotal;
+
+ char * pattern[_XkbListNumComponents];
+ int nFound[_XkbListNumComponents];
+} XkbSrvListInfoRec,*XkbSrvListInfoPtr;
+
+char *
+XkbGetRulesDflts(
+ XkbRF_VarDefsPtr /* defs */
+);
+
+extern void XkbSetRulesUsed(
+ XkbRF_VarDefsPtr /* defs */
+);
+
+
+extern Status XkbDDXList(
+ DeviceIntPtr /* dev */,
+ XkbSrvListInfoPtr /* listing */,
+ ClientPtr /* client */
+);
+
+extern unsigned int XkbDDXLoadKeymapByNames(
+ DeviceIntPtr /* keybd */,
+ XkbComponentNamesPtr /* names */,
+ unsigned int /* want */,
+ unsigned int /* need */,
+ XkbFileInfoPtr /* finfoRtrn */,
+ char * /* keymapNameRtrn */,
+ int /* keymapNameRtrnLen */
+);
+
+extern Bool XkbDDXNamesFromRules(
+ DeviceIntPtr /* keybd */,
+ char * /* rules */,
+ XkbRF_VarDefsPtr /* defs */,
+ XkbComponentNamesPtr /* names */
+);
+
+extern FILE *XkbDDXOpenConfigFile(
+ char * /* mapName */,
+ char * /* fileNameRtrn */,
+ int /* fileNameRtrnLen */
+);
+
+extern Bool XkbDDXApplyConfig(
+ XPointer /* cfg_in */,
+ XkbSrvInfoPtr /* xkbi */
+);
+
+extern XPointer XkbDDXPreloadConfig(
+ char ** /* rulesFileRtrn */,
+ XkbRF_VarDefsPtr /* defs */,
+ XkbComponentNamesPtr /* names */,
+ DeviceIntPtr /* dev */
+);
+
+extern int _XkbStrCaseCmp(
+ char * /* str1 */,
+ char * /* str2 */
+);
+
+
+
+_XFUNCPROTOEND
+
+#endif /* _XKBSRV_H_ */
+
+
diff --git a/nx-X11/programs/Xserver/include/xkbstr.h b/nx-X11/programs/Xserver/include/xkbstr.h
new file mode 100644
index 000000000..f3c901805
--- /dev/null
+++ b/nx-X11/programs/Xserver/include/xkbstr.h
@@ -0,0 +1,608 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifndef _XKBSTR_H_
+#define _XKBSTR_H_
+
+#include <nx-X11/extensions/XKB.h>
+
+#define XkbCharToInt(v) ((v)&0x80?(int)((v)|(~0xff)):(int)((v)&0x7f))
+#define XkbIntTo2Chars(i,h,l) (((h)=((i>>8)&0xff)),((l)=((i)&0xff)))
+
+#define Xkb2CharsToInt(h,l) ((short)(((h)<<8)|(l)))
+
+ /*
+ * Common data structures and access macros
+ */
+
+typedef struct _XkbStateRec {
+ unsigned char group;
+ unsigned char locked_group;
+ unsigned short base_group;
+ unsigned short latched_group;
+ unsigned char mods;
+ unsigned char base_mods;
+ unsigned char latched_mods;
+ unsigned char locked_mods;
+ unsigned char compat_state;
+ unsigned char grab_mods;
+ unsigned char compat_grab_mods;
+ unsigned char lookup_mods;
+ unsigned char compat_lookup_mods;
+ unsigned short ptr_buttons;
+} XkbStateRec,*XkbStatePtr;
+#define XkbModLocks(s) ((s)->locked_mods)
+#define XkbStateMods(s) ((s)->base_mods|(s)->latched_mods|XkbModLocks(s))
+#define XkbGroupLock(s) ((s)->locked_group)
+#define XkbStateGroup(s) ((s)->base_group+(s)->latched_group+XkbGroupLock(s))
+#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods,(s)->group)
+#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods,(s)->group)
+
+typedef struct _XkbMods {
+ unsigned char mask; /* effective mods */
+ unsigned char real_mods;
+ unsigned short vmods;
+} XkbModsRec,*XkbModsPtr;
+
+typedef struct _XkbKTMapEntry {
+ Bool active;
+ unsigned char level;
+ XkbModsRec mods;
+} XkbKTMapEntryRec,*XkbKTMapEntryPtr;
+
+typedef struct _XkbKeyType {
+ XkbModsRec mods;
+ unsigned char num_levels;
+ unsigned char map_count;
+ XkbKTMapEntryPtr map;
+ XkbModsPtr preserve;
+ Atom name;
+ Atom * level_names;
+} XkbKeyTypeRec, *XkbKeyTypePtr;
+
+#define XkbNumGroups(g) ((g)&0x0f)
+#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0)
+#define XkbOutOfRangeGroupAction(g) ((g)&0xc0)
+#define XkbOutOfRangeGroupNumber(g) (((g)&0x30)>>4)
+#define XkbSetGroupInfo(g,w,n) (((w)&0xc0)|(((n)&3)<<4)|((g)&0x0f))
+#define XkbSetNumGroups(g,n) (((g)&0xf0)|((n)&0x0f))
+
+ /*
+ * Structures and access macros used primarily by the server
+ */
+
+typedef struct _XkbBehavior {
+ unsigned char type;
+ unsigned char data;
+} XkbBehavior;
+
+#define XkbAnyActionDataSize 7
+typedef struct _XkbAnyAction {
+ unsigned char type;
+ unsigned char data[XkbAnyActionDataSize];
+} XkbAnyAction;
+
+typedef struct _XkbModAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char mask;
+ unsigned char real_mods;
+ unsigned char vmods1;
+ unsigned char vmods2;
+} XkbModAction;
+#define XkbModActionVMods(a) \
+ ((short)(((a)->vmods1<<8)|((a)->vmods2)))
+#define XkbSetModActionVMods(a,v) \
+ (((a)->vmods1=(((v)>>8)&0xff)),(a)->vmods2=((v)&0xff))
+
+typedef struct _XkbGroupAction {
+ unsigned char type;
+ unsigned char flags;
+ char group_XXX;
+} XkbGroupAction;
+#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX))
+#define XkbSASetGroup(a,g) ((a)->group_XXX=(g))
+
+typedef struct _XkbISOAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char mask;
+ unsigned char real_mods;
+ char group_XXX;
+ unsigned char affect;
+ unsigned char vmods1;
+ unsigned char vmods2;
+} XkbISOAction;
+
+typedef struct _XkbPtrAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char high_XXX;
+ unsigned char low_XXX;
+ unsigned char high_YYY;
+ unsigned char low_YYY;
+} XkbPtrAction;
+#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX,(a)->low_XXX))
+#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY,(a)->low_YYY))
+#define XkbSetPtrActionX(a,x) (XkbIntTo2Chars(x,(a)->high_XXX,(a)->low_XXX))
+#define XkbSetPtrActionY(a,y) (XkbIntTo2Chars(y,(a)->high_YYY,(a)->low_YYY))
+
+typedef struct _XkbPtrBtnAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char count;
+ unsigned char button;
+} XkbPtrBtnAction;
+
+typedef struct _XkbPtrDfltAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char affect;
+ char valueXXX;
+} XkbPtrDfltAction;
+#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX))
+#define XkbSASetPtrDfltValue(a,c) ((a)->valueXXX= ((c)&0xff))
+
+typedef struct _XkbSwitchScreenAction {
+ unsigned char type;
+ unsigned char flags;
+ char screenXXX;
+} XkbSwitchScreenAction;
+#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX))
+#define XkbSASetScreen(a,s) ((a)->screenXXX= ((s)&0xff))
+
+typedef struct _XkbCtrlsAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char ctrls3;
+ unsigned char ctrls2;
+ unsigned char ctrls1;
+ unsigned char ctrls0;
+} XkbCtrlsAction;
+#define XkbActionSetCtrls(a,c) (((a)->ctrls3=(((c)>>24)&0xff)),\
+ ((a)->ctrls2=(((c)>>16)&0xff)),\
+ ((a)->ctrls1=(((c)>>8)&0xff)),\
+ ((a)->ctrls0=((c)&0xff)))
+#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3)<<24)|\
+ (((unsigned int)(a)->ctrls2)<<16)|\
+ (((unsigned int)(a)->ctrls1)<<8)|\
+ ((unsigned int)((a)->ctrls0)))
+
+typedef struct _XkbMessageAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char message[6];
+} XkbMessageAction;
+
+typedef struct _XkbRedirectKeyAction {
+ unsigned char type;
+ unsigned char new_key;
+ unsigned char mods_mask;
+ unsigned char mods;
+ unsigned char vmods_mask0;
+ unsigned char vmods_mask1;
+ unsigned char vmods0;
+ unsigned char vmods1;
+} XkbRedirectKeyAction;
+
+#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1)<<8)|\
+ ((unsigned int)(a)->vmods0))
+#define XkbSARedirectSetVMods(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\
+ ((a)->vmods_mask0=((m)&0xff)))
+#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1)<<8)|\
+ ((unsigned int)(a)->vmods_mask0))
+#define XkbSARedirectSetVModsMask(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\
+ ((a)->vmods_mask0=((m)&0xff)))
+
+typedef struct _XkbDeviceBtnAction {
+ unsigned char type;
+ unsigned char flags;
+ unsigned char count;
+ unsigned char button;
+ unsigned char device;
+} XkbDeviceBtnAction;
+
+typedef struct _XkbDeviceValuatorAction {
+ unsigned char type;
+ unsigned char device;
+ unsigned char v1_what;
+ unsigned char v1_ndx;
+ unsigned char v1_value;
+ unsigned char v2_what;
+ unsigned char v2_ndx;
+ unsigned char v2_value;
+} XkbDeviceValuatorAction;
+
+typedef union _XkbAction {
+ XkbAnyAction any;
+ XkbModAction mods;
+ XkbGroupAction group;
+ XkbISOAction iso;
+ XkbPtrAction ptr;
+ XkbPtrBtnAction btn;
+ XkbPtrDfltAction dflt;
+ XkbSwitchScreenAction screen;
+ XkbCtrlsAction ctrls;
+ XkbMessageAction msg;
+ XkbRedirectKeyAction redirect;
+ XkbDeviceBtnAction devbtn;
+ XkbDeviceValuatorAction devval;
+ unsigned char type;
+} XkbAction;
+
+typedef struct _XkbControls {
+ unsigned char mk_dflt_btn;
+ unsigned char num_groups;
+ unsigned char groups_wrap;
+ XkbModsRec internal;
+ XkbModsRec ignore_lock;
+ unsigned int enabled_ctrls;
+ unsigned short repeat_delay;
+ unsigned short repeat_interval;
+ unsigned short slow_keys_delay;
+ unsigned short debounce_delay;
+ unsigned short mk_delay;
+ unsigned short mk_interval;
+ unsigned short mk_time_to_max;
+ unsigned short mk_max_speed;
+ short mk_curve;
+ unsigned short ax_options;
+ unsigned short ax_timeout;
+ unsigned short axt_opts_mask;
+ unsigned short axt_opts_values;
+ unsigned int axt_ctrls_mask;
+ unsigned int axt_ctrls_values;
+ unsigned char per_key_repeat[XkbPerKeyBitArraySize];
+} XkbControlsRec, *XkbControlsPtr;
+
+#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls&XkbAccessXFeedbackMask)
+#define XkbAX_NeedOption(c,w) ((c)->ax_options&(w))
+#define XkbAX_NeedFeedback(c,w) (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w))
+
+typedef struct _XkbServerMapRec {
+ unsigned short num_acts;
+ unsigned short size_acts;
+ XkbAction *acts;
+
+ XkbBehavior *behaviors;
+ unsigned short *key_acts;
+#if defined(__cplusplus) || defined(c_plusplus)
+ /* explicit is a C++ reserved word */
+ unsigned char *c_explicit;
+#else
+ unsigned char *explicit;
+#endif
+ unsigned char vmods[XkbNumVirtualMods];
+ unsigned short *vmodmap;
+} XkbServerMapRec, *XkbServerMapPtr;
+
+#define XkbSMKeyActionsPtr(m,k) (&(m)->acts[(m)->key_acts[k]])
+
+ /*
+ * Structures and access macros used primarily by clients
+ */
+
+typedef struct _XkbSymMapRec {
+ unsigned char kt_index[XkbNumKbdGroups];
+ unsigned char group_info;
+ unsigned char width;
+ unsigned short offset;
+} XkbSymMapRec, *XkbSymMapPtr;
+
+typedef struct _XkbClientMapRec {
+ unsigned char size_types;
+ unsigned char num_types;
+ XkbKeyTypePtr types;
+
+ unsigned short size_syms;
+ unsigned short num_syms;
+ KeySym *syms;
+ XkbSymMapPtr key_sym_map;
+
+ unsigned char *modmap;
+} XkbClientMapRec, *XkbClientMapPtr;
+
+#define XkbCMKeyGroupInfo(m,k) ((m)->key_sym_map[k].group_info)
+#define XkbCMKeyNumGroups(m,k) (XkbNumGroups((m)->key_sym_map[k].group_info))
+#define XkbCMKeyGroupWidth(m,k,g) (XkbCMKeyType(m,k,g)->num_levels)
+#define XkbCMKeyGroupsWidth(m,k) ((m)->key_sym_map[k].width)
+#define XkbCMKeyTypeIndex(m,k,g) ((m)->key_sym_map[k].kt_index[g&0x3])
+#define XkbCMKeyType(m,k,g) (&(m)->types[XkbCMKeyTypeIndex(m,k,g)])
+#define XkbCMKeyNumSyms(m,k) (XkbCMKeyGroupsWidth(m,k)*XkbCMKeyNumGroups(m,k))
+#define XkbCMKeySymsOffset(m,k) ((m)->key_sym_map[k].offset)
+#define XkbCMKeySymsPtr(m,k) (&(m)->syms[XkbCMKeySymsOffset(m,k)])
+
+ /*
+ * Compatibility structures and access macros
+ */
+
+typedef struct _XkbSymInterpretRec {
+ KeySym sym;
+ unsigned char flags;
+ unsigned char match;
+ unsigned char mods;
+ unsigned char virtual_mod;
+ XkbAnyAction act;
+} XkbSymInterpretRec,*XkbSymInterpretPtr;
+
+typedef struct _XkbCompatMapRec {
+ XkbSymInterpretPtr sym_interpret;
+ XkbModsRec groups[XkbNumKbdGroups];
+ unsigned short num_si;
+ unsigned short size_si;
+} XkbCompatMapRec, *XkbCompatMapPtr;
+
+typedef struct _XkbIndicatorMapRec {
+ unsigned char flags;
+ unsigned char which_groups;
+ unsigned char groups;
+ unsigned char which_mods;
+ XkbModsRec mods;
+ unsigned int ctrls;
+} XkbIndicatorMapRec, *XkbIndicatorMapPtr;
+
+#define XkbIM_IsAuto(i) ((((i)->flags&XkbIM_NoAutomatic)==0)&&\
+ (((i)->which_groups&&(i)->groups)||\
+ ((i)->which_mods&&(i)->mods.mask)||\
+ ((i)->ctrls)))
+#define XkbIM_InUse(i) (((i)->flags)||((i)->which_groups)||\
+ ((i)->which_mods)||((i)->ctrls))
+
+
+typedef struct _XkbIndicatorRec {
+ unsigned long phys_indicators;
+ XkbIndicatorMapRec maps[XkbNumIndicators];
+} XkbIndicatorRec,*XkbIndicatorPtr;
+
+typedef struct _XkbKeyNameRec {
+ char name[XkbKeyNameLength];
+} XkbKeyNameRec,*XkbKeyNamePtr;
+
+typedef struct _XkbKeyAliasRec {
+ char real[XkbKeyNameLength];
+ char alias[XkbKeyNameLength];
+} XkbKeyAliasRec,*XkbKeyAliasPtr;
+
+ /*
+ * Names for everything
+ */
+typedef struct _XkbNamesRec {
+ Atom keycodes;
+ Atom geometry;
+ Atom symbols;
+ Atom types;
+ Atom compat;
+ Atom vmods[XkbNumVirtualMods];
+ Atom indicators[XkbNumIndicators];
+ Atom groups[XkbNumKbdGroups];
+ XkbKeyNamePtr keys;
+ XkbKeyAliasPtr key_aliases;
+ Atom *radio_groups;
+ Atom phys_symbols;
+
+ unsigned char num_keys;
+ unsigned char num_key_aliases;
+ unsigned short num_rg;
+} XkbNamesRec,*XkbNamesPtr;
+
+typedef struct _XkbGeometry *XkbGeometryPtr;
+ /*
+ * Tie it all together into one big keyboard description
+ */
+typedef struct _XkbDesc {
+ struct _XDisplay * dpy;
+ unsigned short flags;
+ unsigned short device_spec;
+ KeyCode min_key_code;
+ KeyCode max_key_code;
+
+ XkbControlsPtr ctrls;
+ XkbServerMapPtr server;
+ XkbClientMapPtr map;
+ XkbIndicatorPtr indicators;
+ XkbNamesPtr names;
+ XkbCompatMapPtr compat;
+ XkbGeometryPtr geom;
+} XkbDescRec, *XkbDescPtr;
+#define XkbKeyKeyTypeIndex(d,k,g) (XkbCMKeyTypeIndex((d)->map,k,g))
+#define XkbKeyKeyType(d,k,g) (XkbCMKeyType((d)->map,k,g))
+#define XkbKeyGroupWidth(d,k,g) (XkbCMKeyGroupWidth((d)->map,k,g))
+#define XkbKeyGroupsWidth(d,k) (XkbCMKeyGroupsWidth((d)->map,k))
+#define XkbKeyGroupInfo(d,k) (XkbCMKeyGroupInfo((d)->map,(k)))
+#define XkbKeyNumGroups(d,k) (XkbCMKeyNumGroups((d)->map,(k)))
+#define XkbKeyNumSyms(d,k) (XkbCMKeyNumSyms((d)->map,(k)))
+#define XkbKeySymsPtr(d,k) (XkbCMKeySymsPtr((d)->map,(k)))
+#define XkbKeySym(d,k,n) (XkbKeySymsPtr(d,k)[n])
+#define XkbKeySymEntry(d,k,sl,g) \
+ (XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))))
+#define XkbKeyAction(d,k,n) \
+ (XkbKeyHasActions(d,k)?&XkbKeyActionsPtr(d,k)[n]:NULL)
+#define XkbKeyActionEntry(d,k,sl,g) \
+ (XkbKeyHasActions(d,k)?\
+ XkbKeyAction(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))):NULL)
+
+#define XkbKeyHasActions(d,k) ((d)->server->key_acts[k]!=0)
+#define XkbKeyNumActions(d,k) (XkbKeyHasActions(d,k)?XkbKeyNumSyms(d,k):1)
+#define XkbKeyActionsPtr(d,k) (XkbSMKeyActionsPtr((d)->server,k))
+#define XkbKeycodeInRange(d,k) (((k)>=(d)->min_key_code)&&\
+ ((k)<=(d)->max_key_code))
+#define XkbNumKeys(d) ((d)->max_key_code-(d)->min_key_code+1)
+
+
+ /*
+ * The following structures can be used to track changes
+ * to a keyboard device
+ */
+typedef struct _XkbMapChanges {
+ unsigned short changed;
+ KeyCode min_key_code;
+ KeyCode max_key_code;
+ unsigned char first_type;
+ unsigned char num_types;
+ KeyCode first_key_sym;
+ unsigned char num_key_syms;
+ KeyCode first_key_act;
+ unsigned char num_key_acts;
+ KeyCode first_key_behavior;
+ unsigned char num_key_behaviors;
+ KeyCode first_key_explicit;
+ unsigned char num_key_explicit;
+ KeyCode first_modmap_key;
+ unsigned char num_modmap_keys;
+ KeyCode first_vmodmap_key;
+ unsigned char num_vmodmap_keys;
+ unsigned char pad;
+ unsigned short vmods;
+} XkbMapChangesRec,*XkbMapChangesPtr;
+
+typedef struct _XkbControlsChanges {
+ unsigned int changed_ctrls;
+ unsigned int enabled_ctrls_changes;
+ Bool num_groups_changed;
+} XkbControlsChangesRec,*XkbControlsChangesPtr;
+
+typedef struct _XkbIndicatorChanges {
+ unsigned int state_changes;
+ unsigned int map_changes;
+} XkbIndicatorChangesRec,*XkbIndicatorChangesPtr;
+
+typedef struct _XkbNameChanges {
+ unsigned int changed;
+ unsigned char first_type;
+ unsigned char num_types;
+ unsigned char first_lvl;
+ unsigned char num_lvls;
+ unsigned char num_aliases;
+ unsigned char num_rg;
+ unsigned char first_key;
+ unsigned char num_keys;
+ unsigned short changed_vmods;
+ unsigned long changed_indicators;
+ unsigned char changed_groups;
+} XkbNameChangesRec,*XkbNameChangesPtr;
+
+typedef struct _XkbCompatChanges {
+ unsigned char changed_groups;
+ unsigned short first_si;
+ unsigned short num_si;
+} XkbCompatChangesRec,*XkbCompatChangesPtr;
+
+typedef struct _XkbChanges {
+ unsigned short device_spec;
+ unsigned short state_changes;
+ XkbMapChangesRec map;
+ XkbControlsChangesRec ctrls;
+ XkbIndicatorChangesRec indicators;
+ XkbNameChangesRec names;
+ XkbCompatChangesRec compat;
+} XkbChangesRec, *XkbChangesPtr;
+
+ /*
+ * These data structures are used to construct a keymap from
+ * a set of components or to list components in the server
+ * database.
+ */
+typedef struct _XkbComponentNames {
+ char * keymap;
+ char * keycodes;
+ char * types;
+ char * compat;
+ char * symbols;
+ char * geometry;
+} XkbComponentNamesRec, *XkbComponentNamesPtr;
+
+typedef struct _XkbComponentName {
+ unsigned short flags;
+ char * name;
+} XkbComponentNameRec,*XkbComponentNamePtr;
+
+typedef struct _XkbComponentList {
+ int num_keymaps;
+ int num_keycodes;
+ int num_types;
+ int num_compat;
+ int num_symbols;
+ int num_geometry;
+ XkbComponentNamePtr keymaps;
+ XkbComponentNamePtr keycodes;
+ XkbComponentNamePtr types;
+ XkbComponentNamePtr compat;
+ XkbComponentNamePtr symbols;
+ XkbComponentNamePtr geometry;
+} XkbComponentListRec, *XkbComponentListPtr;
+
+ /*
+ * The following data structures describe and track changes to a
+ * non-keyboard extension device
+ */
+typedef struct _XkbDeviceLedInfo {
+ unsigned short led_class;
+ unsigned short led_id;
+ unsigned int phys_indicators;
+ unsigned int maps_present;
+ unsigned int names_present;
+ unsigned int state;
+ Atom names[XkbNumIndicators];
+ XkbIndicatorMapRec maps[XkbNumIndicators];
+} XkbDeviceLedInfoRec,*XkbDeviceLedInfoPtr;
+
+typedef struct _XkbDeviceInfo {
+ char * name;
+ Atom type;
+ unsigned short device_spec;
+ Bool has_own_state;
+ unsigned short supported;
+ unsigned short unsupported;
+
+ unsigned short num_btns;
+ XkbAction * btn_acts;
+
+ unsigned short sz_leds;
+ unsigned short num_leds;
+ unsigned short dflt_kbd_fb;
+ unsigned short dflt_led_fb;
+ XkbDeviceLedInfoPtr leds;
+} XkbDeviceInfoRec,*XkbDeviceInfoPtr;
+
+#define XkbXI_DevHasBtnActs(d) (((d)->num_btns>0)&&((d)->btn_acts!=NULL))
+#define XkbXI_LegalDevBtn(d,b) (XkbXI_DevHasBtnActs(d)&&((b)<(d)->num_btns))
+#define XkbXI_DevHasLeds(d) (((d)->num_leds>0)&&((d)->leds!=NULL))
+
+typedef struct _XkbDeviceLedChanges {
+ unsigned short led_class;
+ unsigned short led_id;
+ unsigned int defined; /* names or maps changed */
+ struct _XkbDeviceLedChanges *next;
+} XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr;
+
+typedef struct _XkbDeviceChanges {
+ unsigned int changed;
+ unsigned short first_btn;
+ unsigned short num_btns;
+ XkbDeviceLedChangesRec leds;
+} XkbDeviceChangesRec,*XkbDeviceChangesPtr;
+
+#endif /* _XKBSTR_H_ */
diff --git a/nx-X11/programs/Xserver/mi/Imakefile b/nx-X11/programs/Xserver/mi/Imakefile
new file mode 100644
index 000000000..15e897e8b
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/Imakefile
@@ -0,0 +1,202 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+NULL =
+
+#include <Server.tmpl>
+
+#if ! HasCbrt
+CBRT_SRC = cbrt.c
+CBRT_OBJ = cbrt.o
+#endif
+
+#if HasFfs
+FFS_DEFINES = -DHAS_FFS
+#endif
+
+MIINITEXTSRC = miinitext.c
+MIINITEXTOBJ = miinitext.o
+
+#if (!(defined(NXAgentServer) && NXAgentServer))
+NXAGENT_SKIP_SRCS = \
+ miexpose.c \
+ $(NULL)
+NXAGENT_SKIP_OBJS = \
+ miexpose.o \
+ $(NULL)
+#endif
+
+SRCS = $(CBRT_SRC) \
+ mivaltree.c \
+ mipolyseg.c \
+ mipolyrect.c \
+ mipoly.c \
+ mipolycon.c \
+ mipolygen.c \
+ mipolyutil.c \
+ mifillrct.c \
+ miwideline.c \
+ mispans.c \
+ miarc.c \
+ mizerarc.c \
+ mifillarc.c \
+ miwindow.c \
+ micursor.c \
+ mipolytext.c \
+ mibitblt.c \
+ mipolypnt.c \
+ mipushpxl.c \
+ miglblt.c \
+ mizerline.c \
+ mizerclip.c \
+ mifpolycon.c \
+ midash.c \
+ mibstore.c \
+ $(MIINITEXTSRC) \
+ mieq.c \
+ mipointer.c \
+ misprite.c \
+ midispcur.c \
+ miscrinit.c \
+ miclipn.c \
+ migc.c \
+ micmap.c \
+ mioverlay.c \
+ $(NXAGENT_SKIP_SRCS) \
+ $(NULL)
+
+OBJS = $(CBRT_OBJ) \
+ mivaltree.o \
+ mipolyseg.o \
+ mipolyrect.o \
+ mipoly.o \
+ mipolycon.o \
+ mipolygen.o \
+ mipolyutil.o \
+ mifillrct.o \
+ miwideline.o \
+ mispans.o \
+ miarc.o \
+ mizerarc.o \
+ mifillarc.o \
+ miwindow.o \
+ micursor.o \
+ mipolytext.o \
+ mibitblt.o \
+ mipolypnt.o \
+ mipushpxl.o \
+ miglblt.o \
+ mizerline.o \
+ mizerclip.o \
+ mifpolycon.o \
+ midash.o \
+ mibstore.o \
+ $(MIINITEXTOBJ) \
+ mieq.o \
+ mipointer.o \
+ misprite.o \
+ midispcur.o \
+ miscrinit.o \
+ miclipn.o \
+ migc.o \
+ micmap.o \
+ mioverlay.o \
+ $(NXAGENT_SKIP_OBJS) \
+ $(NULL)
+
+#if defined(XorgVersion)
+/*
+ * Make sure XINPUT, XF86VidTune, etc aren't defined for the miinitext.o
+ * used by Xnest, Xvfb
+ */
+
+#if NXLibraries
+
+/*
+ * To build the NX agent we need the XINPUT symbol
+ * in order to build the XInputExtension, since we
+ * don't use the XF86 module loader.
+ */
+EXT_DEFINES = ExtensionDefines \
+ $(NULL)
+#else
+EXT_DEFINES = ExtensionDefines \
+ -UXINPUT \
+ $(NULL)
+#endif
+
+#endif
+
+INCLUDES = -I. \
+ -I../include \
+ -I../render \
+ -I../xfixes \
+ -I../damageext \
+ -I../miext/damage \
+ -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/Xext \
+ `pkg-config --cflags-only-I pixman-1` \
+ $(NULL)
+
+LINTLIBS = \
+ ../dix/llib-ldix.ln \
+ ../os/llib-los.ln \
+ $(NULL)
+
+DEFINES = $(FFS_DEFINES)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(mi,$(OBJS))
+LintLibraryTarget(mi,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#ifndef Win32Architecture
+NormalLibraryTarget(cbrt,cbrt.o)
+#endif
+
+SpecialCObjectRule(miinitext,$(ICONFIGFILES),$(EXT_DEFINES))
+SpecialCObjectRule(miscrinit,$(ICONFIGFILES),$(EXT_DEFINES))
+
+#ifdef ItsyCompilerBug
+SpecialCObjectRule(mipolycon,$(_NOOP_),-O0)
+#endif
+#if defined(OpenBSDArchitecture) && defined(Sparc64Architecture)
+SpecialCObjectRule(mizerclip,NullParameter,-O0)
+#endif
+
+AllTarget($(EXTRAMIINITEXTOBJ))
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(mi.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mibstore.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(micmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(migc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(miline.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mipointer.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mipointrst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mizerarc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(micoord.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/mi/cbrt.c b/nx-X11/programs/Xserver/mi/cbrt.c
new file mode 100644
index 000000000..c703fd9d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/cbrt.c
@@ -0,0 +1,46 @@
+/*
+
+Copyright 1990, 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.
+
+*/
+
+/* simple cbrt, in case your math library doesn't have a good one */
+
+/*
+ * Would normally include <math.h> for this, but for the sake of compiler
+ * warnings, we don't want to get duplicate declarations for cbrt().
+ */
+
+double pow(double, double);
+double cbrt(double);
+
+double
+cbrt(double x)
+{
+ if (x > 0.0)
+ return pow(x, 1.0/3.0);
+ else
+ return -pow(-x, 1.0/3.0);
+}
diff --git a/nx-X11/programs/Xserver/mi/mi.h b/nx-X11/programs/Xserver/mi/mi.h
new file mode 100644
index 000000000..409e21e34
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mi.h
@@ -0,0 +1,639 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef MI_H
+#define MI_H
+#include <nx-X11/X.h>
+#include "region.h"
+#include "validate.h"
+#include "window.h"
+#include "gc.h"
+#include <X11/fonts/font.h>
+#include "input.h"
+#include "cursor.h"
+
+#define MiBits CARD32
+
+typedef struct _miDash *miDashPtr;
+#define EVEN_DASH 0
+#define ODD_DASH ~0
+
+/* miarc.c */
+
+extern void miPolyArc(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+);
+
+/* mibitblt.c */
+
+extern RegionPtr miCopyArea(
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*xIn*/,
+ int /*yIn*/,
+ int /*widthSrc*/,
+ int /*heightSrc*/,
+ int /*xOut*/,
+ int /*yOut*/
+);
+
+extern void miOpqStipDrawable(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ RegionPtr /*prgnSrc*/,
+ MiBits * /*pbits*/,
+ int /*srcx*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/
+);
+
+extern RegionPtr miCopyPlane(
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+);
+
+extern void miGetImage(
+ DrawablePtr /*pDraw*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+);
+
+extern void miPutImage(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pImage*/
+);
+
+/* miclipn.c */
+
+extern void miClipNotify(
+ void (* /*func*/)(
+ WindowPtr /* pWin */,
+ int /* dx */,
+ int /* dy */
+ )
+);
+
+/* micursor.c */
+
+extern void miRecolorCursor(
+ ScreenPtr /*pScr*/,
+ CursorPtr /*pCurs*/,
+ Bool /*displayed*/
+);
+
+/* midash.c */
+
+extern miDashPtr miDashLine(
+ int /*npt*/,
+ DDXPointPtr /*ppt*/,
+ unsigned int /*nDash*/,
+ unsigned char * /*pDash*/,
+ unsigned int /*offset*/,
+ int * /*pnseg*/
+);
+
+extern void miStepDash(
+ int /*dist*/,
+ int * /*pDashIndex*/,
+ unsigned char * /*pDash*/,
+ int /*numInDashList*/,
+ int * /*pDashOffset*/
+);
+
+/* mieq.c */
+
+
+#ifndef INPUT_H
+typedef struct _DeviceRec *DevicePtr;
+#endif
+
+extern Bool mieqInit(
+ DevicePtr /*pKbd*/,
+ DevicePtr /*pPtr*/
+);
+
+extern void mieqEnqueue(
+ xEventPtr /*e*/
+);
+
+extern void mieqSwitchScreen(
+ ScreenPtr /*pScreen*/,
+ Bool /*fromDIX*/
+);
+
+extern void mieqProcessInputEvents(
+ void
+);
+
+/* miexpose.c */
+
+extern RegionPtr miHandleExposures(
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/
+);
+
+extern void miSendGraphicsExpose(
+ ClientPtr /*client*/,
+ RegionPtr /*pRgn*/,
+ XID /*drawable*/,
+ int /*major*/,
+ int /*minor*/
+);
+
+extern void miSendExposures(
+ WindowPtr /*pWin*/,
+ RegionPtr /*pRgn*/,
+ int /*dx*/,
+ int /*dy*/
+);
+
+extern void miWindowExposures(
+ WindowPtr /*pWin*/,
+ RegionPtr /*prgn*/,
+ RegionPtr /*other_exposed*/
+);
+
+extern void miPaintWindow(
+ WindowPtr /*pWin*/,
+ RegionPtr /*prgn*/,
+ int /*what*/
+);
+
+extern void miClearDrawable(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/
+);
+
+/* mifillrct.c */
+
+extern void miPolyFillRect(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+);
+
+/* miglblt.c */
+
+extern void miPolyGlyphBlt(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ void * /*pglyphBase*/
+);
+
+extern void miImageGlyphBlt(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ void * /*pglyphBase*/
+);
+
+/* mipoly.c */
+
+extern void miFillPolygon(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+);
+
+/* mipolycon.c */
+
+extern Bool miFillConvexPoly(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+);
+
+/* mipolygen.c */
+
+extern Bool miFillGeneralPoly(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+);
+
+/* mipolypnt.c */
+
+extern void miPolyPoint(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ xPoint * /*pptInit*/
+);
+
+/* mipolyrect.c */
+
+extern void miPolyRectangle(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/
+);
+
+/* mipolyseg.c */
+
+extern void miPolySegment(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/
+);
+
+/* mipolytext.c */
+
+extern int miPolyText(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/,
+ FontEncoding /*fontEncoding*/
+);
+
+extern int miPolyText8(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+);
+
+extern int miPolyText16(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+);
+
+extern int miImageText(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/,
+ FontEncoding /*fontEncoding*/
+);
+
+extern void miImageText8(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+);
+
+extern void miImageText16(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+);
+
+/* mipushpxl.c */
+
+extern void miPushPixels(
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+);
+
+/* see also region.h */
+
+extern Bool RegionRectAlloc(
+ RegionPtr /*pRgn*/,
+ int /*n*/
+);
+
+extern void RegionSetExtents(
+ RegionPtr /*pReg*/
+);
+
+extern int miFindMaxBand(
+ RegionPtr /*prgn*/
+);
+
+#ifdef DEBUG
+extern Bool RegionIsValid(
+ RegionPtr /*prgn*/
+);
+#endif
+
+extern Bool RegionBroken(RegionPtr pReg);
+
+/* miscrinit.c */
+
+extern Bool miModifyPixmapHeader(
+ PixmapPtr /*pPixmap*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ void * /*pPixData*/
+);
+
+extern Bool miCloseScreen(
+ ScreenPtr /*pScreen*/
+);
+
+extern Bool miCreateScreenResources(
+ ScreenPtr /*pScreen*/
+);
+
+extern Bool miScreenDevPrivateInit(
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ void * /*pbits*/
+);
+
+extern Bool miScreenInit(
+ ScreenPtr /*pScreen*/,
+ void * /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/,
+ int /*rootDepth*/,
+ int /*numDepths*/,
+ DepthPtr /*depths*/,
+ VisualID /*rootVisual*/,
+ int /*numVisuals*/,
+ VisualPtr /*visuals*/
+);
+
+extern int miAllocateGCPrivateIndex(
+ void
+);
+
+extern PixmapPtr miGetScreenPixmap(
+ ScreenPtr pScreen
+);
+
+extern void miSetScreenPixmap(
+ PixmapPtr pPix
+);
+
+/* mivaltree.c */
+
+extern int miShapedWindowIn(
+ ScreenPtr /*pScreen*/,
+ RegionPtr /*universe*/,
+ RegionPtr /*bounding*/,
+ BoxPtr /*rect*/,
+ int /*x*/,
+ int /*y*/
+);
+
+typedef void
+(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
+
+typedef RegionPtr
+(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
+
+void
+miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
+ GetRedirectBorderClipProcPtr getBorderClip);
+
+extern int miValidateTree(
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/
+);
+
+extern void miWideLine(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pPts*/
+);
+
+extern void miWideDash(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pPts*/
+);
+
+extern void miMiter(
+ void
+);
+
+extern void miNotMiter(
+ void
+);
+
+/* miwindow.c */
+
+extern void miClearToBackground(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/
+);
+
+extern Bool miChangeSaveUnder(
+ WindowPtr /*pWin*/,
+ WindowPtr /*first*/
+);
+
+extern void miPostChangeSaveUnder(
+ WindowPtr /*pWin*/,
+ WindowPtr /*pFirst*/
+);
+
+extern void miMarkWindow(
+ WindowPtr /*pWin*/
+);
+
+extern Bool miMarkOverlappedWindows(
+ WindowPtr /*pWin*/,
+ WindowPtr /*pFirst*/,
+ WindowPtr * /*ppLayerWin*/
+);
+
+extern void miHandleValidateExposures(
+ WindowPtr /*pWin*/
+);
+
+extern void miMoveWindow(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pNextSib*/,
+ VTKind /*kind*/
+);
+
+extern void miSlideAndSizeWindow(
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ WindowPtr /*pSib*/
+);
+
+extern WindowPtr miGetLayerWindow(
+ WindowPtr /*pWin*/
+);
+
+extern void miSetShape(
+ WindowPtr /*pWin*/
+);
+
+extern void miChangeBorderWidth(
+ WindowPtr /*pWin*/,
+ unsigned int /*width*/
+);
+
+extern void miMarkUnrealizedWindow(
+ WindowPtr /*pChild*/,
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/
+);
+
+extern void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth);
+
+/* mizerarc.c */
+
+extern void miZeroPolyArc(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+);
+
+/* mizerline.c */
+
+extern void miZeroLine(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+);
+
+extern void miZeroDashLine(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+);
+
+extern void miPolyFillArc(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+);
+
+#endif /* MI_H */
diff --git a/nx-X11/programs/Xserver/mi/miarc.c b/nx-X11/programs/Xserver/mi/miarc.c
new file mode 100644
index 000000000..5695e24af
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miarc.c
@@ -0,0 +1,3721 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* Author: Keith Packard and Bob Scheifler */
+/* Warning: this code is toxic, do not dally very long here. */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#if defined(_XOPEN_SOURCE) \
+ || (defined(sun) && defined(__SVR4))
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "misc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mifpoly.h"
+#include "mi.h"
+#include "mifillarc.h"
+#include <nx-X11/Xfuncproto.h>
+
+static double miDsin(double a);
+static double miDcos(double a);
+static double miDasin(double v);
+static double miDatan2(double dy, double dx);
+double cbrt(double);
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+/*
+ * some interesting sematic interpretation of the protocol:
+ *
+ * Self intersecting arcs (i.e. those spanning 360 degrees)
+ * never join with other arcs, and are drawn without caps
+ * (unless on/off dashed, in which case each dash segment
+ * is capped, except when the last segment meets the
+ * first segment, when no caps are drawn)
+ *
+ * double dash arcs are drawn in two parts, first the
+ * odd dashes (drawn in background) then the even dashes
+ * (drawn in foreground). This means that overlapping
+ * sections of foreground/background are drawn twice,
+ * first in background then in foreground. The double-draw
+ * occurs even when the function uses the destination values
+ * (e.g. xor mode). This is the same way the wide-line
+ * code works and should be "fixed".
+ *
+ */
+
+#undef max
+#undef min
+
+#if defined (__GNUC__) && !defined (__STRICT_ANSI__)
+#define USE_INLINE
+#endif
+
+#ifdef USE_INLINE
+inline static const int max (const int x, const int y)
+{
+ return x>y? x:y;
+}
+
+inline static const int min (const int x, const int y)
+{
+ return x<y? x:y;
+}
+
+#else
+
+static int
+max (int x, int y)
+{
+ return x>y? x:y;
+}
+
+static int
+min (int x, int y)
+{
+ return x<y? x:y;
+}
+
+#endif
+
+struct bound {
+ double min, max;
+};
+
+struct ibound {
+ int min, max;
+};
+
+#define boundedLe(value, bounds)\
+ ((bounds).min <= (value) && (value) <= (bounds).max)
+
+struct line {
+ double m, b;
+ int valid;
+};
+
+#define intersectLine(y,line) (line.m * (y) + line.b)
+
+/*
+ * these are all y value bounds
+ */
+
+struct arc_bound {
+ struct bound ellipse;
+ struct bound inner;
+ struct bound outer;
+ struct bound right;
+ struct bound left;
+ struct ibound inneri;
+ struct ibound outeri;
+};
+
+struct accelerators {
+ double tail_y;
+ double h2;
+ double w2;
+ double h4;
+ double w4;
+ double h2mw2;
+ double h2l;
+ double w2l;
+ double fromIntX;
+ double fromIntY;
+ struct line left, right;
+ int yorgu;
+ int yorgl;
+ int xorg;
+};
+
+struct arc_def {
+ double w, h, l;
+ double a0, a1;
+};
+
+# define todeg(xAngle) (((double) (xAngle)) / 64.0)
+
+# define RIGHT_END 0
+# define LEFT_END 1
+
+typedef struct _miArcJoin {
+ int arcIndex0, arcIndex1;
+ int phase0, phase1;
+ int end0, end1;
+} miArcJoinRec, *miArcJoinPtr;
+
+typedef struct _miArcCap {
+ int arcIndex;
+ int end;
+} miArcCapRec, *miArcCapPtr;
+
+typedef struct _miArcFace {
+ SppPointRec clock;
+ SppPointRec center;
+ SppPointRec counterClock;
+} miArcFaceRec, *miArcFacePtr;
+
+typedef struct _miArcData {
+ xArc arc;
+ int render; /* non-zero means render after drawing */
+ int join; /* related join */
+ int cap; /* related cap */
+ int selfJoin; /* final dash meets first dash */
+ miArcFaceRec bounds[2];
+ double x0, y0, x1, y1;
+} miArcDataRec, *miArcDataPtr;
+
+/*
+ * This is an entire sequence of arcs, computed and categorized according
+ * to operation. miDashArcs generates either one or two of these.
+ */
+
+typedef struct _miPolyArc {
+ int narcs;
+ miArcDataPtr arcs;
+ int ncaps;
+ miArcCapPtr caps;
+ int njoins;
+ miArcJoinPtr joins;
+} miPolyArcRec, *miPolyArcPtr;
+
+#define GCValsFunction 0
+#define GCValsForeground 1
+#define GCValsBackground 2
+#define GCValsLineWidth 3
+#define GCValsCapStyle 4
+#define GCValsJoinStyle 5
+#define GCValsMask (GCFunction | GCForeground | GCBackground | \
+ GCLineWidth | GCCapStyle | GCJoinStyle)
+static CARD32 gcvals[6];
+
+static void fillSpans(DrawablePtr pDrawable, GCPtr pGC);
+static void newFinalSpan(int y, register int xmin, register int xmax);
+static void drawArc(xArc *tarc, int l, int a0, int a1, miArcFacePtr right,
+ miArcFacePtr left);
+static void drawZeroArc(DrawablePtr pDraw, GCPtr pGC, xArc *tarc, int lw,
+ miArcFacePtr left, miArcFacePtr right);
+static void miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft,
+ miArcFacePtr pRight, int xOrgLeft, int yOrgLeft,
+ double xFtransLeft, double yFtransLeft,
+ int xOrgRight, int yOrgRight,
+ double xFtransRight, double yFtransRight);
+static void miArcCap(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pFace,
+ int end, int xOrg, int yOrg, double xFtrans,
+ double yFtrans);
+static void miRoundCap(DrawablePtr pDraw, GCPtr pGC, SppPointRec pCenter,
+ SppPointRec pEnd, SppPointRec pCorner,
+ SppPointRec pOtherCorner, int fLineEnd,
+ int xOrg, int yOrg, double xFtrans, double yFtrans);
+static void miFreeArcs(miPolyArcPtr arcs, GCPtr pGC);
+static miPolyArcPtr miComputeArcs(xArc *parcs, int narcs, GCPtr pGC);
+static int miGetArcPts(SppArcPtr parc, int cpt, SppPointPtr *ppPts);
+
+# define CUBED_ROOT_2 1.2599210498948732038115849718451499938964
+# define CUBED_ROOT_4 1.5874010519681993173435330390930175781250
+
+/*
+ * draw one segment of the arc using the arc spans generation routines
+ */
+
+static void
+miArcSegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc tarc,
+ miArcFacePtr right,
+ miArcFacePtr left)
+{
+ int l = pGC->lineWidth;
+ int a0, a1, startAngle, endAngle;
+ miArcFacePtr temp;
+
+ if (!l)
+ l = 1;
+
+ if (tarc.width == 0 || tarc.height == 0) {
+ drawZeroArc (pDraw, pGC, &tarc, l, left, right);
+ return;
+ }
+
+ if (pGC->miTranslate) {
+ tarc.x += pDraw->x;
+ tarc.y += pDraw->y;
+ }
+
+ a0 = tarc.angle1;
+ a1 = tarc.angle2;
+ if (a1 > FULLCIRCLE)
+ a1 = FULLCIRCLE;
+ else if (a1 < -FULLCIRCLE)
+ a1 = -FULLCIRCLE;
+ if (a1 < 0) {
+ startAngle = a0 + a1;
+ endAngle = a0;
+ temp = right;
+ right = left;
+ left = temp;
+ } else {
+ startAngle = a0;
+ endAngle = a0 + a1;
+ }
+ /*
+ * bounds check the two angles
+ */
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ if (endAngle < 0)
+ endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
+ if (endAngle > FULLCIRCLE)
+ endAngle = (endAngle-1) % FULLCIRCLE + 1;
+ if ((startAngle == endAngle) && a1) {
+ startAngle = 0;
+ endAngle = FULLCIRCLE;
+ }
+
+ drawArc (&tarc, l, startAngle, endAngle, right, left);
+}
+
+/*
+
+Three equations combine to describe the boundaries of the arc
+
+x^2/w^2 + y^2/h^2 = 1 ellipse itself
+(X-x)^2 + (Y-y)^2 = r^2 circle at (x, y) on the ellipse
+(Y-y) = (X-x)*w^2*y/(h^2*x) normal at (x, y) on the ellipse
+
+These lead to a quartic relating Y and y
+
+y^4 - (2Y)y^3 + (Y^2 + (h^4 - w^2*r^2)/(w^2 - h^2))y^2
+ - (2Y*h^4/(w^2 - h^2))y + (Y^2*h^4)/(w^2 - h^2) = 0
+
+The reducible cubic obtained from this quartic is
+
+z^3 - (3N)z^2 - 2V = 0
+
+where
+
+N = (Y^2 + (h^4 - w^2*r^2/(w^2 - h^2)))/6
+V = w^2*r^2*Y^2*h^4/(4 *(w^2 - h^2)^2)
+
+Let
+
+t = z - N
+p = -N^2
+q = -N^3 - V
+
+Then we get
+
+t^3 + 3pt + 2q = 0
+
+The discriminant of this cubic is
+
+D = q^2 + p^3
+
+When D > 0, a real root is obtained as
+
+z = N + cbrt(-q+sqrt(D)) + cbrt(-q-sqrt(D))
+
+When D < 0, a real root is obtained as
+
+z = N - 2m*cos(acos(-q/m^3)/3)
+
+where
+
+m = sqrt(|p|) * sign(q)
+
+Given a real root Z of the cubic, the roots of the quartic are the roots
+of the two quadratics
+
+y^2 + ((b+A)/2)y + (Z + (bZ - d)/A) = 0
+
+where
+
+A = +/- sqrt(8Z + b^2 - 4c)
+b, c, d are the cubic, quadratic, and linear coefficients of the quartic
+
+Some experimentation is then required to determine which solutions
+correspond to the inner and outer boundaries.
+
+*/
+
+typedef struct {
+ short lx, lw, rx, rw;
+} miArcSpan;
+
+typedef struct {
+ miArcSpan *spans;
+ int count1, count2, k;
+ char top, bot, hole;
+} miArcSpanData;
+
+typedef struct {
+ unsigned long lrustamp;
+ unsigned short lw;
+ unsigned short width, height;
+ miArcSpanData *spdata;
+} arcCacheRec;
+
+#define CACHESIZE 25
+
+static void drawQuadrant(struct arc_def *def, struct accelerators *acc,
+ int a0, int a1, int mask, miArcFacePtr right,
+ miArcFacePtr left, miArcSpanData *spdata);
+
+static arcCacheRec arcCache[CACHESIZE];
+static unsigned long lrustamp;
+static arcCacheRec *lastCacheHit = &arcCache[0];
+static RESTYPE cacheType;
+
+/*
+ * External so it can be called when low on memory.
+ * Call with a zero ID in that case.
+ */
+/*ARGSUSED*/
+int
+miFreeArcCache (data, id)
+ void * data;
+ XID id;
+{
+ int k;
+ arcCacheRec *cent;
+
+ if (id)
+ cacheType = 0;
+
+ for (k = CACHESIZE, cent = &arcCache[0]; --k >= 0; cent++)
+ {
+ if (cent->spdata)
+ {
+ cent->lrustamp = 0;
+ cent->lw = 0;
+ free(cent->spdata);
+ cent->spdata = NULL;
+ }
+ }
+ lrustamp = 0;
+ return Success;
+}
+
+static void
+miComputeCircleSpans(
+ int lw,
+ xArc *parc,
+ miArcSpanData *spdata)
+{
+ register miArcSpan *span;
+ int doinner;
+ register int x, y, e;
+ int xk, yk, xm, ym, dx, dy;
+ register int slw, inslw;
+ int inx = 0, iny, ine = 0;
+ int inxk = 0, inyk = 0, inxm = 0, inym = 0;
+
+ doinner = -lw;
+ slw = parc->width - doinner;
+ y = parc->height >> 1;
+ dy = parc->height & 1;
+ dx = 1 - dy;
+ MIWIDEARCSETUP(x, y, dy, slw, e, xk, xm, yk, ym);
+ inslw = parc->width + doinner;
+ if (inslw > 0)
+ {
+ spdata->hole = spdata->top;
+ MIWIDEARCSETUP(inx, iny, dy, inslw, ine, inxk, inxm, inyk, inym);
+ }
+ else
+ {
+ spdata->hole = FALSE;
+ doinner = -y;
+ }
+ spdata->count1 = -doinner - spdata->top;
+ spdata->count2 = y + doinner;
+ span = spdata->spans;
+ while (y)
+ {
+ MIFILLARCSTEP(slw);
+ span->lx = dy - x;
+ if (++doinner <= 0)
+ {
+ span->lw = slw;
+ span->rx = 0;
+ span->rw = span->lx + slw;
+ }
+ else
+ {
+ MIFILLINARCSTEP(inslw);
+ span->lw = x - inx;
+ span->rx = dy - inx + inslw;
+ span->rw = inx - x + slw - inslw;
+ }
+ span++;
+ }
+ if (spdata->bot)
+ {
+ if (spdata->count2)
+ spdata->count2--;
+ else
+ {
+ if (lw > (int)parc->height)
+ span[-1].rx = span[-1].rw = -((lw - (int)parc->height) >> 1);
+ else
+ span[-1].rw = 0;
+ spdata->count1--;
+ }
+ }
+}
+
+static void
+miComputeEllipseSpans(
+ int lw,
+ xArc *parc,
+ miArcSpanData *spdata)
+{
+ register miArcSpan *span;
+ double w, h, r, xorg;
+ double Hs, Hf, WH, K, Vk, Nk, Fk, Vr, N, Nc, Z, rs;
+ double A, T, b, d, x, y, t, inx, outx = 0.0, hepp, hepm;
+ int flip, solution;
+
+ w = (double)parc->width / 2.0;
+ h = (double)parc->height / 2.0;
+ r = lw / 2.0;
+ rs = r * r;
+ Hs = h * h;
+ WH = w * w - Hs;
+ Nk = w * r;
+ Vk = (Nk * Hs) / (WH + WH);
+ Hf = Hs * Hs;
+ Nk = (Hf - Nk * Nk) / WH;
+ Fk = Hf / WH;
+ hepp = h + EPSILON;
+ hepm = h - EPSILON;
+ K = h + ((lw - 1) >> 1);
+ span = spdata->spans;
+ if (parc->width & 1)
+ xorg = .5;
+ else
+ xorg = 0.0;
+ if (spdata->top)
+ {
+ span->lx = 0;
+ span->lw = 1;
+ span++;
+ }
+ spdata->count1 = 0;
+ spdata->count2 = 0;
+ spdata->hole = (spdata->top &&
+ (int)parc->height * lw <= (int)(parc->width * parc->width) &&
+ lw < (int)parc->height);
+ for (; K > 0.0; K -= 1.0)
+ {
+ N = (K * K + Nk) / 6.0;
+ Nc = N * N * N;
+ Vr = Vk * K;
+ t = Nc + Vr * Vr;
+ d = Nc + t;
+ if (d < 0.0) {
+ d = Nc;
+ b = N;
+ if ( (b < 0.0) == (t < 0.0) )
+ {
+ b = -b;
+ d = -d;
+ }
+ Z = N - 2.0 * b * cos(acos(-t / d) / 3.0);
+ if ( (Z < 0.0) == (Vr < 0.0) )
+ flip = 2;
+ else
+ flip = 1;
+ }
+ else
+ {
+ d = Vr * sqrt(d);
+ Z = N + cbrt(t + d) + cbrt(t - d);
+ flip = 0;
+ }
+ A = sqrt((Z + Z) - Nk);
+ T = (Fk - Z) * K / A;
+ inx = 0.0;
+ solution = FALSE;
+ b = -A + K;
+ d = b * b - 4 * (Z + T);
+ if (d >= 0)
+ {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if ((y >= 0.0) && (y < hepp))
+ {
+ solution = TRUE;
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ if (flip == 2)
+ inx = x - t;
+ else
+ outx = x + t;
+ }
+ }
+ b = A + K;
+ d = b * b - 4 * (Z - T);
+ /* Because of the large magnitudes involved, we lose enough precision
+ * that sometimes we end up with a negative value near the axis, when
+ * it should be positive. This is a workaround.
+ */
+ if (d < 0 && !solution)
+ d = 0.0;
+ if (d >= 0) {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if (y < hepp)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ inx = x - sqrt(rs - (t * t));
+ else
+ inx = x;
+ }
+ y = (b - d) / 2;
+ if (y >= 0.0)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ if (flip == 1)
+ inx = x - t;
+ else
+ outx = x + t;
+ }
+ }
+ span->lx = ICEIL(xorg - outx);
+ if (inx <= 0.0)
+ {
+ spdata->count1++;
+ span->lw = ICEIL(xorg + outx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = -ICEIL(xorg - inx);
+ }
+ else
+ {
+ spdata->count2++;
+ span->lw = ICEIL(xorg - inx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = ICEIL(xorg + outx) - span->rx;
+ }
+ span++;
+ }
+ if (spdata->bot)
+ {
+ outx = w + r;
+ if (r >= h && r <= w)
+ inx = 0.0;
+ else if (Nk < 0.0 && -Nk < Hs)
+ {
+ inx = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk);
+ if (inx > w - r)
+ inx = w - r;
+ }
+ else
+ inx = w - r;
+ span->lx = ICEIL(xorg - outx);
+ if (inx <= 0.0)
+ {
+ span->lw = ICEIL(xorg + outx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = -ICEIL(xorg - inx);
+ }
+ else
+ {
+ span->lw = ICEIL(xorg - inx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = ICEIL(xorg + outx) - span->rx;
+ }
+ }
+ if (spdata->hole)
+ {
+ span = &spdata->spans[spdata->count1];
+ span->lw = -span->lx;
+ span->rx = 1;
+ span->rw = span->lw;
+ spdata->count1--;
+ spdata->count2++;
+ }
+}
+
+static double
+tailX(
+ double K,
+ struct arc_def *def,
+ struct arc_bound *bounds,
+ struct accelerators *acc)
+{
+ double w, h, r;
+ double Hs, Hf, WH, Vk, Nk, Fk, Vr, N, Nc, Z, rs;
+ double A, T, b, d, x, y, t, hepp, hepm;
+ int flip, solution;
+ double xs[2];
+ double *xp;
+
+ w = def->w;
+ h = def->h;
+ r = def->l;
+ rs = r * r;
+ Hs = acc->h2;
+ WH = -acc->h2mw2;
+ Nk = def->w * r;
+ Vk = (Nk * Hs) / (WH + WH);
+ Hf = acc->h4;
+ Nk = (Hf - Nk * Nk) / WH;
+ if (K == 0.0) {
+ if (Nk < 0.0 && -Nk < Hs) {
+ xs[0] = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk);
+ xs[1] = w - r;
+ if (acc->left.valid && boundedLe(K, bounds->left) &&
+ !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0)
+ return xs[1];
+ if (acc->right.valid && boundedLe(K, bounds->right) &&
+ !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0)
+ return xs[1];
+ return xs[0];
+ }
+ return w - r;
+ }
+ Fk = Hf / WH;
+ hepp = h + EPSILON;
+ hepm = h - EPSILON;
+ N = (K * K + Nk) / 6.0;
+ Nc = N * N * N;
+ Vr = Vk * K;
+ xp = xs;
+ xs[0] = 0.0;
+ t = Nc + Vr * Vr;
+ d = Nc + t;
+ if (d < 0.0) {
+ d = Nc;
+ b = N;
+ if ( (b < 0.0) == (t < 0.0) )
+ {
+ b = -b;
+ d = -d;
+ }
+ Z = N - 2.0 * b * cos(acos(-t / d) / 3.0);
+ if ( (Z < 0.0) == (Vr < 0.0) )
+ flip = 2;
+ else
+ flip = 1;
+ }
+ else
+ {
+ d = Vr * sqrt(d);
+ Z = N + cbrt(t + d) + cbrt(t - d);
+ flip = 0;
+ }
+ A = sqrt((Z + Z) - Nk);
+ T = (Fk - Z) * K / A;
+ solution = FALSE;
+ b = -A + K;
+ d = b * b - 4 * (Z + T);
+ if (d >= 0 && flip == 2)
+ {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if ((y >= 0.0) && (y < hepp))
+ {
+ solution = TRUE;
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ *xp++ = x - t;
+ }
+ }
+ b = A + K;
+ d = b * b - 4 * (Z - T);
+ /* Because of the large magnitudes involved, we lose enough precision
+ * that sometimes we end up with a negative value near the axis, when
+ * it should be positive. This is a workaround.
+ */
+ if (d < 0 && !solution)
+ d = 0.0;
+ if (d >= 0) {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if (y < hepp)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ *xp++ = x - sqrt(rs - (t * t));
+ else
+ *xp++ = x;
+ }
+ y = (b - d) / 2;
+ if (y >= 0.0 && flip == 1)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ *xp++ = x - t;
+ }
+ }
+ if (xp > &xs[1]) {
+ if (acc->left.valid && boundedLe(K, bounds->left) &&
+ !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0)
+ return xs[1];
+ if (acc->right.valid && boundedLe(K, bounds->right) &&
+ !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0)
+ return xs[1];
+ }
+ return xs[0];
+}
+
+static miArcSpanData *
+miComputeWideEllipse(
+ int lw,
+ register xArc *parc,
+ Bool *mustFree)
+{
+ register miArcSpanData *spdata;
+ register arcCacheRec *cent, *lruent;
+ register int k;
+ arcCacheRec fakeent;
+
+ if (!lw)
+ lw = 1;
+ if (parc->height <= 1500)
+ {
+ *mustFree = FALSE;
+ cent = lastCacheHit;
+ if (cent->lw == lw &&
+ cent->width == parc->width && cent->height == parc->height)
+ {
+ cent->lrustamp = ++lrustamp;
+ return cent->spdata;
+ }
+ lruent = &arcCache[0];
+ for (k = CACHESIZE, cent = lruent; --k >= 0; cent++)
+ {
+ if (cent->lw == lw &&
+ cent->width == parc->width && cent->height == parc->height)
+ {
+ cent->lrustamp = ++lrustamp;
+ lastCacheHit = cent;
+ return cent->spdata;
+ }
+ if (cent->lrustamp < lruent->lrustamp)
+ lruent = cent;
+ }
+ if (!cacheType)
+ {
+ cacheType = CreateNewResourceType(miFreeArcCache);
+ (void) AddResource(FakeClientID(0), cacheType, NULL);
+ }
+ } else {
+ lruent = &fakeent;
+ lruent->spdata = NULL;
+ *mustFree = TRUE;
+ }
+ k = (parc->height >> 1) + ((lw - 1) >> 1);
+ spdata = lruent->spdata;
+ if (!spdata || spdata->k != k)
+ {
+ if (spdata)
+ free(spdata);
+ spdata = (miArcSpanData *)malloc(sizeof(miArcSpanData) +
+ sizeof(miArcSpan) * (k + 2));
+ lruent->spdata = spdata;
+ if (!spdata)
+ {
+ lruent->lrustamp = 0;
+ lruent->lw = 0;
+ return spdata;
+ }
+ spdata->spans = (miArcSpan *)(spdata + 1);
+ spdata->k = k;
+ }
+ spdata->top = !(lw & 1) && !(parc->width & 1);
+ spdata->bot = !(parc->height & 1);
+ lruent->lrustamp = ++lrustamp;
+ lruent->lw = lw;
+ lruent->width = parc->width;
+ lruent->height = parc->height;
+ if (lruent != &fakeent)
+ lastCacheHit = lruent;
+ if (parc->width == parc->height)
+ miComputeCircleSpans(lw, parc, spdata);
+ else
+ miComputeEllipseSpans(lw, parc, spdata);
+ return spdata;
+}
+
+static void
+miFillWideEllipse(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *parc)
+{
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+ miArcSpanData *spdata;
+ Bool mustFree;
+ register miArcSpan *span;
+ register int xorg, yorgu, yorgl;
+ register int n;
+
+ yorgu = parc->height + pGC->lineWidth;
+ n = (sizeof(int) * 2) * yorgu;
+ widths = (int *)malloc(n + (sizeof(DDXPointRec) * 2) * yorgu);
+ if (!widths)
+ return;
+ points = (DDXPointPtr)((char *)widths + n);
+ spdata = miComputeWideEllipse((int)pGC->lineWidth, parc, &mustFree);
+ if (!spdata)
+ {
+ free(widths);
+ return;
+ }
+ pts = points;
+ wids = widths;
+ span = spdata->spans;
+ xorg = parc->x + (parc->width >> 1);
+ yorgu = parc->y + (parc->height >> 1);
+ yorgl = yorgu + (parc->height & 1);
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorgu += pDraw->y;
+ yorgl += pDraw->y;
+ }
+ yorgu -= spdata->k;
+ yorgl += spdata->k;
+ if (spdata->top)
+ {
+ pts->x = xorg;
+ pts->y = yorgu - 1;
+ pts++;
+ *wids++ = 1;
+ span++;
+ }
+ for (n = spdata->count1; --n >= 0; )
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = pts[0].x;
+ pts[1].y = yorgl;
+ wids[1] = wids[0];
+ yorgu++;
+ yorgl--;
+ pts += 2;
+ wids += 2;
+ span++;
+ }
+ if (spdata->hole)
+ {
+ pts[0].x = xorg;
+ pts[0].y = yorgl;
+ wids[0] = 1;
+ pts++;
+ wids++;
+ }
+ for (n = spdata->count2; --n >= 0; )
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = xorg + span->rx;
+ pts[1].y = pts[0].y;
+ wids[1] = span->rw;
+ pts[2].x = pts[0].x;
+ pts[2].y = yorgl;
+ wids[2] = wids[0];
+ pts[3].x = pts[1].x;
+ pts[3].y = pts[2].y;
+ wids[3] = wids[1];
+ yorgu++;
+ yorgl--;
+ pts += 4;
+ wids += 4;
+ span++;
+ }
+ if (spdata->bot)
+ {
+ if (span->rw <= 0)
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts++;
+ wids++;
+ }
+ else
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = xorg + span->rx;
+ pts[1].y = pts[0].y;
+ wids[1] = span->rw;
+ pts += 2;
+ wids += 2;
+ }
+ }
+ if (mustFree)
+ free(spdata);
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+
+ free(widths);
+}
+
+/*
+ * miPolyArc strategy:
+ *
+ * If arc is zero width and solid, we don't have to worry about the rasterop
+ * or join styles. For wide solid circles, we use a fast integer algorithm.
+ * For wide solid ellipses, we use special case floating point code.
+ * Otherwise, we set up pDrawTo and pGCTo according to the rasterop, then
+ * draw using pGCTo and pDrawTo. If the raster-op was "tricky," that is,
+ * if it involves the destination, then we use PushPixels to move the bits
+ * from the scratch drawable to pDraw. (See the wide line code for a
+ * fuller explanation of this.)
+ */
+
+void
+miPolyArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register int i;
+ xArc *parc;
+ int xMin, xMax, yMin, yMax;
+ int pixmapWidth = 0, pixmapHeight = 0;
+ int xOrg = 0, yOrg = 0;
+ int width;
+ Bool fTricky;
+ DrawablePtr pDrawTo;
+ CARD32 fg, bg;
+ GCPtr pGCTo;
+ miPolyArcPtr polyArcs;
+ int cap[2], join[2];
+ int iphase;
+ int halfWidth;
+
+ width = pGC->lineWidth;
+ if(width == 0 && pGC->lineStyle == LineSolid)
+ {
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ miArcSegment( pDraw, pGC, *parc,
+ (miArcFacePtr) 0, (miArcFacePtr) 0 );
+ fillSpans (pDraw, pGC);
+ }
+ else
+ {
+ if ((pGC->lineStyle == LineSolid) && narcs)
+ {
+ while (parcs->width && parcs->height &&
+ (parcs->angle2 >= FULLCIRCLE ||
+ parcs->angle2 <= -FULLCIRCLE))
+ {
+ miFillWideEllipse(pDraw, pGC, parcs);
+ if (!--narcs)
+ return;
+ parcs++;
+ }
+ }
+
+ /* Set up pDrawTo and pGCTo based on the rasterop */
+ switch(pGC->alu)
+ {
+ case GXclear: /* 0 */
+ case GXcopy: /* src */
+ case GXcopyInverted: /* NOT src */
+ case GXset: /* 1 */
+ fTricky = FALSE;
+ pDrawTo = pDraw;
+ pGCTo = pGC;
+ break;
+ default:
+ fTricky = TRUE;
+
+ /* find bounding box around arcs */
+ xMin = yMin = MAXSHORT;
+ xMax = yMax = MINSHORT;
+
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ {
+ xMin = min (xMin, parc->x);
+ yMin = min (yMin, parc->y);
+ xMax = max (xMax, (parc->x + (int) parc->width));
+ yMax = max (yMax, (parc->y + (int) parc->height));
+ }
+
+ /* expand box to deal with line widths */
+ halfWidth = (width + 1)/2;
+ xMin -= halfWidth;
+ yMin -= halfWidth;
+ xMax += halfWidth;
+ yMax += halfWidth;
+
+ /* compute pixmap size; limit it to size of drawable */
+ xOrg = max(xMin, 0);
+ yOrg = max(yMin, 0);
+ pixmapWidth = min(xMax, pDraw->width) - xOrg;
+ pixmapHeight = min(yMax, pDraw->height) - yOrg;
+
+ /* if nothing left, return */
+ if ( (pixmapWidth <= 0) || (pixmapHeight <= 0) ) return;
+
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ {
+ parc->x -= xOrg;
+ parc->y -= yOrg;
+ }
+ if (pGC->miTranslate)
+ {
+ xOrg += pDraw->x;
+ yOrg += pDraw->y;
+ }
+
+ /* set up scratch GC */
+
+ pGCTo = GetScratchGC(1, pDraw->pScreen);
+ if (!pGCTo)
+ return;
+ gcvals[GCValsFunction] = GXcopy;
+ gcvals[GCValsForeground] = 1;
+ gcvals[GCValsBackground] = 0;
+ gcvals[GCValsLineWidth] = pGC->lineWidth;
+ gcvals[GCValsCapStyle] = pGC->capStyle;
+ gcvals[GCValsJoinStyle] = pGC->joinStyle;
+ dixChangeGC(NullClient, pGCTo, GCValsMask, gcvals, NULL);
+
+ /* allocate a 1 bit deep pixmap of the appropriate size, and
+ * validate it */
+ pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, pixmapWidth, pixmapHeight, 1,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pDrawTo)
+ {
+ FreeScratchGC(pGCTo);
+ return;
+ }
+ ValidateGC(pDrawTo, pGCTo);
+ miClearDrawable(pDrawTo, pGCTo);
+ }
+
+ fg = pGC->fgPixel;
+ bg = pGC->bgPixel;
+ if ((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillOpaqueStippled))
+ bg = fg; /* the protocol sez these don't cause color changes */
+
+ polyArcs = miComputeArcs (parcs, narcs, pGC);
+
+ if (!polyArcs)
+ {
+ if (fTricky) {
+ (*pDraw->pScreen->DestroyPixmap) ((PixmapPtr)pDrawTo);
+ FreeScratchGC (pGCTo);
+ }
+ return;
+ }
+
+ cap[0] = cap[1] = 0;
+ join[0] = join[1] = 0;
+ for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0);
+ iphase >= 0;
+ iphase--)
+ {
+ if (iphase == 1) {
+ dixChangeGC (NullClient, pGC, GCForeground, &bg, NULL);
+ ValidateGC (pDraw, pGC);
+ } else if (pGC->lineStyle == LineDoubleDash) {
+ dixChangeGC (NullClient, pGC, GCForeground, &fg, NULL);
+ ValidateGC (pDraw, pGC);
+ }
+ for (i = 0; i < polyArcs[iphase].narcs; i++) {
+ miArcDataPtr arcData;
+
+ arcData = &polyArcs[iphase].arcs[i];
+ miArcSegment(pDrawTo, pGCTo, arcData->arc,
+ &arcData->bounds[RIGHT_END],
+ &arcData->bounds[LEFT_END]);
+ if (polyArcs[iphase].arcs[i].render) {
+ fillSpans (pDrawTo, pGCTo);
+ /*
+ * don't cap self-joining arcs
+ */
+ if (polyArcs[iphase].arcs[i].selfJoin &&
+ cap[iphase] < polyArcs[iphase].arcs[i].cap)
+ cap[iphase]++;
+ while (cap[iphase] < polyArcs[iphase].arcs[i].cap) {
+ int arcIndex, end;
+ miArcDataPtr arcData0;
+
+ arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex;
+ end = polyArcs[iphase].caps[cap[iphase]].end;
+ arcData0 = &polyArcs[iphase].arcs[arcIndex];
+ miArcCap (pDrawTo, pGCTo,
+ &arcData0->bounds[end], end,
+ arcData0->arc.x, arcData0->arc.y,
+ (double) arcData0->arc.width / 2.0,
+ (double) arcData0->arc.height / 2.0);
+ ++cap[iphase];
+ }
+ while (join[iphase] < polyArcs[iphase].arcs[i].join) {
+ int arcIndex0, arcIndex1, end0, end1;
+ int phase0, phase1;
+ miArcDataPtr arcData0, arcData1;
+ miArcJoinPtr joinp;
+
+ joinp = &polyArcs[iphase].joins[join[iphase]];
+ arcIndex0 = joinp->arcIndex0;
+ end0 = joinp->end0;
+ arcIndex1 = joinp->arcIndex1;
+ end1 = joinp->end1;
+ phase0 = joinp->phase0;
+ phase1 = joinp->phase1;
+ arcData0 = &polyArcs[phase0].arcs[arcIndex0];
+ arcData1 = &polyArcs[phase1].arcs[arcIndex1];
+ miArcJoin (pDrawTo, pGCTo,
+ &arcData0->bounds[end0],
+ &arcData1->bounds[end1],
+ arcData0->arc.x, arcData0->arc.y,
+ (double) arcData0->arc.width / 2.0,
+ (double) arcData0->arc.height / 2.0,
+ arcData1->arc.x, arcData1->arc.y,
+ (double) arcData1->arc.width / 2.0,
+ (double) arcData1->arc.height / 2.0);
+ ++join[iphase];
+ }
+ if (fTricky) {
+ if (pGC->serialNumber != pDraw->serialNumber)
+ ValidateGC (pDraw, pGC);
+ (*pGC->ops->PushPixels) (pGC, (PixmapPtr)pDrawTo,
+ pDraw, pixmapWidth, pixmapHeight, xOrg, yOrg);
+ miClearDrawable ((DrawablePtr) pDrawTo, pGCTo);
+ }
+ }
+ }
+ }
+ miFreeArcs(polyArcs, pGC);
+
+ if(fTricky)
+ {
+ (*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo);
+ FreeScratchGC(pGCTo);
+ }
+ }
+}
+
+static double
+angleBetween (SppPointRec center, SppPointRec point1, SppPointRec point2)
+{
+ double a1, a2, a;
+
+ /*
+ * reflect from X coordinates back to ellipse
+ * coordinates -- y increasing upwards
+ */
+ a1 = miDatan2 (- (point1.y - center.y), point1.x - center.x);
+ a2 = miDatan2 (- (point2.y - center.y), point2.x - center.x);
+ a = a2 - a1;
+ if (a <= -180.0)
+ a += 360.0;
+ else if (a > 180.0)
+ a -= 360.0;
+ return a;
+}
+
+static void
+translateBounds (
+ miArcFacePtr b,
+ int x,
+ int y,
+ double fx,
+ double fy)
+{
+ fx += x;
+ fy += y;
+ b->clock.x -= fx;
+ b->clock.y -= fy;
+ b->center.x -= fx;
+ b->center.y -= fy;
+ b->counterClock.x -= fx;
+ b->counterClock.y -= fy;
+}
+
+static void
+miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft,
+ miArcFacePtr pRight, int xOrgLeft, int yOrgLeft,
+ double xFtransLeft, double yFtransLeft,
+ int xOrgRight, int yOrgRight,
+ double xFtransRight, double yFtransRight)
+{
+ SppPointRec center, corner, otherCorner;
+ SppPointRec poly[5], e;
+ SppPointPtr pArcPts;
+ int cpt;
+ SppArcRec arc;
+ miArcFaceRec Right, Left;
+ int polyLen = 0;
+ int xOrg, yOrg;
+ double xFtrans, yFtrans;
+ double a;
+ double ae, ac2, ec2, bc2, de;
+ double width;
+
+ xOrg = (xOrgRight + xOrgLeft) / 2;
+ yOrg = (yOrgRight + yOrgLeft) / 2;
+ xFtrans = (xFtransLeft + xFtransRight) / 2;
+ yFtrans = (yFtransLeft + yFtransRight) / 2;
+ Right = *pRight;
+ translateBounds (&Right, xOrg - xOrgRight, yOrg - yOrgRight,
+ xFtrans - xFtransRight, yFtrans - yFtransRight);
+ Left = *pLeft;
+ translateBounds (&Left, xOrg - xOrgLeft, yOrg - yOrgLeft,
+ xFtrans - xFtransLeft, yFtrans - yFtransLeft);
+ pRight = &Right;
+ pLeft = &Left;
+
+ if (pRight->clock.x == pLeft->counterClock.x &&
+ pRight->clock.y == pLeft->counterClock.y)
+ return;
+ center = pRight->center;
+ if (0 <= (a = angleBetween (center, pRight->clock, pLeft->counterClock))
+ && a <= 180.0)
+ {
+ corner = pRight->clock;
+ otherCorner = pLeft->counterClock;
+ } else {
+ a = angleBetween (center, pLeft->clock, pRight->counterClock);
+ corner = pLeft->clock;
+ otherCorner = pRight->counterClock;
+ }
+ switch (pGC->joinStyle) {
+ case JoinRound:
+ width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);
+
+ arc.x = center.x - width/2;
+ arc.y = center.y - width/2;
+ arc.width = width;
+ arc.height = width;
+ arc.angle1 = -miDatan2 (corner.y - center.y, corner.x - center.x);
+ arc.angle2 = a;
+ pArcPts = (SppPointPtr) malloc (3 * sizeof (SppPointRec));
+ if (!pArcPts)
+ return;
+ pArcPts[0].x = otherCorner.x;
+ pArcPts[0].y = otherCorner.y;
+ pArcPts[1].x = center.x;
+ pArcPts[1].y = center.y;
+ pArcPts[2].x = corner.x;
+ pArcPts[2].y = corner.y;
+ if( (cpt = miGetArcPts(&arc, 3, &pArcPts)) )
+ {
+ /* by drawing with miFillSppPoly and setting the endpoints of the arc
+ * to be the corners, we assure that the cap will meet up with the
+ * rest of the line */
+ miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, yFtrans);
+ }
+ free(pArcPts);
+ return;
+ case JoinMiter:
+ /*
+ * don't miter arcs with less than 11 degrees between them
+ */
+ if (a < 169.0) {
+ poly[0] = corner;
+ poly[1] = center;
+ poly[2] = otherCorner;
+ bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) +
+ (corner.y - otherCorner.y) * (corner.y - otherCorner.y);
+ ec2 = bc2 / 4;
+ ac2 = (corner.x - center.x) * (corner.x - center.x) +
+ (corner.y - center.y) * (corner.y - center.y);
+ ae = sqrt (ac2 - ec2);
+ de = ec2 / ae;
+ e.x = (corner.x + otherCorner.x) / 2;
+ e.y = (corner.y + otherCorner.y) / 2;
+ poly[3].x = e.x + de * (e.x - center.x) / ae;
+ poly[3].y = e.y + de * (e.y - center.y) / ae;
+ poly[4] = corner;
+ polyLen = 5;
+ break;
+ }
+ case JoinBevel:
+ poly[0] = corner;
+ poly[1] = center;
+ poly[2] = otherCorner;
+ poly[3] = corner;
+ polyLen = 4;
+ break;
+ }
+ miFillSppPoly (pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans);
+}
+
+/*ARGSUSED*/
+static void
+miArcCap (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ miArcFacePtr pFace,
+ int end,
+ int xOrg,
+ int yOrg,
+ double xFtrans,
+ double yFtrans)
+{
+ SppPointRec corner, otherCorner, center, endPoint, poly[5];
+
+ corner = pFace->clock;
+ otherCorner = pFace->counterClock;
+ center = pFace->center;
+ switch (pGC->capStyle) {
+ case CapProjecting:
+ poly[0].x = otherCorner.x;
+ poly[0].y = otherCorner.y;
+ poly[1].x = corner.x;
+ poly[1].y = corner.y;
+ poly[2].x = corner.x -
+ (center.y - corner.y);
+ poly[2].y = corner.y +
+ (center.x - corner.x);
+ poly[3].x = otherCorner.x -
+ (otherCorner.y - center.y);
+ poly[3].y = otherCorner.y +
+ (otherCorner.x - center.x);
+ poly[4].x = otherCorner.x;
+ poly[4].y = otherCorner.y;
+ miFillSppPoly (pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans);
+ break;
+ case CapRound:
+ /*
+ * miRoundCap just needs these to be unequal.
+ */
+ endPoint = center;
+ endPoint.x = endPoint.x + 100;
+ miRoundCap (pDraw, pGC, center, endPoint, corner, otherCorner, 0,
+ -xOrg, -yOrg, xFtrans, yFtrans);
+ break;
+ }
+}
+
+/* MIROUNDCAP -- a private helper function
+ * Put Rounded cap on end. pCenter is the center of this end of the line
+ * pEnd is the center of the other end of the line. pCorner is one of the
+ * two corners at this end of the line.
+ * NOTE: pOtherCorner must be counter-clockwise from pCorner.
+ */
+/*ARGSUSED*/
+static void
+miRoundCap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ SppPointRec pCenter,
+ SppPointRec pEnd,
+ SppPointRec pCorner,
+ SppPointRec pOtherCorner,
+ int fLineEnd,
+ int xOrg,
+ int yOrg,
+ double xFtrans,
+ double yFtrans)
+{
+ int cpt;
+ double width;
+ SppArcRec arc;
+ SppPointPtr pArcPts;
+
+ width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);
+
+ arc.x = pCenter.x - width/2;
+ arc.y = pCenter.y - width/2;
+ arc.width = width;
+ arc.height = width;
+ arc.angle1 = -miDatan2 (pCorner.y - pCenter.y, pCorner.x - pCenter.x);
+ if(PTISEQUAL(pCenter, pEnd))
+ arc.angle2 = - 180.0;
+ else {
+ arc.angle2 = -miDatan2 (pOtherCorner.y - pCenter.y, pOtherCorner.x - pCenter.x) - arc.angle1;
+ if (arc.angle2 < 0)
+ arc.angle2 += 360.0;
+ }
+ pArcPts = (SppPointPtr) NULL;
+ if( (cpt = miGetArcPts(&arc, 0, &pArcPts)) )
+ {
+ /* by drawing with miFillSppPoly and setting the endpoints of the arc
+ * to be the corners, we assure that the cap will meet up with the
+ * rest of the line */
+ miFillSppPoly(pDraw, pGC, cpt, pArcPts, -xOrg, -yOrg, xFtrans, yFtrans);
+ }
+ free(pArcPts);
+}
+
+/*
+ * To avoid inaccuracy at the cardinal points, use trig functions
+ * which are exact for those angles
+ */
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#endif
+
+# define Dsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
+# define Dcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
+# define mod(a,b) ((a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+
+static double
+miDcos (double a)
+{
+ int i;
+
+ if (floor (a/90) == a/90) {
+ i = (int) (a/90.0);
+ switch (mod (i, 4)) {
+ case 0: return 1;
+ case 1: return 0;
+ case 2: return -1;
+ case 3: return 0;
+ }
+ }
+ return cos (a * M_PI / 180.0);
+}
+
+static double
+miDsin (double a)
+{
+ int i;
+
+ if (floor (a/90) == a/90) {
+ i = (int) (a/90.0);
+ switch (mod (i, 4)) {
+ case 0: return 0;
+ case 1: return 1;
+ case 2: return 0;
+ case 3: return -1;
+ }
+ }
+ return sin (a * M_PI / 180.0);
+}
+
+static double
+miDasin (double v)
+{
+ if (v == 0)
+ return 0.0;
+ if (v == 1.0)
+ return 90.0;
+ if (v == -1.0)
+ return -90.0;
+ return asin(v) * (180.0 / M_PI);
+}
+
+static double
+miDatan2 (double dy, double dx)
+{
+ if (dy == 0) {
+ if (dx >= 0)
+ return 0.0;
+ return 180.0;
+ } else if (dx == 0) {
+ if (dy > 0)
+ return 90.0;
+ return -90.0;
+ } else if (Fabs (dy) == Fabs (dx)) {
+ if (dy > 0) {
+ if (dx > 0)
+ return 45.0;
+ return 135.0;
+ } else {
+ if (dx > 0)
+ return 315.0;
+ return 225.0;
+ }
+ } else {
+ return atan2 (dy, dx) * (180.0 / M_PI);
+ }
+}
+
+/* MIGETARCPTS -- Converts an arc into a set of line segments -- a helper
+ * routine for filled arc and line (round cap) code.
+ * Returns the number of points in the arc. Note that it takes a pointer
+ * to a pointer to where it should put the points and an index (cpt).
+ * This procedure allocates the space necessary to fit the arc points.
+ * Sometimes it's convenient for those points to be at the end of an existing
+ * array. (For example, if we want to leave a spare point to make sectors
+ * instead of segments.) So we pass in the malloc()ed chunk that contains the
+ * array and an index saying where we should start stashing the points.
+ * If there isn't an array already, we just pass in a null pointer and
+ * count on realloc() to handle the null pointer correctly.
+ */
+static int
+miGetArcPts(
+ SppArcPtr parc, /* points to an arc */
+ int cpt, /* number of points already in arc list */
+ SppPointPtr *ppPts) /* pointer to pointer to arc-list -- modified */
+{
+ double st, /* Start Theta, start angle */
+ et, /* End Theta, offset from start theta */
+ dt, /* Delta Theta, angle to sweep ellipse */
+ cdt, /* Cos Delta Theta, actually 2 cos(dt) */
+ x0, y0, /* the recurrence formula needs two points to start */
+ x1, y1,
+ x2, y2, /* this will be the new point generated */
+ xc, yc; /* the center point */
+ int count, i;
+ SppPointPtr poly;
+
+ /* The spec says that positive angles indicate counterclockwise motion.
+ * Given our coordinate system (with 0,0 in the upper left corner),
+ * the screen appears flipped in Y. The easiest fix is to negate the
+ * angles given */
+
+ st = - parc->angle1;
+
+ et = - parc->angle2;
+
+ /* Try to get a delta theta that is within 1/2 pixel. Then adjust it
+ * so that it divides evenly into the total.
+ * I'm just using cdt 'cause I'm lazy.
+ */
+ cdt = parc->width;
+ if (parc->height > cdt)
+ cdt = parc->height;
+ cdt /= 2.0;
+ if(cdt <= 0)
+ return 0;
+ if (cdt < 1.0)
+ cdt = 1.0;
+ dt = miDasin ( 1.0 / cdt ); /* minimum step necessary */
+ count = et/dt;
+ count = abs(count) + 1;
+ dt = et/count;
+ count++;
+
+ cdt = 2 * miDcos(dt);
+ if (!(poly = (SppPointPtr) realloc((void *)*ppPts,
+ (cpt + count) * sizeof(SppPointRec))))
+ return(0);
+ *ppPts = poly;
+
+ xc = parc->width/2.0; /* store half width and half height */
+ yc = parc->height/2.0;
+
+ x0 = xc * miDcos(st);
+ y0 = yc * miDsin(st);
+ x1 = xc * miDcos(st + dt);
+ y1 = yc * miDsin(st + dt);
+ xc += parc->x; /* by adding initial point, these become */
+ yc += parc->y; /* the center point */
+
+ poly[cpt].x = (xc + x0);
+ poly[cpt].y = (yc + y0);
+ poly[cpt + 1].x = (xc + x1);
+ poly[cpt + 1].y = (yc + y1);
+
+ for(i = 2; i < count; i++)
+ {
+ x2 = cdt * x1 - x0;
+ y2 = cdt * y1 - y0;
+
+ poly[cpt + i].x = (xc + x2);
+ poly[cpt + i].y = (yc + y2);
+
+ x0 = x1; y0 = y1;
+ x1 = x2; y1 = y2;
+ }
+ /* adjust the last point */
+ if (abs(parc->angle2) >= 360.0)
+ poly[cpt +i -1] = poly[0];
+ else {
+ poly[cpt +i -1].x = (miDcos(st + et) * parc->width/2.0 + xc);
+ poly[cpt +i -1].y = (miDsin(st + et) * parc->height/2.0 + yc);
+ }
+
+ return(count);
+}
+
+struct arcData {
+ double x0, y0, x1, y1;
+ int selfJoin;
+};
+
+# define ADD_REALLOC_STEP 20
+
+static void
+addCap (
+ miArcCapPtr *capsp,
+ int *ncapsp,
+ int *sizep,
+ int end,
+ int arcIndex)
+{
+ int newsize;
+ miArcCapPtr cap;
+
+ if (*ncapsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ cap = (miArcCapPtr) realloc (*capsp,
+ newsize * sizeof (**capsp));
+ if (!cap)
+ return;
+ *sizep = newsize;
+ *capsp = cap;
+ }
+ cap = &(*capsp)[*ncapsp];
+ cap->end = end;
+ cap->arcIndex = arcIndex;
+ ++*ncapsp;
+}
+
+static void
+addJoin (
+ miArcJoinPtr *joinsp,
+ int *njoinsp,
+ int *sizep,
+ int end0,
+ int index0,
+ int phase0,
+ int end1,
+ int index1,
+ int phase1)
+{
+ int newsize;
+ miArcJoinPtr join;
+
+ if (*njoinsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ join = (miArcJoinPtr) realloc (*joinsp,
+ newsize * sizeof (**joinsp));
+ if (!join)
+ return;
+ *sizep = newsize;
+ *joinsp = join;
+ }
+ join = &(*joinsp)[*njoinsp];
+ join->end0 = end0;
+ join->arcIndex0 = index0;
+ join->phase0 = phase0;
+ join->end1 = end1;
+ join->arcIndex1 = index1;
+ join->phase1 = phase1;
+ ++*njoinsp;
+}
+
+static miArcDataPtr
+addArc (
+ miArcDataPtr *arcsp,
+ int *narcsp,
+ int *sizep,
+ xArc *xarc)
+{
+ int newsize;
+ miArcDataPtr arc;
+
+ if (*narcsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ arc = (miArcDataPtr) realloc (*arcsp,
+ newsize * sizeof (**arcsp));
+ if (!arc)
+ return (miArcDataPtr)NULL;
+ *sizep = newsize;
+ *arcsp = arc;
+ }
+ arc = &(*arcsp)[*narcsp];
+ arc->arc = *xarc;
+ ++*narcsp;
+ return arc;
+}
+
+static void
+miFreeArcs(
+ miPolyArcPtr arcs,
+ GCPtr pGC)
+{
+ int iphase;
+
+ for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0);
+ iphase >= 0;
+ iphase--)
+ {
+ if (arcs[iphase].narcs > 0)
+ free(arcs[iphase].arcs);
+ if (arcs[iphase].njoins > 0)
+ free(arcs[iphase].joins);
+ if (arcs[iphase].ncaps > 0)
+ free(arcs[iphase].caps);
+ }
+ free(arcs);
+}
+
+/*
+ * map angles to radial distance. This only deals with the first quadrant
+ */
+
+/*
+ * a polygonal approximation to the arc for computing arc lengths
+ */
+
+# define DASH_MAP_SIZE 91
+
+# define dashIndexToAngle(di) ((((double) (di)) * 90.0) / ((double) DASH_MAP_SIZE - 1))
+# define xAngleToDashIndex(xa) ((((long) (xa)) * (DASH_MAP_SIZE - 1)) / (90 * 64))
+# define dashIndexToXAngle(di) ((((long) (di)) * (90 * 64)) / (DASH_MAP_SIZE - 1))
+# define dashXAngleStep (((double) (90 * 64)) / ((double) (DASH_MAP_SIZE - 1)))
+
+typedef struct {
+ double map[DASH_MAP_SIZE];
+} dashMap;
+
+static int computeAngleFromPath(int startAngle, int endAngle, dashMap *map,
+ int *lenp, int backwards);
+
+static void
+computeDashMap (
+ xArc *arcp,
+ dashMap *map)
+{
+ int di;
+ double a, x, y, prevx = 0.0, prevy = 0.0, dist;
+
+ for (di = 0; di < DASH_MAP_SIZE; di++) {
+ a = dashIndexToAngle (di);
+ x = ((double) arcp->width / 2.0) * miDcos (a);
+ y = ((double) arcp->height / 2.0) * miDsin (a);
+ if (di == 0) {
+ map->map[di] = 0.0;
+ } else {
+ dist = hypot (x - prevx, y - prevy);
+ map->map[di] = map->map[di - 1] + dist;
+ }
+ prevx = x;
+ prevy = y;
+ }
+}
+
+typedef enum {HORIZONTAL, VERTICAL, OTHER} arcTypes;
+
+/* this routine is a bit gory */
+
+static miPolyArcPtr
+miComputeArcs (
+ xArc *parcs,
+ int narcs,
+ GCPtr pGC)
+{
+ int isDashed, isDoubleDash;
+ int dashOffset;
+ miPolyArcPtr arcs;
+ int start, i, j, k = 0, nexti, nextk = 0;
+ int joinSize[2];
+ int capSize[2];
+ int arcSize[2];
+ int angle2;
+ double a0, a1;
+ struct arcData *data;
+ miArcDataPtr arc;
+ xArc xarc;
+ int iphase, prevphase = 0, joinphase;
+ int arcsJoin;
+ int selfJoin;
+
+ int iDash = 0, dashRemaining = 0;
+ int iDashStart = 0, dashRemainingStart = 0, iphaseStart;
+ int startAngle, spanAngle, endAngle, backwards = 0;
+ int prevDashAngle, dashAngle;
+ dashMap map;
+
+ isDashed = !(pGC->lineStyle == LineSolid);
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashOffset = pGC->dashOffset;
+
+ data = (struct arcData *) malloc (narcs * sizeof (struct arcData));
+ if (!data)
+ return (miPolyArcPtr)NULL;
+ arcs = (miPolyArcPtr) malloc (sizeof (*arcs) * (isDoubleDash ? 2 : 1));
+ if (!arcs)
+ {
+ free(data);
+ return (miPolyArcPtr)NULL;
+ }
+ for (i = 0; i < narcs; i++) {
+ a0 = todeg (parcs[i].angle1);
+ angle2 = parcs[i].angle2;
+ if (angle2 > FULLCIRCLE)
+ angle2 = FULLCIRCLE;
+ else if (angle2 < -FULLCIRCLE)
+ angle2 = -FULLCIRCLE;
+ data[i].selfJoin = angle2 == FULLCIRCLE || angle2 == -FULLCIRCLE;
+ a1 = todeg (parcs[i].angle1 + angle2);
+ data[i].x0 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a0));
+ data[i].y0 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a0));
+ data[i].x1 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a1));
+ data[i].y1 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a1));
+ }
+
+ for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) {
+ arcs[iphase].njoins = 0;
+ arcs[iphase].joins = 0;
+ joinSize[iphase] = 0;
+
+ arcs[iphase].ncaps = 0;
+ arcs[iphase].caps = 0;
+ capSize[iphase] = 0;
+
+ arcs[iphase].narcs = 0;
+ arcs[iphase].arcs = 0;
+ arcSize[iphase] = 0;
+ }
+
+ iphase = 0;
+ if (isDashed) {
+ iDash = 0;
+ dashRemaining = pGC->dash[0];
+ while (dashOffset > 0) {
+ if (dashOffset >= dashRemaining) {
+ dashOffset -= dashRemaining;
+ iphase = iphase ? 0 : 1;
+ iDash++;
+ if (iDash == pGC->numInDashList)
+ iDash = 0;
+ dashRemaining = pGC->dash[iDash];
+ } else {
+ dashRemaining -= dashOffset;
+ dashOffset = 0;
+ }
+ }
+ iDashStart = iDash;
+ dashRemainingStart = dashRemaining;
+ }
+ iphaseStart = iphase;
+
+ for (i = narcs - 1; i >= 0; i--) {
+ j = i + 1;
+ if (j == narcs)
+ j = 0;
+ if (data[i].selfJoin || i == j ||
+ (UNEQUAL (data[i].x1, data[j].x0) ||
+ UNEQUAL (data[i].y1, data[j].y0)))
+ {
+ if (iphase == 0 || isDoubleDash)
+ addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END, 0);
+ break;
+ }
+ }
+ start = i + 1;
+ if (start == narcs)
+ start = 0;
+ i = start;
+ for (;;) {
+ j = i + 1;
+ if (j == narcs)
+ j = 0;
+ nexti = i+1;
+ if (nexti == narcs)
+ nexti = 0;
+ if (isDashed) {
+ /*
+ ** deal with dashed arcs. Use special rules for certain 0 area arcs.
+ ** Presumably, the other 0 area arcs still aren't done right.
+ */
+ arcTypes arcType = OTHER;
+ CARD16 thisLength;
+
+ if (parcs[i].height == 0
+ && (parcs[i].angle1 % FULLCIRCLE) == 0x2d00
+ && parcs[i].angle2 == 0x2d00)
+ arcType = HORIZONTAL;
+ else if (parcs[i].width == 0
+ && (parcs[i].angle1 % FULLCIRCLE) == 0x1680
+ && parcs[i].angle2 == 0x2d00)
+ arcType = VERTICAL;
+ if (arcType == OTHER) {
+ /*
+ * precompute an approximation map
+ */
+ computeDashMap (&parcs[i], &map);
+ /*
+ * compute each individual dash segment using the path
+ * length function
+ */
+ startAngle = parcs[i].angle1;
+ spanAngle = parcs[i].angle2;
+ if (spanAngle > FULLCIRCLE)
+ spanAngle = FULLCIRCLE;
+ else if (spanAngle < -FULLCIRCLE)
+ spanAngle = -FULLCIRCLE;
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ endAngle = startAngle + spanAngle;
+ backwards = spanAngle < 0;
+ } else {
+ xarc = parcs[i];
+ if (arcType == VERTICAL) {
+ xarc.angle1 = 0x1680;
+ startAngle = parcs[i].y;
+ endAngle = startAngle + parcs[i].height;
+ } else {
+ xarc.angle1 = 0x2d00;
+ startAngle = parcs[i].x;
+ endAngle = startAngle + parcs[i].width;
+ }
+ }
+ dashAngle = startAngle;
+ selfJoin = data[i].selfJoin &&
+ (iphase == 0 || isDoubleDash);
+ /*
+ * add dashed arcs to each bucket
+ */
+ arc = 0;
+ while (dashAngle != endAngle) {
+ prevDashAngle = dashAngle;
+ if (arcType == OTHER) {
+ dashAngle = computeAngleFromPath (prevDashAngle, endAngle,
+ &map, &dashRemaining, backwards);
+ /* avoid troubles with huge arcs and small dashes */
+ if (dashAngle == prevDashAngle) {
+ if (backwards)
+ dashAngle--;
+ else
+ dashAngle++;
+ }
+ } else {
+ thisLength = (dashAngle + dashRemaining <= endAngle) ?
+ dashRemaining : endAngle - dashAngle;
+ if (arcType == VERTICAL) {
+ xarc.y = dashAngle;
+ xarc.height = thisLength;
+ } else {
+ xarc.x = dashAngle;
+ xarc.width = thisLength;
+ }
+ dashAngle += thisLength;
+ dashRemaining -= thisLength;
+ }
+ if (iphase == 0 || isDoubleDash) {
+ if (arcType == OTHER) {
+ xarc = parcs[i];
+ spanAngle = prevDashAngle;
+ if (spanAngle < 0)
+ spanAngle = FULLCIRCLE - (-spanAngle) % FULLCIRCLE;
+ if (spanAngle >= FULLCIRCLE)
+ spanAngle = spanAngle % FULLCIRCLE;
+ xarc.angle1 = spanAngle;
+ spanAngle = dashAngle - prevDashAngle;
+ if (backwards) {
+ if (dashAngle > prevDashAngle)
+ spanAngle = - FULLCIRCLE + spanAngle;
+ } else {
+ if (dashAngle < prevDashAngle)
+ spanAngle = FULLCIRCLE + spanAngle;
+ }
+ if (spanAngle > FULLCIRCLE)
+ spanAngle = FULLCIRCLE;
+ if (spanAngle < -FULLCIRCLE)
+ spanAngle = -FULLCIRCLE;
+ xarc.angle2 = spanAngle;
+ }
+ arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
+ &arcSize[iphase], &xarc);
+ if (!arc)
+ goto arcfail;
+ /*
+ * cap each end of an on/off dash
+ */
+ if (!isDoubleDash) {
+ if (prevDashAngle != startAngle) {
+ addCap (&arcs[iphase].caps,
+ &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END,
+ arc - arcs[iphase].arcs);
+
+ }
+ if (dashAngle != endAngle) {
+ addCap (&arcs[iphase].caps,
+ &arcs[iphase].ncaps,
+ &capSize[iphase], LEFT_END,
+ arc - arcs[iphase].arcs);
+ }
+ }
+ arc->cap = arcs[iphase].ncaps;
+ arc->join = arcs[iphase].njoins;
+ arc->render = 0;
+ arc->selfJoin = 0;
+ if (dashAngle == endAngle)
+ arc->selfJoin = selfJoin;
+ }
+ prevphase = iphase;
+ if (dashRemaining <= 0) {
+ ++iDash;
+ if (iDash == pGC->numInDashList)
+ iDash = 0;
+ iphase = iphase ? 0:1;
+ dashRemaining = pGC->dash[iDash];
+ }
+ }
+ /*
+ * make sure a place exists for the position data when
+ * drawing a zero-length arc
+ */
+ if (startAngle == endAngle) {
+ prevphase = iphase;
+ if (!isDoubleDash && iphase == 1)
+ prevphase = 0;
+ arc = addArc (&arcs[prevphase].arcs, &arcs[prevphase].narcs,
+ &arcSize[prevphase], &parcs[i]);
+ if (!arc)
+ goto arcfail;
+ arc->join = arcs[prevphase].njoins;
+ arc->cap = arcs[prevphase].ncaps;
+ arc->selfJoin = data[i].selfJoin;
+ }
+ } else {
+ arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
+ &arcSize[iphase], &parcs[i]);
+ if (!arc)
+ goto arcfail;
+ arc->join = arcs[iphase].njoins;
+ arc->cap = arcs[iphase].ncaps;
+ arc->selfJoin = data[i].selfJoin;
+ prevphase = iphase;
+ }
+ if (prevphase == 0 || isDoubleDash)
+ k = arcs[prevphase].narcs - 1;
+ if (iphase == 0 || isDoubleDash)
+ nextk = arcs[iphase].narcs;
+ if (nexti == start) {
+ nextk = 0;
+ if (isDashed) {
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ }
+ arcsJoin = narcs > 1 && i != j &&
+ ISEQUAL (data[i].x1, data[j].x0) &&
+ ISEQUAL (data[i].y1, data[j].y0) &&
+ !data[i].selfJoin && !data[j].selfJoin;
+ if (arc)
+ {
+ if (arcsJoin)
+ arc->render = 0;
+ else
+ arc->render = 1;
+ }
+ if (arcsJoin &&
+ (prevphase == 0 || isDoubleDash) &&
+ (iphase == 0 || isDoubleDash))
+ {
+ joinphase = iphase;
+ if (isDoubleDash) {
+ if (nexti == start)
+ joinphase = iphaseStart;
+ /*
+ * if the join is right at the dash,
+ * draw the join in foreground
+ * This is because the foreground
+ * arcs are computed second, the results
+ * of which are needed to draw the join
+ */
+ if (joinphase != prevphase)
+ joinphase = 0;
+ }
+ if (joinphase == 0 || isDoubleDash) {
+ addJoin (&arcs[joinphase].joins,
+ &arcs[joinphase].njoins,
+ &joinSize[joinphase],
+ LEFT_END, k, prevphase,
+ RIGHT_END, nextk, iphase);
+ arc->join = arcs[prevphase].njoins;
+ }
+ } else {
+ /*
+ * cap the left end of this arc
+ * unless it joins itself
+ */
+ if ((prevphase == 0 || isDoubleDash) &&
+ !arc->selfJoin)
+ {
+ addCap (&arcs[prevphase].caps, &arcs[prevphase].ncaps,
+ &capSize[prevphase], LEFT_END, k);
+ arc->cap = arcs[prevphase].ncaps;
+ }
+ if (isDashed && !arcsJoin) {
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ nextk = arcs[iphase].narcs;
+ if (nexti == start) {
+ nextk = 0;
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ /*
+ * cap the right end of the next arc. If the
+ * next arc is actually the first arc, only
+ * cap it if it joins with this arc. This
+ * case will occur when the final dash segment
+ * of an on/off dash is off. Of course, this
+ * cap will be drawn at a strange time, but that
+ * hardly matters...
+ */
+ if ((iphase == 0 || isDoubleDash) &&
+ (nexti != start || (arcsJoin && isDashed)))
+ addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END, nextk);
+ }
+ i = nexti;
+ if (i == start)
+ break;
+ }
+ /*
+ * make sure the last section is rendered
+ */
+ for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++)
+ if (arcs[iphase].narcs > 0) {
+ arcs[iphase].arcs[arcs[iphase].narcs-1].render = 1;
+ arcs[iphase].arcs[arcs[iphase].narcs-1].join =
+ arcs[iphase].njoins;
+ arcs[iphase].arcs[arcs[iphase].narcs-1].cap =
+ arcs[iphase].ncaps;
+ }
+ free(data);
+ return arcs;
+arcfail:
+ miFreeArcs(arcs, pGC);
+ free(data);
+ return (miPolyArcPtr)NULL;
+}
+
+static double
+angleToLength (
+ int angle,
+ dashMap *map)
+{
+ double len, excesslen, sidelen = map->map[DASH_MAP_SIZE - 1], totallen;
+ int di;
+ int excess;
+ Bool oddSide = FALSE;
+
+ totallen = 0;
+ if (angle >= 0) {
+ while (angle >= 90 * 64) {
+ angle -= 90 * 64;
+ totallen += sidelen;
+ oddSide = !oddSide;
+ }
+ } else {
+ while (angle < 0) {
+ angle += 90 * 64;
+ totallen -= sidelen;
+ oddSide = !oddSide;
+ }
+ }
+ if (oddSide)
+ angle = 90 * 64 - angle;
+
+ di = xAngleToDashIndex (angle);
+ excess = angle - dashIndexToXAngle (di);
+
+ len = map->map[di];
+ /*
+ * linearly interpolate between this point and the next
+ */
+ if (excess > 0) {
+ excesslen = (map->map[di + 1] - map->map[di]) *
+ ((double) excess) / dashXAngleStep;
+ len += excesslen;
+ }
+ if (oddSide)
+ totallen += (sidelen - len);
+ else
+ totallen += len;
+ return totallen;
+}
+
+/*
+ * len is along the arc, but may be more than one rotation
+ */
+
+static int
+lengthToAngle (
+ double len,
+ dashMap *map)
+{
+ double sidelen = map->map[DASH_MAP_SIZE - 1];
+ int angle, angleexcess;
+ Bool oddSide = FALSE;
+ int a0, a1, a;
+
+ angle = 0;
+ /*
+ * step around the ellipse, subtracting sidelens and
+ * adding 90 degrees. oddSide will tell if the
+ * map should be interpolated in reverse
+ */
+ if (len >= 0) {
+ if (sidelen == 0)
+ return 2 * FULLCIRCLE; /* infinity */
+ while (len >= sidelen) {
+ angle += 90 * 64;
+ len -= sidelen;
+ oddSide = !oddSide;
+ }
+ } else {
+ if (sidelen == 0)
+ return -2 * FULLCIRCLE; /* infinity */
+ while (len < 0) {
+ angle -= 90 * 64;
+ len += sidelen;
+ oddSide = !oddSide;
+ }
+ }
+ if (oddSide)
+ len = sidelen - len;
+ a0 = 0;
+ a1 = DASH_MAP_SIZE - 1;
+ /*
+ * binary search for the closest pre-computed length
+ */
+ while (a1 - a0 > 1) {
+ a = (a0 + a1) / 2;
+ if (len > map->map[a])
+ a0 = a;
+ else
+ a1 = a;
+ }
+ angleexcess = dashIndexToXAngle (a0);
+ /*
+ * linearly interpolate to the next point
+ */
+ angleexcess += (len - map->map[a0]) /
+ (map->map[a0+1] - map->map[a0]) * dashXAngleStep;
+ if (oddSide)
+ angle += (90 * 64) - angleexcess;
+ else
+ angle += angleexcess;
+ return angle;
+}
+
+/*
+ * compute the angle of an ellipse which cooresponds to
+ * the given path length. Note that the correct solution
+ * to this problem is an eliptic integral, we'll punt and
+ * approximate (it's only for dashes anyway). This
+ * approximation uses a polygon.
+ *
+ * The remaining portion of len is stored in *lenp -
+ * this will be negative if the arc extends beyond
+ * len and positive if len extends beyond the arc.
+ */
+
+static int
+computeAngleFromPath (
+ int startAngle,
+ int endAngle, /* normalized absolute angles in *64 degrees */
+ dashMap *map,
+ int *lenp,
+ int backwards)
+{
+ int a0, a1, a;
+ double len0;
+ int len;
+
+ a0 = startAngle;
+ a1 = endAngle;
+ len = *lenp;
+ if (backwards) {
+ /*
+ * flip the problem around to always be
+ * forwards
+ */
+ a0 = FULLCIRCLE - a0;
+ a1 = FULLCIRCLE - a1;
+ }
+ if (a1 < a0)
+ a1 += FULLCIRCLE;
+ len0 = angleToLength (a0, map);
+ a = lengthToAngle (len0 + len, map);
+ if (a > a1) {
+ a = a1;
+ len -= angleToLength (a1, map) - len0;
+ } else
+ len = 0;
+ if (backwards)
+ a = FULLCIRCLE - a;
+ *lenp = len;
+ return a;
+}
+
+/*
+ * scan convert wide arcs.
+ */
+
+/*
+ * draw zero width/height arcs
+ */
+
+static void
+drawZeroArc (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *tarc,
+ int lw,
+ miArcFacePtr left,
+ miArcFacePtr right)
+{
+ double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0, w, h, x, y;
+ double xmax, ymax, xmin, ymin;
+ int a0, a1;
+ double a, startAngle, endAngle;
+ double l, lx, ly;
+
+ l = lw / 2.0;
+ a0 = tarc->angle1;
+ a1 = tarc->angle2;
+ if (a1 > FULLCIRCLE)
+ a1 = FULLCIRCLE;
+ else if (a1 < -FULLCIRCLE)
+ a1 = -FULLCIRCLE;
+ w = (double)tarc->width / 2.0;
+ h = (double)tarc->height / 2.0;
+ /*
+ * play in X coordinates right away
+ */
+ startAngle = - ((double) a0 / 64.0);
+ endAngle = - ((double) (a0 + a1) / 64.0);
+
+ xmax = -w;
+ xmin = w;
+ ymax = -h;
+ ymin = h;
+ a = startAngle;
+ for (;;)
+ {
+ x = w * miDcos(a);
+ y = h * miDsin(a);
+ if (a == startAngle)
+ {
+ x0 = x;
+ y0 = y;
+ }
+ if (a == endAngle)
+ {
+ x1 = x;
+ y1 = y;
+ }
+ if (x > xmax)
+ xmax = x;
+ if (x < xmin)
+ xmin = x;
+ if (y > ymax)
+ ymax = y;
+ if (y < ymin)
+ ymin = y;
+ if (a == endAngle)
+ break;
+ if (a1 < 0) /* clockwise */
+ {
+ if (floor (a / 90.0) == floor (endAngle / 90.0))
+ a = endAngle;
+ else
+ a = 90 * (floor (a/90.0) + 1);
+ }
+ else
+ {
+ if (ceil (a / 90.0) == ceil (endAngle / 90.0))
+ a = endAngle;
+ else
+ a = 90 * (ceil (a/90.0) - 1);
+ }
+ }
+ lx = ly = l;
+ if ((x1 - x0) + (y1 - y0) < 0)
+ lx = ly = -l;
+ if (h)
+ {
+ ly = 0.0;
+ lx = -lx;
+ }
+ else
+ lx = 0.0;
+ if (right)
+ {
+ right->center.x = x0;
+ right->center.y = y0;
+ right->clock.x = x0 - lx;
+ right->clock.y = y0 - ly;
+ right->counterClock.x = x0 + lx;
+ right->counterClock.y = y0 + ly;
+ }
+ if (left)
+ {
+ left->center.x = x1;
+ left->center.y = y1;
+ left->clock.x = x1 + lx;
+ left->clock.y = y1 + ly;
+ left->counterClock.x = x1 - lx;
+ left->counterClock.y = y1 - ly;
+ }
+
+ x0 = xmin;
+ x1 = xmax;
+ y0 = ymin;
+ y1 = ymax;
+ if (ymin != y1) {
+ xmin = -l;
+ xmax = l;
+ } else {
+ ymin = -l;
+ ymax = l;
+ }
+ if (xmax != xmin && ymax != ymin) {
+ int minx, maxx, miny, maxy;
+ xRectangle rect;
+
+ minx = ICEIL (xmin + w) + tarc->x;
+ maxx = ICEIL (xmax + w) + tarc->x;
+ miny = ICEIL (ymin + h) + tarc->y;
+ maxy = ICEIL (ymax + h) + tarc->y;
+ rect.x = minx;
+ rect.y = miny;
+ rect.width = maxx - minx;
+ rect.height = maxy - miny;
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect);
+ }
+}
+
+/*
+ * this computes the ellipse y value associated with the
+ * bottom of the tail.
+ */
+
+static void
+tailEllipseY (
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ double t;
+
+ acc->tail_y = 0.0;
+ if (def->w == def->h)
+ return;
+ t = def->l * def->w;
+ if (def->w > def->h) {
+ if (t < acc->h2)
+ return;
+ } else {
+ if (t > acc->h2)
+ return;
+ }
+ t = 2.0 * def->h * t;
+ t = (CUBED_ROOT_4 * acc->h2 - cbrt(t * t)) / acc->h2mw2;
+ if (t > 0.0)
+ acc->tail_y = def->h / CUBED_ROOT_2 * sqrt(t);
+}
+
+/*
+ * inverse functions -- compute edge coordinates
+ * from the ellipse
+ */
+
+static double
+outerXfromXY (
+ double x,
+ double y,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ return x + (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+outerYfromXY (
+ double x,
+ double y,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ return y + (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerXfromXY (
+ double x,
+ double y,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ return x - (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerYfromXY (
+ double x,
+ double y,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerYfromY (
+ double y,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ double x;
+
+ x = (def->w / def->h) * sqrt (acc->h2 - y*y);
+
+ return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static void
+computeLine (
+ double x1,
+ double y1,
+ double x2,
+ double y2,
+ struct line *line)
+{
+ if (y1 == y2)
+ line->valid = 0;
+ else {
+ line->m = (x1 - x2) / (y1 - y2);
+ line->b = x1 - y1 * line->m;
+ line->valid = 1;
+ }
+}
+
+/*
+ * compute various accelerators for an ellipse. These
+ * are simply values that are used repeatedly in
+ * the computations
+ */
+
+static void
+computeAcc (
+ xArc *tarc,
+ int lw,
+ struct arc_def *def,
+ struct accelerators *acc)
+{
+ def->w = ((double) tarc->width) / 2.0;
+ def->h = ((double) tarc->height) / 2.0;
+ def->l = ((double) lw) / 2.0;
+ acc->h2 = def->h * def->h;
+ acc->w2 = def->w * def->w;
+ acc->h4 = acc->h2 * acc->h2;
+ acc->w4 = acc->w2 * acc->w2;
+ acc->h2l = acc->h2 * def->l;
+ acc->w2l = acc->w2 * def->l;
+ acc->h2mw2 = acc->h2 - acc->w2;
+ acc->fromIntX = (tarc->width & 1) ? 0.5 : 0.0;
+ acc->fromIntY = (tarc->height & 1) ? 0.5 : 0.0;
+ acc->xorg = tarc->x + (tarc->width >> 1);
+ acc->yorgu = tarc->y + (tarc->height >> 1);
+ acc->yorgl = acc->yorgu + (tarc->height & 1);
+ tailEllipseY (def, acc);
+}
+
+/*
+ * compute y value bounds of various portions of the arc,
+ * the outer edge, the ellipse and the inner edge.
+ */
+
+static void
+computeBound (
+ struct arc_def *def,
+ struct arc_bound *bound,
+ struct accelerators *acc,
+ miArcFacePtr right,
+ miArcFacePtr left)
+{
+ double t;
+ double innerTaily;
+ double tail_y;
+ struct bound innerx, outerx;
+ struct bound ellipsex;
+
+ bound->ellipse.min = Dsin (def->a0) * def->h;
+ bound->ellipse.max = Dsin (def->a1) * def->h;
+ if (def->a0 == 45 && def->w == def->h)
+ ellipsex.min = bound->ellipse.min;
+ else
+ ellipsex.min = Dcos (def->a0) * def->w;
+ if (def->a1 == 45 && def->w == def->h)
+ ellipsex.max = bound->ellipse.max;
+ else
+ ellipsex.max = Dcos (def->a1) * def->w;
+ bound->outer.min = outerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ bound->outer.max = outerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+ bound->inner.min = innerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ bound->inner.max = innerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+
+ outerx.min = outerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ outerx.max = outerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+ innerx.min = innerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ innerx.max = innerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+
+ /*
+ * save the line end points for the
+ * cap code to use. Careful here, these are
+ * in cartesean coordinates (y increasing upwards)
+ * while the cap code uses inverted coordinates
+ * (y increasing downwards)
+ */
+
+ if (right) {
+ right->counterClock.y = bound->outer.min;
+ right->counterClock.x = outerx.min;
+ right->center.y = bound->ellipse.min;
+ right->center.x = ellipsex.min;
+ right->clock.y = bound->inner.min;
+ right->clock.x = innerx.min;
+ }
+
+ if (left) {
+ left->clock.y = bound->outer.max;
+ left->clock.x = outerx.max;
+ left->center.y = bound->ellipse.max;
+ left->center.x = ellipsex.max;
+ left->counterClock.y = bound->inner.max;
+ left->counterClock.x = innerx.max;
+ }
+
+ bound->left.min = bound->inner.max;
+ bound->left.max = bound->outer.max;
+ bound->right.min = bound->inner.min;
+ bound->right.max = bound->outer.min;
+
+ computeLine (innerx.min, bound->inner.min, outerx.min, bound->outer.min,
+ &acc->right);
+ computeLine (innerx.max, bound->inner.max, outerx.max, bound->outer.max,
+ &acc->left);
+
+ if (bound->inner.min > bound->inner.max) {
+ t = bound->inner.min;
+ bound->inner.min = bound->inner.max;
+ bound->inner.max = t;
+ }
+ tail_y = acc->tail_y;
+ if (tail_y > bound->ellipse.max)
+ tail_y = bound->ellipse.max;
+ else if (tail_y < bound->ellipse.min)
+ tail_y = bound->ellipse.min;
+ innerTaily = innerYfromY (tail_y, def, acc);
+ if (bound->inner.min > innerTaily)
+ bound->inner.min = innerTaily;
+ if (bound->inner.max < innerTaily)
+ bound->inner.max = innerTaily;
+ bound->inneri.min = ICEIL(bound->inner.min - acc->fromIntY);
+ bound->inneri.max = floor(bound->inner.max - acc->fromIntY);
+ bound->outeri.min = ICEIL(bound->outer.min - acc->fromIntY);
+ bound->outeri.max = floor(bound->outer.max - acc->fromIntY);
+}
+
+/*
+ * this section computes the x value of the span at y
+ * intersected with the specified face of the ellipse.
+ *
+ * this is the min/max X value over the set of normal
+ * lines to the entire ellipse, the equation of the
+ * normal lines is:
+ *
+ * ellipse_x h^2 h^2
+ * x = ------------ y + ellipse_x (1 - --- )
+ * ellipse_y w^2 w^2
+ *
+ * compute the derivative with-respect-to ellipse_y and solve
+ * for zero:
+ *
+ * (w^2 - h^2) ellipse_y^3 + h^4 y
+ * 0 = - ----------------------------------
+ * h w ellipse_y^2 sqrt (h^2 - ellipse_y^2)
+ *
+ * ( h^4 y )
+ * ellipse_y = ( ---------- ) ^ (1/3)
+ * ( (h^2 - w^2) )
+ *
+ * The other two solutions to the equation are imaginary.
+ *
+ * This gives the position on the ellipse which generates
+ * the normal with the largest/smallest x intersection point.
+ *
+ * Now compute the second derivative to check whether
+ * the intersection is a minimum or maximum:
+ *
+ * h (y0^3 (w^2 - h^2) + h^2 y (3y0^2 - 2h^2))
+ * - -------------------------------------------
+ * w y0^3 (sqrt (h^2 - y^2)) ^ 3
+ *
+ * as we only care about the sign,
+ *
+ * - (y0^3 (w^2 - h^2) + h^2 y (3y0^2 - 2h^2))
+ *
+ * or (to use accelerators),
+ *
+ * y0^3 (h^2 - w^2) - h^2 y (3y0^2 - 2h^2)
+ *
+ */
+
+/*
+ * computes the position on the ellipse whose normal line
+ * intersects the given scan line maximally
+ */
+
+static double
+hookEllipseY (
+ double scan_y,
+ struct arc_bound *bound,
+ struct accelerators *acc,
+ int left)
+{
+ double ret;
+
+ if (acc->h2mw2 == 0) {
+ if ( (scan_y > 0 && !left) || (scan_y < 0 && left) )
+ return bound->ellipse.min;
+ return bound->ellipse.max;
+ }
+ ret = (acc->h4 * scan_y) / (acc->h2mw2);
+ if (ret >= 0)
+ return cbrt (ret);
+ else
+ return -cbrt (-ret);
+}
+
+/*
+ * computes the X value of the intersection of the
+ * given scan line with the right side of the lower hook
+ */
+
+static double
+hookX (
+ double scan_y,
+ struct arc_def *def,
+ struct arc_bound *bound,
+ struct accelerators *acc,
+ int left)
+{
+ double ellipse_y, x;
+ double maxMin;
+
+ if (def->w != def->h) {
+ ellipse_y = hookEllipseY (scan_y, bound, acc, left);
+ if (boundedLe (ellipse_y, bound->ellipse)) {
+ /*
+ * compute the value of the second
+ * derivative
+ */
+ maxMin = ellipse_y*ellipse_y*ellipse_y * acc->h2mw2 -
+ acc->h2 * scan_y * (3 * ellipse_y*ellipse_y - 2*acc->h2);
+ if ((left && maxMin > 0) || (!left && maxMin < 0)) {
+ if (ellipse_y == 0)
+ return def->w + left ? -def->l : def->l;
+ x = (acc->h2 * scan_y - ellipse_y * acc->h2mw2) *
+ sqrt (acc->h2 - ellipse_y * ellipse_y) /
+ (def->h * def->w * ellipse_y);
+ return x;
+ }
+ }
+ }
+ if (left) {
+ if (acc->left.valid && boundedLe (scan_y, bound->left)) {
+ x = intersectLine (scan_y, acc->left);
+ } else {
+ if (acc->right.valid)
+ x = intersectLine (scan_y, acc->right);
+ else
+ x = def->w - def->l;
+ }
+ } else {
+ if (acc->right.valid && boundedLe (scan_y, bound->right)) {
+ x = intersectLine (scan_y, acc->right);
+ } else {
+ if (acc->left.valid)
+ x = intersectLine (scan_y, acc->left);
+ else
+ x = def->w - def->l;
+ }
+ }
+ return x;
+}
+
+/*
+ * generate the set of spans with
+ * the given y coordinate
+ */
+
+static void
+arcSpan (
+ int y,
+ int lx,
+ int lw,
+ int rx,
+ int rw,
+ struct arc_def *def,
+ struct arc_bound *bounds,
+ struct accelerators *acc,
+ int mask)
+{
+ int linx, loutx, rinx, routx;
+ double x, altx;
+
+ if (boundedLe (y, bounds->inneri)) {
+ linx = -(lx + lw);
+ rinx = rx;
+ } else {
+ /*
+ * intersection with left face
+ */
+ x = hookX (y + acc->fromIntY, def, bounds, acc, 1);
+ if (acc->right.valid &&
+ boundedLe (y + acc->fromIntY, bounds->right))
+ {
+ altx = intersectLine (y + acc->fromIntY, acc->right);
+ if (altx < x)
+ x = altx;
+ }
+ linx = -ICEIL(acc->fromIntX - x);
+ rinx = ICEIL(acc->fromIntX + x);
+ }
+ if (boundedLe (y, bounds->outeri)) {
+ loutx = -lx;
+ routx = rx + rw;
+ } else {
+ /*
+ * intersection with right face
+ */
+ x = hookX (y + acc->fromIntY, def, bounds, acc, 0);
+ if (acc->left.valid &&
+ boundedLe (y + acc->fromIntY, bounds->left))
+ {
+ altx = x;
+ x = intersectLine (y + acc->fromIntY, acc->left);
+ if (x < altx)
+ x = altx;
+ }
+ loutx = -ICEIL(acc->fromIntX - x);
+ routx = ICEIL(acc->fromIntX + x);
+ }
+ if (routx > rinx) {
+ if (mask & 1)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg + rinx, acc->xorg + routx);
+ if (mask & 8)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg + rinx, acc->xorg + routx);
+ }
+ if (loutx > linx) {
+ if (mask & 2)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg - loutx, acc->xorg - linx);
+ if (mask & 4)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg - loutx, acc->xorg - linx);
+ }
+}
+
+static void
+arcSpan0 (
+ int lx,
+ int lw,
+ int rx,
+ int rw,
+ struct arc_def *def,
+ struct arc_bound *bounds,
+ struct accelerators *acc,
+ int mask)
+{
+ double x;
+
+ if (boundedLe (0, bounds->inneri) &&
+ acc->left.valid && boundedLe (0, bounds->left) &&
+ acc->left.b > 0)
+ {
+ x = def->w - def->l;
+ if (acc->left.b < x)
+ x = acc->left.b;
+ lw = ICEIL(acc->fromIntX - x) - lx;
+ rw += rx;
+ rx = ICEIL(acc->fromIntX + x);
+ rw -= rx;
+ }
+ arcSpan (0, lx, lw, rx, rw, def, bounds, acc, mask);
+}
+
+static void
+tailSpan (
+ int y,
+ int lw,
+ int rw,
+ struct arc_def *def,
+ struct arc_bound *bounds,
+ struct accelerators *acc,
+ int mask)
+{
+ double yy, xalt, x, lx, rx;
+ int n;
+
+ if (boundedLe(y, bounds->outeri))
+ arcSpan (y, 0, lw, -rw, rw, def, bounds, acc, mask);
+ else if (def->w != def->h) {
+ yy = y + acc->fromIntY;
+ x = tailX(yy, def, bounds, acc);
+ if (yy == 0.0 && x == -rw - acc->fromIntX)
+ return;
+ if (acc->right.valid && boundedLe (yy, bounds->right)) {
+ rx = x;
+ lx = -x;
+ xalt = intersectLine (yy, acc->right);
+ if (xalt >= -rw - acc->fromIntX && xalt <= rx)
+ rx = xalt;
+ n = ICEIL(acc->fromIntX + lx);
+ if (lw > n) {
+ if (mask & 2)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg + n, acc->xorg + lw);
+ if (mask & 4)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg + n, acc->xorg + lw);
+ }
+ n = ICEIL(acc->fromIntX + rx);
+ if (n > -rw) {
+ if (mask & 1)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg - rw, acc->xorg + n);
+ if (mask & 8)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg - rw, acc->xorg + n);
+ }
+ }
+ arcSpan (y,
+ ICEIL(acc->fromIntX - x), 0,
+ ICEIL(acc->fromIntX + x), 0,
+ def, bounds, acc, mask);
+ }
+}
+
+/*
+ * create whole arcs out of pieces. This code is
+ * very bad.
+ */
+
+static struct finalSpan **finalSpans = NULL;
+static int finalMiny = 0, finalMaxy = -1;
+static int finalSize = 0;
+
+static int nspans = 0; /* total spans, not just y coords */
+
+struct finalSpan {
+ struct finalSpan *next;
+ int min, max; /* x values */
+};
+
+static struct finalSpan *freeFinalSpans, *tmpFinalSpan;
+
+# define allocFinalSpan() (freeFinalSpans ?\
+ ((tmpFinalSpan = freeFinalSpans), \
+ (freeFinalSpans = freeFinalSpans->next), \
+ (tmpFinalSpan->next = 0), \
+ tmpFinalSpan) : \
+ realAllocSpan ())
+
+# define SPAN_CHUNK_SIZE 128
+
+struct finalSpanChunk {
+ struct finalSpan data[SPAN_CHUNK_SIZE];
+ struct finalSpanChunk *next;
+};
+
+static struct finalSpanChunk *chunks;
+
+struct finalSpan *
+realAllocSpan ()
+{
+ register struct finalSpanChunk *newChunk;
+ register struct finalSpan *span;
+ register int i;
+
+ newChunk = (struct finalSpanChunk *) malloc (sizeof (struct finalSpanChunk));
+ if (!newChunk)
+ return (struct finalSpan *) NULL;
+ newChunk->next = chunks;
+ chunks = newChunk;
+ freeFinalSpans = span = newChunk->data + 1;
+ for (i = 1; i < SPAN_CHUNK_SIZE-1; i++) {
+ span->next = span+1;
+ span++;
+ }
+ span->next = 0;
+ span = newChunk->data;
+ span->next = 0;
+ return span;
+}
+
+static void
+disposeFinalSpans (void)
+{
+ struct finalSpanChunk *chunk, *next;
+
+ for (chunk = chunks; chunk; chunk = next) {
+ next = chunk->next;
+ free (chunk);
+ }
+ chunks = 0;
+ freeFinalSpans = 0;
+ free(finalSpans);
+ finalSpans = 0;
+}
+
+static void
+fillSpans (
+ DrawablePtr pDrawable,
+ GCPtr pGC)
+{
+ register struct finalSpan *span;
+ register DDXPointPtr xSpan;
+ register int *xWidth;
+ register int i;
+ register struct finalSpan **f;
+ register int spany;
+ DDXPointPtr xSpans;
+ int *xWidths;
+
+ if (nspans == 0)
+ return;
+ xSpan = xSpans = (DDXPointPtr) malloc (nspans * sizeof (DDXPointRec));
+ xWidth = xWidths = (int *) malloc (nspans * sizeof (int));
+ if (xSpans && xWidths)
+ {
+ i = 0;
+ f = finalSpans;
+ for (spany = finalMiny; spany <= finalMaxy; spany++, f++) {
+ for (span = *f; span; span=span->next) {
+ if (span->max <= span->min)
+ continue;
+ xSpan->x = span->min;
+ xSpan->y = spany;
+ ++xSpan;
+ *xWidth++ = span->max - span->min;
+ ++i;
+ }
+ }
+ (*pGC->ops->FillSpans) (pDrawable, pGC, i, xSpans, xWidths, TRUE);
+ }
+ disposeFinalSpans ();
+ if (xSpans)
+ free (xSpans);
+ if (xWidths)
+ free (xWidths);
+ finalMiny = 0;
+ finalMaxy = -1;
+ finalSize = 0;
+ nspans = 0;
+}
+
+# define SPAN_REALLOC 100
+
+# define findSpan(y) ((finalMiny <= (y) && (y) <= finalMaxy) ? \
+ &finalSpans[(y) - finalMiny] : \
+ realFindSpan (y))
+
+static struct finalSpan **
+realFindSpan (int y)
+{
+ struct finalSpan **newSpans;
+ int newSize, newMiny, newMaxy;
+ int change;
+ int i;
+
+ if (y < finalMiny || y > finalMaxy) {
+ if (!finalSize) {
+ finalMiny = y;
+ finalMaxy = y - 1;
+ }
+ if (y < finalMiny)
+ change = finalMiny - y;
+ else
+ change = y - finalMaxy;
+ if (change >= SPAN_REALLOC)
+ change += SPAN_REALLOC;
+ else
+ change = SPAN_REALLOC;
+ newSize = finalSize + change;
+ newSpans = (struct finalSpan **) malloc
+ (newSize * sizeof (struct finalSpan *));
+ if (!newSpans)
+ return (struct finalSpan **)NULL;
+ newMiny = finalMiny;
+ newMaxy = finalMaxy;
+ if (y < finalMiny)
+ newMiny = finalMiny - change;
+ else
+ newMaxy = finalMaxy + change;
+ if (finalSpans) {
+ memmove(((char *) newSpans) + (finalMiny-newMiny) * sizeof (struct finalSpan *),
+ (char *) finalSpans,
+ finalSize * sizeof (struct finalSpan *));
+ free (finalSpans);
+ }
+ if ((i = finalMiny - newMiny) > 0)
+ bzero ((char *)newSpans, i * sizeof (struct finalSpan *));
+ if ((i = newMaxy - finalMaxy) > 0)
+ bzero ((char *)(newSpans + newSize - i),
+ i * sizeof (struct finalSpan *));
+ finalSpans = newSpans;
+ finalMaxy = newMaxy;
+ finalMiny = newMiny;
+ finalSize = newSize;
+ }
+ return &finalSpans[y - finalMiny];
+}
+
+static void
+newFinalSpan (
+ int y,
+ register int xmin,
+ register int xmax)
+{
+ register struct finalSpan *x;
+ register struct finalSpan **f;
+ struct finalSpan *oldx;
+ struct finalSpan *prev;
+
+ f = findSpan (y);
+ if (!f)
+ return;
+ oldx = 0;
+ for (;;) {
+ prev = 0;
+ for (x = *f; x; x=x->next) {
+ if (x == oldx) {
+ prev = x;
+ continue;
+ }
+ if (x->min <= xmax && xmin <= x->max) {
+ if (oldx) {
+ oldx->min = min (x->min, xmin);
+ oldx->max = max (x->max, xmax);
+ if (prev)
+ prev->next = x->next;
+ else
+ *f = x->next;
+ --nspans;
+ } else {
+ x->min = min (x->min, xmin);
+ x->max = max (x->max, xmax);
+ oldx = x;
+ }
+ xmin = oldx->min;
+ xmax = oldx->max;
+ break;
+ }
+ prev = x;
+ }
+ if (!x)
+ break;
+ }
+ if (!oldx) {
+ x = allocFinalSpan ();
+ if (x)
+ {
+ x->min = xmin;
+ x->max = xmax;
+ x->next = *f;
+ *f = x;
+ ++nspans;
+ }
+ }
+}
+
+static void
+mirrorSppPoint (
+ int quadrant,
+ SppPointPtr sppPoint)
+{
+ switch (quadrant) {
+ case 0:
+ break;
+ case 1:
+ sppPoint->x = -sppPoint->x;
+ break;
+ case 2:
+ sppPoint->x = -sppPoint->x;
+ sppPoint->y = -sppPoint->y;
+ break;
+ case 3:
+ sppPoint->y = -sppPoint->y;
+ break;
+ }
+ /*
+ * and translate to X coordinate system
+ */
+ sppPoint->y = -sppPoint->y;
+}
+
+/*
+ * split an arc into pieces which are scan-converted
+ * in the first-quadrant and mirrored into position.
+ * This is necessary as the scan-conversion code can
+ * only deal with arcs completely contained in the
+ * first quadrant.
+ */
+
+static void
+drawArc (
+ xArc *tarc,
+ int l,
+ int a0,
+ int a1,
+ miArcFacePtr right,
+ miArcFacePtr left) /* save end line points */
+{
+ struct arc_def def;
+ struct accelerators acc;
+ int startq, endq, curq;
+ int rightq, leftq = 0, righta = 0, lefta = 0;
+ miArcFacePtr passRight, passLeft;
+ int q0 = 0, q1 = 0, mask;
+ struct band {
+ int a0, a1;
+ int mask;
+ } band[5], sweep[20];
+ int bandno, sweepno;
+ int i, j;
+ int flipRight = 0, flipLeft = 0;
+ int copyEnd = 0;
+ miArcSpanData *spdata;
+ Bool mustFree;
+
+ spdata = miComputeWideEllipse(l, tarc, &mustFree);
+ if (!spdata)
+ return;
+
+ if (a1 < a0)
+ a1 += 360 * 64;
+ startq = a0 / (90 * 64);
+ if (a0 == a1)
+ endq = startq;
+ else
+ endq = (a1-1) / (90 * 64);
+ bandno = 0;
+ curq = startq;
+ rightq = -1;
+ for (;;) {
+ switch (curq) {
+ case 0:
+ if (a0 > 90 * 64)
+ q0 = 0;
+ else
+ q0 = a0;
+ if (a1 < 360 * 64)
+ q1 = min (a1, 90 * 64);
+ else
+ q1 = 90 * 64;
+ if (curq == startq && a0 == q0 && rightq < 0) {
+ righta = q0;
+ rightq = curq;
+ }
+ if (curq == endq && a1 == q1) {
+ lefta = q1;
+ leftq = curq;
+ }
+ break;
+ case 1:
+ if (a1 < 90 * 64)
+ q0 = 0;
+ else
+ q0 = 180 * 64 - min (a1, 180 * 64);
+ if (a0 > 180 * 64)
+ q1 = 90 * 64;
+ else
+ q1 = 180 * 64 - max (a0, 90 * 64);
+ if (curq == startq && 180 * 64 - a0 == q1) {
+ righta = q1;
+ rightq = curq;
+ }
+ if (curq == endq && 180 * 64 - a1 == q0) {
+ lefta = q0;
+ leftq = curq;
+ }
+ break;
+ case 2:
+ if (a0 > 270 * 64)
+ q0 = 0;
+ else
+ q0 = max (a0, 180 * 64) - 180 * 64;
+ if (a1 < 180 * 64)
+ q1 = 90 * 64;
+ else
+ q1 = min (a1, 270 * 64) - 180 * 64;
+ if (curq == startq && a0 - 180*64 == q0) {
+ righta = q0;
+ rightq = curq;
+ }
+ if (curq == endq && a1 - 180 * 64 == q1) {
+ lefta = q1;
+ leftq = curq;
+ }
+ break;
+ case 3:
+ if (a1 < 270 * 64)
+ q0 = 0;
+ else
+ q0 = 360 * 64 - min (a1, 360 * 64);
+ q1 = 360 * 64 - max (a0, 270 * 64);
+ if (curq == startq && 360 * 64 - a0 == q1) {
+ righta = q1;
+ rightq = curq;
+ }
+ if (curq == endq && 360 * 64 - a1 == q0) {
+ lefta = q0;
+ leftq = curq;
+ }
+ break;
+ }
+ band[bandno].a0 = q0;
+ band[bandno].a1 = q1;
+ band[bandno].mask = 1 << curq;
+ bandno++;
+ if (curq == endq)
+ break;
+ curq++;
+ if (curq == 4) {
+ a0 = 0;
+ a1 -= 360 * 64;
+ curq = 0;
+ endq -= 4;
+ }
+ }
+ sweepno = 0;
+ for (;;) {
+ q0 = 90 * 64;
+ mask = 0;
+ /*
+ * find left-most point
+ */
+ for (i = 0; i < bandno; i++)
+ if (band[i].a0 <= q0) {
+ q0 = band[i].a0;
+ q1 = band[i].a1;
+ mask = band[i].mask;
+ }
+ if (!mask)
+ break;
+ /*
+ * locate next point of change
+ */
+ for (i = 0; i < bandno; i++)
+ if (!(mask & band[i].mask)) {
+ if (band[i].a0 == q0) {
+ if (band[i].a1 < q1)
+ q1 = band[i].a1;
+ mask |= band[i].mask;
+ } else if (band[i].a0 < q1)
+ q1 = band[i].a0;
+ }
+ /*
+ * create a new sweep
+ */
+ sweep[sweepno].a0 = q0;
+ sweep[sweepno].a1 = q1;
+ sweep[sweepno].mask = mask;
+ sweepno++;
+ /*
+ * subtract the sweep from the affected bands
+ */
+ for (i = 0; i < bandno; i++)
+ if (band[i].a0 == q0) {
+ band[i].a0 = q1;
+ /*
+ * check if this band is empty
+ */
+ if (band[i].a0 == band[i].a1)
+ band[i].a1 = band[i].a0 = 90 * 64 + 1;
+ }
+ }
+ computeAcc (tarc, l, &def, &acc);
+ for (j = 0; j < sweepno; j++) {
+ mask = sweep[j].mask;
+ passRight = passLeft = 0;
+ if (mask & (1 << rightq)) {
+ if (sweep[j].a0 == righta)
+ passRight = right;
+ else if (sweep[j].a1 == righta) {
+ passLeft = right;
+ flipRight = 1;
+ }
+ }
+ if (mask & (1 << leftq)) {
+ if (sweep[j].a1 == lefta)
+ {
+ if (passLeft)
+ copyEnd = 1;
+ passLeft = left;
+ }
+ else if (sweep[j].a0 == lefta) {
+ if (passRight)
+ copyEnd = 1;
+ passRight = left;
+ flipLeft = 1;
+ }
+ }
+ drawQuadrant (&def, &acc, sweep[j].a0, sweep[j].a1, mask,
+ passRight, passLeft, spdata);
+ }
+ /*
+ * when copyEnd is set, both ends of the arc were computed
+ * at the same time; drawQuadrant only takes one end though,
+ * so the left end will be the only one holding the data. Copy
+ * it from there.
+ */
+ if (copyEnd)
+ *right = *left;
+ /*
+ * mirror the coordinates generated for the
+ * faces of the arc
+ */
+ if (right) {
+ mirrorSppPoint (rightq, &right->clock);
+ mirrorSppPoint (rightq, &right->center);
+ mirrorSppPoint (rightq, &right->counterClock);
+ if (flipRight) {
+ SppPointRec temp;
+
+ temp = right->clock;
+ right->clock = right->counterClock;
+ right->counterClock = temp;
+ }
+ }
+ if (left) {
+ mirrorSppPoint (leftq, &left->counterClock);
+ mirrorSppPoint (leftq, &left->center);
+ mirrorSppPoint (leftq, &left->clock);
+ if (flipLeft) {
+ SppPointRec temp;
+
+ temp = left->clock;
+ left->clock = left->counterClock;
+ left->counterClock = temp;
+ }
+ }
+ if (mustFree)
+ free(spdata);
+}
+
+static void
+drawQuadrant (
+ struct arc_def *def,
+ struct accelerators *acc,
+ int a0,
+ int a1,
+ int mask,
+ miArcFacePtr right,
+ miArcFacePtr left,
+ miArcSpanData *spdata)
+{
+ struct arc_bound bound;
+ double yy, x, xalt;
+ int y, miny, maxy;
+ int n;
+ miArcSpan *span;
+
+ def->a0 = ((double) a0) / 64.0;
+ def->a1 = ((double) a1) / 64.0;
+ computeBound (def, &bound, acc, right, left);
+ yy = bound.inner.min;
+ if (bound.outer.min < yy)
+ yy = bound.outer.min;
+ miny = ICEIL(yy - acc->fromIntY);
+ yy = bound.inner.max;
+ if (bound.outer.max > yy)
+ yy = bound.outer.max;
+ maxy = floor(yy - acc->fromIntY);
+ y = spdata->k;
+ span = spdata->spans;
+ if (spdata->top)
+ {
+ if (a1 == 90 * 64 && (mask & 1))
+ newFinalSpan (acc->yorgu - y - 1, acc->xorg, acc->xorg + 1);
+ span++;
+ }
+ for (n = spdata->count1; --n >= 0; )
+ {
+ if (y < miny)
+ return;
+ if (y <= maxy) {
+ arcSpan (y,
+ span->lx, -span->lx, 0, span->lx + span->lw,
+ def, &bound, acc, mask);
+ if (span->rw + span->rx)
+ tailSpan (y, -span->rw, -span->rx, def, &bound, acc, mask);
+ }
+ y--;
+ span++;
+ }
+ if (y < miny)
+ return;
+ if (spdata->hole)
+ {
+ if (y <= maxy)
+ arcSpan (y, 0, 0, 0, 1, def, &bound, acc, mask & 0xc);
+ }
+ for (n = spdata->count2; --n >= 0; )
+ {
+ if (y < miny)
+ return;
+ if (y <= maxy)
+ arcSpan (y, span->lx, span->lw, span->rx, span->rw,
+ def, &bound, acc, mask);
+ y--;
+ span++;
+ }
+ if (spdata->bot && miny <= y && y <= maxy)
+ {
+ n = mask;
+ if (y == miny)
+ n &= 0xc;
+ if (span->rw <= 0) {
+ arcSpan0 (span->lx, -span->lx, 0, span->lx + span->lw,
+ def, &bound, acc, n);
+ if (span->rw + span->rx)
+ tailSpan (y, -span->rw, -span->rx, def, &bound, acc, n);
+ }
+ else
+ arcSpan0 (span->lx, span->lw, span->rx, span->rw,
+ def, &bound, acc, n);
+ y--;
+ }
+ while (y >= miny) {
+ yy = y + acc->fromIntY;
+ if (def->w == def->h) {
+ xalt = def->w - def->l;
+ x = -sqrt(xalt * xalt - yy * yy);
+ } else {
+ x = tailX(yy, def, &bound, acc);
+ if (acc->left.valid && boundedLe (yy, bound.left)) {
+ xalt = intersectLine (yy, acc->left);
+ if (xalt < x)
+ x = xalt;
+ }
+ if (acc->right.valid && boundedLe (yy, bound.right)) {
+ xalt = intersectLine (yy, acc->right);
+ if (xalt < x)
+ x = xalt;
+ }
+ }
+ arcSpan (y,
+ ICEIL(acc->fromIntX - x), 0,
+ ICEIL(acc->fromIntX + x), 0,
+ def, &bound, acc, mask);
+ y--;
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mibitblt.c b/nx-X11/programs/Xserver/mi/mibitblt.c
new file mode 100644
index 000000000..67d36a742
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mibitblt.c
@@ -0,0 +1,845 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/* Author: Todd Newman (aided and abetted by Mr. Drewry) */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+
+#include "misc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include <nx-X11/Xmd.h>
+#include "servermd.h"
+
+#ifndef HAS_FFS
+extern int ffs(int);
+#endif
+
+/* MICOPYAREA -- public entry for the CopyArea request
+ * For each rectangle in the source region
+ * get the pixels with GetSpans
+ * set them in the destination with SetSpans
+ * We let SetSpans worry about clipping to the destination.
+ */
+RegionPtr
+miCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int xIn, yIn;
+ int widthSrc, heightSrc;
+ int xOut, yOut;
+{
+ DDXPointPtr ppt, pptFirst;
+ unsigned int *pwidthFirst, *pwidth, *pbits;
+ BoxRec srcBox, *prect;
+ /* may be a new region, or just a copy */
+ RegionPtr prgnSrcClip;
+ /* non-0 if we've created a src clip */
+ RegionPtr prgnExposed;
+ int realSrcClip = 0;
+ int srcx, srcy, dstx, dsty, i, j, y, width, height,
+ xMin, xMax, yMin, yMax;
+ unsigned int *ordering;
+ int numRects;
+ BoxPtr boxes;
+
+ srcx = xIn + pSrcDrawable->x;
+ srcy = yIn + pSrcDrawable->y;
+
+ /* If the destination isn't realized, this is easy */
+ if (pDstDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr)pDstDrawable)->realized)
+ return (RegionPtr)NULL;
+
+ /* clip the source */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ BoxRec box;
+
+ box.x1 = pSrcDrawable->x;
+ box.y1 = pSrcDrawable->y;
+ box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+
+ prgnSrcClip = RegionCreate(&box, 1);
+ realSrcClip = 1;
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors) {
+ prgnSrcClip = NotClippedByChildren ((WindowPtr) pSrcDrawable);
+ realSrcClip = 1;
+ } else
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+
+ /* If the src drawable is a window, we need to translate the srcBox so
+ * that we can compare it with the window's clip region later on. */
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx + widthSrc;
+ srcBox.y2 = srcy + heightSrc;
+
+ dstx = xOut;
+ dsty = yOut;
+ if (pGC->miTranslate)
+ {
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+ }
+
+ pptFirst = ppt = (DDXPointPtr)
+ malloc(heightSrc * sizeof(DDXPointRec));
+ pwidthFirst = pwidth = (unsigned int *)
+ malloc(heightSrc * sizeof(unsigned int));
+ numRects = RegionNumRects(prgnSrcClip);
+ boxes = RegionRects(prgnSrcClip);
+ ordering = (unsigned int *)
+ malloc(numRects * sizeof(unsigned int));
+ if(!pptFirst || !pwidthFirst || !ordering)
+ {
+ if (ordering)
+ free(ordering);
+ if (pwidthFirst)
+ free(pwidthFirst);
+ if (pptFirst)
+ free(pptFirst);
+ return (RegionPtr)NULL;
+ }
+
+ /* If not the same drawable then order of move doesn't matter.
+ Following assumes that boxes are sorted from top
+ to bottom and left to right.
+ */
+ if ((pSrcDrawable != pDstDrawable) &&
+ ((pGC->subWindowMode != IncludeInferiors) ||
+ (pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (pDstDrawable->type == DRAWABLE_PIXMAP)))
+ for (i=0; i < numRects; i++)
+ ordering[i] = i;
+ else { /* within same drawable, must sequence moves carefully! */
+ if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical.
+ Vertical order OK */
+ if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal.
+ Horizontal order OK as well */
+ for (i=0; i < numRects; i++)
+ ordering[i] = i;
+ else { /* scroll right. must reverse horizontal banding of rects. */
+ for (i=0, j=1, xMax=0; i < numRects; j=i+1, xMax=i) {
+ /* find extent of current horizontal band */
+ y=boxes[i].y1; /* band has this y coordinate */
+ while ((j < numRects) && (boxes[j].y1 == y))
+ j++;
+ /* reverse the horizontal band in the output ordering */
+ for (j-- ; j >= xMax; j--, i++)
+ ordering[i] = j;
+ }
+ }
+ }
+ else { /* Scroll down. Must reverse vertical banding. */
+ if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */
+ for (i=numRects-1, j=i-1, yMin=i, yMax=0;
+ i >= 0;
+ j=i-1, yMin=i) {
+ /* find extent of current horizontal band */
+ y=boxes[i].y1; /* band has this y coordinate */
+ while ((j >= 0) && (boxes[j].y1 == y))
+ j--;
+ /* reverse the horizontal band in the output ordering */
+ for (j++ ; j <= yMin; j++, i--, yMax++)
+ ordering[yMax] = j;
+ }
+ }
+ else /* Scroll right or horizontal stationary.
+ Reverse horizontal order as well (if stationary, horizontal
+ order can be swapped without penalty and this is faster
+ to compute). */
+ for (i=0, j=numRects-1; i < numRects; i++, j--)
+ ordering[i] = j;
+ }
+ }
+
+ for(i = 0; i < numRects; i++)
+ {
+ prect = &boxes[ordering[i]];
+ xMin = max(prect->x1, srcBox.x1);
+ xMax = min(prect->x2, srcBox.x2);
+ yMin = max(prect->y1, srcBox.y1);
+ yMax = min(prect->y2, srcBox.y2);
+ /* is there anything visible here? */
+ if(xMax <= xMin || yMax <= yMin)
+ continue;
+
+ ppt = pptFirst;
+ pwidth = pwidthFirst;
+ y = yMin;
+ height = yMax - yMin;
+ width = xMax - xMin;
+
+ for(j = 0; j < height; j++)
+ {
+ /* We must untranslate before calling GetSpans */
+ ppt->x = xMin;
+ ppt++->y = y++;
+ *pwidth++ = width;
+ }
+ pbits = (unsigned int *)malloc(height * PixmapBytePad(width,
+ pSrcDrawable->depth));
+ if (pbits)
+ {
+ (*pSrcDrawable->pScreen->GetSpans)(pSrcDrawable, width, pptFirst,
+ (int *)pwidthFirst, height, (char *)pbits);
+ ppt = pptFirst;
+ pwidth = pwidthFirst;
+ xMin -= (srcx - dstx);
+ y = yMin - (srcy - dsty);
+ for(j = 0; j < height; j++)
+ {
+ ppt->x = xMin;
+ ppt++->y = y++;
+ *pwidth++ = width;
+ }
+
+ (*pGC->ops->SetSpans)(pDstDrawable, pGC, (char *)pbits, pptFirst,
+ (int *)pwidthFirst, height, TRUE);
+ free(pbits);
+ }
+ }
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, (unsigned long)0);
+ if(realSrcClip)
+ RegionDestroy(prgnSrcClip);
+
+ free(ordering);
+ free(pwidthFirst);
+ free(pptFirst);
+ return prgnExposed;
+}
+
+/* MIGETPLANE -- gets a bitmap representing one plane of pDraw
+ * A helper used for CopyPlane and XY format GetImage
+ * No clever strategy here, we grab a scanline at a time, pull out the
+ * bits and then stuff them in a 1 bit deep map.
+ */
+/*
+ * This should be replaced with something more general. mi shouldn't have to
+ * care about such things as scanline padding et alia.
+ */
+static
+MiBits *
+miGetPlane(
+ DrawablePtr pDraw,
+ int planeNum, /* number of the bitPlane */
+ int sx,
+ int sy,
+ int w,
+ int h,
+ MiBits *result)
+{
+ int i, j, k, width, bitsPerPixel, widthInBytes;
+ DDXPointRec pt = {0, 0};
+ MiBits pixel;
+ MiBits bit;
+ unsigned char *pCharsOut = NULL;
+
+#if BITMAP_SCANLINE_UNIT == 8
+#define OUT_TYPE unsigned char
+#endif
+#if BITMAP_SCANLINE_UNIT == 16
+#define OUT_TYPE CARD16
+#endif
+#if BITMAP_SCANLINE_UNIT == 32
+#define OUT_TYPE CARD32
+#endif
+#if BITMAP_SCANLINE_UNIT == 64
+#define OUT_TYPE CARD64
+#endif
+
+ OUT_TYPE *pOut;
+ int delta = 0;
+
+ sx += pDraw->x;
+ sy += pDraw->y;
+ widthInBytes = BitmapBytePad(w);
+ if(!result)
+ result = (MiBits *)malloc(h * widthInBytes);
+ if (!result)
+ return (MiBits *)NULL;
+ bitsPerPixel = pDraw->bitsPerPixel;
+ bzero((char *)result, h * widthInBytes);
+ pOut = (OUT_TYPE *) result;
+ if(bitsPerPixel == 1)
+ {
+ pCharsOut = (unsigned char *) result;
+ width = w;
+ }
+ else
+ {
+ delta = (widthInBytes / (BITMAP_SCANLINE_UNIT / 8)) -
+ (w / BITMAP_SCANLINE_UNIT);
+ width = 1;
+#if IMAGE_BYTE_ORDER == MSBFirst
+ planeNum += (32 - bitsPerPixel);
+#endif
+ }
+ pt.y = sy;
+ for (i = h; --i >= 0; pt.y++)
+ {
+ pt.x = sx;
+ if(bitsPerPixel == 1)
+ {
+ (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
+ (char *)pCharsOut);
+ pCharsOut += widthInBytes;
+ }
+ else
+ {
+ k = 0;
+ for(j = w; --j >= 0; pt.x++)
+ {
+ /* Fetch the next pixel */
+ (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
+ (char *)&pixel);
+ /*
+ * Now get the bit and insert into a bitmap in XY format.
+ */
+ bit = (pixel >> planeNum) & 1;
+#ifndef XFree86Server
+ /* XXX assuming bit order == byte order */
+#if BITMAP_BIT_ORDER == LSBFirst
+ bit <<= k;
+#else
+ bit <<= ((BITMAP_SCANLINE_UNIT - 1) - k);
+#endif
+#else
+ /* XXX assuming byte order == LSBFirst */
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ bit <<= k;
+ else
+ bit <<= ((screenInfo.bitmapScanlineUnit - 1) -
+ (k % screenInfo.bitmapScanlineUnit)) +
+ ((k / screenInfo.bitmapScanlineUnit) *
+ screenInfo.bitmapScanlineUnit);
+#endif
+ *pOut |= (OUT_TYPE) bit;
+ k++;
+ if (k == BITMAP_SCANLINE_UNIT)
+ {
+ pOut++;
+ k = 0;
+ }
+ }
+ pOut += delta;
+ }
+ }
+ return(result);
+
+}
+
+/* MIOPQSTIPDRAWABLE -- use pbits as an opaque stipple for pDraw.
+ * Drawing through the clip mask we SetSpans() the bits into a
+ * bitmap and stipple those bits onto the destination drawable by doing a
+ * PolyFillRect over the whole drawable,
+ * then we invert the bitmap by copying it onto itself with an alu of
+ * GXinvert, invert the foreground/background colors of the gc, and draw
+ * the background bits.
+ * Note how the clipped out bits of the bitmap are always the background
+ * color so that the stipple never causes FillRect to draw them.
+ */
+void
+miOpqStipDrawable(pDraw, pGC, prgnSrc, pbits, srcx, w, h, dstx, dsty)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ RegionPtr prgnSrc;
+ MiBits *pbits;
+ int srcx, w, h, dstx, dsty;
+{
+ int oldfill, i;
+ unsigned long oldfg;
+ int *pwidth, *pwidthFirst;
+ ChangeGCVal gcv[6];
+ PixmapPtr pStipple, pPixmap;
+ DDXPointRec oldOrg;
+ GCPtr pGCT;
+ DDXPointPtr ppt, pptFirst;
+ xRectangle rect;
+ RegionPtr prgnSrcClip;
+
+ pPixmap = (*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, w + srcx, h, 1,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ return;
+
+ /* Put the image into a 1 bit deep pixmap */
+ pGCT = GetScratchGC(1, pDraw->pScreen);
+ if (!pGCT)
+ {
+ (*pDraw->pScreen->DestroyPixmap)(pPixmap);
+ return;
+ }
+ /* First set the whole pixmap to 0 */
+ gcv[0].val = 0;
+ dixChangeGC(NullClient, pGCT, GCBackground, NULL, gcv);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+ miClearDrawable((DrawablePtr)pPixmap, pGCT);
+ ppt = pptFirst = (DDXPointPtr)malloc(h * sizeof(DDXPointRec));
+ pwidth = pwidthFirst = (int *)malloc(h * sizeof(int));
+ if(!pptFirst || !pwidthFirst)
+ {
+ if (pwidthFirst) free(pwidthFirst);
+ if (pptFirst) free(pptFirst);
+ FreeScratchGC(pGCT);
+ return;
+ }
+
+ /* we need a temporary region because ChangeClip must be assumed
+ to destroy what it's sent. note that this means we don't
+ have to free prgnSrcClip ourselves.
+ */
+ prgnSrcClip = RegionCreate(NULL, 0);
+ RegionCopy(prgnSrcClip, prgnSrc);
+ RegionTranslate(prgnSrcClip, srcx, 0);
+ (*pGCT->funcs->ChangeClip)(pGCT, CT_REGION, prgnSrcClip, 0);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+
+ /* Since we know pDraw is always a pixmap, we never need to think
+ * about translation here */
+ for(i = 0; i < h; i++)
+ {
+ ppt->x = 0;
+ ppt++->y = i;
+ *pwidth++ = w + srcx;
+ }
+
+ (*pGCT->ops->SetSpans)((DrawablePtr)pPixmap, pGCT, (char *)pbits,
+ pptFirst, pwidthFirst, h, TRUE);
+ free(pwidthFirst);
+ free(pptFirst);
+
+
+ /* Save current values from the client GC */
+ oldfill = pGC->fillStyle;
+ pStipple = pGC->stipple;
+ if(pStipple)
+ pStipple->refcnt++;
+ oldOrg = pGC->patOrg;
+
+ /* Set a new stipple in the drawable */
+ gcv[0].val = FillStippled;
+ gcv[1].ptr = pPixmap;
+ gcv[2].val = dstx - srcx;
+ gcv[3].val = dsty;
+
+ dixChangeGC(NullClient, pGC,
+ GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin,
+ NULL, gcv);
+ ValidateGC(pDraw, pGC);
+
+ /* Fill the drawable with the stipple. This will draw the
+ * foreground color whereever 1 bits are set, leaving everything
+ * with 0 bits untouched. Note that the part outside the clip
+ * region is all 0s. */
+ rect.x = dstx;
+ rect.y = dsty;
+ rect.width = w;
+ rect.height = h;
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+
+ /* Invert the tiling pixmap. This sets 0s for 1s and 1s for 0s, only
+ * within the clipping region, the part outside is still all 0s */
+ gcv[0].val = GXinvert;
+ dixChangeGC(NullClient, pGCT, GCFunction, NULL, gcv);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+ (*pGCT->ops->CopyArea)((DrawablePtr)pPixmap, (DrawablePtr)pPixmap,
+ pGCT, 0, 0, w + srcx, h, 0, 0);
+
+ /* Swap foreground and background colors on the GC for the drawable.
+ * Now when we fill the drawable, we will fill in the "Background"
+ * values */
+ oldfg = pGC->fgPixel;
+ gcv[0].val = pGC->bgPixel;
+ gcv[1].val = oldfg;
+ gcv[2].ptr = pPixmap;
+ dixChangeGC(NullClient, pGC, GCForeground | GCBackground | GCStipple,
+ NULL, gcv);
+ ValidateGC(pDraw, pGC);
+ /* PolyFillRect might have bashed the rectangle */
+ rect.x = dstx;
+ rect.y = dsty;
+ rect.width = w;
+ rect.height = h;
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+
+ /* Now put things back */
+ if(pStipple)
+ pStipple->refcnt--;
+ gcv[0].val = oldfg;
+ gcv[1].val = pGC->fgPixel;
+ gcv[2].val = oldfill;
+ gcv[3].ptr = pStipple;
+ gcv[4].val = oldOrg.x;
+ gcv[5].val = oldOrg.y;
+ dixChangeGC(NullClient, pGC,
+ GCForeground | GCBackground | GCFillStyle | GCStipple |
+ GCTileStipXOrigin | GCTileStipYOrigin, NULL, gcv);
+
+ ValidateGC(pDraw, pGC);
+ /* put what we hope is a smaller clip region back in the scratch gc */
+ (*pGCT->funcs->ChangeClip)(pGCT, CT_NONE, NULL, 0);
+ FreeScratchGC(pGCT);
+ (*pDraw->pScreen->DestroyPixmap)(pPixmap);
+
+}
+
+/* MICOPYPLANE -- public entry for the CopyPlane request.
+ * strategy:
+ * First build up a bitmap out of the bits requested
+ * build a source clip
+ * Use the bitmap we've built up as a Stipple for the destination
+ */
+RegionPtr
+miCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long bitPlane;
+{
+ MiBits *ptile;
+ BoxRec box;
+ RegionPtr prgnSrc, prgnExposed;
+
+ /* incorporate the source clip */
+
+ box.x1 = srcx + pSrcDrawable->x;
+ box.y1 = srcy + pSrcDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ /* clip to visible drawable */
+ if (box.x1 < pSrcDrawable->x)
+ box.x1 = pSrcDrawable->x;
+ if (box.y1 < pSrcDrawable->y)
+ box.y1 = pSrcDrawable->y;
+ if (box.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ if (box.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ prgnSrc = RegionCreate(&box, 1);
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
+ /* clip to visible drawable */
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ RegionPtr clipList = NotClippedByChildren ((WindowPtr) pSrcDrawable);
+ RegionIntersect(prgnSrc, prgnSrc, clipList);
+ RegionDestroy(clipList);
+ } else
+ RegionIntersect(prgnSrc, prgnSrc,
+ &((WindowPtr)pSrcDrawable)->clipList);
+ }
+
+ box = *RegionExtents(prgnSrc);
+ RegionTranslate(prgnSrc, -box.x1, -box.y1);
+
+ if ((box.x2 > box.x1) && (box.y2 > box.y1))
+ {
+ /* minimize the size of the data extracted */
+ /* note that we convert the plane mask bitPlane into a plane number */
+ box.x1 -= pSrcDrawable->x;
+ box.x2 -= pSrcDrawable->x;
+ box.y1 -= pSrcDrawable->y;
+ box.y2 -= pSrcDrawable->y;
+ ptile = miGetPlane(pSrcDrawable, ffs(bitPlane) - 1,
+ box.x1, box.y1,
+ box.x2 - box.x1, box.y2 - box.y1,
+ (MiBits *) NULL);
+ if (ptile)
+ {
+ miOpqStipDrawable(pDstDrawable, pGC, prgnSrc, ptile, 0,
+ box.x2 - box.x1, box.y2 - box.y1,
+ dstx + box.x1 - srcx, dsty + box.y1 - srcy);
+ free(ptile);
+ }
+ }
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane);
+ RegionDestroy(prgnSrc);
+ return prgnExposed;
+}
+
+/* MIGETIMAGE -- public entry for the GetImage Request
+ * We're getting the image into a memory buffer. While we have to use GetSpans
+ * to read a line from the device (since we don't know what that looks like),
+ * we can just write into the destination buffer
+ *
+ * two different strategies are used, depending on whether we're getting the
+ * image in Z format or XY format
+ * Z format:
+ * Line at a time, GetSpans a line into the destination buffer, then if the
+ * planemask is not all ones, we do a SetSpans into a temporary buffer (to get
+ * bits turned off) and then another GetSpans to get stuff back (because
+ * pixmaps are opaque, and we are passed in the memory to write into). This is
+ * pretty ugly and slow but works. Life is hard.
+ * XY format:
+ * get the single plane specified in planemask
+ */
+void
+miGetImage(pDraw, sx, sy, w, h, format, planeMask, pDst)
+ DrawablePtr pDraw;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char * pDst;
+{
+ unsigned char depth;
+ int i, linelength, width, srcx, srcy;
+ DDXPointRec pt = {0, 0};
+ XID gcv[2];
+ PixmapPtr pPixmap = (PixmapPtr)NULL;
+ GCPtr pGC = NULL;
+
+ depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ if ( (((1<<depth)-1)&planeMask) != (1<<depth)-1 )
+ {
+ xPoint pt;
+
+ pGC = GetScratchGC(depth, pDraw->pScreen);
+ if (!pGC)
+ return;
+ pPixmap = (*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, w, 1, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ {
+ FreeScratchGC(pGC);
+ return;
+ }
+ /*
+ * Clear the pixmap before doing anything else
+ */
+ ValidateGC((DrawablePtr)pPixmap, pGC);
+ pt.x = pt.y = 0;
+ width = w;
+ (*pGC->ops->FillSpans)((DrawablePtr)pPixmap, pGC, 1, &pt, &width,
+ TRUE);
+
+ /* alu is already GXCopy */
+ gcv[0] = (XID)planeMask;
+ DoChangeGC(pGC, GCPlaneMask, gcv, 0);
+ ValidateGC((DrawablePtr)pPixmap, pGC);
+ }
+
+ linelength = PixmapBytePad(w, depth);
+ srcx = sx + pDraw->x;
+ srcy = sy + pDraw->y;
+ for(i = 0; i < h; i++)
+ {
+ pt.x = srcx;
+ pt.y = srcy + i;
+ width = w;
+ (*pDraw->pScreen->GetSpans)(pDraw, w, &pt, &width, 1, pDst);
+ if (pPixmap)
+ {
+ pt.x = 0;
+ pt.y = 0;
+ width = w;
+ (*pGC->ops->SetSpans)((DrawablePtr)pPixmap, pGC, pDst,
+ &pt, &width, 1, TRUE);
+ (*pDraw->pScreen->GetSpans)((DrawablePtr)pPixmap, w, &pt,
+ &width, 1, pDst);
+ }
+ pDst += linelength;
+ }
+ if (pPixmap)
+ {
+ (*pGC->pScreen->DestroyPixmap)(pPixmap);
+ FreeScratchGC(pGC);
+ }
+ }
+ else
+ {
+ (void) miGetPlane(pDraw, ffs(planeMask) - 1, sx, sy, w, h,
+ (MiBits *)pDst);
+ }
+}
+
+/* MIPUTIMAGE -- public entry for the PutImage request
+ * Here we benefit from knowing the format of the bits pointed to by pImage,
+ * even if we don't know how pDraw represents them.
+ * Three different strategies are used depending on the format
+ * XYBitmap Format:
+ * we just use the Opaque Stipple helper function to cover the destination
+ * Note that this covers all the planes of the drawable with the
+ * foreground color (masked with the GC planemask) where there are 1 bits
+ * and the background color (masked with the GC planemask) where there are
+ * 0 bits
+ * XYPixmap format:
+ * what we're called with is a series of XYBitmaps, but we only want
+ * each XYPixmap to update 1 plane, instead of updating all of them.
+ * we set the foreground color to be all 1s and the background to all 0s
+ * then for each plane, we set the plane mask to only effect that one
+ * plane and recursive call ourself with the format set to XYBitmap
+ * (This clever idea courtesy of RGD.)
+ * ZPixmap format:
+ * This part is simple, just call SetSpans
+ */
+void
+miPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int depth, x, y, w, h, leftPad;
+ int format;
+ char *pImage;
+{
+ DDXPointPtr pptFirst, ppt;
+ int *pwidthFirst, *pwidth;
+ RegionPtr prgnSrc;
+ BoxRec box;
+ unsigned long oldFg, oldBg;
+ XID gcv[3];
+ unsigned long oldPlanemask;
+ unsigned long i;
+ long bytesPer;
+
+ if (!w || !h)
+ return;
+ switch(format)
+ {
+ case XYBitmap:
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ prgnSrc = RegionCreate(&box, 1);
+
+ miOpqStipDrawable(pDraw, pGC, prgnSrc, (MiBits *) pImage,
+ leftPad, w, h, x, y);
+ RegionDestroy(prgnSrc);
+ break;
+
+ case XYPixmap:
+ depth = pGC->depth;
+ oldPlanemask = pGC->planemask;
+ oldFg = pGC->fgPixel;
+ oldBg = pGC->bgPixel;
+ gcv[0] = (XID)~0;
+ gcv[1] = (XID)0;
+ DoChangeGC(pGC, GCForeground | GCBackground, gcv, 0);
+ bytesPer = (long)h * BitmapBytePad(w + leftPad);
+
+ for (i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer)
+ {
+ if (i & oldPlanemask)
+ {
+ gcv[0] = (XID)i;
+ DoChangeGC(pGC, GCPlaneMask, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad,
+ XYBitmap, (char *)pImage);
+ }
+ }
+ gcv[0] = (XID)oldPlanemask;
+ gcv[1] = (XID)oldFg;
+ gcv[2] = (XID)oldBg;
+ DoChangeGC(pGC, GCPlaneMask | GCForeground | GCBackground, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ break;
+
+ case ZPixmap:
+ ppt = pptFirst = (DDXPointPtr)malloc(h * sizeof(DDXPointRec));
+ pwidth = pwidthFirst = (int *)malloc(h * sizeof(int));
+ if(!pptFirst || !pwidthFirst)
+ {
+ if (pwidthFirst)
+ free(pwidthFirst);
+ if (pptFirst)
+ free(pptFirst);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ x += pDraw->x;
+ y += pDraw->y;
+ }
+
+ for(i = 0; i < h; i++)
+ {
+ ppt->x = x;
+ ppt->y = y + i;
+ ppt++;
+ *pwidth++ = w;
+ }
+
+ (*pGC->ops->SetSpans)(pDraw, pGC, (char *)pImage, pptFirst,
+ pwidthFirst, h, TRUE);
+ free(pwidthFirst);
+ free(pptFirst);
+ break;
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mibstore.c b/nx-X11/programs/Xserver/mi/mibstore.c
new file mode 100644
index 000000000..3eafac235
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mibstore.c
@@ -0,0 +1,3897 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by 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 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 name The Open Group not be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission.
+
+The University of California makes no representations about the suitability
+of this software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "dixstruct.h" /* For requestingClient */
+#include "mi.h"
+#include "mibstorest.h"
+
+/*
+ * When the server fails to allocate a backing store pixmap, if you want
+ * it to dynamically retry to allocate backing store on every subsequent
+ * graphics op, you can enable BSEAGER; otherwise, backing store will be
+ * disabled on the window until it is unmapped and then remapped.
+ */
+/* #define BSEAGER */
+
+/*-
+ * NOTES ON USAGE:
+ *
+ * The functions in this file implement a machine-independent backing-store
+ * scheme. To use it, the output library must do the following:
+ * - Provide a SaveAreas function that takes a destination pixmap, a
+ * region of the areas to save (in the pixmap's coordinate system)
+ * and the screen origin of the region. It should copy the areas from
+ * the screen into the pixmap.
+ * - Provide a RestoreAreas function that takes a source pixmap, a region
+ * of the areas to restore (in the screen's coordinate system) and the
+ * origin of the pixmap on the screen. It should copy the areas from
+ * the pixmap into the screen.
+ * - Provide a SetClipmaskRgn function that takes a gc and a region
+ * and merges the region into any CT_PIXMAP client clip that
+ * is specified in the GC. This routine is only needed if
+ * miValidateBackingStore will see CT_PIXMAP clip lists; not
+ * true for any of the sample servers (which convert the PIXMAP
+ * clip lists into CT_REGION clip lists; an expensive but simple
+ * to code option).
+ * - The function placed in a window's ClearToBackground vector must call
+ * pScreen->ClearBackingStore with the window, followed by
+ * the window-relative x and y coordinates, followed by the width and
+ * height of the area to be cleared, followed by the generateExposures
+ * flag. This has been taken care of in miClearToBackground.
+ * - Whatever determines GraphicsExpose events for the CopyArea and
+ * CopyPlane requests should call pWin->backStorage->ExposeCopy
+ * with the source and destination drawables, the GC used, a source-
+ * window-relative region of exposed areas, the source and destination
+ * coordinates and the bitplane copied, if CopyPlane, or 0, if
+ * CopyArea.
+ *
+ * JUSTIFICATION
+ * This is a cross between saving everything and just saving the
+ * obscued areas (as in Pike's layers.) This method has the advantage
+ * of only doing each output operation once per pixel, visible or
+ * invisible, and avoids having to do all the crufty storage
+ * management of keeping several separate rectangles. Since the
+ * ddx layer ouput primitives are required to draw through clipping
+ * rectangles anyway, sending multiple drawing requests for each of
+ * several rectangles isn't necessary. (Of course, it could be argued
+ * that the ddx routines should just take one rectangle each and
+ * get called multiple times, but that would make taking advantage of
+ * smart hardware harder, and probably be slower as well.)
+ */
+
+#define SETUP_BACKING_TERSE(pGC) \
+ miBSGCPtr pGCPrivate = (miBSGCPtr)(pGC)->devPrivates[miBSGCIndex].ptr; \
+ GCFuncs *oldFuncs = pGC->funcs;
+
+#define SETUP_BACKING(pDrawable,pGC) \
+ miBSWindowPtr pBackingStore = \
+ (miBSWindowPtr)((WindowPtr)(pDrawable))->backStorage; \
+ DrawablePtr pBackingDrawable = (DrawablePtr) \
+ pBackingStore->pBackingPixmap; \
+ SETUP_BACKING_TERSE(pGC) \
+ GCPtr pBackingGC = pGCPrivate->pBackingGC;
+
+#define PROLOGUE(pGC) { \
+ pGC->ops = pGCPrivate->wrapOps;\
+ pGC->funcs = pGCPrivate->wrapFuncs; \
+ }
+
+#define EPILOGUE(pGC) { \
+ pGCPrivate->wrapOps = (pGC)->ops; \
+ (pGC)->ops = &miBSGCOps; \
+ (pGC)->funcs = oldFuncs; \
+ }
+
+static void miCreateBSPixmap(WindowPtr pWin, BoxPtr pExtents);
+static void miDestroyBSPixmap(WindowPtr pWin);
+static void miTileVirtualBS(WindowPtr pWin);
+static void miBSAllocate(WindowPtr pWin), miBSFree(WindowPtr pWin);
+static Bool miBSCreateGCPrivate(GCPtr pGC);
+static void miBSClearBackingRegion(WindowPtr pWin, RegionPtr pRgn);
+
+#define MoreCopy0 ;
+#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;
+#define MoreCopy4 MoreCopy2 MoreCopy2
+
+#define copyData(src,dst,n,morecopy) \
+{ \
+ register short *srcCopy = (short *)(src); \
+ register short *dstCopy = (short *)(dst); \
+ register int i; \
+ register int bsx = pBackingStore->x; \
+ register int bsy = pBackingStore->y; \
+ for (i = n; --i >= 0; ) \
+ { \
+ *dstCopy++ = *srcCopy++ - bsx; \
+ *dstCopy++ = *srcCopy++ - bsy; \
+ morecopy \
+ } \
+}
+
+#define copyPoints(src,dst,n,mode) \
+if (mode == CoordModeOrigin) \
+{ \
+ copyData(src,dst,n,MoreCopy0); \
+} \
+else \
+{ \
+ memmove((char *)(dst), (char *)(src), (n) << 2); \
+ *((short *)(dst)) -= pBackingStore->x; \
+ *((short *)(dst) + 1) -= pBackingStore->y; \
+}
+
+/*
+ * wrappers for screen funcs
+ */
+
+static int miBSScreenIndex;
+static unsigned long miBSGeneration = 0;
+
+static Bool miBSCloseScreen(ScreenPtr pScreen);
+static void miBSGetImage(DrawablePtr pDrawable, int sx, int sy,
+ int w, int h, unsigned int format,
+ unsigned long planemask, char *pdstLine);
+static void miBSGetSpans(DrawablePtr pDrawable, int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans,
+ char *pdstStart);
+static Bool miBSChangeWindowAttributes(WindowPtr pWin,
+ unsigned long mask);
+static Bool miBSCreateGC(GCPtr pGC);
+static Bool miBSDestroyWindow(WindowPtr pWin);
+
+/*
+ * backing store screen functions
+ */
+
+static void miBSSaveDoomedAreas(WindowPtr pWin, RegionPtr pObscured,
+ int dx, int dy);
+static RegionPtr miBSRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
+static void miBSExposeCopy(WindowPtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr prgnExposed,
+ int srcx, int srcy, int dstx, int dsty,
+ unsigned long plane);
+static RegionPtr miBSTranslateBackingStore(WindowPtr pWin, int windx,
+ int windy, RegionPtr oldClip,
+ int oldx, int oldy);
+static RegionPtr miBSClearBackingStore(WindowPtr pWin, int x, int y,
+ int w, int h, Bool generateExposures);
+static void miBSDrawGuarantee(WindowPtr pWin, GCPtr pGC,
+ int guarantee);
+
+/*
+ * wrapper vectors for GC funcs and ops
+ */
+
+static int miBSGCIndex;
+
+static void miBSValidateGC(GCPtr pGC, unsigned long stateChanges,
+ DrawablePtr pDrawable);
+static void miBSCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void miBSDestroyGC(GCPtr pGC);
+static void miBSChangeGC(GCPtr pGC, unsigned long mask);
+static void miBSChangeClip(GCPtr pGC, int type, void * pvalue, int nrects);
+static void miBSDestroyClip(GCPtr pGC);
+static void miBSCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+static GCFuncs miBSGCFuncs = {
+ miBSValidateGC,
+ miBSChangeGC,
+ miBSCopyGC,
+ miBSDestroyGC,
+ miBSChangeClip,
+ miBSDestroyClip,
+ miBSCopyClip,
+};
+
+static void miBSFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit,
+ int fSorted);
+static void miBSSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans,
+ int fSorted);
+static void miBSPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad,
+ int format, char *pBits);
+static RegionPtr miBSCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty);
+static RegionPtr miBSCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long plane);
+static void miBSPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, xPoint *pptInit);
+static void miBSPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pptInit);
+static void miBSPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSegs);
+static void miBSPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+ int nrects, xRectangle *pRects);
+static void miBSPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+ xArc *parcs);
+static void miBSFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pPts);
+static void miBSPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+static void miBSPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *parcs);
+static int miBSPolyText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars);
+static int miBSPolyText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count,
+ unsigned short *chars);
+static void miBSImageText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char *chars);
+static void miBSImageText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count,
+ unsigned short *chars);
+static void miBSImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void * pglyphBase);
+static void miBSPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void * pglyphBase);
+static void miBSPushPixels(GCPtr pGC, PixmapPtr pBitMap,
+ DrawablePtr pDst, int w, int h,
+ int x, int y);
+#ifdef NEED_LINEHELPER
+static void miBSLineHelper(void);
+#endif
+
+static GCOps miBSGCOps = {
+ miBSFillSpans, miBSSetSpans, miBSPutImage,
+ miBSCopyArea, miBSCopyPlane, miBSPolyPoint,
+ miBSPolylines, miBSPolySegment, miBSPolyRectangle,
+ miBSPolyArc, miBSFillPolygon, miBSPolyFillRect,
+ miBSPolyFillArc, miBSPolyText8, miBSPolyText16,
+ miBSImageText8, miBSImageText16, miBSImageGlyphBlt,
+ miBSPolyGlyphBlt, miBSPushPixels
+#ifdef NEED_LINEHELPER
+ , miBSLineHelper
+#endif
+};
+
+#define FUNC_PROLOGUE(pGC, pPriv) \
+ ((pGC)->funcs = pPriv->wrapFuncs),\
+ ((pGC)->ops = pPriv->wrapOps)
+
+#define FUNC_EPILOGUE(pGC, pPriv) \
+ ((pGC)->funcs = &miBSGCFuncs),\
+ ((pGC)->ops = &miBSGCOps)
+
+/*
+ * every GC in the server is initially wrapped with these
+ * "cheap" functions. This allocates no memory and is used
+ * to discover GCs used with windows which have backing
+ * store enabled
+ */
+
+static void miBSCheapValidateGC(GCPtr pGC, unsigned long stateChanges,
+ DrawablePtr pDrawable);
+static void miBSCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void miBSCheapDestroyGC(GCPtr pGC);
+static void miBSCheapChangeGC(GCPtr pGC, unsigned long mask);
+static void miBSCheapChangeClip(GCPtr pGC, int type, void * pvalue,
+ int nrects);
+static void miBSCheapDestroyClip(GCPtr pGC);
+static void miBSCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+static GCFuncs miBSCheapGCFuncs = {
+ miBSCheapValidateGC,
+ miBSCheapChangeGC,
+ miBSCheapCopyGC,
+ miBSCheapDestroyGC,
+ miBSCheapChangeClip,
+ miBSCheapDestroyClip,
+ miBSCheapCopyClip,
+};
+
+#define CHEAP_FUNC_PROLOGUE(pGC) \
+ ((pGC)->funcs = (GCFuncs *) (pGC)->devPrivates[miBSGCIndex].ptr)
+
+#define CHEAP_FUNC_EPILOGUE(pGC) \
+ ((pGC)->funcs = &miBSCheapGCFuncs)
+
+/*
+ * called from device screen initialization proc. Gets a GCPrivateIndex
+ * and wraps appropriate per-screen functions. pScreen->BackingStoreFuncs
+ * must be previously initialized.
+ */
+
+void
+miInitializeBackingStore (pScreen)
+ ScreenPtr pScreen;
+{
+ miBSScreenPtr pScreenPriv;
+
+ if (miBSGeneration != serverGeneration)
+ {
+ miBSScreenIndex = AllocateScreenPrivateIndex ();
+ if (miBSScreenIndex < 0)
+ return;
+ miBSGCIndex = AllocateGCPrivateIndex ();
+ miBSGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate(pScreen, miBSGCIndex, 0))
+ return;
+ pScreenPriv = (miBSScreenPtr) malloc (sizeof (miBSScreenRec));
+ if (!pScreenPriv)
+ return;
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+
+ pScreen->CloseScreen = miBSCloseScreen;
+ pScreen->GetImage = miBSGetImage;
+ pScreen->GetSpans = miBSGetSpans;
+ pScreen->ChangeWindowAttributes = miBSChangeWindowAttributes;
+ pScreen->CreateGC = miBSCreateGC;
+ pScreen->DestroyWindow = miBSDestroyWindow;
+
+ pScreen->SaveDoomedAreas = miBSSaveDoomedAreas;
+ pScreen->RestoreAreas = miBSRestoreAreas;
+ pScreen->ExposeCopy = miBSExposeCopy;
+ pScreen->TranslateBackingStore = miBSTranslateBackingStore;
+ pScreen->ClearBackingStore = miBSClearBackingStore;
+ pScreen->DrawGuarantee = miBSDrawGuarantee;
+
+ pScreen->devPrivates[miBSScreenIndex].ptr = (void *) pScreenPriv;
+}
+
+/*
+ * Screen function wrappers
+ */
+
+#define SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((miBSScreenPtr) \
+ (pScreen)->devPrivates[miBSScreenIndex].ptr)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+/*
+ * CloseScreen wrapper -- unwrap everything, free the private data
+ * and call the wrapped function
+ */
+
+static Bool
+miBSCloseScreen (pScreen)
+ ScreenPtr pScreen;
+{
+ miBSScreenPtr pScreenPriv;
+
+ pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+
+ free ((void *) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+static void miBSFillVirtualBits(DrawablePtr pDrawable, GCPtr pGC,
+ RegionPtr pRgn, int x, int y, int state,
+ PixUnion pixunion, unsigned long planemask);
+
+static void
+miBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planemask;
+ char *pdstLine;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ BoxRec bounds;
+ unsigned char depth;
+
+ SCREEN_PROLOGUE (pScreen, GetImage);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP &&
+ ((WindowPtr) pDrawable)->visibility != VisibilityUnobscured)
+ {
+ PixmapPtr pPixmap;
+ miBSWindowPtr pWindowPriv;
+ GCPtr pGC = NULL;
+ WindowPtr pWin, pSrcWin;
+ int xoff, yoff;
+ RegionRec Remaining;
+ RegionRec Border;
+ RegionRec Inside;
+ BoxPtr pBox;
+ int n;
+
+ pWin = (WindowPtr) pDrawable;
+ pPixmap = 0;
+ depth = pDrawable->depth;
+ bounds.x1 = sx + pDrawable->x;
+ bounds.y1 = sy + pDrawable->y;
+ bounds.x2 = bounds.x1 + w;
+ bounds.y2 = bounds.y1 + h;
+ RegionInit(&Remaining, &bounds, 0);
+ for (;;)
+ {
+ bounds.x1 = sx + pDrawable->x - pWin->drawable.x;
+ bounds.y1 = sy + pDrawable->y - pWin->drawable.y;
+ bounds.x2 = bounds.x1 + w;
+ bounds.y2 = bounds.y1 + h;
+ if (pWin->viewable && pWin->backStorage &&
+ pWin->drawable.depth == depth &&
+ (RegionContainsRect(&(pWindowPriv =
+ (miBSWindowPtr) pWin->backStorage)->SavedRegion,
+ &bounds) != rgnOUT ||
+ RegionContainsRect(&Remaining,
+ RegionExtents(&pWin->borderSize)) != rgnOUT))
+ {
+ if (!pPixmap)
+ {
+ XID subWindowMode = IncludeInferiors;
+ int x, y;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ goto punt;
+ pGC = GetScratchGC (depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ goto punt;
+ }
+ ChangeGC (pGC, GCSubwindowMode, &subWindowMode);
+ ValidateGC ((DrawablePtr)pPixmap, pGC);
+ RegionNull(&Border);
+ RegionNull(&Inside);
+ pSrcWin = (WindowPtr) pDrawable;
+ x = sx;
+ y = sy;
+ if (pSrcWin->parent)
+ {
+ x += pSrcWin->origin.x;
+ y += pSrcWin->origin.y;
+ pSrcWin = pSrcWin->parent;
+ }
+ (*pGC->ops->CopyArea) ((DrawablePtr)pSrcWin,
+ (DrawablePtr)pPixmap, pGC,
+ x, y, w, h,
+ 0, 0);
+ RegionSubtract(&Remaining, &Remaining,
+ &((WindowPtr) pDrawable)->borderClip);
+ }
+
+ RegionIntersect(&Inside, &Remaining, &pWin->winSize);
+ RegionTranslate(&Inside,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ RegionIntersect(&Inside, &Inside,
+ &pWindowPriv->SavedRegion);
+
+ /* offset of sub-window in GetImage pixmap */
+ xoff = pWin->drawable.x - pDrawable->x - sx;
+ yoff = pWin->drawable.y - pDrawable->y - sy;
+
+ if (RegionNumRects(&Inside) > 0)
+ {
+ switch (pWindowPriv->status)
+ {
+ case StatusContents:
+ pBox = RegionRects(&Inside);
+ for (n = RegionNumRects(&Inside); --n >= 0;)
+ {
+ (*pGC->ops->CopyArea) (
+ (DrawablePtr)pWindowPriv->pBackingPixmap,
+ (DrawablePtr)pPixmap, pGC,
+ pBox->x1 - pWindowPriv->x,
+ pBox->y1 - pWindowPriv->y,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ pBox->x1 + xoff,
+ pBox->y1 + yoff);
+ ++pBox;
+ }
+ break;
+ case StatusVirtual:
+ case StatusVDirty:
+ if (pWindowPriv->backgroundState == BackgroundPixmap ||
+ pWindowPriv->backgroundState == BackgroundPixel)
+ miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Inside,
+ xoff, yoff,
+ (int) pWindowPriv->backgroundState,
+ pWindowPriv->background, ~0L);
+ break;
+ }
+ }
+ RegionSubtract(&Border, &pWin->borderSize,
+ &pWin->winSize);
+ RegionIntersect(&Border, &Border, &Remaining);
+ if (RegionNumRects(&Border) > 0)
+ {
+ RegionTranslate(&Border, -pWin->drawable.x,
+ -pWin->drawable.y);
+ miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Border,
+ xoff, yoff,
+ pWin->borderIsPixel ? (int)BackgroundPixel : (int)BackgroundPixmap,
+ pWin->border, ~0L);
+ }
+ }
+
+ if (pWin->viewable && pWin->firstChild)
+ pWin = pWin->firstChild;
+ else
+ {
+ while (!pWin->nextSib && pWin != (WindowPtr) pDrawable)
+ pWin = pWin->parent;
+ if (pWin == (WindowPtr) pDrawable)
+ break;
+ pWin = pWin->nextSib;
+ }
+ }
+
+ RegionUninit(&Remaining);
+
+ if (pPixmap)
+ {
+ RegionUninit(&Border);
+ RegionUninit(&Inside);
+ (*pScreen->GetImage) ((DrawablePtr) pPixmap,
+ 0, 0, w, h, format, planemask, pdstLine);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ FreeScratchGC (pGC);
+ }
+ else
+ {
+ goto punt;
+ }
+ }
+ else
+ {
+punt: ;
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+ }
+
+ SCREEN_EPILOGUE (pScreen, GetImage, miBSGetImage);
+}
+
+static void
+miBSGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
+ DrawablePtr pDrawable;
+ int wMax;
+ DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ char *pdstStart;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ BoxRec bounds;
+ int i;
+ WindowPtr pWin;
+ int dx, dy;
+
+ SCREEN_PROLOGUE (pScreen, GetSpans);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP && ((WindowPtr) pDrawable)->backStorage)
+ {
+ PixmapPtr pPixmap;
+ miBSWindowPtr pWindowPriv;
+ GCPtr pGC;
+
+ pWin = (WindowPtr) pDrawable;
+ pWindowPriv = (miBSWindowPtr) pWin->backStorage;
+ pPixmap = pWindowPriv->pBackingPixmap;
+
+ bounds.x1 = ppt->x;
+ bounds.y1 = ppt->y;
+ bounds.x2 = bounds.x1 + *pwidth;
+ bounds.y2 = ppt->y;
+ for (i = 0; i < nspans; i++)
+ {
+ if (ppt[i].x < bounds.x1)
+ bounds.x1 = ppt[i].x;
+ if (ppt[i].x + pwidth[i] > bounds.x2)
+ bounds.x2 = ppt[i].x + pwidth[i];
+ if (ppt[i].y < bounds.y1)
+ bounds.y1 = ppt[i].y;
+ else if (ppt[i].y > bounds.y2)
+ bounds.y2 = ppt[i].y;
+ }
+
+ switch (RegionContainsRect(&pWindowPriv->SavedRegion, &bounds))
+ {
+ case rgnPART:
+ if (!pPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!(pPixmap = pWindowPriv->pBackingPixmap))
+ break;
+ }
+ pWindowPriv->status = StatusNoPixmap;
+ pGC = GetScratchGC(pPixmap->drawable.depth,
+ pPixmap->drawable.pScreen);
+ if (pGC)
+ {
+ ValidateGC ((DrawablePtr) pPixmap, pGC);
+ (*pGC->ops->CopyArea)
+ (pDrawable, (DrawablePtr) pPixmap, pGC,
+ bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1,
+ bounds.x1 + pPixmap->drawable.x - pWin->drawable.x -
+ pWindowPriv->x,
+ bounds.y1 + pPixmap->drawable.y - pWin->drawable.y -
+ pWindowPriv->y);
+ FreeScratchGC(pGC);
+ }
+ pWindowPriv->status = StatusContents;
+ /* fall through */
+ case rgnIN:
+ if (!pPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!(pPixmap = pWindowPriv->pBackingPixmap))
+ break;
+ }
+ dx = pPixmap->drawable.x - pWin->drawable.x - pWindowPriv->x;
+ dy = pPixmap->drawable.y - pWin->drawable.y - pWindowPriv->y;
+ for (i = 0; i < nspans; i++)
+ {
+ ppt[i].x += dx;
+ ppt[i].y += dy;
+ }
+ (*pScreen->GetSpans) ((DrawablePtr) pPixmap, wMax, ppt, pwidth,
+ nspans, pdstStart);
+ break;
+ case rgnOUT:
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans,
+ pdstStart);
+ break;
+ }
+ }
+ else
+ {
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ }
+
+ SCREEN_EPILOGUE (pScreen, GetSpans, miBSGetSpans);
+}
+
+static Bool
+miBSChangeWindowAttributes (pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ ScreenPtr pScreen;
+ Bool ret;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
+
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+
+ if (ret && (mask & CWBackingStore))
+ {
+ if (pWin->backingStore != NotUseful || pWin->DIXsaveUnder)
+ miBSAllocate (pWin);
+ else
+ miBSFree (pWin);
+ }
+
+ SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, miBSChangeWindowAttributes);
+
+ return ret;
+}
+
+/*
+ * GC Create wrapper. Set up the cheap GC func wrappers to track
+ * GC validation on BackingStore windows
+ */
+
+static Bool
+miBSCreateGC (pGC)
+ GCPtr pGC;
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ Bool ret;
+
+ SCREEN_PROLOGUE (pScreen, CreateGC);
+
+ if ( (ret = (*pScreen->CreateGC) (pGC)) )
+ {
+ pGC->devPrivates[miBSGCIndex].ptr = (void *) pGC->funcs;
+ pGC->funcs = &miBSCheapGCFuncs;
+ }
+
+ SCREEN_EPILOGUE (pScreen, CreateGC, miBSCreateGC);
+
+ return ret;
+}
+
+static Bool
+miBSDestroyWindow (pWin)
+ WindowPtr pWin;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool ret;
+
+ SCREEN_PROLOGUE (pScreen, DestroyWindow);
+
+ ret = (*pScreen->DestroyWindow) (pWin);
+
+ miBSFree (pWin);
+
+ SCREEN_EPILOGUE (pScreen, DestroyWindow, miBSDestroyWindow);
+
+ return ret;
+}
+
+/*
+ * cheap GC func wrappers. Simply track validation on windows
+ * with backing store to enable the real func/op wrappers
+ */
+
+static void
+miBSCheapValidateGC (pGC, stateChanges, pDrawable)
+ GCPtr pGC;
+ unsigned long stateChanges;
+ DrawablePtr pDrawable;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP &&
+ ((WindowPtr) pDrawable)->backStorage != NULL &&
+ miBSCreateGCPrivate (pGC))
+ {
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+ }
+ else
+ {
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+
+ /* rewrap funcs as Validate may have changed them */
+ pGC->devPrivates[miBSGCIndex].ptr = (void *) pGC->funcs;
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+ }
+}
+
+static void
+miBSCheapChangeGC (pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miBSCheapCopyGC (pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc, pGCDst;
+ unsigned long mask;
+{
+ CHEAP_FUNC_PROLOGUE (pGCDst);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ CHEAP_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+miBSCheapDestroyGC (pGC)
+ GCPtr pGC;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ /* leave it unwrapped */
+}
+
+static void
+miBSCheapChangeClip (pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ void * pvalue;
+ int nrects;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miBSCheapCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ CHEAP_FUNC_PROLOGUE (pgcDst);
+
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ CHEAP_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+miBSCheapDestroyClip(pGC)
+ GCPtr pGC;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+/*
+ * create the full func/op wrappers for a GC
+ */
+
+static Bool
+miBSCreateGCPrivate (pGC)
+ GCPtr pGC;
+{
+ miBSGCRec *pPriv;
+
+ pPriv = (miBSGCRec *) malloc (sizeof (miBSGCRec));
+ if (!pPriv)
+ return FALSE;
+ pPriv->pBackingGC = NULL;
+ pPriv->guarantee = GuaranteeNothing;
+ pPriv->serialNumber = 0;
+ pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
+ pPriv->wrapOps = pGC->ops;
+ pPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &miBSGCFuncs;
+ pGC->ops = &miBSGCOps;
+ pGC->devPrivates[miBSGCIndex].ptr = (void *) pPriv;
+ return TRUE;
+}
+
+static void
+miBSDestroyGCPrivate (GCPtr pGC)
+{
+ miBSGCRec *pPriv;
+
+ pPriv = (miBSGCRec *) pGC->devPrivates[miBSGCIndex].ptr;
+ if (pPriv)
+ {
+ pGC->devPrivates[miBSGCIndex].ptr = (void *) pPriv->wrapFuncs;
+ pGC->funcs = &miBSCheapGCFuncs;
+ pGC->ops = pPriv->wrapOps;
+ if (pPriv->pBackingGC)
+ FreeGC (pPriv->pBackingGC, (GContext) 0);
+ free ((void *) pPriv);
+ }
+}
+
+/*
+ * GC ops -- wrap each GC operation with our own function
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFillSpans --
+ * Perform a FillSpans, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ DDXPointPtr pptCopy, pptReset;
+ int *pwidthCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)malloc(nInit*sizeof(DDXPointRec));
+ pwidthCopy=(int *)malloc(nInit*sizeof(int));
+ if (pptCopy && pwidthCopy)
+ {
+ copyData(pptInit, pptCopy, nInit, MoreCopy0);
+ memmove((char *)pwidthCopy,(char *)pwidthInit,nInit*sizeof(int));
+
+ (* pGC->ops->FillSpans)(pDrawable, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ if (pGC->miTranslate)
+ {
+ int dx, dy;
+ int nReset;
+
+ pptReset = pptCopy;
+ dx = pDrawable->x - pBackingDrawable->x;
+ dy = pDrawable->y - pBackingDrawable->y;
+ nReset = nInit;
+ while (nReset--)
+ {
+ pptReset->x -= dx;
+ pptReset->y -= dy;
+ ++pptReset;
+ }
+ }
+ (* pBackingGC->ops->FillSpans)(pBackingDrawable,
+ pBackingGC, nInit, pptCopy, pwidthCopy,
+ fSorted);
+ }
+ if (pwidthCopy) free(pwidthCopy);
+ if (pptCopy) free(pptCopy);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSSetSpans --
+ * Perform a SetSpans, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *psrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ DDXPointPtr pptCopy, pptReset;
+ int *pwidthCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)malloc(nspans*sizeof(DDXPointRec));
+ pwidthCopy=(int *)malloc(nspans*sizeof(int));
+ if (pptCopy && pwidthCopy)
+ {
+ copyData(ppt, pptCopy, nspans, MoreCopy0);
+ memmove((char *)pwidthCopy,(char *)pwidth,nspans*sizeof(int));
+
+ (* pGC->ops->SetSpans)(pDrawable, pGC, psrc, ppt, pwidth,
+ nspans, fSorted);
+ if (pGC->miTranslate)
+ {
+ int dx, dy;
+ int nReset;
+
+ pptReset = pptCopy;
+ dx = pDrawable->x - pBackingDrawable->x;
+ dy = pDrawable->y - pBackingDrawable->y;
+ nReset = nspans;
+ while (nReset--)
+ {
+ pptReset->x -= dx;
+ pptReset->y -= dy;
+ ++pptReset;
+ }
+ }
+ (* pBackingGC->ops->SetSpans)(pBackingDrawable, pBackingGC,
+ psrc, pptCopy, pwidthCopy, nspans, fSorted);
+ }
+ if (pwidthCopy) free(pwidthCopy);
+ if (pptCopy) free(pptCopy);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPutImage --
+ * Perform a PutImage, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int depth;
+ int x;
+ int y;
+ int w;
+ int h;
+ int leftPad;
+ int format;
+ char *pBits;
+{
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ (*pGC->ops->PutImage)(pDrawable, pGC,
+ depth, x, y, w, h, leftPad, format, pBits);
+ (*pBackingGC->ops->PutImage)(pBackingDrawable, pBackingGC,
+ depth, x - pBackingStore->x, y - pBackingStore->y,
+ w, h, leftPad, format, pBits);
+
+ EPILOGUE (pGC);
+}
+
+typedef RegionPtr (* CopyAreaProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int);
+typedef RegionPtr (* CopyPlaneProcPtr)(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int,
+ unsigned long bitPlane);
+/*-
+ *-----------------------------------------------------------------------
+ * miBSDoCopy --
+ * Perform a CopyArea or CopyPlane within a window that has backing
+ * store enabled.
+ *
+ * Results:
+ * TRUE if the copy was performed or FALSE if a regular one should
+ * be done.
+ *
+ * Side Effects:
+ * Things are copied (no s***!)
+ *
+ * Notes:
+ * The idea here is to form two regions that cover the source box.
+ * One contains the exposed rectangles while the other contains
+ * the obscured ones. An array of <box, drawable> pairs is then
+ * formed where the <box> indicates the area to be copied and the
+ * <drawable> indicates from where it is to be copied (exposed regions
+ * come from the screen while obscured ones come from the backing
+ * pixmap). The array 'sequence' is then filled with the indices of
+ * the pairs in the order in which they should be copied to prevent
+ * things from getting screwed up. A call is also made through the
+ * backingGC to take care of any copying into the backing pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miBSDoCopy(
+ WindowPtr pWin, /* Window being scrolled */
+ GCPtr pGC, /* GC we're called through */
+ int srcx, /* X of source rectangle */
+ int srcy, /* Y of source rectangle */
+ int w, /* Width of source rectangle */
+ int h, /* Height of source rectangle */
+ int dstx, /* X of destination rectangle */
+ int dsty, /* Y of destination rectangle */
+ unsigned long plane, /* Plane to copy (0 for CopyArea) */
+ CopyPlaneProcPtr copyProc, /* Procedure to call to perform the copy */
+ RegionPtr *ppRgn) /* resultant Graphics Expose region */
+{
+ RegionPtr pRgnExp; /* Exposed region */
+ RegionPtr pRgnObs; /* Obscured region */
+ BoxRec box; /* Source box (screen coord) */
+ struct BoxDraw {
+ BoxPtr pBox; /* Source box */
+ enum {
+ win, pix
+ } source; /* Place from which to copy */
+ } *boxes; /* Array of box/drawable pairs covering
+ * source box. */
+ int *sequence; /* Sequence of boxes to move */
+ register int i, j, k, l, y;
+ register BoxPtr pBox;
+ int dx, dy, nrects;
+ Bool graphicsExposures;
+ CopyPlaneProcPtr pixCopyProc;
+ int numRectsExp, numRectsObs;
+ BoxPtr pBoxExp, pBoxObs;
+
+ SETUP_BACKING (pWin, pGC);
+ (void)oldFuncs;
+
+ /*
+ * Create a region of exposed boxes in pRgnExp.
+ */
+ box.x1 = srcx + pWin->drawable.x;
+ box.x2 = box.x1 + w;
+ box.y1 = srcy + pWin->drawable.y;
+ box.y2 = box.y1 + h;
+
+ pRgnExp = RegionCreate(&box, 1);
+ RegionIntersect(pRgnExp, pRgnExp, &pWin->clipList);
+ pRgnObs = RegionCreate(NULL, 1);
+ RegionInverse(pRgnObs, pRgnExp, &box);
+
+ /*
+ * Translate regions into window coordinates for proper calls
+ * to the copyProc, then make sure none of the obscured region sticks
+ * into invalid areas of the backing pixmap.
+ */
+ RegionTranslate(pRgnExp,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ RegionTranslate(pRgnObs,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ RegionIntersect(pRgnObs, pRgnObs, &pBackingStore->SavedRegion);
+
+ /*
+ * If the obscured region is empty, there's no point being fancy.
+ */
+ if (!RegionNotEmpty(pRgnObs))
+ {
+ RegionDestroy(pRgnExp);
+ RegionDestroy(pRgnObs);
+
+ return (FALSE);
+ }
+
+ numRectsExp = RegionNumRects(pRgnExp);
+ pBoxExp = RegionRects(pRgnExp);
+ pBoxObs = RegionRects(pRgnObs);
+ numRectsObs = RegionNumRects(pRgnObs);
+ nrects = numRectsExp + numRectsObs;
+
+ boxes = (struct BoxDraw *)malloc(nrects * sizeof(struct BoxDraw));
+ sequence = (int *) malloc(nrects * sizeof(int));
+ *ppRgn = NULL;
+
+ if (!boxes || !sequence)
+ {
+ if (sequence) free(sequence);
+ if (boxes) free(boxes);
+ RegionDestroy(pRgnExp);
+ RegionDestroy(pRgnObs);
+
+ return(TRUE);
+ }
+
+ /*
+ * Order the boxes in the two regions so we know from which drawable
+ * to copy which box, storing the result in the boxes array
+ */
+ for (i = 0, j = 0, k = 0;
+ (i < numRectsExp) && (j < numRectsObs);
+ k++)
+ {
+ if (pBoxExp[i].y1 < pBoxObs[j].y1)
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ }
+ else if ((pBoxObs[j].y1 < pBoxExp[i].y1) ||
+ (pBoxObs[j].x1 < pBoxExp[i].x1))
+ {
+ boxes[k].pBox = &pBoxObs[j];
+ boxes[k].source = pix;
+ j++;
+ }
+ else
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ }
+ }
+
+ /*
+ * Catch any leftover boxes from either region (note that only
+ * one can have leftover boxes...)
+ */
+ if (i != numRectsExp)
+ {
+ do
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ k++;
+ } while (i < numRectsExp);
+
+ }
+ else
+ {
+ do
+ {
+ boxes[k].pBox = &pBoxObs[j];
+ boxes[k].source = pix;
+ j++;
+ k++;
+ } while (j < numRectsObs);
+ }
+
+ if (dsty <= srcy)
+ {
+ /*
+ * Scroll up or vertically stationary, so vertical order is ok.
+ */
+ if (dstx <= srcx)
+ {
+ /*
+ * Scroll left or horizontally stationary, so horizontal order
+ * is ok as well.
+ */
+ for (i = 0; i < nrects; i++)
+ {
+ sequence[i] = i;
+ }
+ }
+ else
+ {
+ /*
+ * Scroll right. Need to reverse the rectangles within each
+ * band.
+ */
+ for (i = 0, j = 1, k = 0;
+ i < nrects;
+ j = i + 1, k = i)
+ {
+ y = boxes[i].pBox->y1;
+ while ((j < nrects) && (boxes[j].pBox->y1 == y))
+ {
+ j++;
+ }
+ for (j--; j >= k; j--, i++)
+ {
+ sequence[i] = j;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scroll down. Must reverse vertical banding, at least.
+ */
+ if (dstx < srcx)
+ {
+ /*
+ * Scroll left. Horizontal order is ok.
+ */
+ for (i = nrects - 1, j = i - 1, k = i, l = 0;
+ i >= 0;
+ j = i - 1, k = i)
+ {
+ /*
+ * Find extent of current horizontal band, then reverse
+ * the order of the whole band.
+ */
+ y = boxes[i].pBox->y1;
+ while ((j >= 0) && (boxes[j].pBox->y1 == y))
+ {
+ j--;
+ }
+ for (j++; j <= k; j++, i--, l++)
+ {
+ sequence[l] = j;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scroll right or horizontal stationary.
+ * Reverse horizontal order as well (if stationary, horizontal
+ * order can be swapped without penalty and this is faster
+ * to compute).
+ */
+ for (i = 0, j = nrects - 1; i < nrects; i++, j--)
+ {
+ sequence[i] = j;
+ }
+ }
+ }
+
+ /*
+ * XXX: To avoid getting multiple NoExpose events from this operation,
+ * we turn OFF graphicsExposures in the gc and deal with any uncopied
+ * areas later, if there's something not in backing-store.
+ */
+
+ graphicsExposures = pGC->graphicsExposures;
+ pGC->graphicsExposures = FALSE;
+
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+
+ /*
+ * Figure out which copy procedure to use from the backing GC. Note we
+ * must do this because some implementations (sun's, e.g.) have
+ * pBackingGC a fake GC with the real one below it, thus the devPriv for
+ * pBackingGC won't be what the output library expects.
+ */
+ if (plane != 0)
+ {
+ pixCopyProc = pBackingGC->ops->CopyPlane;
+ }
+ else
+ {
+ pixCopyProc = (CopyPlaneProcPtr)pBackingGC->ops->CopyArea;
+ }
+
+ for (i = 0; i < nrects; i++)
+ {
+ pBox = boxes[sequence[i]].pBox;
+
+ /*
+ * If we're copying from the pixmap, we need to place its contents
+ * onto the screen before scrolling the pixmap itself. If we're copying
+ * from the window, we need to copy its contents into the pixmap before
+ * we scroll the window itself.
+ */
+ if (boxes[sequence[i]].source == pix)
+ {
+ (void) (* copyProc) (pBackingDrawable, &(pWin->drawable), pGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ (void) (* pixCopyProc) (pBackingDrawable, pBackingDrawable, pBackingGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx - pBackingStore->x,
+ pBox->y1 + dy - pBackingStore->y, plane);
+ }
+ else
+ {
+ (void) (* pixCopyProc) (&(pWin->drawable), pBackingDrawable, pBackingGC,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx - pBackingStore->x,
+ pBox->y1 + dy - pBackingStore->y, plane);
+ (void) (* copyProc) (&(pWin->drawable), &(pWin->drawable), pGC,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ }
+ }
+ free(sequence);
+ free(boxes);
+
+ pGC->graphicsExposures = graphicsExposures;
+ /*
+ * Form union of rgnExp and rgnObs and see if covers entire area
+ * to be copied. Store the resultant region for miBSCopyArea
+ * to return to dispatch which will send the appropriate expose
+ * events.
+ */
+ RegionUnion(pRgnExp, pRgnExp, pRgnObs);
+ box.x1 = srcx;
+ box.x2 = srcx + w;
+ box.y1 = srcy;
+ box.y2 = srcy + h;
+ if (RegionContainsRect(pRgnExp, &box) == rgnIN)
+ {
+ RegionEmpty(pRgnExp);
+ }
+ else
+ {
+ RegionInverse(pRgnExp, pRgnExp, &box);
+ RegionTranslate(pRgnExp,
+ dx + pWin->drawable.x,
+ dy + pWin->drawable.y);
+ RegionIntersect(pRgnObs, pRgnExp, &pWin->clipList);
+ (*pWin->drawable.pScreen->PaintWindowBackground) (pWin,
+ pRgnObs, PW_BACKGROUND);
+ RegionTranslate(pRgnExp,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ miBSClearBackingRegion (pWin, pRgnExp);
+ }
+ if (graphicsExposures)
+ *ppRgn = pRgnExp;
+ else
+ RegionDestroy(pRgnExp);
+ RegionDestroy(pRgnObs);
+
+ return (TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSCopyArea --
+ * Perform a CopyArea from the source to the destination, extracting
+ * from the source's backing-store and storing into the destination's
+ * backing-store without messing anything up. If the source and
+ * destination are different, there's not too much to worry about:
+ * we can just issue several calls to the regular CopyArea function.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ GCPtr pGC;
+ int srcx;
+ int srcy;
+ int w;
+ int h;
+ int dstx;
+ int dsty;
+{
+ BoxPtr pExtents;
+ long dx, dy;
+ int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
+ RegionPtr pixExposed = 0, winExposed = 0;
+
+ SETUP_BACKING(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if ((pSrc != pDst) ||
+ (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
+ (unsigned long) 0, (CopyPlaneProcPtr)pGC->ops->CopyArea,
+ &winExposed)))
+ {
+ /*
+ * always copy to the backing store first, miBSDoCopy
+ * returns FALSE if the *source* region is disjoint
+ * from the backing store saved region. So, copying
+ * *to* the backing store is always safe
+ */
+ if (pGC->clientClipType != CT_PIXMAP)
+ {
+ /*
+ * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
+ * the backing store. An unnecessary optimisation,
+ * but a useful one when GetSpans is slow.
+ */
+ pExtents = RegionExtents(
+ (RegionPtr)pBackingGC->clientClip);
+ bsrcx = srcx;
+ bsrcy = srcy;
+ bw = w;
+ bh = h;
+ bdstx = dstx;
+ bdsty = dsty;
+ dx = pExtents->x1 - bdstx;
+ if (dx > 0)
+ {
+ bsrcx += dx;
+ bdstx += dx;
+ bw -= dx;
+ }
+ dy = pExtents->y1 - bdsty;
+ if (dy > 0)
+ {
+ bsrcy += dy;
+ bdsty += dy;
+ bh -= dy;
+ }
+ dx = (bdstx + bw) - pExtents->x2;
+ if (dx > 0)
+ bw -= dx;
+ dy = (bdsty + bh) - pExtents->y2;
+ if (dy > 0)
+ bh -= dy;
+ if (bw > 0 && bh > 0)
+ pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
+ pBackingDrawable, pBackingGC,
+ bsrcx, bsrcy, bw, bh, bdstx - pBackingStore->x,
+ bdsty - pBackingStore->y);
+ }
+ else
+ pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
+ pBackingDrawable, pBackingGC,
+ srcx, srcy, w, h,
+ dstx - pBackingStore->x, dsty - pBackingStore->y);
+
+ winExposed = (* pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ }
+
+ /*
+ * compute the composite graphics exposure region
+ */
+ if (winExposed)
+ {
+ if (pixExposed){
+ RegionUnion(winExposed, winExposed, pixExposed);
+ RegionDestroy(pixExposed);
+ }
+ } else
+ winExposed = pixExposed;
+
+ EPILOGUE (pGC);
+
+ return winExposed;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSCopyPlane --
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ register GC *pGC;
+ int srcx,
+ srcy;
+ int w,
+ h;
+ int dstx,
+ dsty;
+ unsigned long plane;
+{
+ BoxPtr pExtents;
+ long dx, dy;
+ int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
+ RegionPtr winExposed = 0, pixExposed = 0;
+ SETUP_BACKING(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if ((pSrc != pDst) ||
+ (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
+ plane, pGC->ops->CopyPlane, &winExposed)))
+ {
+ /*
+ * always copy to the backing store first, miBSDoCopy
+ * returns FALSE if the *source* region is disjoint
+ * from the backing store saved region. So, copying
+ * *to* the backing store is always safe
+ */
+ if (pGC->clientClipType != CT_PIXMAP)
+ {
+ /*
+ * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
+ * the backing store. An unnecessary optimisation,
+ * but a useful one when GetSpans is slow.
+ */
+ pExtents = RegionExtents(
+ (RegionPtr)pBackingGC->clientClip);
+ bsrcx = srcx;
+ bsrcy = srcy;
+ bw = w;
+ bh = h;
+ bdstx = dstx;
+ bdsty = dsty;
+ dx = pExtents->x1 - bdstx;
+ if (dx > 0)
+ {
+ bsrcx += dx;
+ bdstx += dx;
+ bw -= dx;
+ }
+ dy = pExtents->y1 - bdsty;
+ if (dy > 0)
+ {
+ bsrcy += dy;
+ bdsty += dy;
+ bh -= dy;
+ }
+ dx = (bdstx + bw) - pExtents->x2;
+ if (dx > 0)
+ bw -= dx;
+ dy = (bdsty + bh) - pExtents->y2;
+ if (dy > 0)
+ bh -= dy;
+ if (bw > 0 && bh > 0)
+ pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
+ pBackingDrawable,
+ pBackingGC, bsrcx, bsrcy, bw, bh,
+ bdstx - pBackingStore->x,
+ bdsty - pBackingStore->y, plane);
+ }
+ else
+ pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
+ pBackingDrawable,
+ pBackingGC, srcx, srcy, w, h,
+ dstx - pBackingStore->x,
+ dsty - pBackingStore->y, plane);
+
+ winExposed = (* pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ }
+
+ /*
+ * compute the composite graphics exposure region
+ */
+ if (winExposed)
+ {
+ if (pixExposed)
+ {
+ RegionUnion(winExposed, winExposed, pixExposed);
+ RegionDestroy(pixExposed);
+ }
+ } else
+ winExposed = pixExposed;
+
+ EPILOGUE (pGC);
+
+ return winExposed;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyPoint --
+ * Perform a PolyPoint, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyPoint (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+ xPoint *pptCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (xPoint *)malloc(npt*sizeof(xPoint));
+ if (pptCopy)
+ {
+ copyPoints(pptInit, pptCopy, npt, mode);
+
+ (* pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
+
+ (* pBackingGC->ops->PolyPoint) (pBackingDrawable,
+ pBackingGC, mode, npt, pptCopy);
+
+ free(pptCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyLines --
+ * Perform a Polylines, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolylines (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int npt;
+ DDXPointPtr pptInit;
+{
+ DDXPointPtr pptCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)malloc(npt*sizeof(DDXPointRec));
+ if (pptCopy)
+ {
+ copyPoints(pptInit, pptCopy, npt, mode);
+
+ (* pGC->ops->Polylines)(pDrawable, pGC, mode, npt, pptInit);
+ (* pBackingGC->ops->Polylines)(pBackingDrawable,
+ pBackingGC, mode, npt, pptCopy);
+ free(pptCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolySegment --
+ * Perform a PolySegment, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolySegment(pDrawable, pGC, nseg, pSegs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ xSegment *pSegs;
+{
+ xSegment *pSegsCopy;
+
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pSegsCopy = (xSegment *)malloc(nseg*sizeof(xSegment));
+ if (pSegsCopy)
+ {
+ copyData(pSegs, pSegsCopy, nseg << 1, MoreCopy0);
+
+ (* pGC->ops->PolySegment)(pDrawable, pGC, nseg, pSegs);
+ (* pBackingGC->ops->PolySegment)(pBackingDrawable,
+ pBackingGC, nseg, pSegsCopy);
+
+ free(pSegsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyRectangle --
+ * Perform a PolyRectangle, routing output to backing-store as needed.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyRectangle(pDrawable, pGC, nrects, pRects)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ xRectangle *pRectsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pRectsCopy =(xRectangle *)malloc(nrects*sizeof(xRectangle));
+ if (pRectsCopy)
+ {
+ copyData(pRects, pRectsCopy, nrects, MoreCopy2);
+
+ (* pGC->ops->PolyRectangle)(pDrawable, pGC, nrects, pRects);
+ (* pBackingGC->ops->PolyRectangle)(pBackingDrawable,
+ pBackingGC, nrects, pRectsCopy);
+
+ free(pRectsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyArc --
+ * Perform a PolyArc, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ xArc *pArcsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pArcsCopy = (xArc *)malloc(narcs*sizeof(xArc));
+ if (pArcsCopy)
+ {
+ copyData(parcs, pArcsCopy, narcs, MoreCopy4);
+
+ (* pGC->ops->PolyArc)(pDrawable, pGC, narcs, parcs);
+ (* pBackingGC->ops->PolyArc)(pBackingDrawable, pBackingGC,
+ narcs, pArcsCopy);
+
+ free(pArcsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFillPolygon --
+ * Perform a FillPolygon, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int shape, mode;
+ register int count;
+ DDXPointPtr pPts;
+{
+ DDXPointPtr pPtsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pPtsCopy = (DDXPointPtr)malloc(count*sizeof(DDXPointRec));
+ if (pPtsCopy)
+ {
+ copyPoints(pPts, pPtsCopy, count, mode);
+ (* pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, count, pPts);
+ (* pBackingGC->ops->FillPolygon)(pBackingDrawable,
+ pBackingGC, shape, mode,
+ count, pPtsCopy);
+
+ free(pPtsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyFillRect --
+ * Perform a PolyFillRect, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *pRectCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pRectCopy =
+ (xRectangle *)malloc(nrectFill*sizeof(xRectangle));
+ if (pRectCopy)
+ {
+ copyData(prectInit, pRectCopy, nrectFill, MoreCopy2);
+
+ (* pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prectInit);
+ (* pBackingGC->ops->PolyFillRect)(pBackingDrawable,
+ pBackingGC, nrectFill, pRectCopy);
+
+ free(pRectCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyFillArc --
+ * Perform a PolyFillArc, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyFillArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ xArc *pArcsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pArcsCopy = (xArc *)malloc(narcs*sizeof(xArc));
+ if (pArcsCopy)
+ {
+ copyData(parcs, pArcsCopy, narcs, MoreCopy4);
+ (* pGC->ops->PolyFillArc)(pDrawable, pGC, narcs, parcs);
+ (* pBackingGC->ops->PolyFillArc)(pBackingDrawable,
+ pBackingGC, narcs, pArcsCopy);
+ free(pArcsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyText8 --
+ * Perform a PolyText8, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+miBSPolyText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ int result;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ result = (* pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->PolyText8)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+ return result;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyText16 --
+ * Perform a PolyText16, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+miBSPolyText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ int result;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ result = (* pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->PolyText16)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+
+ return result;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageText8 --
+ * Perform a ImageText8, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->ImageText8)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageText16 --
+ * Perform a ImageText16, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->ImageText16)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageGlyphBlt --
+ * Perform a ImageGlyphBlt, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ void * pglyphBase; /* start of array of glyphs */
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
+ pglyphBase);
+ (* pBackingGC->ops->ImageGlyphBlt)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ nglyph, ppci, pglyphBase);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyGlyphBlt --
+ * Perform a PolyGlyphBlt, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ void * pglyphBase; /* start of array of glyphs */
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ (* pBackingGC->ops->PolyGlyphBlt)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ nglyph, ppci, pglyphBase);
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPushPixels --
+ * Perform a PushPixels, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPushPixels(pGC, pBitMap, pDst, w, h, x, y)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDst;
+ int w, h, x, y;
+{
+ SETUP_BACKING (pDst, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->PushPixels)(pGC, pBitMap, pDst, w, h, x, y);
+ if (pGC->miTranslate) {
+ x -= pDst->x;
+ y -= pDst->y;
+ }
+ (* pBackingGC->ops->PushPixels)(pBackingGC, pBitMap,
+ pBackingDrawable, w, h,
+ x - pBackingStore->x, y - pBackingStore->y);
+
+ EPILOGUE (pGC);
+}
+
+#ifdef NEED_LINEHELPER
+/*-
+ *-----------------------------------------------------------------------
+ * miBSLineHelper --
+ *
+ * Results: should never be called
+ *
+ * Side Effects: server dies
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSLineHelper()
+{
+ FatalError("miBSLineHelper called\n");
+}
+#endif
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSClearBackingStore --
+ * Clear the given area of the backing pixmap with the background of
+ * the window, whatever it is. If generateExposures is TRUE, generate
+ * exposure events for the area. Note that if the area has any
+ * part outside the saved portions of the window, we do not allow the
+ * count in the expose events to be 0, since there will be more
+ * expose events to come.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Areas of pixmap are cleared and Expose events are generated.
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSClearBackingStore(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x;
+ int y;
+ int w;
+ int h;
+ Bool generateExposures;
+{
+ RegionPtr pRgn;
+ int i;
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ GCPtr pGC;
+ int ts_x_origin,
+ ts_y_origin;
+ void *gcvalues[4];
+ unsigned long gcmask;
+ xRectangle *rects;
+ BoxPtr pBox;
+ BoxRec box;
+ PixUnion background;
+ char backgroundState;
+ int numRects;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pScreen = pWin->drawable.pScreen;
+
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return NullRegion;
+
+ if (w == 0)
+ w = (int) pWin->drawable.width - x;
+ if (h == 0)
+ h = (int) pWin->drawable.height - y;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + w;
+ box.y2 = y + h;
+ pRgn = RegionCreate(&box, 1);
+ if (!pRgn)
+ return NullRegion;
+ RegionIntersect(pRgn, pRgn, &pBackingStore->SavedRegion);
+
+ if (RegionNotEmpty(pRgn))
+ {
+ /*
+ * if clearing entire window, simply make new virtual
+ * tile. For the root window, we also destroy the pixmap
+ * to save a pile of memory
+ */
+ if (x == 0 && y == 0 &&
+ w == pWin->drawable.width &&
+ h == pWin->drawable.height)
+ {
+ if (!pWin->parent)
+ miDestroyBSPixmap (pWin);
+ if (pBackingStore->status != StatusContents)
+ miTileVirtualBS (pWin);
+ }
+
+ ts_x_origin = ts_y_origin = 0;
+
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+ if (backgroundState == ParentRelative) {
+ WindowPtr pParent;
+
+ pParent = pWin;
+ while (pParent->backgroundState == ParentRelative) {
+ ts_x_origin -= pParent->origin.x;
+ ts_y_origin -= pParent->origin.y;
+ pParent = pParent->parent;
+ }
+ backgroundState = pParent->backgroundState;
+ background = pParent->background;
+ }
+
+ if ((backgroundState != None) &&
+ ((pBackingStore->status == StatusContents) ||
+ !SameBackground (pBackingStore->backgroundState,
+ pBackingStore->background,
+ backgroundState,
+ background)))
+ {
+ if (!pBackingStore->pBackingPixmap)
+ miCreateBSPixmap(pWin, NullBox);
+
+ pGC = GetScratchGC(pWin->drawable.depth, pScreen);
+ if (pGC && pBackingStore->pBackingPixmap)
+ {
+ /*
+ * First take care of any ParentRelative stuff by altering the
+ * tile/stipple origin to match the coordinates of the upper-left
+ * corner of the first ancestor without a ParentRelative background.
+ * This coordinate is, of course, negative.
+ */
+
+ if (backgroundState == BackgroundPixel)
+ {
+ gcvalues[0] = (void *) background.pixel;
+ gcvalues[1] = (void *)FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ }
+ else
+ {
+ gcvalues[0] = (void *)FillTiled;
+ gcvalues[1] = (void *) background.pixmap;
+ gcmask = GCFillStyle|GCTile;
+ }
+ gcvalues[2] = (void *)(long)(ts_x_origin - pBackingStore->x);
+ gcvalues[3] = (void *)(long)(ts_y_origin - pBackingStore->y);
+ gcmask |= GCTileStipXOrigin|GCTileStipYOrigin;
+ DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);
+ ValidateGC((DrawablePtr)pBackingStore->pBackingPixmap, pGC);
+
+ /*
+ * Figure out the array of rectangles to fill and fill them with
+ * PolyFillRect in the proper mode, as set in the GC above.
+ */
+ numRects = RegionNumRects(pRgn);
+ rects = (xRectangle *)malloc(numRects*sizeof(xRectangle));
+
+ if (rects)
+ {
+ for (i = 0, pBox = RegionRects(pRgn);
+ i < numRects;
+ i++, pBox++)
+ {
+ rects[i].x = pBox->x1 - pBackingStore->x;
+ rects[i].y = pBox->y1 - pBackingStore->y;
+ rects[i].width = pBox->x2 - pBox->x1;
+ rects[i].height = pBox->y2 - pBox->y1;
+ }
+ (* pGC->ops->PolyFillRect) (
+ (DrawablePtr)pBackingStore->pBackingPixmap,
+ pGC, numRects, rects);
+ free(rects);
+ }
+ FreeScratchGC(pGC);
+ }
+ }
+
+ if (!generateExposures)
+ {
+ RegionDestroy(pRgn);
+ pRgn = NULL;
+ }
+ else
+ {
+ /*
+ * result must be screen relative, but is currently
+ * drawable relative.
+ */
+ RegionTranslate(pRgn, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+ }
+ else
+ {
+ RegionDestroy(pRgn);
+ pRgn = NULL;
+ }
+ return pRgn;
+}
+
+static void
+miBSClearBackingRegion (pWin, pRgn)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+{
+ BoxPtr pBox;
+ int i;
+
+ i = RegionNumRects(pRgn);
+ pBox = RegionRects(pRgn);
+ while (i--)
+ {
+ (void) miBSClearBackingStore(pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ FALSE);
+ pBox++;
+ }
+}
+
+/*
+ * fill a region of the destination with virtual bits
+ *
+ * pRgn is to be translated by (x,y)
+ */
+
+static void
+miBSFillVirtualBits (pDrawable, pGC, pRgn, x, y, state, pixunion, planeMask)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ RegionPtr pRgn;
+ int x, y;
+ int state;
+ PixUnion pixunion;
+ unsigned long planeMask;
+{
+ int i;
+ BITS32 gcmask;
+ void * gcval[5];
+ xRectangle *pRect;
+ BoxPtr pBox;
+ WindowPtr pWin;
+ int numRects;
+
+ if (state == None)
+ return;
+ numRects = RegionNumRects(pRgn);
+ pRect = (xRectangle *)malloc(numRects * sizeof(xRectangle));
+ if (!pRect)
+ return;
+ pWin = 0;
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ pWin = (WindowPtr) pDrawable;
+ if (!pWin->backStorage)
+ pWin = 0;
+ }
+ i = 0;
+ gcmask = 0;
+ gcval[i++] = (void *)planeMask;
+ gcmask |= GCPlaneMask;
+ if (state == BackgroundPixel)
+ {
+ if (pGC->fgPixel != pixunion.pixel)
+ {
+ gcval[i++] = (void *)pixunion.pixel;
+ gcmask |= GCForeground;
+ }
+ if (pGC->fillStyle != FillSolid)
+ {
+ gcval[i++] = (void *)FillSolid;
+ gcmask |= GCFillStyle;
+ }
+ }
+ else
+ {
+ if (pGC->fillStyle != FillTiled)
+ {
+ gcval[i++] = (void *)FillTiled;
+ gcmask |= GCFillStyle;
+ }
+ if (pGC->tileIsPixel || pGC->tile.pixmap != pixunion.pixmap)
+ {
+ gcval[i++] = (void *)pixunion.pixmap;
+ gcmask |= GCTile;
+ }
+ if (pGC->patOrg.x != x)
+ {
+ gcval[i++] = (void *)(long)x;
+ gcmask |= GCTileStipXOrigin;
+ }
+ if (pGC->patOrg.y != y)
+ {
+ gcval[i++] = (void *)(long)y;
+ gcmask |= GCTileStipYOrigin;
+ }
+ }
+ if (gcmask)
+ DoChangeGC (pGC, gcmask, (XID *)gcval, 1);
+
+ if (pWin)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ if (pDrawable->serialNumber != pGC->serialNumber)
+ ValidateGC (pDrawable, pGC);
+
+ pBox = RegionRects(pRgn);
+ for (i = numRects; --i >= 0; pBox++, pRect++)
+ {
+ pRect->x = pBox->x1 + x;
+ pRect->y = pBox->y1 + y;
+ pRect->width = pBox->x2 - pBox->x1;
+ pRect->height = pBox->y2 - pBox->y1;
+ }
+ pRect -= numRects;
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, numRects, pRect);
+ if (pWin)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+ free (pRect);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSAllocate --
+ * Create and install backing store info for a window
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static void
+miBSAllocate(pWin)
+ WindowPtr pWin;
+{
+ register miBSWindowPtr pBackingStore;
+
+ if (pWin->drawable.pScreen->backingStoreSupport == NotUseful)
+ return;
+ if (!(pBackingStore = (miBSWindowPtr)pWin->backStorage))
+ {
+
+ pBackingStore = (miBSWindowPtr)malloc(sizeof(miBSWindowRec));
+ if (!pBackingStore)
+ return;
+
+ pBackingStore->pBackingPixmap = NullPixmap;
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ RegionNull(&pBackingStore->SavedRegion);
+ pBackingStore->viewable = (char)pWin->viewable;
+ pBackingStore->status = StatusNoPixmap;
+ pBackingStore->backgroundState = None;
+ pWin->backStorage = (void *) pBackingStore;
+ }
+
+ /*
+ * Now want to initialize the backing pixmap and SavedRegion if
+ * necessary. The initialization consists of finding all the
+ * currently-obscured regions, by taking the inverse of the window's
+ * clip list, storing the result in SavedRegion, and exposing those
+ * areas of the window.
+ */
+
+ if (pBackingStore->status == StatusNoPixmap &&
+ ((pWin->backingStore == WhenMapped && pWin->viewable) ||
+ (pWin->backingStore == Always)))
+ {
+ BoxRec box;
+ RegionPtr pSavedRegion;
+
+ pSavedRegion = &pBackingStore->SavedRegion;
+
+ box.x1 = pWin->drawable.x;
+ box.x2 = box.x1 + (int) pWin->drawable.width;
+ box.y1 = pWin->drawable.y;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+
+ RegionInverse(pSavedRegion, &pWin->clipList, &box);
+ RegionTranslate(pSavedRegion,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ RegionIntersect(pSavedRegion, pSavedRegion,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionIntersect(pSavedRegion, pSavedRegion,
+ wClipShape (pWin));
+#endif
+ /* if window is already on-screen, assume it has been drawn to */
+ if (pWin->viewable)
+ pBackingStore->status = StatusVDirty;
+ miTileVirtualBS (pWin);
+
+ /*
+ * deliver all the newly available regions
+ * as exposure events to the window
+ */
+
+ miSendExposures(pWin, pSavedRegion, 0, 0);
+ }
+ else if (!pWin->viewable)
+ {
+ /*
+ * Turn off backing store when we're not supposed to
+ * be saving anything
+ */
+ if (pBackingStore->status != StatusNoPixmap)
+ {
+ RegionEmpty(&pBackingStore->SavedRegion);
+ miDestroyBSPixmap (pWin);
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFree --
+ * Destroy and free all the stuff associated with the backing-store
+ * for the given window.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The backing pixmap and all the regions and GC's are destroyed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFree(pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ if (pBackingStore)
+ {
+ miDestroyBSPixmap (pWin);
+
+ RegionUninit(&pBackingStore->SavedRegion);
+
+ free(pBackingStore);
+ pWin->backStorage = NULL;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miResizeBackingStore --
+ * Alter the size of the backing pixmap as necessary when the
+ * SavedRegion changes size. The contents of the old pixmap are
+ * copied/shifted into the new/same pixmap.
+ *
+ * Results:
+ * The new Pixmap is created as necessary.
+ *
+ * Side Effects:
+ * The old pixmap is destroyed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miResizeBackingStore(
+ WindowPtr pWin,
+ int dx, /* bits are moving this far */
+ int dy, /* bits are moving this far */
+ Bool saveBits) /* bits are useful */
+{
+ miBSWindowPtr pBackingStore;
+ PixmapPtr pBackingPixmap;
+ ScreenPtr pScreen;
+ GC *pGC;
+ BoxPtr extents;
+ PixmapPtr pNewPixmap;
+ int nx, ny;
+ int nw, nh;
+
+ pBackingStore = (miBSWindowPtr)(pWin->backStorage);
+ pBackingPixmap = pBackingStore->pBackingPixmap;
+ if (!pBackingPixmap)
+ return;
+ pScreen = pWin->drawable.pScreen;
+ extents = RegionExtents(&pBackingStore->SavedRegion);
+ pNewPixmap = pBackingPixmap;
+
+ nw = extents->x2 - extents->x1;
+ nh = extents->y2 - extents->y1;
+
+ /* the policy here could be more sophisticated */
+ if (nw != pBackingPixmap->drawable.width ||
+ nh != pBackingPixmap->drawable.height)
+ {
+ if (!saveBits || !nw || !nh)
+ {
+ pNewPixmap = NullPixmap;
+ pBackingStore->status = StatusNoPixmap;
+ }
+ else
+ {
+ pNewPixmap = (PixmapPtr)(*pScreen->CreatePixmap)
+ (pScreen,
+ nw, nh,
+ pWin->drawable.depth, 0);
+ if (!pNewPixmap)
+ {
+#ifdef BSEAGER
+ pBackingStore->status = StatusNoPixmap;
+#else
+ pBackingStore->status = StatusBadAlloc;
+#endif
+ }
+ }
+ }
+ if (!pNewPixmap)
+ {
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ }
+ else
+ {
+ nx = pBackingStore->x - extents->x1 + dx;
+ ny = pBackingStore->y - extents->y1 + dy;
+ pBackingStore->x = extents->x1;
+ pBackingStore->y = extents->y1;
+
+ if (saveBits && (pNewPixmap != pBackingPixmap || nx != 0 || ny != 0))
+ {
+ pGC = GetScratchGC(pNewPixmap->drawable.depth, pScreen);
+ if (pGC)
+ {
+ ValidateGC((DrawablePtr)pNewPixmap, pGC);
+ /* if we implement a policy where the pixmap can be larger than
+ * the region extents, we might want to optimize this copyarea
+ * by only copying the old extents, rather than the entire
+ * pixmap
+ */
+ (*pGC->ops->CopyArea)((DrawablePtr)pBackingPixmap,
+ (DrawablePtr)pNewPixmap, pGC,
+ 0, 0,
+ pBackingPixmap->drawable.width,
+ pBackingPixmap->drawable.height,
+ nx, ny);
+ FreeScratchGC(pGC);
+ }
+ }
+ }
+ /* SavedRegion is used in the backingGC clip; force an update */
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pNewPixmap != pBackingPixmap)
+ {
+ (* pScreen->DestroyPixmap)(pBackingPixmap);
+ pBackingStore->pBackingPixmap = pNewPixmap;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSSaveDoomedAreas --
+ * Saved the areas of the given window that are about to be
+ * obscured. If the window has moved, pObscured is expected to
+ * be at the new screen location and (dx,dy) is expected to be the offset
+ * to the window's previous location.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region is copied from the screen into pBackingPixmap and
+ * SavedRegion is updated.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSSaveDoomedAreas(pWin, pObscured, dx, dy)
+ register WindowPtr pWin;
+ RegionPtr pObscured;
+ int dx, dy;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ int x, y;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * If the window isn't realized, it's being unmapped, thus we don't
+ * want to save anything if backingStore isn't Always.
+ */
+ if (!pWin->realized)
+ {
+ pBackingStore->viewable = (char)pWin->viewable;
+ if (pWin->backingStore != Always)
+ {
+ RegionEmpty(&pBackingStore->SavedRegion);
+ miDestroyBSPixmap (pWin);
+ return;
+ }
+ if (pBackingStore->status == StatusBadAlloc)
+ pBackingStore->status = StatusNoPixmap;
+ }
+
+ /* Don't even pretend to save anything for a virtual background None */
+ if ((pBackingStore->status == StatusVirtual) &&
+ (pBackingStore->backgroundState == None))
+ return;
+
+ if (RegionNotEmpty(pObscured))
+ {
+ BoxRec oldExtents;
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ RegionTranslate(pObscured, -x, -y);
+ oldExtents = *RegionExtents(&pBackingStore->SavedRegion);
+ RegionUnion(&pBackingStore->SavedRegion,
+ &pBackingStore->SavedRegion,
+ pObscured);
+ /*
+ * only save the bits if we've actually
+ * started using backing store
+ */
+ if (pBackingStore->status != StatusVirtual)
+ {
+ if (!pBackingStore->pBackingPixmap)
+ miCreateBSPixmap (pWin, &oldExtents);
+ else
+ miResizeBackingStore(pWin, 0, 0, TRUE);
+
+ if (pBackingStore->pBackingPixmap) {
+ if (pBackingStore->x | pBackingStore->y)
+ {
+ RegionTranslate(pObscured,
+ -pBackingStore->x,
+ -pBackingStore->y);
+ x += pBackingStore->x;
+ y += pBackingStore->y;
+ }
+ (* pScreen->BackingStoreFuncs.SaveAreas)
+ (pBackingStore->pBackingPixmap, pObscured,
+ x - dx, y - dy, pWin);
+ }
+ }
+ RegionTranslate(pObscured, x, y);
+ }
+ else
+ {
+ if (RegionBroken(pObscured))
+ {
+ RegionEmpty(&pBackingStore->SavedRegion);
+ miDestroyBSPixmap (pWin);
+ return;
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSRestoreAreas --
+ * Restore areas from backing-store that are no longer obscured.
+ * expects prgnExposed to contain a screen-relative area.
+ *
+ * Results:
+ * The region to generate exposure events on (which may be
+ * different from the region to paint).
+ *
+ * Side Effects:
+ * Areas are copied from pBackingPixmap to the screen. prgnExposed
+ * is altered to contain the region that could not be restored from
+ * backing-store.
+ *
+ * Notes:
+ * This is called before sending any exposure events to the client,
+ * and so might be called if the window has grown. Changing the backing
+ * pixmap doesn't require revalidating the backingGC because the
+ * client's next output request will result in a call to ValidateGC,
+ * since the window clip region has changed, which will in turn call
+ * miValidateBackingStore.
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSRestoreAreas(pWin, prgnExposed)
+ register WindowPtr pWin;
+ RegionPtr prgnExposed;
+{
+ PixmapPtr pBackingPixmap;
+ miBSWindowPtr pBackingStore;
+ RegionPtr prgnSaved;
+ RegionPtr prgnRestored;
+ register ScreenPtr pScreen;
+ RegionPtr exposures = prgnExposed;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pBackingPixmap = pBackingStore->pBackingPixmap;
+
+ prgnSaved = &pBackingStore->SavedRegion;
+
+ if (pBackingStore->status == StatusContents)
+ {
+ RegionTranslate(prgnSaved, pWin->drawable.x,
+ pWin->drawable.y);
+
+ prgnRestored = RegionCreate((BoxPtr)NULL, 1);
+ RegionIntersect(prgnRestored, prgnExposed, prgnSaved);
+
+ /*
+ * Since prgnExposed is no longer obscured, we no longer
+ * will have a valid copy of it in backing-store, but there is a valid
+ * copy of it on screen, so subtract the area we just restored from
+ * from the area to be exposed.
+ */
+
+ if (RegionNotEmpty(prgnRestored))
+ {
+ RegionSubtract(prgnSaved, prgnSaved, prgnExposed);
+ RegionSubtract(prgnExposed, prgnExposed, prgnRestored);
+
+ /*
+ * Do the actual restoration
+ */
+ (* pScreen->BackingStoreFuncs.RestoreAreas) (pBackingPixmap,
+ prgnRestored,
+ pWin->drawable.x + pBackingStore->x,
+ pWin->drawable.y + pBackingStore->y,
+ pWin);
+ /*
+ * if the saved region is completely empty, dispose of the
+ * backing pixmap, otherwise, retranslate the saved
+ * region to window relative
+ */
+
+ if (RegionNotEmpty(prgnSaved))
+ {
+ RegionTranslate(prgnSaved,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ miResizeBackingStore(pWin, 0, 0, TRUE);
+ }
+ else
+ miDestroyBSPixmap (pWin);
+ }
+ else
+ RegionTranslate(prgnSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+ RegionDestroy(prgnRestored);
+
+ }
+ else if ((pBackingStore->status == StatusVirtual) ||
+ (pBackingStore->status == StatusVDirty))
+ {
+ RegionTranslate(prgnSaved,
+ pWin->drawable.x, pWin->drawable.y);
+ exposures = RegionCreate(NullBox, 1);
+ if (SameBackground (pBackingStore->backgroundState,
+ pBackingStore->background,
+ pWin->backgroundState,
+ pWin->background))
+ {
+ RegionSubtract(exposures, prgnExposed, prgnSaved);
+ }
+ else
+ {
+ miTileVirtualBS(pWin);
+
+ /* we need to expose all we have (virtually) retiled */
+ RegionUnion(exposures, prgnExposed, prgnSaved);
+ }
+ RegionSubtract(prgnSaved, prgnSaved, prgnExposed);
+ RegionTranslate(prgnSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+ }
+ else if (pWin->viewable && !pBackingStore->viewable &&
+ pWin->backingStore != Always)
+ {
+ /*
+ * The window was just mapped and nothing has been saved in
+ * backing-store from the last time it was mapped. We want to capture
+ * any output to regions that are already obscured but there are no
+ * bits to snag off the screen, so we initialize things just as we did
+ * in miBSAllocate, above.
+ */
+ BoxRec box;
+
+ prgnSaved = &pBackingStore->SavedRegion;
+
+ box.x1 = pWin->drawable.x;
+ box.x2 = box.x1 + (int) pWin->drawable.width;
+ box.y1 = pWin->drawable.y;
+ box.y2 = box.y1 + (int) pWin->drawable.height;
+
+ RegionInverse(prgnSaved, &pWin->clipList, &box);
+ RegionTranslate(prgnSaved,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ RegionIntersect(prgnSaved, prgnSaved,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionIntersect(prgnSaved, prgnSaved,
+ wClipShape (pWin));
+#endif
+ miTileVirtualBS(pWin);
+
+ exposures = RegionCreate(&box, 1);
+ }
+ pBackingStore->viewable = (char)pWin->viewable;
+ return exposures;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSTranslateBackingStore --
+ * Shift the backing-store in the given direction. Called when bit
+ * gravity is shifting things around.
+ *
+ * Results:
+ * An occluded region of the window which should be sent exposure events.
+ * This region should be in absolute coordinates (i.e. include
+ * new window position).
+ *
+ * Side Effects:
+ * If the window changed size as well as position, the backing pixmap
+ * is resized. The contents of the backing pixmap are shifted
+ *
+ * Warning:
+ * Bob and I have rewritten this routine quite a few times, each
+ * time it gets a few more cases correct, and introducing some
+ * interesting bugs. Naturally, I think the code is correct this
+ * time.
+ *
+ * Let me try to explain what this routine is for:
+ *
+ * It's called from SlideAndSizeWindow whenever a window
+ * with backing store is resized. There are two separate
+ * possibilities:
+ *
+ * a) The window has ForgetGravity
+ *
+ * In this case, windx, windy will be 0 and oldClip will
+ * be NULL. This indicates that all of the window contents
+ * currently saved offscreen should be discarded, and the
+ * entire window exposed. TranslateBackingStore, then, should
+ * prepare a completely new backing store region based on the
+ * new window clipList and return that region for exposure.
+ *
+ * b) The window has some other gravity
+ *
+ * In this case, windx, windy will be set to the distance
+ * that the bits should move within the window. oldClip
+ * will be set to the old visible portion of the window.
+ * TranslateBackingStore, then, should adjust the backing
+ * store to accommodate the portion of the existing backing
+ * store bits which coorespond to backing store bits which
+ * will still be occluded in the new configuration. oldx,oldy
+ * are set to the old position of the window on the screen.
+ *
+ * Furthermore, in this case any contents of the screen which
+ * are about to become occluded should be fetched from the screen
+ * and placed in backing store. This is to avoid the eventual
+ * occlusion by the win gravity shifting the child window bits around
+ * on top of this window, and potentially losing information
+ *
+ * It's also called from SetShape, but I think (he says not
+ * really knowing for sure) that this code will even work
+ * in that case.
+ *-----------------------------------------------------------------------
+ */
+
+static RegionPtr
+miBSTranslateBackingStore(pWin, windx, windy, oldClip, oldx, oldy)
+ WindowPtr pWin;
+ int windx; /* bit translation distance in window */
+ int windy;
+ RegionPtr oldClip; /* Region being copied */
+ int oldx; /* old window position */
+ int oldy;
+{
+ register miBSWindowPtr pBackingStore;
+ register RegionPtr pSavedRegion;
+ register RegionPtr newSaved, doomed;
+ register ScreenPtr pScreen;
+ BoxRec extents;
+ int scrdx; /* bit translation distance on screen */
+ int scrdy;
+ int dx; /* distance window moved on screen */
+ int dy;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr)(pWin->backStorage);
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return NullRegion;
+
+ /*
+ * Compute the new saved region
+ */
+
+ newSaved = RegionCreate(NullBox, 1);
+ extents.x1 = pWin->drawable.x;
+ extents.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ extents.y1 = pWin->drawable.y;
+ extents.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ RegionInverse(newSaved, &pWin->clipList, &extents);
+
+ RegionTranslate(newSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ if (wBoundingShape (pWin))
+ RegionIntersect(newSaved, newSaved,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ RegionIntersect(newSaved, newSaved, wClipShape (pWin));
+ }
+#endif
+
+ pSavedRegion = &pBackingStore->SavedRegion;
+
+ /* now find any visible areas we can save from the screen */
+ /* and then translate newSaved to old local coordinates */
+ if (oldClip)
+ {
+ /* bit gravity makes things virtually too hard, punt */
+ if (((windx != 0) || (windy != 0)) &&
+ (pBackingStore->status != StatusContents))
+ miCreateBSPixmap(pWin, NullBox);
+
+ /*
+ * The window is moving this far on the screen
+ */
+ dx = pWin->drawable.x - oldx;
+ dy = pWin->drawable.y - oldy;
+ /*
+ * The bits will be moving on the screen by the
+ * amount the window is moving + the amount the
+ * bits are moving within the window
+ */
+ scrdx = windx + dx;
+ scrdy = windy + dy;
+
+ /*
+ * intersect at old bit position to discover the
+ * bits on the screen which can be put into the
+ * new backing store
+ */
+ RegionTranslate(oldClip, windx - oldx, windy - oldy);
+ doomed = RegionCreate(NullBox, 1);
+ RegionIntersect(doomed, oldClip, newSaved);
+ RegionTranslate(oldClip, oldx - windx, oldy - windy);
+
+ /*
+ * Translate the old saved region to the position in the
+ * window where it will appear to be
+ */
+ RegionTranslate(pSavedRegion, windx, windy);
+
+ /*
+ * Add the old saved region to the new saved region, so
+ * that calls to RestoreAreas will be able to fetch those
+ * bits back
+ */
+ RegionUnion(newSaved, newSaved, pSavedRegion);
+
+ /*
+ * Swap the new saved region into the window
+ */
+ {
+ RegionRec tmp;
+
+ tmp = *pSavedRegion;
+ *pSavedRegion = *newSaved;
+ *newSaved = tmp;
+ }
+ miResizeBackingStore (pWin, windx, windy, TRUE);
+
+ /*
+ * Compute the newly enabled region
+ * of backing store. This region will be
+ * set to background in the backing pixmap and
+ * sent as exposure events to the client.
+ */
+ RegionSubtract(newSaved, pSavedRegion, newSaved);
+
+ /*
+ * Fetch bits which will be obscured from
+ * the screen
+ */
+ if (RegionNotEmpty(doomed))
+ {
+ /*
+ * Don't clear regions which have bits on the
+ * screen
+ */
+ RegionSubtract(newSaved, newSaved, doomed);
+
+ /*
+ * Make the region to SaveDoomedAreas absolute, instead
+ * of window relative.
+ */
+ RegionTranslate(doomed,
+ pWin->drawable.x, pWin->drawable.y);
+ (* pScreen->SaveDoomedAreas) (pWin, doomed, scrdx, scrdy);
+ }
+
+ RegionDestroy(doomed);
+
+ /*
+ * and clear whatever there is that's new
+ */
+ if (RegionNotEmpty(newSaved))
+ {
+ miBSClearBackingRegion (pWin, newSaved);
+ /*
+ * Make the exposed region absolute
+ */
+ RegionTranslate(newSaved,
+ pWin->drawable.x,
+ pWin->drawable.y);
+ }
+ else
+ {
+ RegionDestroy(newSaved);
+ newSaved = NullRegion;
+ }
+ }
+ else
+ {
+ /*
+ * ForgetGravity: just reset backing store and
+ * expose the whole mess
+ */
+ RegionCopy(pSavedRegion, newSaved);
+ RegionTranslate(newSaved,
+ pWin->drawable.x, pWin->drawable.y);
+
+ miResizeBackingStore (pWin, 0, 0, FALSE);
+ (void) miBSClearBackingStore (pWin, 0, 0, 0, 0, FALSE);
+ }
+
+ return newSaved;
+}
+
+/*
+ * Inform the backing store layer that you are about to validate
+ * a gc with a window, and that subsequent output to the window
+ * is (or is not) guaranteed to be already clipped to the visible
+ * regions of the window.
+ */
+
+static void
+miBSDrawGuarantee (pWin, pGC, guarantee)
+ WindowPtr pWin;
+ GCPtr pGC;
+ int guarantee;
+{
+ miBSGCPtr pPriv;
+
+ if (pWin->backStorage)
+ {
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+ if (!pPriv)
+ (void) miBSCreateGCPrivate (pGC);
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+ if (pPriv)
+ {
+ /*
+ * XXX KLUDGE ALERT
+ *
+ * when the GC is Cheap pPriv will point
+ * at some device's gc func structure. guarantee
+ * will point at the ChangeGC entry of that struct
+ * and will never match a valid guarantee value.
+ */
+ switch (pPriv->guarantee)
+ {
+ case GuaranteeNothing:
+ case GuaranteeVisBack:
+ pPriv->guarantee = guarantee;
+ break;
+ }
+ }
+ }
+}
+
+#define noBackingCopy (GCGraphicsExposures|GCClipXOrigin|GCClipYOrigin| \
+ GCClipMask|GCSubwindowMode| \
+ GCTileStipXOrigin|GCTileStipYOrigin)
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSValidateGC --
+ * Wrapper around output-library's ValidateGC routine
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * The idea here is to perform several functions:
+ * - All the output calls must be intercepted and routed to
+ * backing-store as necessary.
+ * - pGC in the window's devBackingStore must be set up with the
+ * clip list appropriate for writing to pBackingPixmap (i.e.
+ * the inverse of the window's clipList intersected with the
+ * clientClip of the GC). Since the destination for this GC is
+ * a pixmap, it is sufficient to set the clip list as its
+ * clientClip.
+ *-----------------------------------------------------------------------
+ */
+
+static void
+miBSValidateGC (pGC, stateChanges, pDrawable)
+ GCPtr pGC;
+ unsigned long stateChanges;
+ DrawablePtr pDrawable;
+{
+ GCPtr pBackingGC;
+ miBSWindowPtr pWindowPriv = NULL;
+ miBSGCPtr pPriv;
+ WindowPtr pWin;
+ int lift_functions;
+ RegionPtr backingCompositeClip = NULL;
+
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ pWin = (WindowPtr) pDrawable;
+ pWindowPriv = (miBSWindowPtr) pWin->backStorage;
+ lift_functions = (pWindowPriv == (miBSWindowPtr) NULL);
+ }
+ else
+ {
+ pWin = (WindowPtr) NULL;
+ lift_functions = TRUE;
+ }
+
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+
+ /*
+ * rewrap funcs and ops as Validate may have changed them
+ */
+
+ pPriv->wrapFuncs = pGC->funcs;
+ pPriv->wrapOps = pGC->ops;
+
+ if (!lift_functions && ((pPriv->guarantee == GuaranteeVisBack) ||
+ (pWindowPriv->status == StatusNoPixmap) ||
+ (pWindowPriv->status == StatusBadAlloc)))
+ lift_functions = TRUE;
+
+ /*
+ * check to see if a new backingCompositeClip region must
+ * be generated
+ */
+
+ if (!lift_functions &&
+ ((pDrawable->serialNumber != pPriv->serialNumber) ||
+ (stateChanges&(GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode))))
+ {
+ if (RegionNotEmpty(&pWindowPriv->SavedRegion))
+ {
+ backingCompositeClip = RegionCreate(NULL, 1);
+ if ((pGC->clientClipType == CT_NONE) ||
+ (pGC->clientClipType == CT_PIXMAP))
+ {
+ RegionCopy(backingCompositeClip,
+ &pWindowPriv->SavedRegion);
+ }
+ else
+ {
+ /*
+ * Make a new copy of the client clip, translated to
+ * its proper origin.
+ */
+
+ RegionCopy(backingCompositeClip,
+ pGC->clientClip);
+ RegionTranslate(backingCompositeClip,
+ pGC->clipOrg.x,
+ pGC->clipOrg.y);
+ RegionIntersect(backingCompositeClip,
+ backingCompositeClip,
+ &pWindowPriv->SavedRegion);
+ }
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ RegionPtr translatedClip;
+
+ /* XXX
+ * any output in IncludeInferiors mode will not
+ * be redirected to Inferiors backing store. This
+ * can be fixed only at great cost to the shadow routines.
+ */
+ translatedClip = NotClippedByChildren (pWin);
+ RegionTranslate(translatedClip,
+ -pDrawable->x,
+ -pDrawable->y);
+ RegionSubtract(backingCompositeClip,
+ backingCompositeClip, translatedClip);
+ RegionDestroy(translatedClip);
+ }
+ if (!RegionNotEmpty(backingCompositeClip))
+ lift_functions = TRUE;
+ }
+ else
+ {
+ lift_functions = TRUE;
+ }
+
+ /* Reset the status when drawing to an unoccluded window so that
+ * future SaveAreas will actually copy bits from the screen. Note that
+ * output to root window in IncludeInferiors mode will not cause this
+ * to change. This causes all transient graphics by the window
+ * manager to the root window to not enable backing store.
+ */
+ if (lift_functions && (pWindowPriv->status == StatusVirtual) &&
+ (pWin->parent || pGC->subWindowMode != IncludeInferiors))
+ pWindowPriv->status = StatusVDirty;
+ }
+
+ /*
+ * if no backing store has been allocated, and it's needed,
+ * create it now.
+ */
+
+ if (!lift_functions && !pWindowPriv->pBackingPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!pWindowPriv->pBackingPixmap)
+ lift_functions = TRUE;
+ }
+
+ /*
+ * create the backing GC if needed, lift functions
+ * if the creation fails
+ */
+
+ if (!lift_functions && !pPriv->pBackingGC)
+ {
+ int status;
+ XID noexpose = xFalse;
+
+ /* We never want ops with the backingGC to generate GraphicsExpose */
+ pBackingGC = CreateGC ((DrawablePtr)pWindowPriv->pBackingPixmap,
+ GCGraphicsExposures, &noexpose, &status);
+ if (status != Success)
+ lift_functions = TRUE;
+ else
+ pPriv->pBackingGC = pBackingGC;
+ }
+
+ pBackingGC = pPriv->pBackingGC;
+
+ pPriv->stateChanges |= stateChanges;
+
+ if (lift_functions)
+ {
+ if (backingCompositeClip)
+ RegionDestroy(backingCompositeClip);
+
+ /* unwrap the GC again */
+ miBSDestroyGCPrivate (pGC);
+
+ return;
+ }
+
+ /*
+ * the rest of this function gets the pBackingGC
+ * into shape for possible draws
+ */
+
+ pPriv->stateChanges &= ~noBackingCopy;
+ if (pPriv->stateChanges)
+ CopyGC(pGC, pBackingGC, pPriv->stateChanges);
+ if ((pGC->patOrg.x - pWindowPriv->x) != pBackingGC->patOrg.x ||
+ (pGC->patOrg.y - pWindowPriv->y) != pBackingGC->patOrg.y)
+ {
+ XID vals[2];
+ vals[0] = pGC->patOrg.x - pWindowPriv->x;
+ vals[1] = pGC->patOrg.y - pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
+ }
+ pPriv->stateChanges = 0;
+
+ if (backingCompositeClip)
+ {
+ XID vals[2];
+
+ if (pGC->clientClipType == CT_PIXMAP)
+ {
+ (*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
+ RegionTranslate(backingCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ vals[0] = pGC->clipOrg.x - pWindowPriv->x;
+ vals[1] = pGC->clipOrg.y - pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (* pGC->pScreen->BackingStoreFuncs.SetClipmaskRgn)
+ (pBackingGC, backingCompositeClip);
+ RegionDestroy(backingCompositeClip);
+ }
+ else
+ {
+ vals[0] = -pWindowPriv->x;
+ vals[1] = -pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, backingCompositeClip, 0);
+ }
+ pPriv->serialNumber = pDrawable->serialNumber;
+ }
+
+ if (pWindowPriv->pBackingPixmap->drawable.serialNumber
+ != pBackingGC->serialNumber)
+ {
+ ValidateGC((DrawablePtr)pWindowPriv->pBackingPixmap, pBackingGC);
+ }
+
+ if (pBackingGC->clientClip == 0)
+ ErrorF ("backing store clip list nil");
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSChangeGC (pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSCopyGC (pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc, pGCDst;
+ unsigned long mask;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGCDst)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGCDst, pPriv);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ FUNC_EPILOGUE (pGCDst, pPriv);
+}
+
+static void
+miBSDestroyGC (pGC)
+ GCPtr pGC;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ if (pPriv->pBackingGC)
+ FreeGC(pPriv->pBackingGC, (GContext)0);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+
+ free(pPriv);
+}
+
+static void
+miBSChangeClip(pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ void * pvalue;
+ int nrects;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (* pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pgcDst)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pgcDst, pPriv);
+
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ FUNC_EPILOGUE (pgcDst, pPriv);
+}
+
+static void
+miBSDestroyClip(pGC)
+ GCPtr pGC;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miDestroyBSPixmap (pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->pBackingPixmap)
+ (* pScreen->DestroyPixmap)(pBackingStore->pBackingPixmap);
+ pBackingStore->pBackingPixmap = NullPixmap;
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap)(pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = None;
+ pBackingStore->status = StatusNoPixmap;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+}
+
+static void
+miTileVirtualBS (pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pWin->drawable.pScreen->DestroyPixmap)
+ (pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = pWin->backgroundState;
+ pBackingStore->background = pWin->background;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ pBackingStore->background.pixmap->refcnt++;
+
+ if (pBackingStore->status != StatusVDirty)
+ pBackingStore->status = StatusVirtual;
+
+ /*
+ * punt parent relative tiles and do it now
+ */
+ if (pBackingStore->backgroundState == ParentRelative)
+ miCreateBSPixmap (pWin, NullBox);
+}
+
+#ifdef DEBUG
+static int BSAllocationsFailed = 0;
+#define FAILEDSIZE 32
+static struct { int w, h; } failedRecord[FAILEDSIZE];
+static int failedIndex;
+#endif
+
+static void
+miCreateBSPixmap (pWin, pExtents)
+ WindowPtr pWin;
+ BoxPtr pExtents;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ PixUnion background;
+ char backgroundState = 0;
+ BoxPtr extents;
+ Bool backSet;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->status == StatusBadAlloc)
+ return;
+ backSet = ((pBackingStore->status == StatusVirtual) ||
+ (pBackingStore->status == StatusVDirty));
+
+ extents = RegionExtents(&pBackingStore->SavedRegion);
+
+ if (!pBackingStore->pBackingPixmap &&
+ extents->x2 != extents->x1 &&
+ extents->y2 != extents->y1)
+ {
+ /* the policy here could be more sophisticated */
+ pBackingStore->x = extents->x1;
+ pBackingStore->y = extents->y1;
+ pBackingStore->pBackingPixmap =
+ (PixmapPtr)(* pScreen->CreatePixmap)
+ (pScreen,
+ extents->x2 - extents->x1,
+ extents->y2 - extents->y1,
+ pWin->drawable.depth, 0);
+ }
+ if (!pBackingStore->pBackingPixmap)
+ {
+#ifdef DEBUG
+ BSAllocationsFailed++;
+ /*
+ * record failed allocations
+ */
+ failedRecord[failedIndex].w = pWin->drawable.width;
+ failedRecord[failedIndex].h = pWin->drawable.height;
+ failedIndex++;
+ if (failedIndex == FAILEDSIZE)
+ failedIndex = 0;
+#endif
+#ifdef BSEAGER
+ pBackingStore->status = StatusNoPixmap;
+#else
+ pBackingStore->status = StatusBadAlloc;
+#endif
+ return;
+ }
+
+ pBackingStore->status = StatusContents;
+
+ if (backSet)
+ {
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ pWin->backgroundState = pBackingStore->backgroundState;
+ pWin->background = pBackingStore->background;
+ if (pWin->backgroundState == BackgroundPixmap)
+ pWin->background.pixmap->refcnt++;
+ }
+
+ if (!pExtents)
+ pExtents = extents;
+
+ if (pExtents->y1 != pExtents->y2)
+ {
+ RegionPtr exposed;
+
+ exposed = miBSClearBackingStore(pWin,
+ pExtents->x1, pExtents->y1,
+ pExtents->x2 - pExtents->x1,
+ pExtents->y2 - pExtents->y1,
+ !backSet);
+ if (exposed)
+ {
+ miSendExposures(pWin, exposed, pWin->drawable.x, pWin->drawable.y);
+ RegionDestroy(exposed);
+ }
+ }
+
+ if (backSet)
+ {
+ if (pWin->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap) (pWin->background.pixmap);
+ pWin->backgroundState = backgroundState;
+ pWin->background = background;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap) (pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = None;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSExposeCopy --
+ * Handle the restoration of areas exposed by graphics operations.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * prgnExposed has the areas exposed from backing-store removed
+ * from it.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSExposeCopy (pSrc, pDst, pGC, prgnExposed, srcx, srcy, dstx, dsty, plane)
+ WindowPtr pSrc;
+ DrawablePtr pDst;
+ GCPtr pGC;
+ RegionPtr prgnExposed;
+ int srcx, srcy;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ RegionRec tempRgn;
+ miBSWindowPtr pBackingStore;
+ CopyPlaneProcPtr copyProc;
+ GCPtr pScratchGC;
+ register BoxPtr pBox;
+ register int i;
+ register int dx, dy;
+ BITS32 gcMask;
+
+ if (!RegionNotEmpty(prgnExposed))
+ return;
+ pBackingStore = (miBSWindowPtr)pSrc->backStorage;
+
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return;
+
+ RegionNull(&tempRgn);
+ RegionIntersect(&tempRgn, prgnExposed,
+ &pBackingStore->SavedRegion);
+ RegionSubtract(prgnExposed, prgnExposed, &tempRgn);
+
+ if (plane != 0) {
+ copyProc = pGC->ops->CopyPlane;
+ } else {
+ copyProc = (CopyPlaneProcPtr)pGC->ops->CopyArea;
+ }
+
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+
+ switch (pBackingStore->status) {
+ case StatusVirtual:
+ case StatusVDirty:
+ pScratchGC = GetScratchGC (pDst->depth, pDst->pScreen);
+ if (pScratchGC)
+ {
+ gcMask = 0;
+ if (pGC->alu != pScratchGC->alu)
+ gcMask = GCFunction;
+ if (pGC->planemask != pScratchGC->planemask)
+ gcMask |= GCPlaneMask;
+ if (gcMask)
+ CopyGC (pGC, pScratchGC, gcMask);
+ miBSFillVirtualBits (pDst, pScratchGC, &tempRgn, dx, dy,
+ (int) pBackingStore->backgroundState,
+ pBackingStore->background,
+ ~0L);
+ FreeScratchGC (pScratchGC);
+ }
+ break;
+ case StatusContents:
+ for (i = RegionNumRects(&tempRgn), pBox = RegionRects(&tempRgn);
+ --i >= 0;
+ pBox++)
+ {
+ (* copyProc) (&(pBackingStore->pBackingPixmap->drawable), pDst, pGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ }
+ break;
+ }
+ RegionUninit(&tempRgn);
+}
diff --git a/nx-X11/programs/Xserver/mi/mibstore.h b/nx-X11/programs/Xserver/mi/mibstore.h
new file mode 100644
index 000000000..5f3597074
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mibstore.h
@@ -0,0 +1,29 @@
+/*-
+ * mibstore.h --
+ * Header file for users of the MI backing-store scheme.
+ *
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * "$Xorg: mibstore.h,v 1.3 2000/08/17 19:53:37 cpqbld Exp $
+ */
+
+
+
+#ifndef _MIBSTORE_H
+#define _MIBSTORE_H
+
+#include "screenint.h"
+
+extern void miInitializeBackingStore(
+ ScreenPtr /*pScreen*/
+);
+
+#endif /* _MIBSTORE_H */
diff --git a/nx-X11/programs/Xserver/mi/mibstorest.h b/nx-X11/programs/Xserver/mi/mibstorest.h
new file mode 100644
index 000000000..ccf4fb701
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mibstorest.h
@@ -0,0 +1,91 @@
+/*
+ * mibstorest.h
+ *
+ * internal structure definitions for mi backing store
+ */
+
+
+/*
+
+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.
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "mibstore.h"
+#include "regionstr.h"
+
+/*
+ * One of these structures is allocated per GC used with a backing-store
+ * drawable.
+ */
+
+typedef struct {
+ GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
+ * set FALSE and the clientClip set to
+ * clip output to the valid regions of the
+ * backing pixmap. */
+ int guarantee; /* GuaranteeNothing, etc. */
+ unsigned long serialNumber; /* clientClip computed time */
+ unsigned long stateChanges; /* changes in parent gc since last copy */
+ GCOps *wrapOps; /* wrapped ops */
+ GCFuncs *wrapFuncs; /* wrapped funcs */
+} miBSGCRec, *miBSGCPtr;
+
+/*
+ * one of these structures is allocated per Window with backing store
+ */
+
+typedef struct {
+ PixmapPtr pBackingPixmap; /* Pixmap for saved areas */
+ short x; /* origin of pixmap relative to window */
+ short y;
+ RegionRec SavedRegion; /* Valid area in pBackingPixmap */
+ char viewable; /* Tracks pWin->viewable so SavedRegion may
+ * be initialized correctly when the window
+ * is first mapped */
+ char status; /* StatusNoPixmap, etc. */
+ char backgroundState; /* background type */
+ PixUnion background; /* background pattern */
+} miBSWindowRec, *miBSWindowPtr;
+
+#define StatusNoPixmap 1 /* pixmap has not been created */
+#define StatusVirtual 2 /* pixmap is virtual, tiled with background */
+#define StatusVDirty 3 /* pixmap is virtual, visiblt has contents */
+#define StatusBadAlloc 4 /* pixmap create failed, do not try again */
+#define StatusContents 5 /* pixmap is created, has valid contents */
+
+typedef struct {
+ /*
+ * screen func wrappers
+ */
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ CreateGCProcPtr CreateGC;
+ DestroyWindowProcPtr DestroyWindow;
+} miBSScreenRec, *miBSScreenPtr;
diff --git a/nx-X11/programs/Xserver/mi/miclipn.c b/nx-X11/programs/Xserver/mi/miclipn.c
new file mode 100644
index 000000000..8bc7c3f44
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miclipn.c
@@ -0,0 +1,82 @@
+/*
+
+Copyright 1990, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "mi.h"
+
+static void (*clipNotify)(WindowPtr,int,int) = 0;
+static void (*ClipNotifies[MAXSCREENS])(WindowPtr,int,int);
+
+static void
+miClipNotifyWrapper(
+ WindowPtr pWin,
+ int dx,
+ int dy )
+{
+ if (clipNotify)
+ (*clipNotify)(pWin, dx, dy);
+ if (ClipNotifies[pWin->drawable.pScreen->myNum])
+ (*ClipNotifies[pWin->drawable.pScreen->myNum])(pWin, dx, dy);
+}
+
+/*
+ * miClipNotify --
+ * Hook to let DDX request notification when the clipList of
+ * a window is recomputed on any screen. For R4 compatibility;
+ * better if you wrap the ClipNotify screen proc yourself.
+ */
+
+static unsigned long clipGeneration = 0;
+
+void
+miClipNotify (
+ void (*func)(
+ WindowPtr /* pWin */,
+ int /* dx */,
+ int /* dy */
+ ) )
+{
+ int i;
+
+ clipNotify = func;
+ if (clipGeneration != serverGeneration)
+ {
+ clipGeneration = serverGeneration;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ClipNotifies[i] = screenInfo.screens[i]->ClipNotify;
+ screenInfo.screens[i]->ClipNotify = miClipNotifyWrapper;
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/micmap.c b/nx-X11/programs/Xserver/mi/micmap.c
new file mode 100644
index 000000000..c01d7d333
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/micmap.c
@@ -0,0 +1,696 @@
+/* $XConsortium: cfbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+
+/*
+ * This is based on cfbcmap.c. The functions here are useful independently
+ * of cfb, which is the reason for including them here. How "mi" these
+ * are may be debatable.
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "globals.h"
+#include "micmap.h"
+
+ColormapPtr miInstalledMaps[MAXSCREENS];
+
+static Bool miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis);
+
+miInitVisualsProcPtr miInitVisualsProc = miDoInitVisuals;
+
+int
+miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ if (miInstalledMaps[pScreen->myNum]) {
+ *pmaps = miInstalledMaps[pScreen->myNum]->mid;
+ return (1);
+ }
+ return 0;
+}
+
+void
+miInstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr oldpmap = miInstalledMaps[index];
+
+ if(pmap != oldpmap)
+ {
+ /* Uninstall pInstalledMap. No hardware changes required, just
+ * notify all interested parties. */
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ miInstalledMaps[index] = pmap;
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+ }
+}
+
+void
+miUninstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr curpmap = miInstalledMaps[index];
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+void
+miResolveColor(unsigned short *pred, unsigned short *pgreen,
+ unsigned short *pblue, VisualPtr pVisual)
+{
+ int shift = 16 - pVisual->bitsPerRGBValue;
+ unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class | DynamicClass) == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else
+ {
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+miInitializeColormap(ColormapPtr pmap)
+{
+ register unsigned i;
+ register VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+ if (pVisual->class == TrueColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((i * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->green[i].co.local.green =
+ ((((i * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->blue[i].co.local.blue =
+ ((((i * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((((i & pVisual->redMask) >> pVisual->offsetRed)
+ * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.green =
+ ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
+ * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.blue =
+ ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
+ * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
+ * 65535) / lim;
+ pmap->red[i].co.local.green = pmap->red[i].co.local.red;
+ pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
+ }
+ }
+ return TRUE;
+}
+
+/* When simulating DirectColor on PseudoColor hardware, multiple
+ entries of the colormap must be updated
+ */
+
+#define AddElement(mask) { \
+ pixel = red | green | blue; \
+ for (i = 0; i < nresult; i++) \
+ if (outdefs[i].pixel == pixel) \
+ break; \
+ if (i == nresult) \
+ { \
+ nresult++; \
+ outdefs[i].pixel = pixel; \
+ outdefs[i].flags = 0; \
+ } \
+ outdefs[i].flags |= (mask); \
+ outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
+ outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
+ outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
+}
+
+int
+miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ register int red, green, blue;
+ int maxred, maxgreen, maxblue;
+ int stepred, stepgreen, stepblue;
+ VisualPtr pVisual;
+ register int pixel;
+ register int nresult;
+ register int i;
+
+ pVisual = pmap->pVisual;
+
+ stepred = 1 << pVisual->offsetRed;
+ stepgreen = 1 << pVisual->offsetGreen;
+ stepblue = 1 << pVisual->offsetBlue;
+ maxred = pVisual->redMask;
+ maxgreen = pVisual->greenMask;
+ maxblue = pVisual->blueMask;
+ nresult = 0;
+ for (;ndef--; indefs++)
+ {
+ if (indefs->flags & DoRed)
+ {
+ red = indefs->pixel & pVisual->redMask;
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoRed)
+ }
+ }
+ }
+ if (indefs->flags & DoGreen)
+ {
+ green = indefs->pixel & pVisual->greenMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoGreen)
+ }
+ }
+ }
+ if (indefs->flags & DoBlue)
+ {
+ blue = indefs->pixel & pVisual->blueMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ AddElement (DoBlue)
+ }
+ }
+ }
+ }
+ return nresult;
+}
+
+Bool
+miCreateDefColormap(ScreenPtr pScreen)
+{
+/*
+ * In the following sources PC X server vendors may want to delete
+ * "_not_tog" from "#ifdef WIN32_not_tog"
+ */
+#ifdef WIN32_not_tog
+ /*
+ * these are the MS-Windows desktop colors, adjusted for X's 16-bit
+ * color specifications.
+ */
+ static xColorItem citems[] = {
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 0x8000, 0, 0, 0, 0 },
+ { 2, 0, 0x8000, 0, 0, 0 },
+ { 3, 0x8000, 0x8000, 0, 0, 0 },
+ { 4, 0, 0, 0x8000, 0, 0 },
+ { 5, 0x8000, 0, 0x8000, 0, 0 },
+ { 6, 0, 0x8000, 0x8000, 0, 0 },
+ { 7, 0xc000, 0xc000, 0xc000, 0, 0 },
+ { 8, 0xc000, 0xdc00, 0xc000, 0, 0 },
+ { 9, 0xa600, 0xca00, 0xf000, 0, 0 },
+ { 246, 0xff00, 0xfb00, 0xf000, 0, 0 },
+ { 247, 0xa000, 0xa000, 0xa400, 0, 0 },
+ { 248, 0x8000, 0x8000, 0x8000, 0, 0 },
+ { 249, 0xff00, 0, 0, 0, 0 },
+ { 250, 0, 0xff00, 0, 0, 0 },
+ { 251, 0xff00, 0xff00, 0, 0, 0 },
+ { 252, 0, 0, 0xff00, 0, 0 },
+ { 253, 0xff00, 0, 0xff00, 0, 0 },
+ { 254, 0, 0xff00, 0xff00, 0, 0 },
+ { 255, 0xff00, 0xff00, 0xff00, 0, 0 }
+ };
+#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
+ int i;
+#else
+ unsigned short zero = 0, ones = 0xFFFF;
+#endif
+ Pixel wp, bp;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ int alloctype;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
+ alloctype = AllocNone;
+ else
+ alloctype = AllocAll;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ alloctype, 0) != Success)
+ return FALSE;
+
+ if (pScreen->rootDepth > 1) {
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+#ifdef WIN32_not_tog
+ for (i = 0; i < NUM_DESKTOP_COLORS; i++) {
+ if (AllocColor (cmap,
+ &citems[i].red, &citems[i].green, &citems[i].blue,
+ &citems[i].pixel, 0) != Success)
+ return FALSE;
+ }
+#else
+ if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+#endif
+ }
+
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+/*
+ * Default true color bitmasks, should be overridden by
+ * driver
+ */
+
+#define _RZ(d) ((d + 2) / 3)
+#define _RS(d) 0
+#define _RM(d) ((1 << _RZ(d)) - 1)
+#define _GZ(d) ((d - _RZ(d) + 1) / 2)
+#define _GS(d) _RZ(d)
+#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
+#define _BZ(d) (d - _RZ(d) - _GZ(d))
+#define _BS(d) (_RZ(d) + _GZ(d))
+#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
+#define _CE(d) (1 << _RZ(d))
+
+typedef struct _miVisuals {
+ struct _miVisuals *next;
+ int depth;
+ int bitsPerRGB;
+ int visuals;
+ int count;
+ int preferredCVC;
+ Pixel redMask, greenMask, blueMask;
+} miVisualsRec, *miVisualsPtr;
+
+static int miVisualPriority[] = {
+ PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
+};
+
+#define NUM_PRIORITY 6
+
+static miVisualsPtr miVisuals;
+
+void
+miClearVisualTypes()
+{
+ miVisualsPtr v;
+
+ while ((v = miVisuals)) {
+ miVisuals = v->next;
+ free(v);
+ }
+}
+
+
+Bool
+miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
+ int preferredCVC,
+ Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+ miVisualsPtr new, *prev, v;
+ int count;
+
+ new = (miVisualsPtr) malloc (sizeof *new);
+ if (!new)
+ return FALSE;
+ if (!redMask || !greenMask || !blueMask)
+ {
+ redMask = _RM(depth);
+ greenMask = _GM(depth);
+ blueMask = _BM(depth);
+ }
+ new->next = 0;
+ new->depth = depth;
+ new->visuals = visuals;
+ new->bitsPerRGB = bitsPerRGB;
+ new->preferredCVC = preferredCVC;
+ new->redMask = redMask;
+ new->greenMask = greenMask;
+ new->blueMask = blueMask;
+ count = (visuals >> 1) & 033333333333;
+ count = visuals - count - ((count >> 1) & 033333333333);
+ count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
+ new->count = count;
+ for (prev = &miVisuals; (v = *prev); prev = &v->next);
+ *prev = new;
+ return TRUE;
+}
+
+Bool
+miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
+{
+ return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
+ preferredCVC, 0, 0, 0);
+}
+
+int
+miGetDefaultVisualMask(int depth)
+{
+ if (depth > MAX_PSEUDO_DEPTH)
+ return LARGE_VISUALS;
+ else if (depth >= MIN_TRUE_DEPTH)
+ return ALL_VISUALS;
+ else if (depth == 1)
+ return StaticGrayMask;
+ else
+ return SMALL_VISUALS;
+}
+
+static Bool
+miVisualTypesSet (int depth)
+{
+ miVisualsPtr visuals;
+
+ for (visuals = miVisuals; visuals; visuals = visuals->next)
+ if (visuals->depth == depth)
+ return TRUE;
+ return FALSE;
+}
+
+Bool
+miSetPixmapDepths (void)
+{
+ int d, f;
+
+ /* Add any unlisted depths from the pixmap formats */
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ if (!miVisualTypesSet (d))
+ {
+ if (!miSetVisualTypes (d, 0, 0, -1))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+Bool
+miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis)
+
+{
+ if (miInitVisualsProc)
+ return miInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ else
+ return FALSE;
+}
+
+/*
+ * Distance to least significant one bit
+ */
+static int
+maskShift (Pixel p)
+{
+ int s;
+
+ if (!p) return 0;
+ s = 0;
+ while (!(p & 1))
+ {
+ s++;
+ p >>= 1;
+ }
+ return s;
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which corespond to
+ * the set which can be used with this version of cfb.
+ */
+
+static Bool
+miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis)
+{
+ int i, j = 0, k;
+ VisualPtr visual;
+ DepthPtr depth;
+ VisualID *vid;
+ int d, b;
+ int f;
+ int ndepth, nvisual;
+ int nvtype;
+ int vtype;
+ miVisualsPtr visuals, nextVisuals;
+ int *preferredCVCs, *prefp;
+ int first_depth;
+
+ /* none specified, we'll guess from pixmap formats */
+ if (!miVisuals)
+ {
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ b = screenInfo.formats[f].bitsPerPixel;
+ if (sizes & (1 << (b - 1)))
+ vtype = miGetDefaultVisualMask(d);
+ else
+ vtype = 0;
+ if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1))
+ return FALSE;
+ }
+ }
+ nvisual = 0;
+ ndepth = 0;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ ndepth++;
+ nvisual += visuals->count;
+ }
+ depth = (DepthPtr) malloc (ndepth * sizeof (DepthRec));
+ visual = (VisualPtr) malloc (nvisual * sizeof (VisualRec));
+ preferredCVCs = (int *)malloc(ndepth * sizeof(int));
+ if (!depth || !visual || !preferredCVCs)
+ {
+ free (depth);
+ free (visual);
+ free (preferredCVCs);
+ return FALSE;
+ }
+ *depthp = depth;
+ *visualp = visual;
+ *ndepthp = ndepth;
+ *nvisualp = nvisual;
+ prefp = preferredCVCs;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ d = visuals->depth;
+ vtype = visuals->visuals;
+ nvtype = visuals->count;
+ *prefp = visuals->preferredCVC;
+ prefp++;
+ vid = NULL;
+ if (nvtype)
+ {
+ vid = (VisualID *) malloc (nvtype * sizeof (VisualID));
+ if (!vid)
+ return FALSE;
+ }
+ depth->depth = d;
+ depth->numVids = nvtype;
+ depth->vids = vid;
+ depth++;
+ for (i = 0; i < NUM_PRIORITY; i++) {
+ if (! (vtype & (1 << miVisualPriority[i])))
+ continue;
+ visual->class = miVisualPriority[i];
+ visual->bitsPerRGBValue = visuals->bitsPerRGB;
+ visual->ColormapEntries = 1 << d;
+ visual->nplanes = d;
+ visual->vid = *vid = FakeClientID (0);
+ switch (visual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ visual->redMask = 0;
+ visual->greenMask = 0;
+ visual->blueMask = 0;
+ visual->offsetRed = 0;
+ visual->offsetGreen = 0;
+ visual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ visual->ColormapEntries = _CE(d);
+ /* fall through */
+ case StaticColor:
+ visual->redMask = visuals->redMask;
+ visual->greenMask = visuals->greenMask;
+ visual->blueMask = visuals->blueMask;
+ visual->offsetRed = maskShift (visuals->redMask);
+ visual->offsetGreen = maskShift (visuals->greenMask);
+ visual->offsetBlue = maskShift (visuals->blueMask);
+ }
+ vid++;
+ visual++;
+ }
+ free (visuals);
+ }
+ miVisuals = NULL;
+ visual = *visualp;
+ depth = *depthp;
+
+ /*
+ * if we did not supplyied by a preferred visual class
+ * check if there is a preferred class in one of the depth
+ * structures - if there is, we want to start looking for the
+ * default visual/depth from that depth.
+ */
+ first_depth = 0;
+ if (preferredVis < 0 && defaultColorVisualClass < 0 ) {
+ for (i = 0; i < ndepth; i++) {
+ if (preferredCVCs[i] >= 0) {
+ first_depth = i;
+ break;
+ }
+ }
+ }
+
+ for (i = first_depth; i < ndepth; i++)
+ {
+ int prefColorVisualClass = -1;
+
+ if (defaultColorVisualClass >= 0)
+ prefColorVisualClass = defaultColorVisualClass;
+ else if (preferredVis >= 0)
+ prefColorVisualClass = preferredVis;
+ else if (preferredCVCs[i] >= 0)
+ prefColorVisualClass = preferredCVCs[i];
+
+ if (*rootDepthp && *rootDepthp != depth[i].depth)
+ continue;
+
+ for (j = 0; j < depth[i].numVids; j++)
+ {
+ for (k = 0; k < nvisual; k++)
+ if (visual[k].vid == depth[i].vids[j])
+ break;
+ if (k == nvisual)
+ continue;
+ if (prefColorVisualClass < 0 ||
+ visual[k].class == prefColorVisualClass)
+ break;
+ }
+ if (j != depth[i].numVids)
+ break;
+ }
+ if (i == ndepth) {
+ i = 0;
+ j = 0;
+ }
+ *rootDepthp = depth[i].depth;
+ *defaultVisp = depth[i].vids[j];
+ free(preferredCVCs);
+
+ return TRUE;
+}
+
+void
+miResetInitVisuals()
+{
+ miInitVisualsProc = miDoInitVisuals;
+}
+
diff --git a/nx-X11/programs/Xserver/mi/micmap.h b/nx-X11/programs/Xserver/mi/micmap.h
new file mode 100644
index 000000000..9ee9f4ae4
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/micmap.h
@@ -0,0 +1,64 @@
+
+#include "colormapst.h"
+
+#ifndef _MICMAP_H_
+#define _MICMAP_H_
+
+extern ColormapPtr miInstalledMaps[MAXSCREENS];
+
+typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
+ int *, VisualID *, unsigned long, int,
+ int);
+
+extern miInitVisualsProcPtr miInitVisualsProc;
+
+int miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+void miInstallColormap(ColormapPtr pmap);
+void miUninstallColormap(ColormapPtr pmap);
+
+void miResolveColor(unsigned short *, unsigned short *, unsigned short *,
+ VisualPtr);
+Bool miInitializeColormap(ColormapPtr);
+int miExpandDirectColors(ColormapPtr, int, xColorItem *, xColorItem *);
+Bool miCreateDefColormap(ScreenPtr);
+void miClearVisualTypes(void);
+Bool miSetVisualTypes(int, int, int, int);
+Bool miSetPixmapDepths(void);
+Bool miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
+ int preferredCVC,
+ Pixel redMask, Pixel greenMask, Pixel blueMask);
+int miGetDefaultVisualMask(int);
+Bool miInitVisuals(VisualPtr *, DepthPtr *, int *, int *, int *, VisualID *,
+ unsigned long, int, int);
+void miResetInitVisuals(void);
+
+void miHookInitVisuals(void (**old)(miInitVisualsProcPtr *),
+ void (*new)(miInitVisualsProcPtr *));
+
+
+#define MAX_PSEUDO_DEPTH 10
+#define MIN_TRUE_DEPTH 6
+
+#define StaticGrayMask (1 << StaticGray)
+#define GrayScaleMask (1 << GrayScale)
+#define StaticColorMask (1 << StaticColor)
+#define PseudoColorMask (1 << PseudoColor)
+#define TrueColorMask (1 << TrueColor)
+#define DirectColorMask (1 << DirectColor)
+
+#define ALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask|\
+ TrueColorMask|\
+ DirectColorMask)
+
+#define LARGE_VISUALS (TrueColorMask|\
+ DirectColorMask)
+
+#define SMALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask)
+
+#endif /* _MICMAP_H_ */
diff --git a/nx-X11/programs/Xserver/mi/micoord.h b/nx-X11/programs/Xserver/mi/micoord.h
new file mode 100644
index 000000000..3e45cfede
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/micoord.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * 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 THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ *
+ */
+
+#ifndef _MICOORD_H_
+#define _MICOORD_H_ 1
+
+#include "servermd.h"
+
+/* Macros which handle a coordinate in a single register */
+
+/*
+ * Most compilers will convert divisions by 65536 into shifts, if signed
+ * shifts exist. If your machine does arithmetic shifts and your compiler
+ * can't get it right, add to this line.
+ */
+
+/*
+ * mips compiler - what a joke - it CSEs the 65536 constant into a reg
+ * forcing as to use div instead of shift. Let's be explicit.
+ */
+
+#if defined(mips) || \
+ defined(sparc) || defined(__sparc64__) || \
+ defined(__alpha) || defined(__alpha__) || \
+ defined(__i386__) || defined(i386) || \
+ defined(__ia64__) || defined(ia64) || \
+ defined(__s390x__) || defined(__s390__) || \
+ defined(__amd64__) || defined(amd64) || defined(__amd64)
+#define GetHighWord(x) (((int) (x)) >> 16)
+#else
+#define GetHighWord(x) (((int) (x)) / 65536)
+#endif
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | ((y) & 0xffff))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int) ((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | ((x) & 0xffff))
+#define intToX(i) ((int) ((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
+
+#endif /* _MICOORD_H_ */
diff --git a/nx-X11/programs/Xserver/mi/micursor.c b/nx-X11/programs/Xserver/mi/micursor.c
new file mode 100644
index 000000000..e95c43b3d
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/micursor.c
@@ -0,0 +1,75 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "cursor.h"
+#include "misc.h"
+#include "mi.h"
+
+extern Bool Must_have_memory;
+
+void
+miRecolorCursor( pScr, pCurs, displayed)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+ Bool displayed;
+{
+ /*
+ * This is guaranteed to correct any color-dependent state which may have
+ * been bound up in private state created by RealizeCursor
+ */
+ (* pScr->UnrealizeCursor)( pScr, pCurs);
+ Must_have_memory = TRUE; /* XXX */
+ (* pScr->RealizeCursor)( pScr, pCurs);
+ Must_have_memory = FALSE; /* XXX */
+ if ( displayed)
+ (* pScr->DisplayCursor)( pScr, pCurs);
+
+}
diff --git a/nx-X11/programs/Xserver/mi/midash.c b/nx-X11/programs/Xserver/mi/midash.c
new file mode 100644
index 000000000..33fac339b
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/midash.c
@@ -0,0 +1,313 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include "mistruct.h"
+#include "mifpoly.h"
+
+static miDashPtr CheckDashStorage(miDashPtr *ppseg, int nseg, int *pnsegMax);
+
+/* return a list of DashRec. there will be an extra
+entry at the end holding the last point of the polyline.
+ this means that the code that actually draws dashes can
+get a pair of points for every dash. only the point in the last
+dash record is useful; the other fields are not used.
+ nseg is the number of segments, not the number of points.
+
+example:
+
+ dash1.start
+ dash2.start
+ dash3.start
+ last-point
+
+defines a list of segments
+ (dash1.pt, dash2.pt)
+ (dash2.pt, dash3.pt)
+ (dash3.pt, last-point)
+and nseg == 3.
+
+NOTE:
+ EVEN_DASH == ~ODD_DASH
+
+NOTE ALSO:
+ miDashLines may return 0 segments, going from pt[0] to pt[0] with one dash.
+*/
+
+miDashPtr
+miDashLine(npt, ppt, nDash, pDash, offset, pnseg)
+int npt;
+DDXPointPtr ppt;
+unsigned int nDash;
+unsigned char *pDash;
+unsigned int offset;
+int *pnseg;
+{
+ DDXPointRec pt1, pt2;
+ int lenCur; /* npt used from this dash */
+ int lenMax; /* npt in this dash */
+ int iDash = 0; /* index of current dash */
+ int which; /* EVEN_DASH or ODD_DASH */
+ miDashPtr pseg; /* list of dash segments */
+ miDashPtr psegBase; /* start of list */
+ int nseg = 0; /* number of dashes so far */
+ int nsegMax = 0; /* num segs we can fit in this list */
+
+ int x, y, len;
+ int adx, ady, signdx, signdy;
+ int du, dv, e1, e2, e, base_e = 0;
+
+ lenCur = offset;
+ which = EVEN_DASH;
+ while(lenCur >= pDash[iDash])
+ {
+ lenCur -= pDash[iDash];
+ iDash++;
+ if (iDash >= nDash)
+ iDash = 0;
+ which = ~which;
+ }
+ lenMax = pDash[iDash];
+
+ psegBase = (miDashPtr)NULL;
+ pt2 = ppt[0]; /* just in case there is only one point */
+
+ while(--npt)
+ {
+ if (PtEqual(ppt[0], ppt[1]))
+ {
+ ppt++;
+ continue; /* no duplicated points in polyline */
+ }
+ pt1 = *ppt++;
+ pt2 = *ppt;
+
+ adx = pt2.x - pt1.x;
+ ady = pt2.y - pt1.y;
+ signdx = sign(adx);
+ signdy = sign(ady);
+ adx = abs(adx);
+ ady = abs(ady);
+
+ if (adx > ady)
+ {
+ du = adx;
+ dv = ady;
+ len = adx;
+ }
+ else
+ {
+ du = ady;
+ dv = adx;
+ len = ady;
+ }
+
+ e1 = dv * 2;
+ e2 = e1 - 2*du;
+ e = e1 - du;
+ x = pt1.x;
+ y = pt1.y;
+
+ nseg++;
+ pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt = pt1;
+ pseg->e1 = e1;
+ pseg->e2 = e2;
+ base_e = pseg->e = e;
+ pseg->which = which;
+ pseg->newLine = 1;
+
+ while (len--)
+ {
+ if (adx > ady)
+ {
+ /* X_AXIS */
+ if (((signdx > 0) && (e < 0)) ||
+ ((signdx <=0) && (e <=0))
+ )
+ {
+ e += e1;
+ }
+ else
+ {
+ y += signdy;
+ e += e2;
+ }
+ x += signdx;
+ }
+ else
+ {
+ /* Y_AXIS */
+ if (((signdx > 0) && (e < 0)) ||
+ ((signdx <=0) && (e <=0))
+ )
+ {
+ e +=e1;
+ }
+ else
+ {
+ x += signdx;
+ e += e2;
+ }
+ y += signdy;
+ }
+
+ lenCur++;
+ if (lenCur >= lenMax && (len || npt <= 1))
+ {
+ nseg++;
+ pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt.x = x;
+ pseg->pt.y = y;
+ pseg->e1 = e1;
+ pseg->e2 = e2;
+ pseg->e = e;
+ which = ~which;
+ pseg->which = which;
+ pseg->newLine = 0;
+
+ /* move on to next dash */
+ iDash++;
+ if (iDash >= nDash)
+ iDash = 0;
+ lenMax = pDash[iDash];
+ lenCur = 0;
+ }
+ } /* while len-- */
+ } /* while --npt */
+
+ if (lenCur == 0 && nseg != 0)
+ {
+ nseg--;
+ which = ~which;
+ }
+ *pnseg = nseg;
+ pseg = CheckDashStorage(&psegBase, nseg+1, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt = pt2;
+ pseg->e = base_e;
+ pseg->which = which;
+ pseg->newLine = 0;
+ return psegBase;
+}
+
+
+#define NSEGDELTA 16
+
+/* returns a pointer to the pseg[nseg-1], growing the storage as
+necessary. this interface seems unnecessarily cumbersome.
+
+*/
+
+static
+miDashPtr
+CheckDashStorage(
+ miDashPtr *ppseg, /* base pointer */
+ int nseg, /* number of segment we want to write to */
+ int *pnsegMax) /* size (in segments) of list so far */
+{
+ if (nseg > *pnsegMax)
+ {
+ miDashPtr newppseg;
+
+ *pnsegMax += NSEGDELTA;
+ newppseg = (miDashPtr)realloc(*ppseg,
+ (*pnsegMax)*sizeof(miDashRec));
+ if (!newppseg)
+ {
+ free(*ppseg);
+ return (miDashPtr)NULL;
+ }
+ *ppseg = newppseg;
+ }
+ return(*ppseg+(nseg-1));
+}
+
+void
+miStepDash (dist, pDashIndex, pDash, numInDashList, pDashOffset)
+ int dist; /* distance to step */
+ int *pDashIndex; /* current dash */
+ unsigned char *pDash; /* dash list */
+ int numInDashList; /* total length of dash list */
+ int *pDashOffset; /* offset into current dash */
+{
+ int dashIndex, dashOffset;
+ int totallen;
+ int i;
+
+ dashIndex = *pDashIndex;
+ dashOffset = *pDashOffset;
+ if (dist < pDash[dashIndex] - dashOffset)
+ {
+ *pDashOffset = dashOffset + dist;
+ return;
+ }
+ dist -= pDash[dashIndex] - dashOffset;
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ totallen = 0;
+ for (i = 0; i < numInDashList; i++)
+ totallen += pDash[i];
+ if (totallen <= dist)
+ dist = dist % totallen;
+ while (dist >= pDash[dashIndex])
+ {
+ dist -= pDash[dashIndex];
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ }
+ *pDashIndex = dashIndex;
+ *pDashOffset = dist;
+}
diff --git a/nx-X11/programs/Xserver/mi/midispcur.c b/nx-X11/programs/Xserver/mi/midispcur.c
new file mode 100644
index 000000000..92d0fb15c
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/midispcur.c
@@ -0,0 +1,813 @@
+/*
+ * midispcur.c
+ *
+ * machine independent cursor display routines
+ */
+
+
+/*
+
+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.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# include <nx-X11/X.h>
+# include "misc.h"
+# include "input.h"
+# include "cursorstr.h"
+# include "windowstr.h"
+# include "regionstr.h"
+# include "dixstruct.h"
+# include "scrnintstr.h"
+# include "servermd.h"
+# include "mipointer.h"
+# include "misprite.h"
+# include "gcstruct.h"
+
+#ifdef ARGB_CURSOR
+# include "picturestr.h"
+#endif
+
+/* per-screen private data */
+
+static int miDCScreenIndex;
+static unsigned long miDCGeneration = 0;
+
+static Bool miDCCloseScreen(ScreenPtr pScreen);
+
+typedef struct {
+ GCPtr pSourceGC, pMaskGC;
+ GCPtr pSaveGC, pRestoreGC;
+ GCPtr pMoveGC;
+ GCPtr pPixSourceGC, pPixMaskGC;
+ CloseScreenProcPtr CloseScreen;
+ PixmapPtr pSave, pTemp;
+#ifdef ARGB_CURSOR
+ PicturePtr pRootPicture;
+ PicturePtr pTempPicture;
+#endif
+} miDCScreenRec, *miDCScreenPtr;
+
+/* per-cursor per-screen private data */
+typedef struct {
+ PixmapPtr sourceBits; /* source bits */
+ PixmapPtr maskBits; /* mask bits */
+#ifdef ARGB_CURSOR
+ PicturePtr pPicture;
+#endif
+} miDCCursorRec, *miDCCursorPtr;
+
+/*
+ * sprite/cursor method table
+ */
+
+static Bool miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static Bool miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static Bool miDCPutUpCursor(ScreenPtr pScreen, CursorPtr pCursor,
+ int x, int y, unsigned long source,
+ unsigned long mask);
+static Bool miDCSaveUnderCursor(ScreenPtr pScreen, int x, int y,
+ int w, int h);
+static Bool miDCRestoreUnderCursor(ScreenPtr pScreen, int x, int y,
+ int w, int h);
+static Bool miDCMoveCursor(ScreenPtr pScreen, CursorPtr pCursor,
+ int x, int y, int w, int h, int dx, int dy,
+ unsigned long source, unsigned long mask);
+static Bool miDCChangeSave(ScreenPtr pScreen, int x, int y, int w, int h,
+ int dx, int dy);
+
+static miSpriteCursorFuncRec miDCFuncs = {
+ miDCRealizeCursor,
+ miDCUnrealizeCursor,
+ miDCPutUpCursor,
+ miDCSaveUnderCursor,
+ miDCRestoreUnderCursor,
+ miDCMoveCursor,
+ miDCChangeSave,
+};
+
+Bool
+miDCInitialize (pScreen, screenFuncs)
+ ScreenPtr pScreen;
+ miPointerScreenFuncPtr screenFuncs;
+{
+ miDCScreenPtr pScreenPriv;
+
+ if (miDCGeneration != serverGeneration)
+ {
+ miDCScreenIndex = AllocateScreenPrivateIndex ();
+ if (miDCScreenIndex < 0)
+ return FALSE;
+ miDCGeneration = serverGeneration;
+ }
+ pScreenPriv = (miDCScreenPtr) malloc (sizeof (miDCScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+
+ /*
+ * initialize the entire private structure to zeros
+ */
+
+ pScreenPriv->pSourceGC =
+ pScreenPriv->pMaskGC =
+ pScreenPriv->pSaveGC =
+ pScreenPriv->pRestoreGC =
+ pScreenPriv->pMoveGC =
+ pScreenPriv->pPixSourceGC =
+ pScreenPriv->pPixMaskGC = NULL;
+#ifdef ARGB_CURSOR
+ pScreenPriv->pRootPicture = NULL;
+ pScreenPriv->pTempPicture = NULL;
+#endif
+
+ pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = miDCCloseScreen;
+
+ pScreen->devPrivates[miDCScreenIndex].ptr = (void *) pScreenPriv;
+
+ if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
+ {
+ free ((void *) pScreenPriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0)
+#define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
+#define tossPict(pict) (pict ? FreePicture (pict, 0) : 0)
+
+static Bool
+miDCCloseScreen (pScreen)
+ ScreenPtr pScreen;
+{
+ miDCScreenPtr pScreenPriv;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ tossGC (pScreenPriv->pSourceGC);
+ tossGC (pScreenPriv->pMaskGC);
+ tossGC (pScreenPriv->pSaveGC);
+ tossGC (pScreenPriv->pRestoreGC);
+ tossGC (pScreenPriv->pMoveGC);
+ tossGC (pScreenPriv->pPixSourceGC);
+ tossGC (pScreenPriv->pPixMaskGC);
+ tossPix (pScreenPriv->pSave);
+ tossPix (pScreenPriv->pTemp);
+#ifdef ARGB_CURSOR
+ tossPict (pScreenPriv->pRootPicture);
+ tossPict (pScreenPriv->pTempPicture);
+#endif
+ free ((void *) pScreenPriv);
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+static Bool
+miDCRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ if (pCursor->bits->refcnt <= 1)
+ pCursor->bits->devPriv[pScreen->myNum] = (void *)NULL;
+ return TRUE;
+}
+
+#ifdef ARGB_CURSOR
+#define EnsurePicture(picture,draw,win) (picture || miDCMakePicture(&picture,draw,win))
+
+static VisualPtr
+miDCGetWindowVisual (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VisualID vid = wVisual (pWin);
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == vid)
+ return &pScreen->visuals[i];
+ return 0;
+}
+
+static PicturePtr
+miDCMakePicture (PicturePtr *ppPicture, DrawablePtr pDraw, WindowPtr pWin)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ VisualPtr pVisual;
+ PictFormatPtr pFormat;
+ XID subwindow_mode = IncludeInferiors;
+ PicturePtr pPicture;
+ int error;
+
+ pVisual = miDCGetWindowVisual (pWin);
+ if (!pVisual)
+ return 0;
+ pFormat = PictureMatchVisual (pScreen, pDraw->depth, pVisual);
+ if (!pFormat)
+ return 0;
+ pPicture = CreatePicture (0, pDraw, pFormat,
+ CPSubwindowMode, &subwindow_mode,
+ serverClient, &error);
+ *ppPicture = pPicture;
+ return pPicture;
+}
+#endif
+
+static miDCCursorPtr
+miDCRealize (
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ miDCCursorPtr pPriv;
+ GCPtr pGC;
+ XID gcvals[3];
+
+ pPriv = (miDCCursorPtr) malloc (sizeof (miDCCursorRec));
+ if (!pPriv)
+ return (miDCCursorPtr)NULL;
+#ifdef ARGB_CURSOR
+ if (pCursor->bits->argb)
+ {
+ PixmapPtr pPixmap;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+
+ pPriv->sourceBits = 0;
+ pPriv->maskBits = 0;
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
+ pCursor->bits->height, 32,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ {
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pGC = GetScratchGC (32, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ ValidateGC (&pPixmap->drawable, pGC);
+ (*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32,
+ 0, 0, pCursor->bits->width,
+ pCursor->bits->height,
+ 0, ZPixmap, (char *) pCursor->bits->argb);
+ FreeScratchGC (pGC);
+ pPriv->pPicture = CreatePicture (0, &pPixmap->drawable,
+ pFormat, 0, 0, serverClient, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ if (!pPriv->pPicture)
+ {
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pCursor->bits->devPriv[pScreen->myNum] = (void *) pPriv;
+ return pPriv;
+ }
+ pPriv->pPicture = 0;
+#endif
+ pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0);
+ if (!pPriv->sourceBits)
+ {
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1, 0);
+ if (!pPriv->maskBits)
+ {
+ (*pScreen->DestroyPixmap) (pPriv->sourceBits);
+ free ((void *) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pCursor->bits->devPriv[pScreen->myNum] = (void *) pPriv;
+
+ /* create the two sets of bits, clipping as appropriate */
+
+ pGC = GetScratchGC (1, pScreen);
+ if (!pGC)
+ {
+ (void) miDCUnrealizeCursor (pScreen, pCursor);
+ return (miDCCursorPtr)NULL;
+ }
+
+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->source);
+ gcvals[0] = GXand;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->mask);
+
+ /* mask bits -- pCursor->mask & ~pCursor->source */
+ gcvals[0] = GXcopy;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->mask);
+ gcvals[0] = GXandInverted;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->source);
+ FreeScratchGC (pGC);
+ return pPriv;
+}
+
+static Bool
+miDCUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miDCCursorPtr pPriv;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (pPriv && (pCursor->bits->refcnt <= 1))
+ {
+ if (pPriv->sourceBits)
+ (*pScreen->DestroyPixmap) (pPriv->sourceBits);
+ if (pPriv->maskBits)
+ (*pScreen->DestroyPixmap) (pPriv->maskBits);
+#ifdef ARGB_CURSOR
+ if (pPriv->pPicture)
+ FreePicture (pPriv->pPicture, 0);
+#endif
+ free ((void *) pPriv);
+ pCursor->bits->devPriv[pScreen->myNum] = (void *)NULL;
+ }
+ return TRUE;
+}
+
+static void
+miDCPutBits (
+ DrawablePtr pDrawable,
+ miDCCursorPtr pPriv,
+ GCPtr sourceGC,
+ GCPtr maskGC,
+ int x_org,
+ int y_org,
+ unsigned w,
+ unsigned h,
+ unsigned long source,
+ unsigned long mask)
+{
+ XID gcvals[1];
+ int x, y;
+
+ if (sourceGC->fgPixel != source)
+ {
+ gcvals[0] = source;
+ DoChangeGC (sourceGC, GCForeground, gcvals, 0);
+ }
+ if (sourceGC->serialNumber != pDrawable->serialNumber)
+ ValidateGC (pDrawable, sourceGC);
+
+ if(sourceGC->miTranslate)
+ {
+ x = pDrawable->x + x_org;
+ y = pDrawable->y + y_org;
+ }
+ else
+ {
+ x = x_org;
+ y = y_org;
+ }
+
+ (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
+ if (maskGC->fgPixel != mask)
+ {
+ gcvals[0] = mask;
+ DoChangeGC (maskGC, GCForeground, gcvals, 0);
+ }
+ if (maskGC->serialNumber != pDrawable->serialNumber)
+ ValidateGC (pDrawable, maskGC);
+
+ if(maskGC->miTranslate)
+ {
+ x = pDrawable->x + x_org;
+ y = pDrawable->y + y_org;
+ }
+ else
+ {
+ x = x_org;
+ y = y_org;
+ }
+
+ (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
+}
+
+#define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
+
+static GCPtr
+miDCMakeGC(
+ GCPtr *ppGC,
+ WindowPtr pWin)
+{
+ GCPtr pGC;
+ int status;
+ XID gcvals[2];
+
+ gcvals[0] = IncludeInferiors;
+ gcvals[1] = FALSE;
+ pGC = CreateGC((DrawablePtr)pWin,
+ GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
+ if (pGC && pWin->drawable.pScreen->DrawGuarantee)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+ *ppGC = pGC;
+ return pGC;
+}
+
+
+static Bool
+miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ int x, y;
+ unsigned long source, mask;
+{
+ miDCScreenPtr pScreenPriv;
+ miDCCursorPtr pPriv;
+ WindowPtr pWin;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (!pPriv)
+ {
+ pPriv = miDCRealize(pScreen, pCursor);
+ if (!pPriv)
+ return FALSE;
+ }
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pWin = pScreen->root;
+#ifdef ARGB_CURSOR
+ if (pPriv->pPicture)
+ {
+ if (!EnsurePicture(pScreenPriv->pRootPicture, &pWin->drawable, pWin))
+ return FALSE;
+ CompositePicture (PictOpOver,
+ pPriv->pPicture,
+ NULL,
+ pScreenPriv->pRootPicture,
+ 0, 0, 0, 0,
+ x, y,
+ pCursor->bits->width,
+ pCursor->bits->height);
+ }
+ else
+#endif
+ {
+ if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
+ {
+ FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
+ pScreenPriv->pSourceGC = 0;
+ return FALSE;
+ }
+ miDCPutBits ((DrawablePtr)pWin, pPriv,
+ pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
+ x, y, pCursor->bits->width, pCursor->bits->height,
+ source, mask);
+ }
+ return TRUE;
+}
+
+static Bool
+miDCSaveUnderCursor (pScreen, x, y, w, h)
+ ScreenPtr pScreen;
+ int x, y, w, h;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = pScreen->root;
+ if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
+ {
+ if (pSave)
+ (*pScreen->DestroyPixmap) (pSave);
+ pScreenPriv->pSave = pSave =
+ (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth, 0);
+ if (!pSave)
+ return FALSE;
+ }
+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pSaveGC;
+ if (pSave->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pSave, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y, w, h, 0, 0);
+ return TRUE;
+}
+
+static Bool
+miDCRestoreUnderCursor (pScreen, x, y, w, h)
+ ScreenPtr pScreen;
+ int x, y, w, h;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = pScreen->root;
+ if (!pSave)
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, 0, w, h, x, y);
+ return TRUE;
+}
+
+static Bool
+miDCChangeSave (pScreen, x, y, w, h, dx, dy)
+ ScreenPtr pScreen;
+ int x, y, w, h, dx, dy;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+ int sourcex, sourcey, destx, desty, copyw, copyh;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = pScreen->root;
+ /*
+ * restore the bits which are about to get trashed
+ */
+ if (!pSave)
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+ /*
+ * copy the old bits to the screen.
+ */
+ if (dy > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, h - dy, w, dy, x + dx, y + h);
+ }
+ else if (dy < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, 0, w, -dy, x + dx, y + dy);
+ }
+ if (dy >= 0)
+ {
+ desty = y + dy;
+ sourcey = 0;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = y;
+ sourcey = - dy;
+ copyh = h + dy;
+ }
+ if (dx > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ w - dx, sourcey, dx, copyh, x + w, desty);
+ }
+ else if (dx < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, sourcey, -dx, copyh, x + dx, desty);
+ }
+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pSaveGC;
+ if (pSave->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pSave, pGC);
+ /*
+ * move the bits that are still valid within the pixmap
+ */
+ if (dx >= 0)
+ {
+ sourcex = 0;
+ destx = dx;
+ copyw = w - dx;
+ }
+ else
+ {
+ destx = 0;
+ sourcex = - dx;
+ copyw = w + dx;
+ }
+ if (dy >= 0)
+ {
+ sourcey = 0;
+ desty = dy;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = 0;
+ sourcey = -dy;
+ copyh = h + dy;
+ }
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
+ sourcex, sourcey, copyw, copyh, destx, desty);
+ /*
+ * copy the new bits from the screen into the remaining areas of the
+ * pixmap
+ */
+ if (dy > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y, w, dy, 0, 0);
+ }
+ else if (dy < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y + h + dy, w, -dy, 0, h + dy);
+ }
+ if (dy >= 0)
+ {
+ desty = dy;
+ sourcey = y + dy;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = 0;
+ sourcey = y;
+ copyh = h + dy;
+ }
+ if (dx > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, sourcey, dx, copyh, 0, desty);
+ }
+ else if (dx < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x + w + dx, sourcey, -dx, copyh, w + dx, desty);
+ }
+ return TRUE;
+}
+
+static Bool
+miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ int x, y, w, h, dx, dy;
+ unsigned long source, mask;
+{
+ miDCCursorPtr pPriv;
+ miDCScreenPtr pScreenPriv;
+ int status;
+ WindowPtr pWin;
+ GCPtr pGC;
+ XID gcval = FALSE;
+ PixmapPtr pTemp;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (!pPriv)
+ {
+ pPriv = miDCRealize(pScreen, pCursor);
+ if (!pPriv)
+ return FALSE;
+ }
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pWin = pScreen->root;
+ pTemp = pScreenPriv->pTemp;
+ if (!pTemp ||
+ pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
+ pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
+ {
+ if (pTemp)
+ (*pScreen->DestroyPixmap) (pTemp);
+#ifdef ARGB_CURSOR
+ if (pScreenPriv->pTempPicture)
+ {
+ FreePicture (pScreenPriv->pTempPicture, 0);
+ pScreenPriv->pTempPicture = 0;
+ }
+#endif
+ pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
+ (pScreen, w, h, pScreenPriv->pSave->drawable.depth, 0);
+ if (!pTemp)
+ return FALSE;
+ }
+ if (!pScreenPriv->pMoveGC)
+ {
+ pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pMoveGC)
+ return FALSE;
+ }
+ /*
+ * copy the saved area to a temporary pixmap
+ */
+ pGC = pScreenPriv->pMoveGC;
+ if (pGC->serialNumber != pTemp->drawable.serialNumber)
+ ValidateGC ((DrawablePtr) pTemp, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave,
+ (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0);
+
+ /*
+ * draw the cursor in the temporary pixmap
+ */
+#ifdef ARGB_CURSOR
+ if (pPriv->pPicture)
+ {
+ if (!EnsurePicture(pScreenPriv->pTempPicture, &pTemp->drawable, pWin))
+ return FALSE;
+ CompositePicture (PictOpOver,
+ pPriv->pPicture,
+ NULL,
+ pScreenPriv->pTempPicture,
+ 0, 0, 0, 0,
+ dx, dy,
+ pCursor->bits->width,
+ pCursor->bits->height);
+ }
+ else
+#endif
+ {
+ if (!pScreenPriv->pPixSourceGC)
+ {
+ pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pPixSourceGC)
+ return FALSE;
+ }
+ if (!pScreenPriv->pPixMaskGC)
+ {
+ pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pPixMaskGC)
+ return FALSE;
+ }
+ miDCPutBits ((DrawablePtr)pTemp, pPriv,
+ pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
+ dx, dy, pCursor->bits->width, pCursor->bits->height,
+ source, mask);
+ }
+
+ /*
+ * copy the temporary pixmap onto the screen
+ */
+
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+
+ (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
+ pGC,
+ 0, 0, w, h, x, y);
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/mi/mieq.c b/nx-X11/programs/Xserver/mi/mieq.c
new file mode 100644
index 000000000..fefb222c4
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mieq.c
@@ -0,0 +1,204 @@
+/*
+ * $Xorg: mieq.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $
+ *
+Copyright 1990, 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: Keith Packard, MIT X Consortium
+ */
+
+/*
+ * mieq.c
+ *
+ * Machine independent event queue
+ *
+ */
+
+# include <nx-X11/X.h>
+# include <nx-X11/Xmd.h>
+# include <nx-X11/Xproto.h>
+# include "misc.h"
+# include "windowstr.h"
+# include "pixmapstr.h"
+# include "inputstr.h"
+# include "mi.h"
+# include "scrnintstr.h"
+
+#ifdef DPMSExtension
+# include "dpmsproc.h"
+# define DPMS_SERVER
+# include <nx-X11/extensions/dpms.h>
+#endif
+
+#define QUEUE_SIZE 256
+
+typedef struct _Event {
+ xEvent event;
+ ScreenPtr pScreen;
+} EventRec, *EventPtr;
+
+typedef struct _EventQueue {
+ HWEventQueueType head, tail; /* long for SetInputCheck */
+ CARD32 lastEventTime; /* to avoid time running backwards */
+ Bool lastMotion;
+ EventRec events[QUEUE_SIZE]; /* static allocation for signals */
+ DevicePtr pKbd, pPtr; /* device pointer, to get funcs */
+ ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
+ ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
+} EventQueueRec, *EventQueuePtr;
+
+static EventQueueRec miEventQueue;
+
+Bool
+mieqInit (pKbd, pPtr)
+ DevicePtr pKbd, pPtr;
+{
+ miEventQueue.head = miEventQueue.tail = 0;
+ miEventQueue.lastEventTime = GetTimeInMillis ();
+ miEventQueue.pKbd = pKbd;
+ miEventQueue.pPtr = pPtr;
+ miEventQueue.lastMotion = FALSE;
+ miEventQueue.pEnqueueScreen = screenInfo.screens[0];
+ miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
+ SetInputCheck (&miEventQueue.head, &miEventQueue.tail);
+ return TRUE;
+}
+
+/*
+ * Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
+ * will never be interrupted. If this is called from both signal
+ * handlers and regular code, make sure the signal is suspended when
+ * called from regular code.
+ */
+
+void
+mieqEnqueue (e)
+ xEvent *e;
+{
+ HWEventQueueType oldtail, newtail;
+ Bool isMotion;
+
+ oldtail = miEventQueue.tail;
+ isMotion = e->u.u.type == MotionNotify;
+ if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head)
+ {
+ if (oldtail == 0)
+ oldtail = QUEUE_SIZE;
+ oldtail = oldtail - 1;
+ }
+ else
+ {
+ newtail = oldtail + 1;
+ if (newtail == QUEUE_SIZE)
+ newtail = 0;
+ /* Toss events which come in late */
+ if (newtail == miEventQueue.head)
+ return;
+ miEventQueue.tail = newtail;
+ }
+ miEventQueue.lastMotion = isMotion;
+ miEventQueue.events[oldtail].event = *e;
+ /*
+ * Make sure that event times don't go backwards - this
+ * is "unnecessary", but very useful
+ */
+ if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
+ miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
+ {
+ miEventQueue.events[oldtail].event.u.keyButtonPointer.time =
+ miEventQueue.lastEventTime;
+ }
+ miEventQueue.lastEventTime =
+ miEventQueue.events[oldtail].event.u.keyButtonPointer.time;
+ miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
+}
+
+void
+mieqSwitchScreen (pScreen, fromDIX)
+ ScreenPtr pScreen;
+ Bool fromDIX;
+{
+ miEventQueue.pEnqueueScreen = pScreen;
+ if (fromDIX)
+ miEventQueue.pDequeueScreen = pScreen;
+}
+
+/*
+ * Call this from ProcessInputEvents()
+ */
+
+void mieqProcessInputEvents ()
+{
+ EventRec *e;
+ int x, y;
+ xEvent xe;
+
+ while (miEventQueue.head != miEventQueue.tail)
+ {
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
+
+#ifdef DPMSExtension
+ else if (DPMSPowerLevel != DPMSModeOn)
+ SetScreenSaverTimer();
+
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(DPMSModeOn);
+#endif
+
+ e = &miEventQueue.events[miEventQueue.head];
+ /*
+ * Assumption - screen switching can only occur on motion events
+ */
+ if (e->pScreen != miEventQueue.pDequeueScreen)
+ {
+ miEventQueue.pDequeueScreen = e->pScreen;
+ x = e->event.u.keyButtonPointer.rootX;
+ y = e->event.u.keyButtonPointer.rootY;
+ if (miEventQueue.head == QUEUE_SIZE - 1)
+ miEventQueue.head = 0;
+ else
+ ++miEventQueue.head;
+ NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
+ }
+ else
+ {
+ xe = e->event;
+ if (miEventQueue.head == QUEUE_SIZE - 1)
+ miEventQueue.head = 0;
+ else
+ ++miEventQueue.head;
+ switch (xe.u.u.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ (*miEventQueue.pKbd->processInputProc)
+ (&xe, (DeviceIntPtr)miEventQueue.pKbd, 1);
+ break;
+ default:
+ (*miEventQueue.pPtr->processInputProc)
+ (&xe, (DeviceIntPtr)miEventQueue.pPtr, 1);
+ break;
+ }
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/miexpose.c b/nx-X11/programs/Xserver/mi/miexpose.c
new file mode 100644
index 000000000..c39221000
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miexpose.c
@@ -0,0 +1,906 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <nx-X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ machine-independent graphics exposure code. any device that uses
+the region package can call this.
+*/
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25 /* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+#ifndef NXAGENT_SERVER
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+ /* This prevents warning about pscr not being used. */
+ pGC->pScreen = pscr = pGC->pScreen;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ RegionDestroy(prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ RegionNull(prgnSrcClip);
+ RegionCopy(prgnSrcClip, &pSrcWin->clipList);
+ }
+ RegionTranslate(prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ RegionInit(prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ RegionNull(prgnDstClip);
+ RegionCopy(prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ RegionTranslate(prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ RegionInit(prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ RegionInit(&rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ RegionTranslate(&rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RegionContainsRect(region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *RegionExtents(&rgnExposed);
+ RegionReset(&rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ RegionTranslate(&rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ RegionReset(&rgnExposed, &expBox);
+ }
+ else
+ RegionTranslate(&rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ RegionUninit(prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ RegionDestroy(prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ RegionUninit(prgnSrcClip);
+ }
+ else
+ {
+ RegionDestroy(prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = RegionCreate(NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ RegionUninit(&rgnExposed);
+ return NULL;
+ }
+}
+#endif
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+ ClientPtr client;
+ RegionPtr pRgn;
+ XID drawable;
+ int major;
+ int minor;
+{
+ if (pRgn && !RegionNil(pRgn))
+ {
+ xEvent *pEvent;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ numRects = RegionNumRects(pRgn);
+ pBox = RegionRects(pRgn);
+ if(!(pEvent = (xEvent *)malloc(numRects * sizeof(xEvent))))
+ return;
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = GraphicsExpose;
+ pe->u.graphicsExposure.drawable = drawable;
+ pe->u.graphicsExposure.x = pBox->x1;
+ pe->u.graphicsExposure.y = pBox->y1;
+ pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+ pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+ pe->u.graphicsExposure.count = numRects - i;
+ pe->u.graphicsExposure.majorEvent = major;
+ pe->u.graphicsExposure.minorEvent = minor;
+ }
+ TryClientEvents(client, pEvent, numRects,
+ (Mask)0, NoEventMask, NullGrab);
+ free(pEvent);
+ }
+ else
+ {
+ xEvent event;
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = NoExpose;
+ event.u.noExposure.drawable = drawable;
+ event.u.noExposure.majorEvent = major;
+ event.u.noExposure.minorEvent = minor;
+ TryClientEvents(client, &event, 1,
+ (Mask)0, NoEventMask, NullGrab);
+ }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+ register int dx, dy;
+{
+ register BoxPtr pBox;
+ int numRects;
+ register xEvent *pEvent, *pe;
+ register int i;
+
+ pBox = RegionRects(pRgn);
+ numRects = RegionNumRects(pRgn);
+ if(!(pEvent = (xEvent *) malloc(numRects * sizeof(xEvent))))
+ return;
+ memset(pEvent, 0, numRects * sizeof(xEvent));
+
+ for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pWin->drawable.id;
+ pe->u.expose.x = pBox->x1 - dx;
+ pe->u.expose.y = pBox->y1 - dy;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = i;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int scrnum = pWin->drawable.pScreen->myNum;
+ int x = 0, y = 0;
+ XID realWin = 0;
+
+ if(!pWin->parent) {
+ x = panoramiXdataPtr[scrnum].x;
+ y = panoramiXdataPtr[scrnum].y;
+ pWin = screenInfo.screens[0]->root;
+ realWin = pWin->drawable.id;
+ } else if (scrnum) {
+ PanoramiXRes *win;
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW,
+ pWin->drawable.id, scrnum);
+ if(!win) {
+ free(pEvent);
+ return;
+ }
+ realWin = win->info[0].id;
+ pWin = LookupIDByType(realWin, RT_WINDOW);
+ }
+ if(x || y || scrnum)
+ for (i = 0; i < numRects; i++) {
+ pEvent[i].u.expose.window = realWin;
+ pEvent[i].u.expose.x += x;
+ pEvent[i].u.expose.y += y;
+ }
+ }
+#endif
+
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+ free(pEvent);
+}
+
+#ifndef NXAGENT_SERVER
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !RegionNil(prgn)) ||
+ (exposures && !RegionNil(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ RegionUnion(other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ RegionDestroy(exposures);
+ }
+ exposures = other_exposed;
+ }
+ if (clientInterested && exposures && (RegionNumRects(exposures) > RECTLIMIT))
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *RegionExtents(exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ RegionInit(exposures, &box, 1);
+ RegionReset(prgn, &box);
+ } else {
+ RegionReset(exposures, &box);
+ RegionUnion(prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ RegionIntersect(prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !RegionNil(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !RegionNil(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ RegionUninit(exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ RegionDestroy(exposures);
+ if (prgn)
+ RegionEmpty(prgn);
+ }
+ else if (exposures && exposures != prgn)
+ RegionDestroy(exposures);
+}
+#endif
+
+/*
+ this code is highly unlikely. it is not haile selassie.
+
+ there is some hair here. we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used. it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+ void * value,
+ XID id)
+{
+ GCPtr pGC = (GCPtr)value;
+ screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+ FreeGC (pGC, id);
+ numGCs--;
+ if (!numGCs)
+ ResType = 0;
+
+ return 0;
+}
+
+#ifndef NXAGENT_SERVER
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS] = {{ 0 }};
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (void *)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (void *)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)malloc(RegionNumRects(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = screenInfo.screens[i]->root;
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ free(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ RegionInit(&pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (void *)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = RegionNumRects(prgn);
+ pbox = RegionRects(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ free(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ RegionUninit(&pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
+#endif
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC. Useful when we have a scratch drawable and need to initialize
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+{
+ XID fg = pGC->fgPixel;
+ XID bg = pGC->bgPixel;
+ xRectangle rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = pDraw->width;
+ rect.height = pDraw->height;
+ DoChangeGC(pGC, GCForeground, &bg, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+ DoChangeGC(pGC, GCForeground, &fg, 0);
+ ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/mi/mifillarc.c b/nx-X11/programs/Xserver/mi/mifillarc.c
new file mode 100644
index 000000000..c967f3ab2
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mifillarc.c
@@ -0,0 +1,815 @@
+/************************************************************
+
+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: Bob Scheifler, MIT X Consortium
+
+********************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mifpoly.h"
+#include "mi.h"
+#include "mifillarc.h"
+
+#define QUADRANT (90 * 64)
+#define HALFCIRCLE (180 * 64)
+#define QUADRANT3 (270 * 64)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define Dsin(d) sin((double)d*(M_PI/11520.0))
+#define Dcos(d) cos((double)d*(M_PI/11520.0))
+
+void
+miFillArcSetup(arc, info)
+ register xArc *arc;
+ register miFillArcRec *info;
+{
+ info->y = arc->height >> 1;
+ info->dy = arc->height & 1;
+ info->yorg = arc->y + info->y;
+ info->dx = arc->width & 1;
+ info->xorg = arc->x + (arc->width >> 1) + info->dx;
+ info->dx = 1 - info->dx;
+ if (arc->width == arc->height)
+ {
+ /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->ym = 8;
+ info->xm = 8;
+ info->yk = info->y << 3;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = -1;
+ }
+ else
+ {
+ info->y++;
+ info->yk += 4;
+ info->xk = -4;
+ info->e = - (info->y << 3);
+ }
+ }
+ else
+ {
+ /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->ym = (arc->width * arc->width) << 3;
+ info->xm = (arc->height * arc->height) << 3;
+ info->yk = info->y * info->ym;
+ if (!info->dy)
+ info->yk -= info->ym >> 1;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = - (info->xm >> 3);
+ }
+ else
+ {
+ info->y++;
+ info->yk += info->ym;
+ info->xk = -(info->xm >> 1);
+ info->e = info->xk - info->yk;
+ }
+ }
+}
+
+void
+miFillArcDSetup(arc, info)
+ register xArc *arc;
+ register miFillArcDRec *info;
+{
+ /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->y = arc->height >> 1;
+ info->dy = arc->height & 1;
+ info->yorg = arc->y + info->y;
+ info->dx = arc->width & 1;
+ info->xorg = arc->x + (arc->width >> 1) + info->dx;
+ info->dx = 1 - info->dx;
+ info->ym = ((double)arc->width) * (arc->width * 8);
+ info->xm = ((double)arc->height) * (arc->height * 8);
+ info->yk = info->y * info->ym;
+ if (!info->dy)
+ info->yk -= info->ym / 2.0;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = - (info->xm / 8.0);
+ }
+ else
+ {
+ info->y++;
+ info->yk += info->ym;
+ info->xk = -info->xm / 2.0;
+ info->e = info->xk - info->yk;
+ }
+}
+
+static void
+miGetArcEdge(
+ register xArc *arc,
+ register miSliceEdgePtr edge,
+ int k,
+ Bool top,
+ Bool left )
+{
+ register int xady, y;
+
+ y = arc->height >> 1;
+ if (!(arc->width & 1))
+ y++;
+ if (!top)
+ {
+ y = -y;
+ if (arc->height & 1)
+ y--;
+ }
+ xady = k + y * edge->dx;
+ if (xady <= 0)
+ edge->x = - ((-xady) / edge->dy + 1);
+ else
+ edge->x = (xady - 1) / edge->dy;
+ edge->e = xady - edge->x * edge->dy;
+ if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
+ edge->e = edge->dy - edge->e + 1;
+ if (left)
+ edge->x++;
+ edge->x += arc->x + (arc->width >> 1);
+ if (edge->dx > 0)
+ {
+ edge->deltax = 1;
+ edge->stepx = edge->dx / edge->dy;
+ edge->dx = edge->dx % edge->dy;
+ }
+ else
+ {
+ edge->deltax = -1;
+ edge->stepx = - ((-edge->dx) / edge->dy);
+ edge->dx = (-edge->dx) % edge->dy;
+ }
+ if (!top)
+ {
+ edge->deltax = -edge->deltax;
+ edge->stepx = -edge->stepx;
+ }
+}
+
+void
+miEllipseAngleToSlope (angle, width, height, dxp, dyp, d_dxp, d_dyp)
+ int angle;
+ int width;
+ int height;
+ int *dxp;
+ int *dyp;
+ double *d_dxp;
+ double *d_dyp;
+{
+ int dx, dy;
+ double d_dx, d_dy, scale;
+ Bool negative_dx, negative_dy;
+
+ switch (angle) {
+ case 0:
+ *dxp = -1;
+ *dyp = 0;
+ if (d_dxp) {
+ *d_dxp = width / 2.0;
+ *d_dyp = 0;
+ }
+ break;
+ case QUADRANT:
+ *dxp = 0;
+ *dyp = 1;
+ if (d_dxp) {
+ *d_dxp = 0;
+ *d_dyp = - height / 2.0;
+ }
+ break;
+ case HALFCIRCLE:
+ *dxp = 1;
+ *dyp = 0;
+ if (d_dxp) {
+ *d_dxp = - width / 2.0;
+ *d_dyp = 0;
+ }
+ break;
+ case QUADRANT3:
+ *dxp = 0;
+ *dyp = -1;
+ if (d_dxp) {
+ *d_dxp = 0;
+ *d_dyp = height / 2.0;
+ }
+ break;
+ default:
+ d_dx = Dcos(angle) * width;
+ d_dy = Dsin(angle) * height;
+ if (d_dxp) {
+ *d_dxp = d_dx / 2.0;
+ *d_dyp = - d_dy / 2.0;
+ }
+ negative_dx = FALSE;
+ if (d_dx < 0.0)
+ {
+ d_dx = -d_dx;
+ negative_dx = TRUE;
+ }
+ negative_dy = FALSE;
+ if (d_dy < 0.0)
+ {
+ d_dy = -d_dy;
+ negative_dy = TRUE;
+ }
+ scale = d_dx;
+ if (d_dy > d_dx)
+ scale = d_dy;
+ dx = floor ((d_dx * 32768) / scale + 0.5);
+ if (negative_dx)
+ dx = -dx;
+ *dxp = dx;
+ dy = floor ((d_dy * 32768) / scale + 0.5);
+ if (negative_dy)
+ dy = -dy;
+ *dyp = dy;
+ break;
+ }
+}
+
+static void
+miGetPieEdge(
+ register xArc *arc,
+ register int angle,
+ register miSliceEdgePtr edge,
+ Bool top,
+ Bool left )
+{
+ register int k;
+ int dx, dy;
+
+ miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
+
+ if (dy == 0)
+ {
+ edge->x = left ? -65536 : 65536;
+ edge->stepx = 0;
+ edge->e = 0;
+ edge->dx = -1;
+ return;
+ }
+ if (dx == 0)
+ {
+ edge->x = arc->x + (arc->width >> 1);
+ if (left && (arc->width & 1))
+ edge->x++;
+ else if (!left && !(arc->width & 1))
+ edge->x--;
+ edge->stepx = 0;
+ edge->e = 0;
+ edge->dx = -1;
+ return;
+ }
+ if (dy < 0) {
+ dx = -dx;
+ dy = -dy;
+ }
+ k = (arc->height & 1) ? dx : 0;
+ if (arc->width & 1)
+ k += dy;
+ edge->dx = dx << 1;
+ edge->dy = dy << 1;
+ miGetArcEdge(arc, edge, k, top, left);
+}
+
+void
+miFillArcSliceSetup(arc, slice, pGC)
+ register xArc *arc;
+ register miArcSliceRec *slice;
+ GCPtr pGC;
+{
+ register int angle1, angle2;
+
+ angle1 = arc->angle1;
+ if (arc->angle2 < 0)
+ {
+ angle2 = angle1;
+ angle1 += arc->angle2;
+ }
+ else
+ angle2 = angle1 + arc->angle2;
+ while (angle1 < 0)
+ angle1 += FULLCIRCLE;
+ while (angle1 >= FULLCIRCLE)
+ angle1 -= FULLCIRCLE;
+ while (angle2 < 0)
+ angle2 += FULLCIRCLE;
+ while (angle2 >= FULLCIRCLE)
+ angle2 -= FULLCIRCLE;
+ slice->min_top_y = 0;
+ slice->max_top_y = arc->height >> 1;
+ slice->min_bot_y = 1 - (arc->height & 1);
+ slice->max_bot_y = slice->max_top_y - 1;
+ slice->flip_top = FALSE;
+ slice->flip_bot = FALSE;
+ if (pGC->arcMode == ArcPieSlice)
+ {
+ slice->edge1_top = (angle1 < HALFCIRCLE);
+ slice->edge2_top = (angle2 <= HALFCIRCLE);
+ if ((angle2 == 0) || (angle1 == HALFCIRCLE))
+ {
+ if (angle2 ? slice->edge2_top : slice->edge1_top)
+ slice->min_top_y = slice->min_bot_y;
+ else
+ slice->min_top_y = arc->height;
+ slice->min_bot_y = 0;
+ }
+ else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
+ {
+ slice->min_top_y = slice->min_bot_y;
+ if (angle1 ? slice->edge1_top : slice->edge2_top)
+ slice->min_bot_y = arc->height;
+ else
+ slice->min_bot_y = 0;
+ }
+ else if (slice->edge1_top == slice->edge2_top)
+ {
+ if (angle2 < angle1)
+ {
+ slice->flip_top = slice->edge1_top;
+ slice->flip_bot = !slice->edge1_top;
+ }
+ else if (slice->edge1_top)
+ {
+ slice->min_top_y = 1;
+ slice->min_bot_y = arc->height;
+ }
+ else
+ {
+ slice->min_bot_y = 0;
+ slice->min_top_y = arc->height;
+ }
+ }
+ miGetPieEdge(arc, angle1, &slice->edge1,
+ slice->edge1_top, !slice->edge1_top);
+ miGetPieEdge(arc, angle2, &slice->edge2,
+ slice->edge2_top, slice->edge2_top);
+ }
+ else
+ {
+ double w2, h2, x1, y1, x2, y2, dx, dy, scale;
+ int signdx, signdy, y, k;
+ Bool isInt1 = TRUE, isInt2 = TRUE;
+
+ w2 = (double)arc->width / 2.0;
+ h2 = (double)arc->height / 2.0;
+ if ((angle1 == 0) || (angle1 == HALFCIRCLE))
+ {
+ x1 = angle1 ? -w2 : w2;
+ y1 = 0.0;
+ }
+ else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
+ {
+ x1 = 0.0;
+ y1 = (angle1 == QUADRANT) ? h2 : -h2;
+ }
+ else
+ {
+ isInt1 = FALSE;
+ x1 = Dcos(angle1) * w2;
+ y1 = Dsin(angle1) * h2;
+ }
+ if ((angle2 == 0) || (angle2 == HALFCIRCLE))
+ {
+ x2 = angle2 ? -w2 : w2;
+ y2 = 0.0;
+ }
+ else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
+ {
+ x2 = 0.0;
+ y2 = (angle2 == QUADRANT) ? h2 : -h2;
+ }
+ else
+ {
+ isInt2 = FALSE;
+ x2 = Dcos(angle2) * w2;
+ y2 = Dsin(angle2) * h2;
+ }
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (arc->height & 1)
+ {
+ y1 -= 0.5;
+ y2 -= 0.5;
+ }
+ if (arc->width & 1)
+ {
+ x1 += 0.5;
+ x2 += 0.5;
+ }
+ if (dy < 0.0)
+ {
+ dy = -dy;
+ signdy = -1;
+ }
+ else
+ signdy = 1;
+ if (dx < 0.0)
+ {
+ dx = -dx;
+ signdx = -1;
+ }
+ else
+ signdx = 1;
+ if (isInt1 && isInt2)
+ {
+ slice->edge1.dx = dx * 2;
+ slice->edge1.dy = dy * 2;
+ }
+ else
+ {
+ scale = (dx > dy) ? dx : dy;
+ slice->edge1.dx = floor((dx * 32768) / scale + .5);
+ slice->edge1.dy = floor((dy * 32768) / scale + .5);
+ }
+ if (!slice->edge1.dy)
+ {
+ if (signdx < 0)
+ {
+ y = floor(y1 + 1.0);
+ if (y >= 0)
+ {
+ slice->min_top_y = y;
+ slice->min_bot_y = arc->height;
+ }
+ else
+ {
+ slice->max_bot_y = -y - (arc->height & 1);
+ }
+ }
+ else
+ {
+ y = floor(y1);
+ if (y >= 0)
+ slice->max_top_y = y;
+ else
+ {
+ slice->min_top_y = arc->height;
+ slice->min_bot_y = -y - (arc->height & 1);
+ }
+ }
+ slice->edge1_top = TRUE;
+ slice->edge1.x = 65536;
+ slice->edge1.stepx = 0;
+ slice->edge1.e = 0;
+ slice->edge1.dx = -1;
+ slice->edge2 = slice->edge1;
+ slice->edge2_top = FALSE;
+ }
+ else if (!slice->edge1.dx)
+ {
+ if (signdy < 0)
+ x1 -= 1.0;
+ slice->edge1.x = ceil(x1);
+ slice->edge1_top = signdy < 0;
+ slice->edge1.x += arc->x + (arc->width >> 1);
+ slice->edge1.stepx = 0;
+ slice->edge1.e = 0;
+ slice->edge1.dx = -1;
+ slice->edge2_top = !slice->edge1_top;
+ slice->edge2 = slice->edge1;
+ }
+ else
+ {
+ if (signdx < 0)
+ slice->edge1.dx = -slice->edge1.dx;
+ if (signdy < 0)
+ slice->edge1.dx = -slice->edge1.dx;
+ k = ceil(((x1 + x2) * slice->edge1.dy - (y1 + y2) * slice->edge1.dx) / 2.0);
+ slice->edge2.dx = slice->edge1.dx;
+ slice->edge2.dy = slice->edge1.dy;
+ slice->edge1_top = signdy < 0;
+ slice->edge2_top = !slice->edge1_top;
+ miGetArcEdge(arc, &slice->edge1, k,
+ slice->edge1_top, !slice->edge1_top);
+ miGetArcEdge(arc, &slice->edge2, k,
+ slice->edge2_top, slice->edge2_top);
+ }
+ }
+}
+
+#define ADDSPANS() \
+ pts->x = xorg - x; \
+ pts->y = yorg - y; \
+ *wids = slw; \
+ pts++; \
+ wids++; \
+ if (miFillArcLower(slw)) \
+ { \
+ pts->x = xorg - x; \
+ pts->y = yorg + y + dy; \
+ pts++; \
+ *wids++ = slw; \
+ }
+
+static void
+miFillEllipseI(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc )
+{
+ register int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ int slw;
+ miFillArcRec info;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * arc->height);
+ if (!points)
+ return;
+ widths = (int *)malloc(sizeof(int) * arc->height);
+ if (!widths)
+ {
+ free(points);
+ return;
+ }
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ ADDSPANS();
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ free(widths);
+ free(points);
+}
+
+static void
+miFillEllipseD(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc )
+{
+ register int x, y;
+ int xorg, yorg, dx, dy, slw;
+ double e, yk, xk, ym, xm;
+ miFillArcDRec info;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * arc->height);
+ if (!points)
+ return;
+ widths = (int *)malloc(sizeof(int) * arc->height);
+ if (!widths)
+ {
+ free(points);
+ return;
+ }
+ miFillArcDSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ ADDSPANS();
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ free(widths);
+ free(points);
+}
+
+#define ADDSPAN(l,r) \
+ if (r >= l) \
+ { \
+ pts->x = l; \
+ pts->y = ya; \
+ pts++; \
+ *wids++ = r - l + 1; \
+ }
+
+#define ADDSLICESPANS(flip) \
+ if (!flip) \
+ { \
+ ADDSPAN(xl, xr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ ADDSPAN(xc, xr); \
+ xc += slw - 1; \
+ ADDSPAN(xl, xc); \
+ }
+
+static void
+miFillArcSliceI(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc )
+{
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * slw);
+ if (!points)
+ return;
+ widths = (int *)malloc(sizeof(int) * slw);
+ if (!widths)
+ {
+ free(points);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ free(widths);
+ free(points);
+}
+
+static void
+miFillArcSliceD(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc )
+{
+ register int x, y;
+ int dx, dy, xorg, yorg, slw;
+ double e, yk, xk, ym, xm;
+ miFillArcDRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ miFillArcDSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * slw);
+ if (!points)
+ return;
+ widths = (int *)malloc(sizeof(int) * slw);
+ if (!widths)
+ {
+ free(points);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ free(widths);
+ free(points);
+}
+
+/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
+ * Since we don't have to worry about overlapping segments, we can just
+ * fill each arc as it comes.
+ */
+void
+miPolyFillArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register int i;
+ register xArc *arc;
+
+ for(i = narcs, arc = parcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;;
+ if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
+ {
+ if (miCanFillArc(arc))
+ miFillEllipseI(pDraw, pGC, arc);
+ else
+ miFillEllipseD(pDraw, pGC, arc);
+ }
+ else
+ {
+ if (miCanFillArc(arc))
+ miFillArcSliceI(pDraw, pGC, arc);
+ else
+ miFillArcSliceD(pDraw, pGC, arc);
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mifillarc.h b/nx-X11/programs/Xserver/mi/mifillarc.h
new file mode 100644
index 000000000..0afee1c5e
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mifillarc.h
@@ -0,0 +1,214 @@
+/************************************************************
+
+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.
+
+********************************************************/
+
+
+#ifndef __MIFILLARC_H__
+#define __MIFILLARC_H__
+
+#define FULLCIRCLE (360 * 64)
+
+typedef struct _miFillArc {
+ int xorg, yorg;
+ int y;
+ int dx, dy;
+ int e;
+ int ym, yk, xm, xk;
+} miFillArcRec;
+
+/* could use 64-bit integers */
+typedef struct _miFillArcD {
+ int xorg, yorg;
+ int y;
+ int dx, dy;
+ double e;
+ double ym, yk, xm, xk;
+} miFillArcDRec;
+
+#define miFillArcEmpty(arc) (!(arc)->angle2 || \
+ !(arc)->width || !(arc)->height || \
+ (((arc)->width == 1) && ((arc)->height & 1)))
+
+#define miCanFillArc(arc) (((arc)->width == (arc)->height) || \
+ (((arc)->width <= 800) && ((arc)->height <= 800)))
+
+#define MIFILLARCSETUP() \
+ x = 0; \
+ y = info.y; \
+ e = info.e; \
+ xk = info.xk; \
+ xm = info.xm; \
+ yk = info.yk; \
+ ym = info.ym; \
+ dx = info.dx; \
+ dy = info.dy; \
+ xorg = info.xorg; \
+ yorg = info.yorg
+
+#define MIFILLARCSTEP(slw) \
+ e += yk; \
+ while (e >= 0) \
+ { \
+ x++; \
+ xk -= xm; \
+ e += xk; \
+ } \
+ y--; \
+ yk -= ym; \
+ slw = (x << 1) + dx; \
+ if ((e == xk) && (slw > 1)) \
+ slw--
+
+#define MIFILLCIRCSTEP(slw) MIFILLARCSTEP(slw)
+#define MIFILLELLSTEP(slw) MIFILLARCSTEP(slw)
+
+#define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk)))
+
+typedef struct _miSliceEdge {
+ int x;
+ int stepx;
+ int deltax;
+ int e;
+ int dy;
+ int dx;
+} miSliceEdgeRec, *miSliceEdgePtr;
+
+typedef struct _miArcSlice {
+ miSliceEdgeRec edge1, edge2;
+ int min_top_y, max_top_y;
+ int min_bot_y, max_bot_y;
+ Bool edge1_top, edge2_top;
+ Bool flip_top, flip_bot;
+} miArcSliceRec;
+
+#define MIARCSLICESTEP(edge) \
+ edge.x -= edge.stepx; \
+ edge.e -= edge.dx; \
+ if (edge.e <= 0) \
+ { \
+ edge.x -= edge.deltax; \
+ edge.e += edge.dy; \
+ }
+
+#define miFillSliceUpper(slice) \
+ ((y >= slice.min_top_y) && (y <= slice.max_top_y))
+
+#define miFillSliceLower(slice) \
+ ((y >= slice.min_bot_y) && (y <= slice.max_bot_y))
+
+#define MIARCSLICEUPPER(xl,xr,slice,slw) \
+ xl = xorg - x; \
+ xr = xl + slw - 1; \
+ if (slice.edge1_top && (slice.edge1.x < xr)) \
+ xr = slice.edge1.x; \
+ if (slice.edge2_top && (slice.edge2.x > xl)) \
+ xl = slice.edge2.x;
+
+#define MIARCSLICELOWER(xl,xr,slice,slw) \
+ xl = xorg - x; \
+ xr = xl + slw - 1; \
+ if (!slice.edge1_top && (slice.edge1.x > xl)) \
+ xl = slice.edge1.x; \
+ if (!slice.edge2_top && (slice.edge2.x < xr)) \
+ xr = slice.edge2.x;
+
+#define MIWIDEARCSETUP(x,y,dy,slw,e,xk,xm,yk,ym) \
+ x = 0; \
+ y = slw >> 1; \
+ yk = y << 3; \
+ xm = 8; \
+ ym = 8; \
+ if (dy) \
+ { \
+ xk = 0; \
+ if (slw & 1) \
+ e = -1; \
+ else \
+ e = -(y << 2) - 2; \
+ } \
+ else \
+ { \
+ y++; \
+ yk += 4; \
+ xk = -4; \
+ if (slw & 1) \
+ e = -(y << 2) - 3; \
+ else \
+ e = - (y << 3); \
+ }
+
+#define MIFILLINARCSTEP(slw) \
+ ine += inyk; \
+ while (ine >= 0) \
+ { \
+ inx++; \
+ inxk -= inxm; \
+ ine += inxk; \
+ } \
+ iny--; \
+ inyk -= inym; \
+ slw = (inx << 1) + dx; \
+ if ((ine == inxk) && (slw > 1)) \
+ slw--
+
+#define miFillInArcLower(slw) (((iny + dy) != 0) && \
+ ((slw > 1) || (ine != inxk)))
+
+extern int miFreeArcCache(
+ void * /*data*/,
+ XID /*id*/
+);
+
+extern struct finalSpan *realAllocSpan(
+ void
+);
+
+extern void miFillArcSetup(
+ xArc * /*arc*/,
+ miFillArcRec * /*info*/
+);
+
+extern void miFillArcDSetup(
+ xArc * /*arc*/,
+ miFillArcDRec * /*info*/
+);
+
+extern void miEllipseAngleToSlope(
+ int /*angle*/,
+ int /*width*/,
+ int /*height*/,
+ int * /*dxp*/,
+ int * /*dyp*/,
+ double * /*d_dxp*/,
+ double * /*d_dyp*/
+);
+
+extern void miFillArcSliceSetup(
+ xArc * /*arc*/,
+ miArcSliceRec * /*slice*/,
+ GCPtr /*pGC*/
+);
+
+#endif /* __MIFILLARC_H__ */
diff --git a/nx-X11/programs/Xserver/mi/mifillrct.c b/nx-X11/programs/Xserver/mi/mifillrct.c
new file mode 100644
index 000000000..ba1d29141
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mifillrct.c
@@ -0,0 +1,142 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "misc.h"
+
+/* mi rectangles
+ written by newman, with debts to all and sundry
+*/
+
+/* MIPOLYFILLRECT -- public entry for PolyFillRect request
+ * very straight forward: translate rectangles if necessary
+ * then call FillSpans to fill each rectangle. We let FillSpans worry about
+ * clipping to the destination
+ */
+void
+miPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ int i;
+ register int height;
+ register int width;
+ register xRectangle *prect;
+ int xorg;
+ register int yorg;
+ int maxheight;
+ DDXPointPtr pptFirst;
+ register DDXPointPtr ppt;
+ int *pwFirst;
+ register int *pw;
+
+ if (pGC->miTranslate)
+ {
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ prect = prectInit;
+ maxheight = 0;
+ for (i = 0; i<nrectFill; i++, prect++)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ maxheight = max(maxheight, prect->height);
+ }
+ }
+ else
+ {
+ prect = prectInit;
+ maxheight = 0;
+ for (i = 0; i<nrectFill; i++, prect++)
+ maxheight = max(maxheight, prect->height);
+ }
+
+ pptFirst = (DDXPointPtr) malloc(maxheight * sizeof(DDXPointRec));
+ pwFirst = (int *) malloc(maxheight * sizeof(int));
+ if(!pptFirst || !pwFirst)
+ {
+ if (pwFirst) free(pwFirst);
+ if (pptFirst) free(pptFirst);
+ return;
+ }
+
+ prect = prectInit;
+ while(nrectFill--)
+ {
+ ppt = pptFirst;
+ pw = pwFirst;
+ height = prect->height;
+ width = prect->width;
+ xorg = prect->x;
+ yorg = prect->y;
+ while(height--)
+ {
+ *pw++ = width;
+ ppt->x = xorg;
+ ppt->y = yorg;
+ ppt++;
+ yorg++;
+ }
+ (* pGC->ops->FillSpans)(pDrawable, pGC,
+ prect->height, pptFirst, pwFirst,
+ 1);
+ prect++;
+ }
+ free(pwFirst);
+ free(pptFirst);
+}
diff --git a/nx-X11/programs/Xserver/mi/mifpoly.h b/nx-X11/programs/Xserver/mi/mifpoly.h
new file mode 100644
index 000000000..8f0507601
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mifpoly.h
@@ -0,0 +1,109 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef __MIFPOLY_H__
+#define __MIFPOLY_H__
+
+#define EPSILON 0.000001
+#define ISEQUAL(a,b) (Fabs((a) - (b)) <= EPSILON)
+#define UNEQUAL(a,b) (Fabs((a) - (b)) > EPSILON)
+#define WITHINHALF(a, b) (((a) - (b) > 0.0) ? (a) - (b) < 0.5 : \
+ (b) - (a) <= 0.5)
+#define ROUNDTOINT(x) ((int) (((x) > 0.0) ? ((x) + 0.5) : ((x) - 0.5)))
+#define ISZERO(x) (Fabs((x)) <= EPSILON)
+#define PTISEQUAL(a,b) (ISEQUAL(a.x,b.x) && ISEQUAL(a.y,b.y))
+#define PTUNEQUAL(a,b) (UNEQUAL(a.x,b.x) || UNEQUAL(a.y,b.y))
+#define PtEqual(a, b) (((a).x == (b).x) && ((a).y == (b).y))
+
+#define NotEnd 0
+#define FirstEnd 1
+#define SecondEnd 2
+
+#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */
+#define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */
+
+#ifdef NOINLINEICEIL
+#define ICEIL(x) ((int)ceil(x))
+#else
+#ifdef __GNUC__
+static __inline int ICEIL(double x)
+{
+ int _cTmp = x;
+ return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
+}
+#else
+#define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
+#define ICEILTEMPDECL static int _cTmp;
+#endif
+#endif
+
+/* Point with sub-pixel positioning. In this case we use doubles, but
+ * see mifpolycon.c for other suggestions
+ */
+typedef struct _SppPoint {
+ double x, y;
+} SppPointRec, *SppPointPtr;
+
+typedef struct _SppArc {
+ double x, y, width, height;
+ double angle1, angle2;
+} SppArcRec, *SppArcPtr;
+
+/* mifpolycon.c */
+
+extern void miFillSppPoly(
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ SppPointPtr /*ptsIn*/,
+ int /*xTrans*/,
+ int /*yTrans*/,
+ double /*xFtrans*/,
+ double /*yFtrans*/
+);
+
+#endif /* __MIFPOLY_H__ */
diff --git a/nx-X11/programs/Xserver/mi/mifpolycon.c b/nx-X11/programs/Xserver/mi/mifpolycon.c
new file mode 100644
index 000000000..d544555e0
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mifpolycon.c
@@ -0,0 +1,282 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <math.h>
+#include <nx-X11/X.h>
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mifpoly.h"
+
+static int GetFPolyYBounds(register SppPointPtr pts, int n, double yFtrans,
+ int *by, int *ty);
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+/*
+ * Written by Todd Newman; April. 1987.
+ *
+ * Fill a convex polygon. If the given polygon
+ * is not convex, then the result is undefined.
+ * The algorithm is to order the edges from smallest
+ * y to largest by partitioning the array into a left
+ * edge list and a right edge list. The algorithm used
+ * to traverse each edge is digital differencing analyzer
+ * line algorithm with y as the major axis. There's some funny linear
+ * interpolation involved because of the subpixel postioning.
+ */
+void
+miFillSppPoly(dst, pgc, count, ptsIn, xTrans, yTrans, xFtrans, yFtrans)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ SppPointPtr ptsIn; /* the points */
+ int xTrans, yTrans; /* Translate each point by this */
+ double xFtrans, yFtrans; /* translate before conversion
+ by this amount. This provides
+ a mechanism to match rounding
+ errors with any shape that must
+ meet the polygon exactly.
+ */
+{
+ double xl = 0.0, xr = 0.0, /* x vals of left and right edges */
+ ml = 0.0, /* left edge slope */
+ mr = 0.0, /* right edge slope */
+ dy, /* delta y */
+ i; /* loop counter */
+ int y, /* current scanline */
+ j,
+ imin, /* index of vertex with smallest y */
+ ymin, /* y-extents of polygon */
+ ymax,
+ *width,
+ *FirstWidth, /* output buffer */
+ *Marked; /* set if this vertex has been used */
+ register int left, right, /* indices to first endpoints */
+ nextleft,
+ nextright; /* indices to second endpoints */
+ DDXPointPtr ptsOut,
+ FirstPoint; /* output buffer */
+
+ if (pgc->miTranslate)
+ {
+ xTrans += dst->x;
+ yTrans += dst->y;
+ }
+
+ imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);
+
+ y = ymax - ymin + 1;
+ if ((count < 3) || (y <= 0))
+ return;
+ ptsOut = FirstPoint = (DDXPointPtr)malloc(sizeof(DDXPointRec) * y);
+ width = FirstWidth = (int *) malloc(sizeof(int) * y);
+ Marked = (int *) malloc(sizeof(int) * count);
+
+ if(!ptsOut || !width || !Marked)
+ {
+ if (Marked) free(Marked);
+ if (width) free(width);
+ if (ptsOut) free(ptsOut);
+ return;
+ }
+
+ for(j = 0; j < count; j++)
+ Marked[j] = 0;
+ nextleft = nextright = imin;
+ Marked[imin] = -1;
+ y = ICEIL(ptsIn[nextleft].y + yFtrans);
+
+ /*
+ * loop through all edges of the polygon
+ */
+ do
+ {
+ /* add a left edge if we need to */
+ if ((y > (ptsIn[nextleft].y + yFtrans) ||
+ ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
+ Marked[nextleft] != 1)
+ {
+ Marked[nextleft]++;
+ left = nextleft++;
+
+ /* find the next edge, considering the end conditions */
+ if (nextleft >= count)
+ nextleft = 0;
+
+ /* now compute the starting point and slope */
+ dy = ptsIn[nextleft].y - ptsIn[left].y;
+ if (dy != 0.0)
+ {
+ ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
+ dy = y - (ptsIn[left].y + yFtrans);
+ xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0);
+ }
+ }
+
+ /* add a right edge if we need to */
+ if ((y > ptsIn[nextright].y + yFtrans) ||
+ (ISEQUAL(y, ptsIn[nextright].y + yFtrans)
+ && Marked[nextright] != 1))
+ {
+ Marked[nextright]++;
+ right = nextright--;
+
+ /* find the next edge, considering the end conditions */
+ if (nextright < 0)
+ nextright = count - 1;
+
+ /* now compute the starting point and slope */
+ dy = ptsIn[nextright].y - ptsIn[right].y;
+ if (dy != 0.0)
+ {
+ mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
+ dy = y - (ptsIn[right].y + yFtrans);
+ xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0);
+ }
+ }
+
+
+ /*
+ * generate scans to fill while we still have
+ * a right edge as well as a left edge.
+ */
+ i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;
+
+ if (i < EPSILON)
+ {
+ if(Marked[nextleft] && Marked[nextright])
+ {
+ /* Arrgh, we're trapped! (no more points)
+ * Out, we've got to get out of here before this decadence saps
+ * our will completely! */
+ break;
+ }
+ continue;
+ }
+ else
+ {
+ j = (int) i;
+ if(!j)
+ j++;
+ }
+ while (j > 0)
+ {
+ int cxl, cxr;
+
+ ptsOut->y = (y) + yTrans;
+
+ cxl = ICEIL(xl);
+ cxr = ICEIL(xr);
+ /* reverse the edges if necessary */
+ if (xl < xr)
+ {
+ *(width++) = cxr - cxl;
+ (ptsOut++)->x = cxl + xTrans;
+ }
+ else
+ {
+ *(width++) = cxl - cxr;
+ (ptsOut++)->x = cxr + xTrans;
+ }
+ y++;
+
+ /* increment down the edges */
+ xl += ml;
+ xr += mr;
+ j--;
+ }
+ } while (y <= ymax);
+
+ /* Finally, fill the spans we've collected */
+ (*pgc->ops->FillSpans)(dst, pgc,
+ ptsOut-FirstPoint, FirstPoint, FirstWidth, 1);
+ free(Marked);
+ free(FirstWidth);
+ free(FirstPoint);
+}
+
+
+/* Find the index of the point with the smallest y.also return the
+ * smallest and largest y */
+static
+int
+GetFPolyYBounds(
+ register SppPointPtr pts,
+ int n,
+ double yFtrans,
+ int *by,
+ int *ty)
+{
+ register SppPointPtr ptMin;
+ double ymin, ymax;
+ SppPointPtr ptsStart = pts;
+
+ ptMin = pts;
+ ymin = ymax = (pts++)->y;
+
+ while (--n > 0) {
+ if (pts->y < ymin)
+ {
+ ptMin = pts;
+ ymin = pts->y;
+ }
+ if(pts->y > ymax)
+ ymax = pts->y;
+
+ pts++;
+ }
+
+ *by = ICEIL(ymin + yFtrans);
+ *ty = ICEIL(ymax + yFtrans - 1);
+ return(ptMin-ptsStart);
+}
diff --git a/nx-X11/programs/Xserver/mi/migc.c b/nx-X11/programs/Xserver/mi/migc.c
new file mode 100644
index 000000000..4d67cbf5d
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/migc.c
@@ -0,0 +1,300 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "migc.h"
+
+/* ARGSUSED */
+void
+miChangeGC(pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ return;
+}
+
+void
+miDestroyGC(pGC)
+ GCPtr pGC;
+{
+ if (pGC->pRotatedPixmap)
+ (*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
+ if (pGC->freeCompClip)
+ RegionDestroy(pGC->pCompositeClip);
+ miDestroyGCOps(pGC->ops);
+}
+
+/*
+ * create a private op array for a gc
+ */
+
+GCOpsPtr
+miCreateGCOps(prototype)
+ GCOpsPtr prototype;
+{
+ GCOpsPtr ret;
+
+ /* XXX */ Must_have_memory = TRUE;
+ ret = (GCOpsPtr) malloc(sizeof(GCOps));
+ /* XXX */ Must_have_memory = FALSE;
+ if (!ret)
+ return 0;
+ *ret = *prototype;
+ ret->devPrivate.val = 1;
+ return ret;
+}
+
+void
+miDestroyGCOps(ops)
+ GCOpsPtr ops;
+{
+ if (ops->devPrivate.val)
+ free(ops);
+}
+
+
+void
+miDestroyClip(pGC)
+ GCPtr pGC;
+{
+ if (pGC->clientClipType == CT_NONE)
+ return;
+ else if (pGC->clientClipType == CT_PIXMAP)
+ {
+ (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
+ }
+ else
+ {
+ /*
+ * we know we'll never have a list of rectangles, since ChangeClip
+ * immediately turns them into a region
+ */
+ RegionDestroy(pGC->clientClip);
+ }
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+}
+
+void
+miChangeClip(pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ void *pvalue;
+ int nrects;
+{
+ (*pGC->funcs->DestroyClip) (pGC);
+ if (type == CT_PIXMAP)
+ {
+ /* convert the pixmap to a region */
+ pGC->clientClip = (void *) BitmapToRegion(pGC->pScreen,
+ (PixmapPtr) pvalue);
+ (*pGC->pScreen->DestroyPixmap) (pvalue);
+ }
+ else if (type == CT_REGION)
+ {
+ /* stuff the region in the GC */
+ pGC->clientClip = pvalue;
+ }
+ else if (type != CT_NONE)
+ {
+ pGC->clientClip = (void *) RegionFromRects(nrects,
+ (xRectangle *) pvalue,
+ type);
+ free(pvalue);
+ }
+ pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
+ pGC->stateChanges |= GCClipMask;
+}
+
+void
+miCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ RegionPtr prgnNew;
+
+ switch (pgcSrc->clientClipType)
+ {
+ case CT_PIXMAP:
+ ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
+ /* Fall through !! */
+ case CT_NONE:
+ (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
+ pgcSrc->clientClip, 0);
+ break;
+ case CT_REGION:
+ prgnNew = RegionCreate(NULL, 1);
+ RegionCopy(prgnNew,
+ (RegionPtr) (pgcSrc->clientClip));
+ (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (void *) prgnNew, 0);
+ break;
+ }
+}
+
+/* ARGSUSED */
+void
+miCopyGC(pGCSrc, changes, pGCDst)
+ GCPtr pGCSrc;
+ unsigned long changes;
+ GCPtr pGCDst;
+{
+ return;
+}
+
+void
+miComputeCompositeClip(pGC, pDrawable)
+ GCPtr pGC;
+ DrawablePtr pDrawable;
+{
+ ScreenPtr pScreen;
+
+ /* This prevents warnings about pScreen not being used. */
+ pGC->pScreen = pScreen = pGC->pScreen;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else
+ {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy (or
+ * maybe re-use) it later. this way, we avoid unnecessary copying of
+ * regions. (this wins especially if many clients clip by children
+ * and have no client clip.)
+ */
+ if (pGC->clientClipType == CT_NONE)
+ {
+ if (freeCompClip)
+ RegionDestroy(pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ }
+ else
+ {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ RegionTranslate(pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+
+ if (freeCompClip)
+ {
+ RegionIntersect(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ if (freeTmpClip)
+ RegionDestroy(pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ RegionIntersect(pregWin, pregWin, pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pGC->pCompositeClip = RegionCreate(NullBox, 0);
+ RegionIntersect(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ RegionTranslate(pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ }
+ } /* end of composite clip for a window */
+ else
+ {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ /* If you want pixmaps in offscreen memory, yes */
+ pixbounds.x1 = pDrawable->x;
+ pixbounds.y1 = pDrawable->y;
+ pixbounds.x2 = pDrawable->x + pDrawable->width;
+ pixbounds.y2 = pDrawable->y + pDrawable->height;
+
+ if (pGC->freeCompClip)
+ {
+ RegionReset(pGC->pCompositeClip, &pixbounds);
+ }
+ else
+ {
+ pGC->freeCompClip = TRUE;
+ pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
+ }
+
+ if (pGC->clientClipType == CT_REGION)
+ {
+ if(pDrawable->x || pDrawable->y) {
+ RegionTranslate(pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+ RegionIntersect(pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ RegionTranslate(pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ } else {
+ RegionTranslate(pGC->pCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ RegionIntersect(pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ RegionTranslate(pGC->pCompositeClip,
+ pGC->clipOrg.x, pGC->clipOrg.y);
+ }
+ }
+ } /* end of composite clip for pixmap */
+} /* end miComputeCompositeClip */
diff --git a/nx-X11/programs/Xserver/mi/migc.h b/nx-X11/programs/Xserver/mi/migc.h
new file mode 100644
index 000000000..9c579961c
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/migc.h
@@ -0,0 +1,72 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+
+extern void miChangeGC(
+ GCPtr /*pGC*/,
+ unsigned long /*mask*/
+);
+
+extern void miDestroyGC(
+ GCPtr /*pGC*/
+);
+
+extern GCOpsPtr miCreateGCOps(
+ GCOpsPtr /*prototype*/
+);
+
+extern void miDestroyGCOps(
+ GCOpsPtr /*ops*/
+);
+
+extern void miDestroyClip(
+ GCPtr /*pGC*/
+);
+
+extern void miChangeClip(
+ GCPtr /*pGC*/,
+ int /*type*/,
+ void * /*pvalue*/,
+ int /*nrects*/
+);
+
+extern void miCopyClip(
+ GCPtr /*pgcDst*/,
+ GCPtr /*pgcSrc*/
+);
+
+extern void miCopyGC(
+ GCPtr /*pGCSrc*/,
+ unsigned long /*changes*/,
+ GCPtr /*pGCDst*/
+);
+
+extern void miComputeCompositeClip(
+ GCPtr /*pGC*/,
+ DrawablePtr /*pDrawable*/
+);
diff --git a/nx-X11/programs/Xserver/mi/miglblt.c b/nx-X11/programs/Xserver/mi/miglblt.c
new file mode 100644
index 000000000..462534bb6
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miglblt.c
@@ -0,0 +1,264 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS_XFONT2 */
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmap.h"
+#include "servermd.h"
+#include "mi.h"
+
+/*
+ machine-independent glyph blt.
+ assumes that glyph bits in snf are written in bytes,
+have same bit order as the server's bitmap format,
+and are byte padded. this corresponds to the snf distributed
+with the sample server.
+
+ get a scratch GC.
+ in the scratch GC set alu = GXcopy, fg = 1, bg = 0
+ allocate a bitmap big enough to hold the largest glyph in the font
+ validate the scratch gc with the bitmap
+ for each glyph
+ carefully put the bits of the glyph in a buffer,
+ padded to the server pixmap scanline padding rules
+ fake a call to PutImage from the buffer into the bitmap
+ use the bitmap in a call to PushPixels
+*/
+
+void
+miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ void *pglyphBase; /* start of array of glyphs */
+{
+ int width, height;
+ PixmapPtr pPixmap;
+ int nbyLine; /* bytes per line of padded pixmap */
+ FontPtr pfont;
+ GCPtr pGCtmp;
+ register int i;
+ register int j;
+ unsigned char *pbits; /* buffer for PutImage */
+ register unsigned char *pb; /* temp pointer into buffer */
+ register CharInfoPtr pci; /* currect char info */
+ register unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ register int nbyGlyphWidth; /* bytes per scanline of glyph */
+ int nbyPadGlyph; /* server padded line of glyph */
+
+ XID gcvals[3];
+
+ if (pGC->miTranslate)
+ {
+ x += pDrawable->x;
+ y += pDrawable->y;
+ }
+
+ pfont = pGC->font;
+ width = FONTMAXBOUNDS(pfont,rightSideBearing) -
+ FONTMINBOUNDS(pfont,leftSideBearing);
+ height = FONTMAXBOUNDS(pfont,ascent) +
+ FONTMAXBOUNDS(pfont,descent);
+
+ pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen,
+ width, height, 1,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ return;
+
+ pGCtmp = GetScratchGC(1, pDrawable->pScreen);
+ if (!pGCtmp)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ return;
+ }
+
+ gcvals[0] = GXcopy;
+ gcvals[1] = 1;
+ gcvals[2] = 0;
+
+ DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
+
+ nbyLine = BitmapBytePad(width);
+ pbits = (unsigned char *)malloc(height*nbyLine);
+ if (!pbits)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ FreeScratchGC(pGCtmp);
+ return;
+ }
+ while(nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
+ nbyPadGlyph = BitmapBytePad(gWidth);
+
+ if (nbyGlyphWidth == nbyPadGlyph
+#if GLYPHPADBYTES != 4
+ && (((int) pglyph) & 3) == 0
+#endif
+ )
+ {
+ pb = pglyph;
+ }
+ else
+ {
+ for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
+ for (j = 0; j < nbyGlyphWidth; j++)
+ *pb++ = *pglyph++;
+ pb = pbits;
+ }
+
+ if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
+ ValidateGC((DrawablePtr)pPixmap, pGCtmp);
+ (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp,
+ pPixmap->drawable.depth,
+ 0, 0, gWidth, gHeight,
+ 0, XYBitmap, (char *)pb);
+
+ if ((pGC->serialNumber) != (pDrawable->serialNumber))
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
+ gWidth, gHeight,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent);
+ }
+ x += pci->metrics.characterWidth;
+ }
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ free(pbits);
+ FreeScratchGC(pGCtmp);
+}
+
+
+void
+miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ void *pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by xfont2_query_glyph_extents (libXfont2)
+ resp. QueryGlyphExtents() (libXfont1) */
+ XID gcvals[3];
+ int oldAlu, oldFS;
+ unsigned long oldFG;
+ xRectangle backrect;
+
+#ifdef HAS_XFONT2
+ xfont2_query_glyph_extents(pGC->font, ppci, (unsigned long) nglyph, &info);
+#else
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+#endif /* HAS_XFONT2 */
+
+ if (info.overallWidth >= 0)
+ {
+ backrect.x = x;
+ backrect.width = info.overallWidth;
+ }
+ else
+ {
+ backrect.x = x + info.overallWidth;
+ backrect.width = -info.overallWidth;
+ }
+ backrect.y = y - FONTASCENT(pGC->font);
+ backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+ oldAlu = pGC->alu;
+ oldFG = pGC->fgPixel;
+ oldFS = pGC->fillStyle;
+
+ /* fill in the background */
+ gcvals[0] = GXcopy;
+ gcvals[1] = pGC->bgPixel;
+ gcvals[2] = FillSolid;
+ DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect);
+
+ /* put down the glyphs */
+ gcvals[0] = oldFG;
+ DoChangeGC(pGC, GCForeground, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
+ pglyphBase);
+
+ /* put all the toys away when done playing */
+ gcvals[0] = oldAlu;
+ gcvals[1] = oldFG;
+ gcvals[2] = oldFS;
+ DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+
+}
diff --git a/nx-X11/programs/Xserver/mi/miinitext.c b/nx-X11/programs/Xserver/mi/miinitext.c
new file mode 100644
index 000000000..6f6d67841
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miinitext.c
@@ -0,0 +1,488 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#undef DPMSExtension
+#endif
+
+#include "misc.h"
+#include "extension.h"
+#include "micmap.h"
+
+extern Bool noTestExtensions;
+
+#ifdef BIGREQS
+extern Bool noBigReqExtension;
+#endif
+#ifdef COMPOSITE
+extern Bool noCompositeExtension;
+#endif
+#ifdef DAMAGE
+extern Bool noDamageExtension;
+#endif
+#ifdef DBE
+extern Bool noDbeExtension;
+#endif
+#ifdef DPSEXT
+extern Bool noDPSExtension;
+#endif
+#ifdef DPMSExtension
+extern Bool noDPMSExtension;
+#endif
+#ifdef GLXEXT
+extern Bool noGlxExtension;
+#endif
+#ifdef SCREENSAVER
+extern Bool noScreenSaverExtension;
+#endif
+#ifdef MITSHM
+extern Bool noMITShmExtension;
+#endif
+#ifdef RANDR
+extern Bool noRRExtension;
+#endif
+#ifdef RENDER
+extern Bool noRenderExtension;
+#endif
+#ifdef SHAPE
+extern Bool noShapeExtension;
+#endif
+#ifdef XCSECURITY
+extern Bool noSecurityExtension;
+#endif
+#ifdef XSYNC
+extern Bool noSyncExtension;
+#endif
+#ifdef RES
+extern Bool noResExtension;
+#endif
+#ifdef XCMISC
+extern Bool noXCMiscExtension;
+#endif
+#ifdef XF86BIGFONT
+extern Bool noXFree86BigfontExtension;
+#endif
+#ifdef XF86DRI
+extern Bool noXFree86DRIExtension;
+#endif
+#ifdef XFIXES
+extern Bool noXFixesExtension;
+#endif
+#ifdef XKB
+/* |noXkbExtension| is defined in xc/programs/Xserver/xkb/xkbInit.c */
+extern Bool noXkbExtension;
+#endif
+#ifdef PANORAMIX
+extern Bool noPanoramiXExtension;
+#endif
+#ifdef XINPUT
+extern Bool noXInputExtension;
+#endif
+#ifdef XIDLE
+extern Bool noXIdleExtension;
+#endif
+#ifdef XV
+extern Bool noXvExtension;
+#endif
+
+#define INITARGS void
+typedef void (*InitExtension)(void);
+
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include <X11/extensions/shmproto.h>
+#endif
+#ifdef XTEST
+#define _XTEST_SERVER_
+#include <nx-X11/extensions/xtestconst.h>
+#endif
+#ifdef XKB
+#include <nx-X11/extensions/XKB.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/securstr.h>
+#endif
+#ifdef PANORAMIX
+#include <nx-X11/extensions/panoramiXproto.h>
+#endif
+#ifdef XF86BIGFONT
+#include <nx-X11/extensions/xf86bigfproto.h>
+#endif
+#ifdef RES
+#include <nx-X11/extensions/XResproto.h>
+#endif
+
+/* FIXME: this whole block of externs should be from the appropriate headers */
+#ifdef XTESTEXT1
+extern void XTestExtension1Init(void);
+#endif
+#ifdef SHAPE
+extern void ShapeExtensionInit(void);
+#endif
+#ifdef MITSHM
+extern void ShmExtensionInit(void);
+#endif
+#ifdef PANORAMIX
+extern void PanoramiXExtensionInit(void);
+#endif
+#ifdef XINPUT
+extern void XInputExtensionInit(void);
+#endif
+#ifdef XTEST
+extern void XTestExtensionInit(void);
+#endif
+#ifdef BIGREQS
+extern void BigReqExtensionInit(void);
+#endif
+#ifdef XIDLE
+extern void XIdleExtensionInit(void);
+#endif
+#ifdef SCREENSAVER
+extern void ScreenSaverExtensionInit (void);
+#endif
+#ifdef XV
+extern void XvExtensionInit(void);
+extern void XvMCExtensionInit(void);
+#endif
+#ifdef XSYNC
+extern void SyncExtensionInit(void);
+#endif
+#ifdef XKB
+extern void XkbExtensionInit(void);
+#endif
+#ifdef XCMISC
+extern void XCMiscExtensionInit(void);
+#endif
+#ifdef XRECORD
+extern void RecordExtensionInit(void);
+#endif
+#ifdef DBE
+extern void DbeExtensionInit(void);
+#endif
+#ifdef XCSECURITY
+extern void SecurityExtensionInit(void);
+#endif
+#ifdef XF86BIGFONT
+extern void XFree86BigfontExtensionInit(void);
+#endif
+#ifdef GLXEXT
+#ifndef __DARWIN__
+extern void GlxExtensionInit(void);
+extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+#else
+extern void DarwinGlxExtensionInit(void);
+extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *);
+#endif
+#endif
+#ifdef XF86DRI
+extern void XFree86DRIExtensionInit(void);
+#endif
+#ifdef DPMSExtension
+extern void DPMSExtensionInit(void);
+#endif
+#ifdef DPSEXT
+extern void DPSExtensionInit(void);
+#endif
+#ifdef RENDER
+extern void RenderExtensionInit(void);
+#endif
+#ifdef RANDR
+extern void RRExtensionInit(void);
+#endif
+#ifdef RES
+extern void ResExtensionInit(void);
+#endif
+#ifdef DMXEXT
+extern void DMXExtensionInit(void);
+#endif
+#ifdef XFIXES
+extern void XFixesExtensionInit(void);
+#endif
+#ifdef DAMAGE
+extern void DamageExtensionInit(void);
+#endif
+#ifdef COMPOSITE
+extern void CompositeExtensionInit(void);
+#endif
+
+/* The following is only a small first step towards run-time
+ * configurable extensions.
+ */
+typedef struct {
+ char *name;
+ Bool *disablePtr;
+} ExtensionToggle;
+
+static ExtensionToggle ExtensionToggleList[] =
+{
+ /* sort order is extension name string as shown in xdpyinfo */
+#ifdef BIGREQS
+ { "BIG-REQUESTS", &noBigReqExtension },
+#endif
+#ifdef COMPOSITE
+ { "Composite", &noCompositeExtension },
+#endif
+#ifdef DAMAGE
+ { "DAMAGE", &noDamageExtension },
+#endif
+#ifdef DBE
+ { "DOUBLE-BUFFER", &noDbeExtension },
+#endif
+#ifdef DPSEXT
+ { "DPSExtension", &noDPSExtension },
+#endif
+#ifdef DPMSExtension
+ { "DPMS", &noDPMSExtension },
+#endif
+#ifdef GLXEXT
+ { "GLX", &noGlxExtension },
+#endif
+#ifdef SCREENSAVER
+ { "MIT-SCREEN-SAVER", &noScreenSaverExtension },
+#endif
+#ifdef MITSHM
+ { SHMNAME, &noMITShmExtension },
+#endif
+#ifdef RANDR
+ { "RANDR", &noRRExtension },
+#endif
+#ifdef RENDER
+ { "RENDER", &noRenderExtension },
+#endif
+#ifdef SHAPE
+ { "SHAPE", &noShapeExtension },
+#endif
+#ifdef XCSECURITY
+ { "SECURITY", &noSecurityExtension },
+#endif
+#ifdef XSYNC
+ { "SYNC", &noSyncExtension },
+#endif
+#ifdef RES
+ { "X-Resource", &noResExtension },
+#endif
+#ifdef XCMISC
+ { "XC-MISC", &noXCMiscExtension },
+#endif
+#ifdef XF86BIGFONT
+ { "XFree86-Bigfont", &noXFree86BigfontExtension },
+#endif
+#ifdef XF86DRI
+ { "XFree86-DRI", &noXFree86DRIExtension },
+#endif
+#ifdef XFIXES
+ { "XFIXES", &noXFixesExtension },
+#endif
+#ifdef PANORAMIX
+ { "XINERAMA", &noPanoramiXExtension },
+#endif
+#ifdef XINPUT
+ { "XInputExtension", &noXInputExtension },
+#endif
+#ifdef XKB
+ { "XKEYBOARD", &noXkbExtension },
+#endif
+ { "XTEST", &noTestExtensions },
+#ifdef XV
+ { "XVideo", &noXvExtension },
+#endif
+ { NULL, NULL }
+};
+
+Bool EnableDisableExtension(char *name, Bool enable)
+{
+ ExtensionToggle *ext = &ExtensionToggleList[0];
+
+ for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++) {
+ if (strcmp(name, ext->name) == 0) {
+ *ext->disablePtr = !enable;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void EnableDisableExtensionError(char *name, Bool enable)
+{
+ ExtensionToggle *ext = &ExtensionToggleList[0];
+
+ ErrorF("Extension \"%s\" is not recognized\n", name);
+ ErrorF("Only the following extensions can be run-time %s:\n",
+ enable ? "enabled" : "disabled");
+ for (ext = &ExtensionToggleList[0]; ext->name != NULL; ext++)
+ ErrorF(" %s\n", ext->name);
+}
+
+/*ARGSUSED*/
+void
+InitExtensions(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef PANORAMIX
+# if !defined(PRINT_ONLY_SERVER) && !defined(NO_PANORAMIX)
+ if (!noPanoramiXExtension) PanoramiXExtensionInit();
+# endif
+#endif
+#ifdef XTESTEXT1
+ if (!noTestExtensions) XTestExtension1Init();
+#endif
+#ifdef SHAPE
+ if (!noShapeExtension) ShapeExtensionInit();
+#endif
+#ifdef MITSHM
+ if (!noMITShmExtension) ShmExtensionInit();
+#endif
+#if defined(XINPUT) && !defined(NO_HW_ONLY_EXTS)
+ if (!noXInputExtension) XInputExtensionInit();
+#endif
+#ifdef XTEST
+ if (!noTestExtensions) XTestExtensionInit();
+#endif
+#ifdef BIGREQS
+ if (!noBigReqExtension) BigReqExtensionInit();
+#endif
+#ifdef XIDLE
+ if (!noXIdleExtension) XIdleExtensionInit();
+#endif
+#if defined(SCREENSAVER) && !defined(PRINT_ONLY_SERVER)
+ if (!noScreenSaverExtension) ScreenSaverExtensionInit ();
+#endif
+#ifdef XV
+ if (!noXvExtension) {
+ XvExtensionInit();
+ XvMCExtensionInit();
+ }
+#endif
+#ifdef XSYNC
+ if (!noSyncExtension) SyncExtensionInit();
+#endif
+#if defined(XKB) && !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
+ if (!noXkbExtension) XkbExtensionInit();
+#endif
+#ifdef XCMISC
+ if (!noXCMiscExtension) XCMiscExtensionInit();
+#endif
+#ifdef XRECORD
+ if (!noTestExtensions) RecordExtensionInit();
+#endif
+#ifdef DBE
+ if (!noDbeExtension) DbeExtensionInit();
+#endif
+#ifdef XCSECURITY
+ if (!noSecurityExtension) SecurityExtensionInit();
+#endif
+#if defined(DPMSExtension) && !defined(NO_HW_ONLY_EXTS)
+ if (!noDPMSExtension) DPMSExtensionInit();
+#endif
+#ifdef XF86BIGFONT
+ if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
+#endif
+#if !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
+#ifdef XF86DRI
+ if (!noXFree86DRIExtension) XFree86DRIExtensionInit();
+#endif
+#endif
+#ifdef GLXEXT
+#ifndef __DARWIN__
+ if (!noGlxExtension) GlxExtensionInit();
+#else
+ if (!noGlxExtension) DarwinGlxExtensionInit();
+#endif
+#endif
+#ifdef XFIXES
+ /* must be before Render to layer DisplayCursor correctly */
+ if (!noXFixesExtension) XFixesExtensionInit();
+#endif
+#ifdef RENDER
+ if (!noRenderExtension) RenderExtensionInit();
+#endif
+#ifdef RANDR
+ if (!noRRExtension) RRExtensionInit();
+#endif
+#ifdef RES
+ if (!noResExtension) ResExtensionInit();
+#endif
+#ifdef DMXEXT
+ DMXExtensionInit(); /* server-specific extension, cannot be disabled */
+#endif
+#ifdef COMPOSITE
+ if (!noCompositeExtension) CompositeExtensionInit();
+#endif
+#ifdef DAMAGE
+ if (!noDamageExtension) DamageExtensionInit();
+#endif
+}
+
+void
+InitVisualWrap()
+{
+ miResetInitVisuals();
+#ifdef GLXEXT
+#ifndef __DARWIN__
+ GlxWrapInitVisuals(&miInitVisualsProc);
+#else
+ DarwinGlxWrapInitVisuals(&miInitVisualsProc);
+#endif
+#endif
+}
+
diff --git a/nx-X11/programs/Xserver/mi/miline.h b/nx-X11/programs/Xserver/mi/miline.h
new file mode 100644
index 000000000..7028485f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miline.h
@@ -0,0 +1,172 @@
+
+/*
+
+Copyright 1994, 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.
+
+*/
+
+#ifndef MILINE_H
+
+#include "screenint.h"
+
+/*
+ * Public definitions used for configuring basic pixelization aspects
+ * of the sample implementation line-drawing routines provided in
+ * {mfb,mi,cfb*} at run-time.
+ */
+
+#define XDECREASING 4
+#define YDECREASING 2
+#define YMAJOR 1
+
+#define OCTANT1 (1 << (YDECREASING))
+#define OCTANT2 (1 << (YDECREASING|YMAJOR))
+#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
+#define OCTANT4 (1 << (XDECREASING|YDECREASING))
+#define OCTANT5 (1 << (XDECREASING))
+#define OCTANT6 (1 << (XDECREASING|YMAJOR))
+#define OCTANT7 (1 << (YMAJOR))
+#define OCTANT8 (1 << (0))
+
+#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
+
+#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
+
+/*
+ * Devices can configure the rendering of routines in mi, mfb, and cfb*
+ * by specifying a thin line bias to be applied to a particular screen
+ * using the following function. The bias parameter is an OR'ing of
+ * the appropriate OCTANT constants defined above to indicate which
+ * octants to bias a line to prefer an axial step when the Bresenham
+ * error term is exactly zero. The octants are mapped as follows:
+ *
+ * \ | /
+ * \ 3 | 2 /
+ * \ | /
+ * 4 \ | / 1
+ * \|/
+ * -----------
+ * /|\
+ * 5 / | \ 8
+ * / | \
+ * / 6 | 7 \
+ * / | \
+ *
+ * For more information, see "Ambiguities in Incremental Line Rastering,"
+ * Jack E. Bresenham, IEEE CG&A, May 1987.
+ */
+
+extern void miSetZeroLineBias(
+ ScreenPtr /* pScreen */,
+ unsigned int /* bias */
+);
+
+/*
+ * Private definitions needed for drawing thin (zero width) lines
+ * Used by the mi, mfb, and all cfb* components.
+ */
+
+#define X_AXIS 0
+#define Y_AXIS 1
+
+#define OUT_LEFT 0x08
+#define OUT_RIGHT 0x04
+#define OUT_ABOVE 0x02
+#define OUT_BELOW 0x01
+
+#define OUTCODES(_result, _x, _y, _pbox) \
+ if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
+ else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
+ if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
+ else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
+
+#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
+{\
+ if (x < xmin) outcode |= OUT_LEFT;\
+ if (x > xmax) outcode |= OUT_RIGHT;\
+ if (y < ymin) outcode |= OUT_ABOVE;\
+ if (y > ymax) outcode |= OUT_BELOW;\
+}
+
+#define SWAPINT(i, j) \
+{ register int _t = i; i = j; j = _t; }
+
+#define SWAPPT(i, j) \
+{ DDXPointRec _t; _t = i; i = j; j = _t; }
+
+#define SWAPINT_PAIR(x1, y1, x2, y2)\
+{ int t = x1; x1 = x2; x2 = t;\
+ t = y1; y1 = y2; y2 = t;\
+}
+
+#define miGetZeroLineBias(_pScreen) \
+ ((miZeroLineScreenIndex < 0) ? \
+ 0 : ((_pScreen)->devPrivates[miZeroLineScreenIndex].uval))
+
+#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
+ (_octant) = 0; \
+ (_sx) = (_SX); \
+ if (((_adx) = (_x2) - (_x1)) < 0) { \
+ (_adx) = -(_adx); \
+ (_sx = -(_sx)); \
+ (_octant) |= XDECREASING; \
+ } \
+ (_sy) = (_SY); \
+ if (((_ady) = (_y2) - (_y1)) < 0) { \
+ (_ady) = -(_ady); \
+ (_sy = -(_sy)); \
+ (_octant) |= YDECREASING; \
+ }
+
+#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
+
+#define FIXUP_ERROR(_e, _octant, _bias) \
+ (_e) -= (((_bias) >> (_octant)) & 1)
+
+#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
+#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
+#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
+#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
+
+extern int miZeroLineScreenIndex;
+
+extern int miZeroClipLine(
+ int /*xmin*/,
+ int /*ymin*/,
+ int /*xmax*/,
+ int /*ymax*/,
+ int * /*new_x1*/,
+ int * /*new_y1*/,
+ int * /*new_x2*/,
+ int * /*new_y2*/,
+ unsigned int /*adx*/,
+ unsigned int /*ady*/,
+ int * /*pt1_clipped*/,
+ int * /*pt2_clipped*/,
+ int /*octant*/,
+ unsigned int /*bias*/,
+ int /*oc1*/,
+ int /*oc2*/
+);
+
+#endif /* MILINE_H */
diff --git a/nx-X11/programs/Xserver/mi/mioverlay.c b/nx-X11/programs/Xserver/mi/mioverlay.c
new file mode 100644
index 000000000..c0d923a0f
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mioverlay.c
@@ -0,0 +1,2077 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+#include "mioverlay.h"
+#include "migc.h"
+
+#include "globals.h"
+
+
+typedef struct {
+ RegionRec exposed;
+ RegionRec borderExposed;
+ RegionPtr borderVisible;
+ DDXPointRec oldAbsCorner;
+} miOverlayValDataRec, *miOverlayValDataPtr;
+
+typedef struct _TreeRec {
+ WindowPtr pWin;
+ struct _TreeRec *parent;
+ struct _TreeRec *firstChild;
+ struct _TreeRec *lastChild;
+ struct _TreeRec *prevSib;
+ struct _TreeRec *nextSib;
+ RegionRec borderClip;
+ RegionRec clipList;
+ unsigned visibility;
+ miOverlayValDataPtr valdata;
+} miOverlayTreeRec, *miOverlayTreePtr;
+
+typedef struct {
+ miOverlayTreePtr tree;
+} miOverlayWindowRec, *miOverlayWindowPtr;
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ RealizeWindowProcPtr RealizeWindow;
+ miOverlayTransFunc MakeTransparent;
+ miOverlayInOverlayFunc InOverlay;
+ Bool underlayMarked;
+ Bool copyUnderlay;
+} miOverlayScreenRec, *miOverlayScreenPtr;
+
+static unsigned long miOverlayGeneration = 0;
+int miOverlayWindowIndex = -1;
+int miOverlayScreenIndex = -1;
+
+static void RebuildTree(WindowPtr);
+static Bool HasUnderlayChildren(WindowPtr);
+static void MarkUnderlayWindow(WindowPtr);
+static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
+
+static Bool miOverlayCloseScreen(ScreenPtr);
+static Bool miOverlayCreateWindow(WindowPtr);
+static Bool miOverlayDestroyWindow(WindowPtr);
+static Bool miOverlayUnrealizeWindow(WindowPtr);
+static Bool miOverlayRealizeWindow(WindowPtr);
+static void miOverlayMarkWindow(WindowPtr);
+static void miOverlayReparentWindow(WindowPtr, WindowPtr);
+static void miOverlayRestackWindow(WindowPtr, WindowPtr);
+static Bool miOverlayMarkOverlappedWindows(WindowPtr, WindowPtr, WindowPtr*);
+static void miOverlayMarkUnrealizedWindow(WindowPtr, WindowPtr, Bool);
+static int miOverlayValidateTree(WindowPtr, WindowPtr, VTKind);
+static void miOverlayHandleExposures(WindowPtr);
+static void miOverlayMoveWindow(WindowPtr, int, int, WindowPtr, VTKind);
+static void miOverlayWindowExposures(WindowPtr, RegionPtr, RegionPtr);
+static void miOverlayResizeWindow(WindowPtr, int, int, unsigned int,
+ unsigned int, WindowPtr);
+static void miOverlayClearToBackground(WindowPtr, int, int, int, int, Bool);
+
+#ifdef SHAPE
+static void miOverlaySetShape(WindowPtr);
+#endif
+static void miOverlayChangeBorderWidth(WindowPtr, unsigned int);
+
+#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) \
+ ((miOverlayScreenPtr)((pScreen)->devPrivates[miOverlayScreenIndex].ptr))
+#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) \
+ ((miOverlayWindowPtr)((pWin)->devPrivates[miOverlayWindowIndex].ptr))
+#define MIOVERLAY_GET_WINDOW_TREE(pWin) \
+ (MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
+
+#define IN_UNDERLAY(w) MIOVERLAY_GET_WINDOW_TREE(w)
+#define IN_OVERLAY(w) !MIOVERLAY_GET_WINDOW_TREE(w)
+
+#define MARK_OVERLAY(w) miMarkWindow(w)
+#define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+ HasBorder(w) && \
+ (w)->backgroundState == ParentRelative)
+
+Bool
+miInitOverlay(
+ ScreenPtr pScreen,
+ miOverlayInOverlayFunc inOverlayFunc,
+ miOverlayTransFunc transFunc
+){
+ miOverlayScreenPtr pScreenPriv;
+
+ if(!inOverlayFunc || !transFunc) return FALSE;
+
+ if(miOverlayGeneration != serverGeneration) {
+ if(((miOverlayScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((miOverlayWindowIndex = AllocateWindowPrivateIndex()) < 0))
+ return FALSE;
+
+ miOverlayGeneration = serverGeneration;
+ }
+
+ if(!AllocateWindowPrivate(pScreen, miOverlayWindowIndex,
+ sizeof(miOverlayWindowRec)))
+ return FALSE;
+
+ if(!(pScreenPriv = malloc(sizeof(miOverlayScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[miOverlayScreenIndex].ptr = (void *)pScreenPriv;
+
+ pScreenPriv->InOverlay = inOverlayFunc;
+ pScreenPriv->MakeTransparent = transFunc;
+ pScreenPriv->underlayMarked = FALSE;
+
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->CreateWindow = pScreen->CreateWindow;
+ pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreenPriv->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreenPriv->RealizeWindow = pScreen->RealizeWindow;
+
+ pScreen->CloseScreen = miOverlayCloseScreen;
+ pScreen->CreateWindow = miOverlayCreateWindow;
+ pScreen->DestroyWindow = miOverlayDestroyWindow;
+ pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+ pScreen->RealizeWindow = miOverlayRealizeWindow;
+
+ pScreen->ReparentWindow = miOverlayReparentWindow;
+ pScreen->RestackWindow = miOverlayRestackWindow;
+ pScreen->MarkOverlappedWindows = miOverlayMarkOverlappedWindows;
+ pScreen->MarkUnrealizedWindow = miOverlayMarkUnrealizedWindow;
+ pScreen->ValidateTree = miOverlayValidateTree;
+ pScreen->HandleExposures = miOverlayHandleExposures;
+ pScreen->MoveWindow = miOverlayMoveWindow;
+ pScreen->WindowExposures = miOverlayWindowExposures;
+ pScreen->ResizeWindow = miOverlayResizeWindow;
+ pScreen->MarkWindow = miOverlayMarkWindow;
+ pScreen->ClearToBackground = miOverlayClearToBackground;
+#ifdef SHAPE
+ pScreen->SetShape = miOverlaySetShape;
+#endif
+ pScreen->ChangeBorderWidth = miOverlayChangeBorderWidth;
+
+ return TRUE;
+}
+
+
+static Bool
+miOverlayCloseScreen(ScreenPtr pScreen)
+{
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreateWindow = pScreenPriv->CreateWindow;
+ pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+ pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+ pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+
+ free(pScreenPriv);
+
+ return (*pScreen->CloseScreen)(pScreen);
+}
+
+
+static Bool
+miOverlayCreateWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ miOverlayWindowPtr pWinPriv = MIOVERLAY_GET_WINDOW_PRIVATE(pWin);
+ miOverlayTreePtr pTree = NULL;
+ Bool result = TRUE;
+
+ pWinPriv->tree = NULL;
+
+ if(!pWin->parent || !((*pScreenPriv->InOverlay)(pWin))) {
+ if(!(pTree = (miOverlayTreePtr)calloc(1, sizeof(miOverlayTreeRec))))
+ return FALSE;
+ }
+
+ if(pScreenPriv->CreateWindow) {
+ pScreen->CreateWindow = pScreenPriv->CreateWindow;
+ result = (*pScreen->CreateWindow)(pWin);
+ pScreen->CreateWindow = miOverlayCreateWindow;
+ }
+
+ if (pTree) {
+ if(result) {
+ pTree->pWin = pWin;
+ pTree->visibility = VisibilityNotViewable;
+ pWinPriv->tree = pTree;
+ if(pWin->parent) {
+ RegionNull(&(pTree->borderClip));
+ RegionNull(&(pTree->clipList));
+ RebuildTree(pWin);
+ } else {
+ BoxRec fullBox;
+ fullBox.x1 = 0;
+ fullBox.y1 = 0;
+ fullBox.x2 = pScreen->width;
+ fullBox.y2 = pScreen->height;
+ RegionInit(&(pTree->borderClip), &fullBox, 1);
+ RegionInit(&(pTree->clipList), &fullBox, 1);
+ }
+ } else free(pTree);
+ }
+
+ return TRUE;
+}
+
+
+static Bool
+miOverlayDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ Bool result = TRUE;
+
+ if (pTree) {
+ if(pTree->prevSib)
+ pTree->prevSib->nextSib = pTree->nextSib;
+ else if(pTree->parent)
+ pTree->parent->firstChild = pTree->nextSib;
+
+ if(pTree->nextSib)
+ pTree->nextSib->prevSib = pTree->prevSib;
+ else if(pTree->parent)
+ pTree->parent->lastChild = pTree->prevSib;
+
+ RegionUninit(&(pTree->borderClip));
+ RegionUninit(&(pTree->clipList));
+ free(pTree);
+ }
+
+ if(pScreenPriv->DestroyWindow) {
+ pScreen->DestroyWindow = pScreenPriv->DestroyWindow;
+ result = (*pScreen->DestroyWindow)(pWin);
+ pScreen->DestroyWindow = miOverlayDestroyWindow;
+ }
+
+ return result;
+}
+
+static Bool
+miOverlayUnrealizeWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ Bool result = TRUE;
+
+ if(pTree) pTree->visibility = VisibilityNotViewable;
+
+ if(pScreenPriv->UnrealizeWindow) {
+ pScreen->UnrealizeWindow = pScreenPriv->UnrealizeWindow;
+ result = (*pScreen->UnrealizeWindow)(pWin);
+ pScreen->UnrealizeWindow = miOverlayUnrealizeWindow;
+ }
+
+ return result;
+}
+
+
+static Bool
+miOverlayRealizeWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ Bool result = TRUE;
+
+ if(pScreenPriv->RealizeWindow) {
+ pScreen->RealizeWindow = pScreenPriv->RealizeWindow;
+ result = (*pScreen->RealizeWindow)(pWin);
+ pScreen->RealizeWindow = miOverlayRealizeWindow;
+ }
+
+ /* we only need to catch the root window realization */
+
+ if(result && !pWin->parent && !((*pScreenPriv->InOverlay)(pWin)))
+ {
+ BoxRec box;
+ box.x1 = box.y1 = 0;
+ box.x2 = pWin->drawable.width;
+ box.y2 = pWin->drawable.height;
+ (*pScreenPriv->MakeTransparent)(pScreen, 1, &box);
+ }
+
+ return result;
+}
+
+
+static void
+miOverlayReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
+{
+ if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+ /* This could probably be more optimal */
+ RebuildTree(pWin->drawable.pScreen->root->firstChild);
+ }
+}
+
+static void
+miOverlayRestackWindow(WindowPtr pWin, WindowPtr oldNextSib)
+{
+ if(IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin)) {
+ /* This could probably be more optimal */
+ RebuildTree(pWin);
+ }
+}
+
+
+static Bool
+miOverlayMarkOverlappedWindows(
+ WindowPtr pWin,
+ WindowPtr pFirst,
+ WindowPtr *pLayerWin
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pChild, pLast;
+ Bool overMarked, underMarked, doUnderlay, markAll;
+ miOverlayTreePtr pTree = NULL, tLast, tChild;
+ BoxPtr box;
+
+ overMarked = underMarked = markAll = FALSE;
+
+ if(pLayerWin) *pLayerWin = pWin; /* hah! */
+
+ doUnderlay = (IN_UNDERLAY(pWin) || HasUnderlayChildren(pWin));
+
+ box = RegionExtents(&pWin->borderSize);
+
+ if((pChild = pFirst)) {
+ pLast = pChild->parent->lastChild;
+ while (1) {
+ if (pChild == pWin) markAll = TRUE;
+
+ if(doUnderlay && IN_UNDERLAY(pChild))
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+ if(pChild->viewable) {
+ if (RegionBroken(&pChild->winSize))
+ SetWinSize (pChild);
+ if (RegionBroken(&pChild->borderSize))
+ SetBorderSize (pChild);
+
+ if (markAll ||
+ RegionContainsRect(&pChild->borderSize, box))
+ {
+ MARK_OVERLAY(pChild);
+ overMarked = TRUE;
+ if(doUnderlay && IN_UNDERLAY(pChild)) {
+ MARK_UNDERLAY(pChild);
+ underMarked = TRUE;
+ }
+ if (pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast)) {
+ pChild = pChild->parent;
+ if(doUnderlay && IN_UNDERLAY(pChild))
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+ }
+
+ if(pChild == pWin) markAll = FALSE;
+
+ if (pChild == pLast) break;
+
+ pChild = pChild->nextSib;
+ }
+ if(overMarked)
+ MARK_OVERLAY(pWin->parent);
+ }
+
+ if(doUnderlay && !pTree) {
+ if(!(pTree = MIOVERLAY_GET_WINDOW_TREE(pWin))) {
+ pChild = pWin->lastChild;
+ while(1) {
+ if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild)))
+ break;
+
+ if(pChild->lastChild) {
+ pChild = pChild->lastChild;
+ continue;
+ }
+
+ while(!pChild->prevSib) pChild = pChild->parent;
+
+ pChild = pChild->prevSib;
+ }
+ }
+ }
+
+ if(pTree && pTree->nextSib) {
+ tChild = pTree->parent->lastChild;
+ tLast = pTree->nextSib;
+
+ while(1) {
+ if(tChild->pWin->viewable) {
+ if (RegionBroken(&tChild->pWin->winSize))
+ SetWinSize (tChild->pWin);
+ if (RegionBroken(&tChild->pWin->borderSize))
+ SetBorderSize (tChild->pWin);
+
+ if(RegionContainsRect(&(tChild->pWin->borderSize), box))
+ {
+ MARK_UNDERLAY(tChild->pWin);
+ underMarked = TRUE;
+ }
+ }
+
+ if(tChild->lastChild) {
+ tChild = tChild->lastChild;
+ continue;
+ }
+
+ while(!tChild->prevSib && (tChild != tLast))
+ tChild = tChild->parent;
+
+ if(tChild == tLast) break;
+
+ tChild = tChild->prevSib;
+ }
+ }
+
+ if(underMarked) {
+ MARK_UNDERLAY(pTree->parent->pWin);
+ MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->underlayMarked = TRUE;
+ }
+
+ return (underMarked || overMarked);
+}
+
+
+static void
+miOverlayComputeClips(
+ WindowPtr pParent,
+ RegionPtr universe,
+ VTKind kind,
+ RegionPtr exposed
+){
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ int oldVis, newVis, dx, dy;
+ BoxRec borderSize;
+ RegionPtr borderVisible;
+ RegionRec childUniverse, childUnion;
+ miOverlayTreePtr tParent = MIOVERLAY_GET_WINDOW_TREE(pParent);
+ miOverlayTreePtr tChild;
+ Bool overlap;
+
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width +
+ wBorderWidth(pParent);
+ if (dx > 32767) dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height +
+ wBorderWidth(pParent);
+ if (dy > 32767) dy = 32767;
+ borderSize.y2 = dy;
+
+ oldVis = tParent->visibility;
+ switch (RegionContainsRect(universe, &borderSize)) {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent))) {
+ switch (miShapedWindowIn (pScreen, universe, pBounding,
+ &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ tParent->visibility = newVis;
+
+ dx = pParent->drawable.x - tParent->valdata->oldAbsCorner.x;
+ dy = pParent->drawable.y - tParent->valdata->oldAbsCorner.y;
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ tChild = tParent;
+ while (1) {
+ if (tChild->pWin->viewable) {
+ if (tChild->visibility != VisibilityFullyObscured) {
+ RegionTranslate(&tChild->borderClip, dx, dy);
+ RegionTranslate(&tChild->clipList, dx, dy);
+
+ tChild->pWin->drawable.serialNumber =
+ NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (tChild->pWin, dx, dy);
+ }
+ if (tChild->valdata) {
+ RegionNull(&tChild->valdata->borderExposed);
+ if (HasParentRelativeBorder(tChild->pWin)){
+ RegionSubtract(
+ &tChild->valdata->borderExposed,
+ &tChild->borderClip,
+ &tChild->pWin->winSize);
+ }
+ RegionNull(&tChild->valdata->exposed);
+ }
+ if (tChild->firstChild) {
+ tChild = tChild->firstChild;
+ continue;
+ }
+ }
+ while (!tChild->nextSib && (tChild != tParent))
+ tChild = tChild->parent;
+ if (tChild == tParent)
+ break;
+ tChild = tChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ if (dx || dy) {
+ RegionTranslate(&tParent->borderClip, dx, dy);
+ RegionTranslate(&tParent->clipList, dx, dy);
+ }
+ break;
+ case VTBroken:
+ RegionEmpty(&tParent->borderClip);
+ RegionEmpty(&tParent->clipList);
+ break;
+ }
+
+ borderVisible = tParent->valdata->borderVisible;
+ RegionNull(&tParent->valdata->borderExposed);
+ RegionNull(&tParent->valdata->exposed);
+
+ if (HasBorder (pParent)) {
+ if (borderVisible) {
+ RegionSubtract(exposed, universe, borderVisible);
+ RegionDestroy(borderVisible);
+ } else
+ RegionSubtract(exposed, universe, &tParent->borderClip);
+
+ if (HasParentRelativeBorder(pParent) && (dx || dy))
+ RegionSubtract(&tParent->valdata->borderExposed,
+ universe, &pParent->winSize);
+ else
+ RegionSubtract(&tParent->valdata->borderExposed,
+ exposed, &pParent->winSize);
+
+ RegionCopy(&tParent->borderClip, universe);
+ RegionIntersect(universe, universe, &pParent->winSize);
+ }
+ else
+ RegionCopy(&tParent->borderClip, universe);
+
+ if ((tChild = tParent->firstChild) && pParent->mapped) {
+ RegionNull(&childUniverse);
+ RegionNull(&childUnion);
+
+ for (; tChild; tChild = tChild->nextSib) {
+ if (tChild->pWin->viewable)
+ RegionAppend(&childUnion, &tChild->pWin->borderSize);
+ }
+
+ RegionValidate(&childUnion, &overlap);
+
+ for (tChild = tParent->firstChild;
+ tChild;
+ tChild = tChild->nextSib)
+ {
+ if (tChild->pWin->viewable) {
+ if (tChild->valdata) {
+ RegionIntersect(&childUniverse, universe,
+ &tChild->pWin->borderSize);
+ miOverlayComputeClips (tChild->pWin, &childUniverse,
+ kind, exposed);
+ }
+ if (overlap)
+ RegionSubtract(universe, universe,
+ &tChild->pWin->borderSize);
+ }
+ }
+ if (!overlap)
+ RegionSubtract(universe, universe, &childUnion);
+ RegionUninit(&childUnion);
+ RegionUninit(&childUniverse);
+ }
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ RegionCopy(&tParent->valdata->exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ RegionSubtract(&tParent->valdata->exposed,
+ universe, &tParent->clipList);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = tParent->clipList;
+ tParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+
+static void
+miOverlayMarkWindow(WindowPtr pWin)
+{
+ miOverlayTreePtr pTree = NULL;
+ WindowPtr pChild, pGrandChild;
+
+ miMarkWindow(pWin);
+
+ /* look for UnmapValdata among immediate children */
+
+ if(!(pChild = pWin->firstChild)) return;
+
+ for( ; pChild; pChild = pChild->nextSib) {
+ if(pChild->valdata == UnmapValData) {
+ if(IN_UNDERLAY(pChild)) {
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+ pTree->valdata = (miOverlayValDataPtr)UnmapValData;
+ continue;
+ } else {
+ if(!(pGrandChild = pChild->firstChild))
+ continue;
+
+ while(1) {
+ if(IN_UNDERLAY(pGrandChild)) {
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pGrandChild);
+ pTree->valdata = (miOverlayValDataPtr)UnmapValData;
+ } else if(pGrandChild->firstChild) {
+ pGrandChild = pGrandChild->firstChild;
+ continue;
+ }
+
+ while(!pGrandChild->nextSib && (pGrandChild != pChild))
+ pGrandChild = pGrandChild->parent;
+
+ if(pChild == pGrandChild) break;
+
+ pGrandChild = pGrandChild->nextSib;
+ }
+ }
+ }
+ }
+
+ if(pTree) {
+ MARK_UNDERLAY(pTree->parent->pWin);
+ MIOVERLAY_GET_SCREEN_PRIVATE(
+ pWin->drawable.pScreen)->underlayMarked = TRUE;
+ }
+}
+
+static void
+miOverlayMarkUnrealizedWindow(
+ WindowPtr pChild,
+ WindowPtr pWin,
+ Bool fromConfigure
+){
+ if ((pChild != pWin) || fromConfigure) {
+ miOverlayTreePtr pTree;
+
+ RegionEmpty(&pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ RegionEmpty(&pChild->borderClip);
+ if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+ if(pTree->valdata != (miOverlayValDataPtr)UnmapValData) {
+ RegionEmpty(&pTree->clipList);
+ RegionEmpty(&pTree->borderClip);
+ }
+ }
+ }
+}
+
+
+static int
+miOverlayValidateTree(
+ WindowPtr pParent,
+ WindowPtr pChild, /* first child effected */
+ VTKind kind
+){
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ RegionRec totalClip, childClip, exposed;
+ miOverlayTreePtr tParent, tChild, tWin;
+ Bool overlap;
+ WindowPtr newParent;
+
+ if(!pPriv->underlayMarked)
+ goto SKIP_UNDERLAY;
+
+ if (!pChild) pChild = pParent->firstChild;
+
+ RegionNull(&totalClip);
+ RegionNull(&childClip);
+ RegionNull(&exposed);
+
+ newParent = pParent;
+
+ while(IN_OVERLAY(newParent))
+ newParent = newParent->parent;
+
+ tParent = MIOVERLAY_GET_WINDOW_TREE(newParent);
+
+ if(IN_UNDERLAY(pChild))
+ tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+ else
+ tChild = tParent->firstChild;
+
+ if (RegionBroken(&tParent->clipList) &&
+ !RegionBroken(&tParent->borderClip))
+ {
+ kind = VTBroken;
+ RegionCopy(&totalClip, &tParent->borderClip);
+ RegionIntersect(&totalClip, &totalClip,
+ &tParent->pWin->winSize);
+
+ for (tWin = tParent->firstChild; tWin != tChild; tWin = tWin->nextSib) {
+ if (tWin->pWin->viewable)
+ RegionSubtract(&totalClip, &totalClip,
+ &tWin->pWin->borderSize);
+ }
+ RegionEmpty(&tParent->clipList);
+ } else {
+ for(tWin = tChild; tWin; tWin = tWin->nextSib) {
+ if(tWin->valdata)
+ RegionAppend(&totalClip, &tWin->borderClip);
+ }
+ RegionValidate(&totalClip, &overlap);
+ }
+
+ if(kind != VTStack)
+ RegionUnion(&totalClip, &totalClip, &tParent->clipList);
+
+ for(tWin = tChild; tWin; tWin = tWin->nextSib) {
+ if(tWin->valdata) {
+ if(tWin->pWin->viewable) {
+ RegionIntersect(&childClip, &totalClip,
+ &tWin->pWin->borderSize);
+ miOverlayComputeClips(tWin->pWin, &childClip, kind, &exposed);
+ RegionSubtract(&totalClip, &totalClip,
+ &tWin->pWin->borderSize);
+ } else { /* Means we are unmapping */
+ RegionEmpty(&tWin->clipList);
+ RegionEmpty(&tWin->borderClip);
+ tWin->valdata = NULL;
+ }
+ }
+ }
+
+ RegionUninit(&childClip);
+
+ if(!((*pPriv->InOverlay)(newParent))) {
+ RegionNull(&tParent->valdata->exposed);
+ RegionNull(&tParent->valdata->borderExposed);
+ }
+
+ switch (kind) {
+ case VTStack:
+ break;
+ default:
+ if(!((*pPriv->InOverlay)(newParent)))
+ RegionSubtract(&tParent->valdata->exposed, &totalClip,
+ &tParent->clipList);
+ /* fall through */
+ case VTMap:
+ RegionCopy(&tParent->clipList, &totalClip);
+ if(!((*pPriv->InOverlay)(newParent)))
+ newParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ break;
+ }
+
+ RegionUninit(&totalClip);
+ RegionUninit(&exposed);
+
+SKIP_UNDERLAY:
+
+ miValidateTree(pParent, pChild, kind);
+
+ return 1;
+}
+
+
+static void
+miOverlayHandleExposures(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ WindowPtr pChild;
+ ValidatePtr val;
+ void (* WindowExposures)(WindowPtr, RegionPtr, RegionPtr);
+
+ WindowExposures = pWin->drawable.pScreen->WindowExposures;
+ if(pPriv->underlayMarked) {
+ miOverlayTreePtr pTree;
+ miOverlayValDataPtr mival;
+
+ pChild = pWin;
+ while(IN_OVERLAY(pChild))
+ pChild = pChild->parent;
+
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pChild);
+
+ while (1) {
+ if((mival = pTree->valdata)) {
+ if(!((*pPriv->InOverlay)(pTree->pWin))) {
+ if (RegionNotEmpty(&mival->borderExposed))
+ (*pWin->drawable.pScreen->PaintWindowBorder)(
+ pTree->pWin, &mival->borderExposed, PW_BORDER);
+ RegionUninit(&mival->borderExposed);
+
+ (*WindowExposures)(pTree->pWin,&mival->exposed,NullRegion);
+ RegionUninit(&mival->exposed);
+ }
+ free(mival);
+ pTree->valdata = NULL;
+ if (pTree->firstChild) {
+ pTree = pTree->firstChild;
+ continue;
+ }
+ }
+ while (!pTree->nextSib && (pTree->pWin != pChild))
+ pTree = pTree->parent;
+ if (pTree->pWin == pChild)
+ break;
+ pTree = pTree->nextSib;
+ }
+ pPriv->underlayMarked = FALSE;
+ }
+
+ pChild = pWin;
+ while (1) {
+ if ( (val = pChild->valdata) ) {
+ if(!((*pPriv->InOverlay)(pChild))) {
+ RegionUnion(&val->after.exposed, &val->after.exposed,
+ &val->after.borderExposed);
+
+ if (RegionNotEmpty(&val->after.exposed)) {
+ (*(MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent))(
+ pScreen,
+ RegionNumRects(&val->after.exposed),
+ RegionRects(&val->after.exposed));
+ }
+ } else {
+ if (RegionNotEmpty(&val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ }
+ RegionUninit(&val->after.borderExposed);
+ RegionUninit(&val->after.exposed);
+ free(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+
+static void
+miOverlayMoveWindow(
+ WindowPtr pWin,
+ int x,
+ int y,
+ WindowPtr pNextSib,
+ VTKind kind
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ WindowPtr pParent, windowToValidate;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionRec overReg, underReg;
+ DDXPointRec oldpt;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+
+ if (!(pParent = pWin->parent))
+ return ;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable) {
+ RegionNull(&overReg);
+ RegionNull(&underReg);
+ if(pTree) {
+ RegionCopy(&overReg, &pWin->borderClip);
+ RegionCopy(&underReg, &pTree->borderClip);
+ } else {
+ RegionCopy(&overReg, &pWin->borderClip);
+ CollectUnderlayChildrenRegions(pWin, &underReg);
+ }
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable) {
+ miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ (*pScreen->MarkOverlappedWindows) (pWin, windowToValidate, NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ dosave = (*pScreen->ChangeSaveUnder)(pWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+
+ (*pScreen->ValidateTree)(pWin->parent, NullWindow, kind);
+ if(RegionNotEmpty(&underReg)) {
+ pPriv->copyUnderlay = TRUE;
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &underReg);
+ }
+ RegionUninit(&underReg);
+ if(RegionNotEmpty(&overReg)) {
+ pPriv->copyUnderlay = FALSE;
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, &overReg);
+ }
+ RegionUninit(&overReg);
+ (*pScreen->HandleExposures)(pWin->parent);
+
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25
+#endif
+
+static void
+miOverlayWindowExposures(
+ WindowPtr pWin,
+ register RegionPtr prgn,
+ RegionPtr other_exposed
+){
+ RegionPtr exposures = prgn;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (pWin->backStorage && prgn)
+ exposures = (*pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !RegionNil(prgn)) ||
+ (exposures && !RegionNil(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) &
+ ExposureMask;
+ if (other_exposed) {
+ if (exposures) {
+ RegionUnion(other_exposed, exposures, other_exposed);
+ if (exposures != prgn)
+ RegionDestroy(exposures);
+ }
+ exposures = other_exposed;
+ }
+ if (clientInterested && exposures &&
+ (RegionNumRects(exposures) > RECTLIMIT))
+ {
+ miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ BoxRec box;
+
+ box = *RegionExtents(exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ RegionInit(exposures, &box, 1);
+ RegionReset(prgn, &box);
+ } else {
+ RegionReset(exposures, &box);
+ RegionUnion(prgn, prgn, exposures);
+ }
+ /* This is the only reason why we are replacing mi's version
+ of this file */
+
+ if(!((*pPriv->InOverlay)(pWin))) {
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ RegionIntersect(prgn, prgn, &pTree->clipList);
+ } else
+ RegionIntersect(prgn, prgn, &pWin->clipList);
+
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (*pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !RegionNil(prgn))
+ (*pScreen->PaintWindowBackground)(
+ pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !RegionNil(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec) {
+ RegionUninit(exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ RegionDestroy(exposures);
+ if (prgn)
+ RegionEmpty(prgn);
+ }
+ else if (exposures && exposures != prgn)
+ RegionDestroy(exposures);
+}
+
+
+typedef struct {
+ RegionPtr over;
+ RegionPtr under;
+} miOverlayTwoRegions;
+
+static int
+miOverlayRecomputeExposures (
+ WindowPtr pWin,
+ void * value
+){
+ register ScreenPtr pScreen;
+ miOverlayTwoRegions *pValid = (miOverlayTwoRegions*)value;
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ /* This prevents warning about pScreen not being used. */
+ pWin->drawable.pScreen = pScreen = pWin->drawable.pScreen;
+
+ if (pWin->valdata) {
+ /*
+ * compute exposed regions of this window
+ */
+ RegionSubtract(&pWin->valdata->after.exposed,
+ &pWin->clipList, pValid->over);
+ /*
+ * compute exposed regions of the border
+ */
+ RegionSubtract(&pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ RegionSubtract(&pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid->over);
+ }
+
+ if(pTree && pTree->valdata) {
+ RegionSubtract(&pTree->valdata->exposed,
+ &pTree->clipList, pValid->under);
+ RegionSubtract(&pTree->valdata->borderExposed,
+ &pTree->borderClip, &pWin->winSize);
+ RegionSubtract(&pTree->valdata->borderExposed,
+ &pTree->valdata->borderExposed, pValid->under);
+ } else if (!pWin->valdata)
+ return WT_NOMATCH;
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+miOverlayResizeWindow(
+ WindowPtr pWin,
+ int x, int y,
+ unsigned int w, unsigned int h,
+ WindowPtr pSib
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent;
+ miOverlayTreePtr tChild, pTree;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width;
+ unsigned short height = pWin->drawable.height;
+ short oldx = pWin->drawable.x;
+ short oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion = NULL, oldRegion2 = NULL;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ RegionPtr gravitate2[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion = NULL;
+ RegionPtr destClip, destClip2;
+ RegionPtr oldWinClip = NULL, oldWinClip2 = NULL;
+ RegionPtr borderVisible = NullRegion;
+ RegionPtr borderVisible2 = NullRegion;
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ Bool doUnderlay;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ doUnderlay = ((pTree) || HasUnderlayChildren(pWin));
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = RegionCreate(NullBox, 1);
+ RegionCopy(oldRegion, &pWin->winSize);
+ if(doUnderlay) {
+ oldRegion2 = RegionCreate(NullBox, 1);
+ RegionCopy(oldRegion2, &pWin->winSize);
+ }
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = gravitate2[g] = NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+ g = pChild->winGravity;
+ if (g != UnmapGravity) {
+ if (!gravitate[g])
+ gravitate[g] = RegionCreate(NullBox, 1);
+ RegionUnion(gravitate[g],
+ gravitate[g], &pChild->borderClip);
+
+ if(doUnderlay) {
+ if (!gravitate2[g])
+ gravitate2[g] = RegionCreate(NullBox, 0);
+
+ if((tChild = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+ RegionUnion(gravitate2[g],
+ gravitate2[g], &tChild->borderClip);
+ } else
+ CollectUnderlayChildrenRegions(pChild, gravitate2[g]);
+ }
+ } else {
+ UnmapWindow(pChild, TRUE);
+ }
+ }
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+
+ oldWinClip = oldWinClip2 = NULL;
+ if (pWin->bitGravity != ForgetGravity) {
+ oldWinClip = RegionCreate(NullBox, 1);
+ RegionCopy(oldWinClip, &pWin->clipList);
+ if(pTree) {
+ oldWinClip2 = RegionCreate(NullBox, 1);
+ RegionCopy(oldWinClip2, &pTree->clipList);
+ }
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = RegionCreate(NullBox, 1);
+ if(pTree)
+ borderVisible2 = RegionCreate(NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ RegionSubtract(borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ RegionCopy(borderVisible,
+ &pWin->borderClip);
+ if(pTree) {
+ if (shrunk || moved)
+ RegionSubtract(borderVisible,
+ &pTree->borderClip,
+ &pWin->winSize);
+ else
+ RegionCopy(borderVisible,
+ &pTree->borderClip);
+ }
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable) {
+ pRegion = RegionCreate(NullBox, 1);
+ if (pWin->backStorage)
+ RegionCopy(pRegion, &pWin->clipList);
+
+ (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange, NULL);
+
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ if(pTree)
+ pTree->valdata->borderVisible = borderVisible2;
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ dosave = (*pScreen->ChangeSaveUnder)(pWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+
+ (*pScreen->ValidateTree)(pWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
+ if(pTree)
+ RegionCopy(&pTree->valdata->exposed, &pTree->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+
+ if (WasViewable) {
+ miOverlayScreenPtr pPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ miOverlayTwoRegions TwoRegions;
+
+ /* avoid the border */
+ if (HasBorder (pWin)) {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++) {
+ if (!gravitate[g] && !gravitate2[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy) {
+ RegionTranslate(&pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ if(gravitate[g])
+ RegionIntersect(gravitate[g], gravitate[g],
+ &pWin->winSize);
+ if(gravitate2[g])
+ RegionIntersect(gravitate2[g], gravitate2[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ RegionTranslate(&pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip2)
+ {
+ RegionCopy(pRegion, oldWinClip2);
+ RegionTranslate(pRegion, nx - oldx, ny - oldy);
+ RegionIntersect(oldWinClip2, pRegion, &pTree->clipList);
+
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+ if (gravitate2[g])
+ RegionSubtract(oldWinClip2, oldWinClip2,
+ gravitate2[g]);
+ }
+ RegionTranslate(oldWinClip2, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate2[g])
+ gravitate2[g] = oldWinClip2;
+ else {
+ RegionUnion(gravitate2[g],gravitate2[g],oldWinClip2);
+ RegionDestroy(oldWinClip2);
+ }
+ }
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ RegionCopy(pRegion, oldWinClip);
+ RegionTranslate(pRegion, nx - oldx, ny - oldy);
+ RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++) {
+ if (gravitate[g])
+ RegionSubtract(oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else {
+ RegionUnion(gravitate[g], gravitate[g], oldWinClip);
+ RegionDestroy(oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = destClip2 = NULL;
+
+ for (g = 0; g <= StaticGravity; g++) {
+ if (!gravitate[g] && !gravitate2[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ if(gravitate[g])
+ RegionIntersect(gravitate[g],
+ gravitate[g], oldRegion);
+ if(gravitate2[g])
+ RegionIntersect(gravitate2[g],
+ gravitate2[g], oldRegion2);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip && gravitate[g]) {
+ RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
+ RegionSubtract(gravitate[g], gravitate[g], destClip);
+ RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
+ }
+ if (destClip2 && gravitate2[g]) {
+ RegionTranslate(destClip2, oldpt.x - x, oldpt.y - y);
+ RegionSubtract(gravitate2[g],gravitate2[g],destClip2);
+ RegionTranslate(destClip2, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y) {
+ if(gravitate2[g]) {
+ pPriv->copyUnderlay = TRUE;
+ (*pWin->drawable.pScreen->CopyWindow)(
+ pWin, oldpt, gravitate2[g]);
+ }
+ if(gravitate[g]) {
+ pPriv->copyUnderlay = FALSE;
+ (*pWin->drawable.pScreen->CopyWindow)(
+ pWin, oldpt, gravitate[g]);
+ }
+ }
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ if(gravitate[g])
+ RegionSubtract(oldRegion, oldRegion, gravitate[g]);
+ if(gravitate2[g])
+ RegionSubtract(oldRegion2, oldRegion2, gravitate2[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+ if (pChild->winGravity != g)
+ continue;
+
+ TwoRegions.over = gravitate[g];
+ TwoRegions.under = gravitate2[g];
+
+ TraverseTree (pChild, miOverlayRecomputeExposures,
+ (void *)(&TwoRegions));
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity) {
+ if(gravitate[g])
+ RegionSubtract(&pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if(gravitate2[g] && pTree)
+ RegionSubtract(&pTree->valdata->exposed,
+ &pTree->valdata->exposed, gravitate2[g]);
+ }
+ if(gravitate[g]) {
+ if (!destClip)
+ destClip = gravitate[g];
+ else {
+ RegionUnion(destClip, destClip, gravitate[g]);
+ RegionDestroy(gravitate[g]);
+ }
+ }
+ if(gravitate2[g]) {
+ if (!destClip2)
+ destClip2 = gravitate2[g];
+ else {
+ RegionUnion(destClip2, destClip2, gravitate2[g]);
+ RegionDestroy(gravitate2[g]);
+ }
+ }
+ }
+
+ RegionDestroy(pRegion);
+ RegionDestroy(oldRegion);
+ if(doUnderlay)
+ RegionDestroy(oldRegion2);
+ if (destClip)
+ RegionDestroy(destClip);
+ if (destClip2)
+ RegionDestroy(destClip2);
+ if (bsExposed) {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ RegionEmpty(valExposed);
+ RegionDestroy(bsExposed);
+ }
+ (*pScreen->HandleExposures)(pWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin->parent, pFirstChange, VTOther);
+ }
+ else if (bsExposed) {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ RegionDestroy(bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+#ifdef SHAPE
+static void
+miOverlaySetShape(WindowPtr pWin)
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+
+ if (WasViewable) {
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+ if (HasBorder (pWin)) {
+ RegionPtr borderVisible;
+
+ borderVisible = RegionCreate(NullBox, 1);
+ RegionSubtract(borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ pWin->valdata->before.resized = TRUE;
+ if(IN_UNDERLAY(pWin)) {
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ RegionPtr borderVisible2;
+
+ borderVisible2 = RegionCreate(NULL, 1);
+ RegionSubtract(borderVisible2,
+ &pTree->borderClip, &pWin->winSize);
+ pTree->valdata->borderVisible = borderVisible2;
+ }
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable) {
+ if (pWin->backStorage) {
+ pOldClip = RegionCreate(NullBox, 1);
+ RegionCopy(pOldClip, &pWin->clipList);
+ }
+
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin);
+#endif /* DO_SAVE_UNDERS */
+
+ (*pScreen->ValidateTree)(pWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage && ((pWin->backingStore == Always) || WasViewable)) {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ RegionDestroy(pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ RegionEmpty(valExposed);
+ RegionDestroy(bsExposed);
+ }
+ }
+ if (WasViewable) {
+ (*pScreen->HandleExposures)(pWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pWin, pWin);
+#endif /* DO_SAVE_UNDERS */
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+
+
+static void
+miOverlayChangeBorderWidth(
+ WindowPtr pWin,
+ unsigned int width
+){
+ int oldwidth;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ if (WasViewable && (width < oldwidth))
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable) {
+ if (width > oldwidth) {
+ (*pScreen->MarkOverlappedWindows)(pWin, pWin, NULL);
+
+ if (HadBorder) {
+ RegionPtr borderVisible;
+ borderVisible = RegionCreate(NULL, 1);
+ RegionSubtract(borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ if(IN_UNDERLAY(pWin)) {
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ RegionPtr borderVisible2;
+
+ borderVisible2 = RegionCreate(NULL, 1);
+ RegionSubtract(borderVisible2,
+ &pTree->borderClip, &pWin->winSize);
+ pTree->valdata->borderVisible = borderVisible2;
+ }
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ dosave = (*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ (*pScreen->ValidateTree)(pWin->parent, pWin, VTOther);
+ (*pScreen->HandleExposures)(pWin->parent);
+
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin->parent, pWin, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+/* We need this as an addition since the xf86 common code doesn't
+ know about the second tree which is static to this file. */
+
+void
+miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
+{
+ WindowPtr pRoot = pScreen->root;
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
+
+ MARK_UNDERLAY(pRoot);
+
+ if(enable) {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+
+ RegionReset(&pTree->borderClip, &box);
+ } else
+ RegionEmpty(&pTree->borderClip);
+
+ RegionBreak(&pTree->clipList);
+}
+
+static void
+miOverlayClearToBackground(
+ WindowPtr pWin,
+ int x, int y,
+ int w, int h,
+ Bool generateExposures
+)
+{
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ miOverlayScreenPtr pScreenPriv = MIOVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ RegionPtr clipList;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ clipList = ((*pScreenPriv->InOverlay)(pWin)) ? &pWin->clipList :
+ &pTree->clipList;
+
+ extents = RegionExtents(clipList);
+
+ if (x1 < extents->x1) x1 = extents->x1;
+ if (x2 > extents->x2) x2 = extents->x2;
+ if (y1 < extents->y1) y1 = extents->y1;
+ if (y2 > extents->y2) y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ x2 = x1 = y2 = y1 = 0;
+
+ box.x1 = x1; box.x2 = x2;
+ box.y1 = y1; box.y2 = y2;
+
+ RegionInit(&reg, &box, 1);
+ if (pWin->backStorage) {
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ RegionIntersect(&reg, &reg, clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ RegionUninit(&reg);
+ if (pBSReg)
+ RegionDestroy(pBSReg);
+}
+
+
+/****************************************************************/
+
+/* not used */
+Bool
+miOverlayGetPrivateClips(
+ WindowPtr pWin,
+ RegionPtr *borderClip,
+ RegionPtr *clipList
+){
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ if(pTree) {
+ *borderClip = &(pTree->borderClip);
+ *clipList = &(pTree->clipList);
+ return TRUE;
+ }
+
+ *borderClip = *clipList = NULL;
+
+ return FALSE;
+}
+
+void
+miOverlaySetTransFunction (
+ ScreenPtr pScreen,
+ miOverlayTransFunc transFunc
+){
+ MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
+}
+
+Bool
+miOverlayCopyUnderlay(ScreenPtr pScreen)
+{
+ return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
+}
+
+void
+miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if(!pTree) {
+ miComputeCompositeClip(pGC, &pWin->drawable);
+ return;
+ }
+
+ if (pGC->subWindowMode == IncludeInferiors) {
+ pregWin = RegionCreate(NullBox, 1);
+ freeTmpClip = TRUE;
+ if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
+ !HasSaverWindow (pScreen->myNum))
+ {
+ RegionIntersect(pregWin,&pTree->borderClip,&pWin->winSize);
+ }
+ } else {
+ pregWin = &pTree->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+ if (pGC->clientClipType == CT_NONE) {
+ if (freeCompClip)
+ RegionDestroy(pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ } else {
+ RegionTranslate(pGC->clientClip,
+ pWin->drawable.x + pGC->clipOrg.x,
+ pWin->drawable.y + pGC->clipOrg.y);
+
+ if (freeCompClip) {
+ RegionIntersect(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ if (freeTmpClip)
+ RegionDestroy(pregWin);
+ } else if (freeTmpClip) {
+ RegionIntersect(pregWin, pregWin, pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ } else {
+ pGC->pCompositeClip = RegionCreate(NullBox, 0);
+ RegionIntersect(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ RegionTranslate(pGC->clientClip,
+ -(pWin->drawable.x + pGC->clipOrg.x),
+ -(pWin->drawable.y + pGC->clipOrg.y));
+ }
+}
+
+Bool
+miOverlayCollectUnderlayRegions(
+ WindowPtr pWin,
+ RegionPtr *region
+){
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ if(pTree) {
+ *region = &pTree->borderClip;
+ return FALSE;
+ }
+
+ *region = RegionCreate(NullBox, 0);
+
+ CollectUnderlayChildrenRegions(pWin, *region);
+
+ return TRUE;
+}
+
+
+static miOverlayTreePtr
+DoLeaf(
+ WindowPtr pWin,
+ miOverlayTreePtr parent,
+ miOverlayTreePtr prevSib
+){
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ pTree->parent = parent;
+ pTree->firstChild = NULL;
+ pTree->lastChild = NULL;
+ pTree->prevSib = prevSib;
+ pTree->nextSib = NULL;
+
+ if(prevSib)
+ prevSib->nextSib = pTree;
+
+ if(!parent->firstChild)
+ parent->firstChild = parent->lastChild = pTree;
+ else if(parent->lastChild == prevSib)
+ parent->lastChild = pTree;
+
+ return pTree;
+}
+
+static void
+RebuildTree(WindowPtr pWin)
+{
+ miOverlayTreePtr parent, prevSib, tChild;
+ WindowPtr pChild;
+
+ prevSib = tChild = NULL;
+
+ pWin = pWin->parent;
+
+ while(IN_OVERLAY(pWin))
+ pWin = pWin->parent;
+
+ parent = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ pChild = pWin->firstChild;
+ parent->firstChild = parent->lastChild = NULL;
+
+ while(1) {
+ if(IN_UNDERLAY(pChild))
+ prevSib = tChild = DoLeaf(pChild, parent, prevSib);
+
+ if(pChild->firstChild) {
+ if(IN_UNDERLAY(pChild)) {
+ parent = tChild;
+ prevSib = NULL;
+ }
+ pChild = pChild->firstChild;
+ continue;
+ }
+
+ while(!pChild->nextSib) {
+ pChild = pChild->parent;
+ if(pChild == pWin) return;
+ if(IN_UNDERLAY(pChild)) {
+ prevSib = tChild = MIOVERLAY_GET_WINDOW_TREE(pChild);
+ parent = tChild->parent;
+ }
+ }
+
+ pChild = pChild->nextSib;
+ }
+}
+
+
+static Bool
+HasUnderlayChildren(WindowPtr pWin)
+{
+ WindowPtr pChild;
+
+ if(!(pChild = pWin->firstChild))
+ return FALSE;
+
+ while(1) {
+ if(IN_UNDERLAY(pChild))
+ return TRUE;
+
+ if(pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+
+ while(!pChild->nextSib && (pWin != pChild))
+ pChild = pChild->parent;
+
+ if(pChild == pWin) break;
+
+ pChild = pChild->nextSib;
+ }
+
+ return FALSE;
+}
+
+
+static Bool
+CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
+{
+ WindowPtr pChild;
+ miOverlayTreePtr pTree;
+ Bool hasUnderlay;
+
+ if(!(pChild = pWin->firstChild))
+ return FALSE;
+
+ hasUnderlay = FALSE;
+
+ while(1) {
+ if((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
+ RegionAppend(pReg, &pTree->borderClip);
+ hasUnderlay = TRUE;
+ } else
+ if(pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+
+ while(!pChild->nextSib && (pWin != pChild))
+ pChild = pChild->parent;
+
+ if(pChild == pWin) break;
+
+ pChild = pChild->nextSib;
+ }
+
+ if(hasUnderlay) {
+ Bool overlap;
+ RegionValidate(pReg, &overlap);
+ }
+
+ return hasUnderlay;
+}
+
+
+static void
+MarkUnderlayWindow(WindowPtr pWin)
+{
+ miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
+
+ if(pTree->valdata) return;
+ pTree->valdata = (miOverlayValDataPtr)xnfalloc(sizeof(miOverlayValDataRec));
+ pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
+ pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
+ pTree->valdata->borderVisible = NullRegion;
+}
diff --git a/nx-X11/programs/Xserver/mi/mioverlay.h b/nx-X11/programs/Xserver/mi/mioverlay.h
new file mode 100644
index 000000000..24b74f51c
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mioverlay.h
@@ -0,0 +1,32 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef __MIOVERLAY_H
+#define __MIOVERLAY_H
+
+typedef void (*miOverlayTransFunc)(ScreenPtr, int, BoxPtr);
+typedef Bool (*miOverlayInOverlayFunc)(WindowPtr);
+
+Bool
+miInitOverlay(
+ ScreenPtr pScreen,
+ miOverlayInOverlayFunc inOverlay,
+ miOverlayTransFunc trans
+);
+
+Bool
+miOverlayGetPrivateClips(
+ WindowPtr pWin,
+ RegionPtr *borderClip,
+ RegionPtr *clipList
+);
+
+Bool miOverlayCollectUnderlayRegions(WindowPtr, RegionPtr*);
+void miOverlayComputeCompositeClip(GCPtr, WindowPtr);
+Bool miOverlayCopyUnderlay(ScreenPtr);
+void miOverlaySetTransFunction(ScreenPtr, miOverlayTransFunc);
+void miOverlaySetRootClip(ScreenPtr, Bool);
+
+#endif /* __MIOVERLAY_H */
diff --git a/nx-X11/programs/Xserver/mi/mipointer.c b/nx-X11/programs/Xserver/mi/mipointer.c
new file mode 100644
index 000000000..dc5a4985d
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipointer.c
@@ -0,0 +1,545 @@
+/*
+ * mipointer.c
+ */
+
+
+/*
+
+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.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# include <nx-X11/X.h>
+# include <nx-X11/Xmd.h>
+# include <nx-X11/Xproto.h>
+# include "misc.h"
+# include "windowstr.h"
+# include "pixmapstr.h"
+# include "mi.h"
+# include "scrnintstr.h"
+# include "mipointrst.h"
+# include "cursorstr.h"
+# include "dixstruct.h"
+# include <nx-X11/extensions/XI.h>
+
+int miPointerScreenIndex;
+static unsigned long miPointerGeneration = 0;
+
+#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
+#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s)
+
+/*
+ * until more than one pointer device exists.
+ */
+
+static miPointerRec miPointer;
+
+static Bool miPointerRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static Bool miPointerUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static Bool miPointerDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static void miPointerConstrainCursor(ScreenPtr pScreen, BoxPtr pBox);
+static void miPointerPointerNonInterestBox(ScreenPtr pScreen, BoxPtr pBox);
+static void miPointerCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
+ BoxPtr pHotBox, BoxPtr pTopLeftBox);
+static Bool miPointerSetCursorPosition(ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+static Bool miPointerCloseScreen(ScreenPtr pScreen);
+static void miPointerMove(ScreenPtr pScreen, int x, int y, unsigned long time);
+
+Bool
+miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
+ ScreenPtr pScreen;
+ miPointerSpriteFuncPtr spriteFuncs;
+ miPointerScreenFuncPtr screenFuncs;
+ Bool waitForUpdate;
+{
+ miPointerScreenPtr pScreenPriv;
+
+ if (miPointerGeneration != serverGeneration)
+ {
+ miPointerScreenIndex = AllocateScreenPrivateIndex();
+ if (miPointerScreenIndex < 0)
+ return FALSE;
+ miPointerGeneration = serverGeneration;
+ }
+ pScreenPriv = (miPointerScreenPtr) malloc (sizeof (miPointerScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+ pScreenPriv->spriteFuncs = spriteFuncs;
+ pScreenPriv->screenFuncs = screenFuncs;
+ /*
+ * check for uninitialized methods
+ */
+ if (!screenFuncs->EnqueueEvent)
+ screenFuncs->EnqueueEvent = mieqEnqueue;
+ if (!screenFuncs->NewEventScreen)
+ screenFuncs->NewEventScreen = mieqSwitchScreen;
+ pScreenPriv->waitForUpdate = waitForUpdate;
+ pScreenPriv->showTransparent = FALSE;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = miPointerCloseScreen;
+ pScreen->devPrivates[miPointerScreenIndex].ptr = (void *) pScreenPriv;
+ /*
+ * set up screen cursor method table
+ */
+ pScreen->ConstrainCursor = miPointerConstrainCursor;
+ pScreen->CursorLimits = miPointerCursorLimits;
+ pScreen->DisplayCursor = miPointerDisplayCursor;
+ pScreen->RealizeCursor = miPointerRealizeCursor;
+ pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
+ pScreen->SetCursorPosition = miPointerSetCursorPosition;
+ pScreen->RecolorCursor = miRecolorCursor;
+ pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox;
+ /*
+ * set up the pointer object
+ */
+ miPointer.pScreen = NULL;
+ miPointer.pSpriteScreen = NULL;
+ miPointer.pCursor = NULL;
+ miPointer.pSpriteCursor = NULL;
+ miPointer.limits.x1 = 0;
+ miPointer.limits.x2 = 32767;
+ miPointer.limits.y1 = 0;
+ miPointer.limits.y2 = 32767;
+ miPointer.confined = FALSE;
+ miPointer.x = 0;
+ miPointer.y = 0;
+ miPointer.history_start = miPointer.history_end = 0;
+ return TRUE;
+}
+
+static Bool
+miPointerCloseScreen (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen(pScreen);
+
+ if (pScreen == miPointer.pScreen)
+ miPointer.pScreen = 0;
+ if (pScreen == miPointer.pSpriteScreen)
+ miPointer.pSpriteScreen = 0;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ free ((void *) pScreenPriv);
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+/*
+ * DIX/DDX interface routines
+ */
+
+static Bool
+miPointerRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ SetupScreen(pScreen);
+
+ return (*pScreenPriv->spriteFuncs->RealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miPointerUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ SetupScreen(pScreen);
+
+ return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miPointerDisplayCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miPointer.pCursor = pCursor;
+ miPointer.pScreen = pScreen;
+ miPointerUpdate ();
+ return TRUE;
+}
+
+static void
+miPointerConstrainCursor (pScreen, pBox)
+ ScreenPtr pScreen;
+ BoxPtr pBox;
+{
+ miPointer.limits = *pBox;
+ miPointer.confined = PointerConfinedToScreen();
+}
+
+/*ARGSUSED*/
+static void
+miPointerPointerNonInterestBox (pScreen, pBox)
+ ScreenPtr pScreen;
+ BoxPtr pBox;
+{
+ /* until DIX uses this, this will remain a stub */
+}
+
+/*ARGSUSED*/
+static void
+miPointerCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ BoxPtr pHotBox;
+ BoxPtr pTopLeftBox;
+{
+ *pTopLeftBox = *pHotBox;
+}
+
+static Bool GenerateEvent;
+
+static Bool
+miPointerSetCursorPosition(pScreen, x, y, generateEvent)
+ ScreenPtr pScreen;
+ int x, y;
+ Bool generateEvent;
+{
+ SetupScreen (pScreen);
+
+ GenerateEvent = generateEvent;
+
+ if (pScreen->ConstrainCursorHarder)
+ pScreen->ConstrainCursorHarder(pScreen, Absolute, &x, &y);
+
+ /* device dependent - must pend signal and call miPointerWarpCursor */
+ (*pScreenPriv->screenFuncs->WarpCursor) (pScreen, x, y);
+ if (!generateEvent)
+ miPointerUpdate();
+ return TRUE;
+}
+
+/* Once signals are ignored, the WarpCursor function can call this */
+
+void
+miPointerWarpCursor (pScreen, x, y)
+ ScreenPtr pScreen;
+ int x, y;
+{
+ SetupScreen (pScreen);
+
+ if (miPointer.pScreen != pScreen)
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE);
+
+ if (GenerateEvent)
+ {
+ miPointerMove (pScreen, x, y, GetTimeInMillis());
+ }
+ else
+ {
+ /* everything from miPointerMove except the event and history */
+
+ if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+ miPointer.x = x;
+ miPointer.y = y;
+ miPointer.pScreen = pScreen;
+ }
+}
+
+/*
+ * Pointer/CursorDisplay interface routines
+ */
+
+int
+miPointerGetMotionBufferSize ()
+{
+ return MOTION_SIZE;
+}
+
+int
+miPointerGetMotionEvents (pPtr, coords, start, stop, pScreen)
+ DeviceIntPtr pPtr;
+ xTimecoord *coords;
+ unsigned long start, stop;
+ ScreenPtr pScreen;
+{
+ int i;
+ int count = 0;
+ miHistoryPtr h;
+
+ for (i = miPointer.history_start; i != miPointer.history_end;)
+ {
+ h = &miPointer.history[i];
+ if (h->event.time >= stop)
+ break;
+ if (h->event.time >= start)
+ {
+ *coords++ = h->event;
+ count++;
+ }
+ if (++i == MOTION_SIZE) i = 0;
+ }
+ return count;
+}
+
+
+/*
+ * miPointerUpdate
+ *
+ * Syncronize the sprite with the cursor - called from ProcessInputEvents
+ */
+
+void
+miPointerUpdate ()
+{
+ ScreenPtr pScreen;
+ miPointerScreenPtr pScreenPriv;
+ CursorPtr pCursor;
+ int x, y, devx, devy;
+
+ pScreen = miPointer.pScreen;
+ x = miPointer.x;
+ y = miPointer.y;
+ devx = miPointer.devx;
+ devy = miPointer.devy;
+ if (!pScreen)
+ return;
+ pScreenPriv = GetScreenPrivate (pScreen);
+ /*
+ * if the cursor has switched screens, disable the sprite
+ * on the old screen
+ */
+ if (pScreen != miPointer.pSpriteScreen)
+ {
+ if (miPointer.pSpriteScreen)
+ {
+ miPointerScreenPtr pOldPriv;
+
+ pOldPriv = GetScreenPrivate (miPointer.pSpriteScreen);
+ if (miPointer.pCursor)
+ {
+ (*pOldPriv->spriteFuncs->SetCursor)
+ (miPointer.pSpriteScreen, NullCursor, 0, 0);
+ }
+ (*pOldPriv->screenFuncs->CrossScreen) (miPointer.pSpriteScreen, FALSE);
+ }
+ (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
+ (*pScreenPriv->spriteFuncs->SetCursor)
+ (pScreen, miPointer.pCursor, x, y);
+ miPointer.devx = x;
+ miPointer.devy = y;
+ miPointer.pSpriteCursor = miPointer.pCursor;
+ miPointer.pSpriteScreen = pScreen;
+ }
+ /*
+ * if the cursor has changed, display the new one
+ */
+ else if (miPointer.pCursor != miPointer.pSpriteCursor)
+ {
+ pCursor = miPointer.pCursor;
+ if (pCursor->bits->emptyMask && !pScreenPriv->showTransparent)
+ pCursor = NullCursor;
+ (*pScreenPriv->spriteFuncs->SetCursor) (pScreen, pCursor, x, y);
+
+ miPointer.devx = x;
+ miPointer.devy = y;
+ miPointer.pSpriteCursor = miPointer.pCursor;
+ }
+ else if (x != devx || y != devy)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+}
+
+/*
+ * miPointerDeltaCursor. The void * has moved dx,dy from it's previous
+ * position.
+ */
+
+void
+miPointerDeltaCursor (dx, dy, time)
+ int dx, dy;
+ unsigned long time;
+{
+ miPointerAbsoluteCursor (miPointer.x + dx, miPointer.y + dy, time);
+}
+
+void
+miPointerSetNewScreen(int screen_no, int x, int y)
+{
+ miPointerScreenPtr pScreenPriv;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[screen_no];
+ pScreenPriv = GetScreenPrivate (pScreen);
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+ NewCurrentScreen (pScreen, x, y);
+ miPointer.limits.x2 = pScreen->width;
+ miPointer.limits.y2 = pScreen->height;
+}
+
+ScreenPtr
+miPointerCurrentScreen ()
+{
+ return (miPointer.pScreen);
+}
+
+/*
+ * miPointerAbsoluteCursor. The void * has moved to x,y
+ */
+
+void
+miPointerAbsoluteCursor (x, y, time)
+ int x, y;
+ unsigned long time;
+{
+ miPointerScreenPtr pScreenPriv;
+ ScreenPtr pScreen;
+ ScreenPtr newScreen;
+
+ pScreen = miPointer.pScreen;
+ if (!pScreen)
+ return; /* called before ready */
+ if (x < 0 || x >= pScreen->width || y < 0 || y >= pScreen->height)
+ {
+ pScreenPriv = GetScreenPrivate (pScreen);
+ if (!miPointer.confined)
+ {
+ newScreen = pScreen;
+ (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y);
+ if (newScreen != pScreen)
+ {
+ pScreen = newScreen;
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+ pScreenPriv = GetScreenPrivate (pScreen);
+ /* Smash the confine to the new screen */
+ miPointer.limits.x2 = pScreen->width;
+ miPointer.limits.y2 = pScreen->height;
+ }
+ }
+ }
+ /*
+ * constrain the hot-spot to the current
+ * limits
+ */
+ if (x < miPointer.limits.x1)
+ x = miPointer.limits.x1;
+ if (x >= miPointer.limits.x2)
+ x = miPointer.limits.x2 - 1;
+ if (y < miPointer.limits.y1)
+ y = miPointer.limits.y1;
+ if (y >= miPointer.limits.y2)
+ y = miPointer.limits.y2 - 1;
+ if (miPointer.x == x && miPointer.y == y && miPointer.pScreen == pScreen)
+ return;
+ miPointerMove (pScreen, x, y, time);
+}
+
+void
+miPointerPosition (x, y)
+ int *x, *y;
+{
+ *x = miPointer.x;
+ *y = miPointer.y;
+}
+
+/*
+ * miPointerMove. The void * has moved to x,y on current screen
+ */
+
+static void
+miPointerMove (pScreen, x, y, time)
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned long time;
+{
+ SetupScreen(pScreen);
+ xEvent xE;
+ miHistoryPtr history;
+ int prev, end, start;
+
+ if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+ miPointer.x = x;
+ miPointer.y = y;
+ miPointer.pScreen = pScreen;
+
+ xE.u.u.type = MotionNotify;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ xE.u.keyButtonPointer.time = time;
+ (*pScreenPriv->screenFuncs->EnqueueEvent) (&xE);
+
+ end = miPointer.history_end;
+ start = miPointer.history_start;
+ prev = end - 1;
+ if (end == 0)
+ prev = MOTION_SIZE - 1;
+ history = &miPointer.history[prev];
+ if (end == start || history->event.time != time)
+ {
+ history = &miPointer.history[end];
+ if (++end == MOTION_SIZE)
+ end = 0;
+ if (end == start)
+ {
+ start = end + 1;
+ if (start == MOTION_SIZE)
+ start = 0;
+ miPointer.history_start = start;
+ }
+ miPointer.history_end = end;
+ }
+ history->event.x = x;
+ history->event.y = y;
+ history->event.time = time;
+ history->pScreen = pScreen;
+}
+
+void
+_miRegisterPointerDevice (pScreen, pDevice)
+ ScreenPtr pScreen;
+ DeviceIntPtr pDevice;
+{
+ miPointer.pPointer = (DevicePtr)pDevice;
+}
+
+/* obsolete: for binary compatibility */
+
+#ifdef miRegisterPointerDevice
+#undef miRegisterPointerDevice
+void
+miRegisterPointerDevice (pScreen, pDevice)
+ ScreenPtr pScreen;
+ DevicePtr pDevice;
+{
+ miPointer.pPointer = pDevice;
+}
+#endif /* miRegisterPointerDevice */
diff --git a/nx-X11/programs/Xserver/mi/mipointer.h b/nx-X11/programs/Xserver/mi/mipointer.h
new file mode 100644
index 000000000..4fd326fce
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipointer.h
@@ -0,0 +1,160 @@
+/*
+ * mipointer.h
+ *
+ */
+
+
+/*
+
+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.
+*/
+
+#ifndef MIPOINTER_H
+#define MIPOINTER_H
+
+#include "cursor.h"
+#include "input.h"
+
+typedef struct _miPointerSpriteFuncRec {
+ Bool (*RealizeCursor)(
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */
+ );
+ Bool (*UnrealizeCursor)(
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */
+ );
+ void (*SetCursor)(
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */,
+ int /* x */,
+ int /* y */
+ );
+ void (*MoveCursor)(
+ ScreenPtr /* pScr */,
+ int /* x */,
+ int /* y */
+ );
+} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
+
+typedef struct _miPointerScreenFuncRec {
+ Bool (*CursorOffScreen)(
+ ScreenPtr* /* ppScr */,
+ int* /* px */,
+ int* /* py */
+ );
+ void (*CrossScreen)(
+ ScreenPtr /* pScr */,
+ int /* entering */
+ );
+ void (*WarpCursor)(
+ ScreenPtr /* pScr */,
+ int /* x */,
+ int /* y */
+ );
+ void (*EnqueueEvent)(
+ xEventPtr /* event */
+ );
+ void (*NewEventScreen)(
+ ScreenPtr /* pScr */,
+ Bool /* fromDIX */
+ );
+} miPointerScreenFuncRec, *miPointerScreenFuncPtr;
+
+extern Bool miDCInitialize(
+ ScreenPtr /*pScreen*/,
+ miPointerScreenFuncPtr /*screenFuncs*/
+);
+
+extern Bool miPointerInitialize(
+ ScreenPtr /*pScreen*/,
+ miPointerSpriteFuncPtr /*spriteFuncs*/,
+ miPointerScreenFuncPtr /*screenFuncs*/,
+ Bool /*waitForUpdate*/
+);
+
+extern void miPointerWarpCursor(
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/
+);
+
+extern int miPointerGetMotionBufferSize(
+ void
+);
+
+extern int miPointerGetMotionEvents(
+ DeviceIntPtr /*pPtr*/,
+ xTimecoord * /*coords*/,
+ unsigned long /*start*/,
+ unsigned long /*stop*/,
+ ScreenPtr /*pScreen*/
+);
+
+extern void miPointerUpdate(
+ void
+);
+
+extern void miPointerDeltaCursor(
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+);
+
+extern void miPointerAbsoluteCursor(
+ int /*x*/,
+ int /*y*/,
+ unsigned long /*time*/
+);
+
+extern void miPointerPosition(
+ int * /*x*/,
+ int * /*y*/
+);
+
+#undef miRegisterPointerDevice
+extern void miRegisterPointerDevice(
+ ScreenPtr /*pScreen*/,
+ DevicePtr /*pDevice*/
+);
+
+extern void miPointerSetNewScreen(
+ int, /*screen_no*/
+ int, /*x*/
+ int /*y*/
+);
+extern ScreenPtr miPointerCurrentScreen(
+ void
+);
+
+#define miRegisterPointerDevice(pScreen,pDevice) \
+ _miRegisterPointerDevice(pScreen,pDevice)
+
+extern void _miRegisterPointerDevice(
+ ScreenPtr /*pScreen*/,
+ DeviceIntPtr /*pDevice*/
+);
+
+extern int miPointerScreenIndex;
+
+#endif /* MIPOINTER_H */
diff --git a/nx-X11/programs/Xserver/mi/mipointrst.h b/nx-X11/programs/Xserver/mi/mipointrst.h
new file mode 100644
index 000000000..f1fbfe4f9
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipointrst.h
@@ -0,0 +1,62 @@
+/*
+ * mipointrst.h
+ *
+ */
+
+
+/*
+
+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.
+*/
+
+#include "mipointer.h"
+#include "scrnintstr.h"
+
+#define MOTION_SIZE 256
+
+typedef struct {
+ xTimecoord event;
+ ScreenPtr pScreen;
+} miHistoryRec, *miHistoryPtr;
+
+typedef struct {
+ ScreenPtr pScreen; /* current screen */
+ ScreenPtr pSpriteScreen;/* screen containing current sprite */
+ CursorPtr pCursor; /* current cursor */
+ CursorPtr pSpriteCursor;/* cursor on screen */
+ BoxRec limits; /* current constraints */
+ Bool confined; /* pointer can't change screens */
+ int x, y; /* hot spot location */
+ int devx, devy; /* sprite position */
+ DevicePtr pPointer; /* pointer device structure */
+ miHistoryRec history[MOTION_SIZE];
+ int history_start, history_end;
+} miPointerRec, *miPointerPtr;
+
+typedef struct {
+ miPointerSpriteFuncPtr spriteFuncs; /* sprite-specific methods */
+ miPointerScreenFuncPtr screenFuncs; /* screen-specific methods */
+ CloseScreenProcPtr CloseScreen;
+ Bool waitForUpdate; /* don't move cursor in SIGIO */
+ Bool showTransparent; /* show empty cursors */
+} miPointerScreenRec, *miPointerScreenPtr;
diff --git a/nx-X11/programs/Xserver/mi/mipoly.c b/nx-X11/programs/Xserver/mi/mipoly.c
new file mode 100644
index 000000000..97fe6669e
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipoly.c
@@ -0,0 +1,127 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*
+ * mipoly.c
+ *
+ * Written by Brian Kelleher; June 1986
+ *
+ * Draw polygons. This routine translates the point by the
+ * origin if pGC->miTranslate is non-zero, and calls
+ * to the appropriate routine to actually scan convert the
+ * polygon.
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#include "regionstr.h"
+
+
+void
+miFillPolygon(dst, pgc, shape, mode, count, pPts)
+ DrawablePtr dst;
+ register GCPtr pgc;
+ int shape, mode;
+ register int count;
+ DDXPointPtr pPts;
+{
+ int i;
+ register int xorg, yorg;
+ register DDXPointPtr ppt;
+
+ if (count == 0)
+ return;
+
+ ppt = pPts;
+ if (pgc->miTranslate)
+ {
+ xorg = dst->x;
+ yorg = dst->y;
+
+ if (mode == CoordModeOrigin)
+ {
+ for (i = 0; i<count; i++)
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ }
+ }
+ else
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ else
+ {
+ if (mode == CoordModePrevious)
+ {
+ ppt++;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ if (shape == Convex)
+ miFillConvexPoly(dst, pgc, count, pPts);
+ else
+ miFillGeneralPoly(dst, pgc, count, pPts);
+}
diff --git a/nx-X11/programs/Xserver/mi/mipoly.h b/nx-X11/programs/Xserver/mi/mipoly.h
new file mode 100644
index 000000000..8e04f6737
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipoly.h
@@ -0,0 +1,215 @@
+/*
+
+Copyright 1987, 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.
+
+*/
+
+
+/*
+ * fill.h
+ *
+ * Created by Brian Kelleher; Oct 1985
+ *
+ * Include file for filled polygon routines.
+ *
+ * These are the data structures needed to scan
+ * convert regions. Two different scan conversion
+ * methods are available -- the even-odd method, and
+ * the winding number method.
+ * The even-odd rule states that a point is inside
+ * the polygon if a ray drawn from that point in any
+ * direction will pass through an odd number of
+ * path segments.
+ * By the winding number rule, a point is decided
+ * to be inside the polygon if a ray drawn from that
+ * point in any direction passes through a different
+ * number of clockwise and counter-clockwise path
+ * segments.
+ *
+ * These data structures are adapted somewhat from
+ * the algorithm in (Foley/Van Dam) for scan converting
+ * polygons.
+ * The basic algorithm is to start at the top (smallest y)
+ * of the polygon, stepping down to the bottom of
+ * the polygon by incrementing the y coordinate. We
+ * keep a list of edges which the current scanline crosses,
+ * sorted by x. This list is called the Active Edge Table (AET)
+ * As we change the y-coordinate, we update each entry in
+ * in the active edge table to reflect the edges new xcoord.
+ * This list must be sorted at each scanline in case
+ * two edges intersect.
+ * We also keep a data structure known as the Edge Table (ET),
+ * which keeps track of all the edges which the current
+ * scanline has not yet reached. The ET is basically a
+ * list of ScanLineList structures containing a list of
+ * edges which are entered at a given scanline. There is one
+ * ScanLineList per scanline at which an edge is entered.
+ * When we enter a new edge, we move it from the ET to the AET.
+ *
+ * From the AET, we can implement the even-odd rule as in
+ * (Foley/Van Dam).
+ * The winding number rule is a little trickier. We also
+ * keep the EdgeTableEntries in the AET linked by the
+ * nextWETE (winding EdgeTableEntry) link. This allows
+ * the edges to be linked just as before for updating
+ * purposes, but only uses the edges linked by the nextWETE
+ * link as edges representing spans of the polygon to
+ * drawn (as with the even-odd rule).
+ */
+
+/*
+ * for the winding number rule
+ */
+#define CLOCKWISE 1
+#define COUNTERCLOCKWISE -1
+
+typedef struct _EdgeTableEntry {
+ int ymax; /* ycoord at which we exit this edge. */
+ BRESINFO bres; /* Bresenham info to run the edge */
+ struct _EdgeTableEntry *next; /* next in the list */
+ struct _EdgeTableEntry *back; /* for insertion sort */
+ struct _EdgeTableEntry *nextWETE; /* for winding num rule */
+ int ClockWise; /* flag for winding number rule */
+} EdgeTableEntry;
+
+
+typedef struct _ScanLineList{
+ int scanline; /* the scanline represented */
+ EdgeTableEntry *edgelist; /* header node */
+ struct _ScanLineList *next; /* next in the list */
+} ScanLineList;
+
+
+typedef struct {
+ int ymax; /* ymax for the polygon */
+ int ymin; /* ymin for the polygon */
+ ScanLineList scanlines; /* header node */
+} EdgeTable;
+
+
+/*
+ * Here is a struct to help with storage allocation
+ * so we can allocate a big chunk at a time, and then take
+ * pieces from this heap when we need to.
+ */
+#define SLLSPERBLOCK 25
+
+typedef struct _ScanLineListBlock {
+ ScanLineList SLLs[SLLSPERBLOCK];
+ struct _ScanLineListBlock *next;
+} ScanLineListBlock;
+
+/*
+ * number of points to buffer before sending them off
+ * to scanlines() : Must be an even number
+ */
+#define NUMPTSTOBUFFER 200
+
+
+/*
+ *
+ * a few macros for the inner loops of the fill code where
+ * performance considerations don't allow a procedure call.
+ *
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The winding number rule is in effect, so we must notify
+ * the caller when the edge has been removed so he
+ * can reorder the Winding Active Edge Table.
+ */
+#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ fixWAET = 1; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+
+/*
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The even-odd rule is in effect.
+ */
+#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+/* mipolyutil.c */
+
+extern Bool miInsertEdgeInET(
+ EdgeTable * /*ET*/,
+ EdgeTableEntry * /*ETE*/,
+ int /*scanline*/,
+ ScanLineListBlock ** /*SLLBlock*/,
+ int * /*iSLLBlock*/
+);
+
+extern Bool miCreateETandAET(
+ int /*count*/,
+ DDXPointPtr /*pts*/,
+ EdgeTable * /*ET*/,
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*pETEs*/,
+ ScanLineListBlock * /*pSLLBlock*/
+);
+
+extern void miloadAET(
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*ETEs*/
+);
+
+extern void micomputeWAET(
+ EdgeTableEntry * /*AET*/
+);
+
+extern int miInsertionSort(
+ EdgeTableEntry * /*AET*/
+);
+
+extern void miFreeStorage(
+ ScanLineListBlock * /*pSLLBlock*/
+);
diff --git a/nx-X11/programs/Xserver/mi/mipolycon.c b/nx-X11/programs/Xserver/mi/mipolycon.c
new file mode 100644
index 000000000..39d13f914
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolycon.c
@@ -0,0 +1,246 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "gcstruct.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "miscanfill.h"
+
+static int getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty);
+
+/*
+ * convexpoly.c
+ *
+ * Written by Brian Kelleher; Dec. 1985.
+ *
+ * Fill a convex polygon. If the given polygon
+ * is not convex, then the result is undefined.
+ * The algorithm is to order the edges from smallest
+ * y to largest by partitioning the array into a left
+ * edge list and a right edge list. The algorithm used
+ * to traverse each edge is an extension of Bresenham's
+ * line algorithm with y as the major axis.
+ * For a derivation of the algorithm, see the author of
+ * this code.
+ */
+Bool
+miFillConvexPoly(dst, pgc, count, ptsIn)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ DDXPointPtr ptsIn; /* the points */
+{
+ register int xl = 0, xr = 0; /* x vals of left and right edges */
+ register int dl = 0, dr = 0; /* decision variables */
+ register int ml = 0, m1l = 0;/* left edge slope and slope+1 */
+ int mr = 0, m1r = 0; /* right edge slope and slope+1 */
+ int incr1l = 0, incr2l = 0; /* left edge error increments */
+ int incr1r = 0, incr2r = 0; /* right edge error increments */
+ int dy; /* delta y */
+ int y; /* current scanline */
+ int left, right; /* indices to first endpoints */
+ int i; /* loop counter */
+ int nextleft, nextright; /* indices to second endpoints */
+ DDXPointPtr ptsOut, FirstPoint; /* output buffer */
+ int *width, *FirstWidth; /* output buffer */
+ int imin; /* index of smallest vertex (in y) */
+ int ymin; /* y-extents of polygon */
+ int ymax;
+
+ /*
+ * find leftx, bottomy, rightx, topy, and the index
+ * of bottomy. Also translate the points.
+ */
+ imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);
+
+ dy = ymax - ymin + 1;
+ if ((count < 3) || (dy < 0))
+ return(TRUE);
+ ptsOut = FirstPoint = (DDXPointPtr )malloc(sizeof(DDXPointRec)*dy);
+ width = FirstWidth = (int *)malloc(sizeof(int) * dy);
+ if(!FirstPoint || !FirstWidth)
+ {
+ if (FirstWidth) free(FirstWidth);
+ if (FirstPoint) free(FirstPoint);
+ return(FALSE);
+ }
+
+ nextleft = nextright = imin;
+ y = ptsIn[nextleft].y;
+
+ /*
+ * loop through all edges of the polygon
+ */
+ do {
+ /*
+ * add a left edge if we need to
+ */
+ if (ptsIn[nextleft].y == y) {
+ left = nextleft;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextleft++;
+ if (nextleft >= count)
+ nextleft = 0;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextleft].y-ptsIn[left].y,
+ ptsIn[left].x,ptsIn[nextleft].x,
+ xl, dl, ml, m1l, incr1l, incr2l);
+ }
+
+ /*
+ * add a right edge if we need to
+ */
+ if (ptsIn[nextright].y == y) {
+ right = nextright;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextright--;
+ if (nextright < 0)
+ nextright = count-1;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextright].y-ptsIn[right].y,
+ ptsIn[right].x,ptsIn[nextright].x,
+ xr, dr, mr, m1r, incr1r, incr2r);
+ }
+
+ /*
+ * generate scans to fill while we still have
+ * a right edge as well as a left edge.
+ */
+ i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
+ /* in case we're called with non-convex polygon */
+ if(i < 0)
+ {
+ free(FirstWidth);
+ free(FirstPoint);
+ return(TRUE);
+ }
+ while (i-- > 0)
+ {
+ ptsOut->y = y;
+
+ /*
+ * reverse the edges if necessary
+ */
+ if (xl < xr)
+ {
+ *(width++) = xr - xl;
+ (ptsOut++)->x = xl;
+ }
+ else
+ {
+ *(width++) = xl - xr;
+ (ptsOut++)->x = xr;
+ }
+ y++;
+
+ /* increment down the edges */
+ BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
+ BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
+ }
+ } while (y != ymax);
+
+ /*
+ * Finally, fill the <remaining> spans
+ */
+ (*pgc->ops->FillSpans)(dst, pgc,
+ ptsOut-FirstPoint,FirstPoint,FirstWidth,
+ 1);
+ free(FirstWidth);
+ free(FirstPoint);
+ return(TRUE);
+}
+
+
+/*
+ * Find the index of the point with the smallest y.
+ */
+static int
+getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty)
+{
+ register DDXPointPtr ptMin;
+ int ymin, ymax;
+ DDXPointPtr ptsStart = pts;
+
+ ptMin = pts;
+ ymin = ymax = (pts++)->y;
+
+ while (--n > 0) {
+ if (pts->y < ymin)
+ {
+ ptMin = pts;
+ ymin = pts->y;
+ }
+ if(pts->y > ymax)
+ ymax = pts->y;
+
+ pts++;
+ }
+
+ *by = ymin;
+ *ty = ymax;
+ return(ptMin-ptsStart);
+}
diff --git a/nx-X11/programs/Xserver/mi/mipolygen.c b/nx-X11/programs/Xserver/mi/mipolygen.c
new file mode 100644
index 000000000..9eb7568d4
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolygen.c
@@ -0,0 +1,230 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "gcstruct.h"
+#include "miscanfill.h"
+#include "mipoly.h"
+#include "pixmap.h"
+#include "mi.h"
+
+/*
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * Routine to fill a polygon. Two fill rules are
+ * supported: frWINDING and frEVENODD.
+ *
+ * See fillpoly.h for a complete description of the algorithm.
+ */
+
+Bool
+miFillGeneralPoly(dst, pgc, count, ptsIn)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ DDXPointPtr ptsIn; /* the points */
+{
+ register EdgeTableEntry *pAET; /* the Active Edge Table */
+ register int y; /* the current scanline */
+ register int nPts = 0; /* number of pts in buffer */
+ register EdgeTableEntry *pWETE; /* Winding Edge Table */
+ register ScanLineList *pSLL; /* Current ScanLineList */
+ register DDXPointPtr ptsOut; /* ptr to output buffers */
+ int *width;
+ DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
+ int FirstWidth[NUMPTSTOBUFFER];
+ EdgeTableEntry *pPrevAET; /* previous AET entry */
+ EdgeTable ET; /* Edge Table header node */
+ EdgeTableEntry AET; /* Active ET header node */
+ EdgeTableEntry *pETEs; /* Edge Table Entries buff */
+ ScanLineListBlock SLLBlock; /* header for ScanLineList */
+ int fixWAET = 0;
+
+ if (count < 3)
+ return(TRUE);
+
+ if(!(pETEs = (EdgeTableEntry *)
+ malloc(sizeof(EdgeTableEntry) * count)))
+ return(FALSE);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock))
+ {
+ free(pETEs);
+ return(FALSE);
+ }
+ pSLL = ET.scanlines.next;
+
+ if (pgc->fillRule == EvenOddRule)
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->next->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer when its full
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(dst, pgc,
+ nPts, FirstPoint, FirstWidth,
+ 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
+ }
+ miInsertionSort(&AET);
+ }
+ }
+ else /* default to WindingNumber */
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ micomputeWAET(&AET);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+ pWETE = pAET;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ /*
+ * if the next edge in the active edge table is
+ * also the next edge in the winding active edge
+ * table.
+ */
+ if (pWETE == pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint,
+ FirstWidth, 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+
+ pWETE = pWETE->nextWETE;
+ while (pWETE != pAET)
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ pWETE = pWETE->nextWETE;
+ }
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ }
+
+ /*
+ * reevaluate the Winding active edge table if we
+ * just had to resort it or if we just exited an edge.
+ */
+ if (miInsertionSort(&AET) || fixWAET)
+ {
+ micomputeWAET(&AET);
+ fixWAET = 0;
+ }
+ }
+ }
+
+ /*
+ * Get any spans that we missed by buffering
+ */
+ (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint, FirstWidth, 1);
+ free(pETEs);
+ miFreeStorage(SLLBlock.next);
+ return(TRUE);
+}
diff --git a/nx-X11/programs/Xserver/mi/mipolypnt.c b/nx-X11/programs/Xserver/mi/mipolypnt.c
new file mode 100644
index 000000000..ff35213b6
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolypnt.c
@@ -0,0 +1,123 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "mi.h"
+
+void
+miPolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+
+ int xorg;
+ int yorg;
+ int nptTmp;
+ XID fsOld, fsNew;
+ int *pwidthInit, *pwidth;
+ int i;
+ register xPoint *ppt;
+
+ /* make pointlist origin relative */
+ if (mode == CoordModePrevious)
+ {
+ ppt = pptInit;
+ nptTmp = npt;
+ nptTmp--;
+ while(nptTmp--)
+ {
+ ppt++;
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ }
+
+ if(pGC->miTranslate)
+ {
+ ppt = pptInit;
+ nptTmp = npt;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ while(nptTmp--)
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ }
+ }
+
+ fsOld = pGC->fillStyle;
+ fsNew = FillSolid;
+ if(pGC->fillStyle != FillSolid)
+ {
+ DoChangeGC(pGC, GCFillStyle, &fsNew, 0);
+ ValidateGC(pDrawable, pGC);
+ }
+ if(!(pwidthInit = (int *)malloc(npt * sizeof(int))))
+ return;
+ pwidth = pwidthInit;
+ for(i = 0; i < npt; i++)
+ *pwidth++ = 1;
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, pptInit, pwidthInit, FALSE);
+
+ if(fsOld != FillSolid)
+ {
+ DoChangeGC(pGC, GCFillStyle, &fsOld, 0);
+ ValidateGC(pDrawable, pGC);
+ }
+ free(pwidthInit);
+}
+
diff --git a/nx-X11/programs/Xserver/mi/mipolyrect.c b/nx-X11/programs/Xserver/mi/mipolyrect.c
new file mode 100644
index 000000000..ee0688513
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolyrect.c
@@ -0,0 +1,191 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "pixmap.h"
+#include "mi.h"
+
+void
+miPolyRectangle(pDraw, pGC, nrects, pRects)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ int i;
+ xRectangle *pR = pRects;
+ DDXPointRec rect[5];
+ int bound_tmp;
+
+#define MINBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp < -32768) \
+ bound_tmp = -32768; \
+ dst = bound_tmp;
+
+#define MAXBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 32767) \
+ bound_tmp = 32767; \
+ dst = bound_tmp;
+
+#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 65535) \
+ bound_tmp = 65535; \
+ dst = bound_tmp;
+
+ if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter &&
+ pGC->lineWidth != 0)
+ {
+ xRectangle *tmp, *t;
+ int ntmp;
+ int offset1, offset2, offset3;
+ int x, y, width, height;
+
+ ntmp = (nrects << 2);
+ offset2 = pGC->lineWidth;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+ tmp = (xRectangle *) malloc(ntmp * sizeof (xRectangle));
+ if (!tmp)
+ return;
+ t = tmp;
+ for (i = 0; i < nrects; i++)
+ {
+ x = pR->x;
+ y = pR->y;
+ width = pR->width;
+ height = pR->height;
+ pR++;
+ if (width == 0 && height == 0)
+ {
+ rect[0].x = x;
+ rect[0].y = y;
+ rect[1].x = x;
+ rect[1].y = y;
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2, rect);
+ }
+ else if (height < offset2 || width < offset1)
+ {
+ if (height == 0)
+ {
+ t->x = x;
+ t->width = width;
+ }
+ else
+ {
+ MINBOUND (t->x, x - offset1)
+ MAXUBOUND (t->width, width + offset2)
+ }
+ if (width == 0)
+ {
+ t->y = y;
+ t->height = height;
+ }
+ else
+ {
+ MINBOUND (t->y, y - offset1)
+ MAXUBOUND (t->height, height + offset2)
+ }
+ t++;
+ }
+ else
+ {
+ MINBOUND(t->x, x - offset1)
+ MINBOUND(t->y, y - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + offset3);
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MAXBOUND(t->x, x + width - offset1);
+ MAXBOUND(t->y, y + offset3)
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + height - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ }
+ }
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp);
+ free ((void *) tmp);
+ }
+ else
+ {
+
+ for (i=0; i<nrects; i++)
+ {
+ rect[0].x = pR->x;
+ rect[0].y = pR->y;
+
+ MAXBOUND(rect[1].x, pR->x + (int) pR->width)
+ rect[1].y = rect[0].y;
+
+ rect[2].x = rect[1].x;
+ MAXBOUND(rect[2].y, pR->y + (int) pR->height);
+
+ rect[3].x = rect[0].x;
+ rect[3].y = rect[2].y;
+
+ rect[4].x = rect[0].x;
+ rect[4].y = rect[0].y;
+
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 5, rect);
+ pR++;
+ }
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mipolyseg.c b/nx-X11/programs/Xserver/mi/mipolyseg.c
new file mode 100644
index 000000000..13a9e7222
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolyseg.c
@@ -0,0 +1,83 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "pixmap.h"
+#include "mi.h"
+
+/*****************************************************************
+ * miPolySegment
+ *
+ * For each segment, draws a line between (x1, y1) and (x2, y2). The
+ * lines are drawn in the order listed.
+ *
+ * Walks the segments, compressing them into format for PolyLines.
+ *
+ *****************************************************************/
+
+
+void
+miPolySegment(pDraw, pGC, nseg, pSegs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int nseg;
+ xSegment *pSegs;
+{
+ int i;
+
+ for (i=0; i<nseg; i++)
+ {
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2,(DDXPointPtr)pSegs);
+ pSegs++;
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mipolytext.c b/nx-X11/programs/Xserver/mi/mipolytext.c
new file mode 100644
index 000000000..fcc834f60
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolytext.c
@@ -0,0 +1,200 @@
+/*******************************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+************************************************************************/
+/*
+ * mipolytext.c - text routines
+ *
+ * Author: haynes
+ * Digital Equipment Corporation
+ * Western Software Laboratory
+ * Date: Thu Feb 5 1987
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "gcstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "mi.h"
+
+int
+miPolyText(pDraw, pGC, x, y, count, chars, fontEncoding)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+ FontEncoding fontEncoding;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ fontEncoding, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miPolyText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miPolyText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miImageText(pDraw, pGC, x, y, count, chars, fontEncoding)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+ FontEncoding fontEncoding;
+{
+ unsigned long n, i;
+ FontPtr font = pGC->font;
+ int w;
+ CharInfoPtr charinfo[255];
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ fontEncoding, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+ return x+w;
+}
+
+
+void
+miImageText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
+
+
+void
+miImageText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
diff --git a/nx-X11/programs/Xserver/mi/mipolyutil.c b/nx-X11/programs/Xserver/mi/mipolyutil.c
new file mode 100644
index 000000000..5e1b0a609
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipolyutil.c
@@ -0,0 +1,399 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include "gc.h"
+#include "miscanfill.h"
+#include "mipoly.h"
+#include "misc.h" /* MAXINT */
+
+/*
+ * fillUtils.c
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * This module contains all of the utility functions
+ * needed to scan convert a polygon.
+ *
+ */
+
+/*
+ * InsertEdgeInET
+ *
+ * Insert the given edge into the edge table.
+ * First we must find the correct bucket in the
+ * Edge table, then find the right slot in the
+ * bucket. Finally, we can insert it.
+ *
+ */
+Bool
+miInsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock)
+ EdgeTable *ET;
+ EdgeTableEntry *ETE;
+ int scanline;
+ ScanLineListBlock **SLLBlock;
+ int *iSLLBlock;
+{
+ register EdgeTableEntry *start, *prev;
+ register ScanLineList *pSLL, *pPrevSLL;
+ ScanLineListBlock *tmpSLLBlock;
+
+ /*
+ * find the right bucket to put the edge into
+ */
+ pPrevSLL = &ET->scanlines;
+ pSLL = pPrevSLL->next;
+ while (pSLL && (pSLL->scanline < scanline))
+ {
+ pPrevSLL = pSLL;
+ pSLL = pSLL->next;
+ }
+
+ /*
+ * reassign pSLL (pointer to ScanLineList) if necessary
+ */
+ if ((!pSLL) || (pSLL->scanline > scanline))
+ {
+ if (*iSLLBlock > SLLSPERBLOCK-1)
+ {
+ tmpSLLBlock =
+ (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
+ if (!tmpSLLBlock)
+ return FALSE;
+ (*SLLBlock)->next = tmpSLLBlock;
+ tmpSLLBlock->next = (ScanLineListBlock *)NULL;
+ *SLLBlock = tmpSLLBlock;
+ *iSLLBlock = 0;
+ }
+ pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+ pSLL->next = pPrevSLL->next;
+ pSLL->edgelist = (EdgeTableEntry *)NULL;
+ pPrevSLL->next = pSLL;
+ }
+ pSLL->scanline = scanline;
+
+ /*
+ * now insert the edge in the right bucket
+ */
+ prev = (EdgeTableEntry *)NULL;
+ start = pSLL->edgelist;
+ while (start && (start->bres.minor < ETE->bres.minor))
+ {
+ prev = start;
+ start = start->next;
+ }
+ ETE->next = start;
+
+ if (prev)
+ prev->next = ETE;
+ else
+ pSLL->edgelist = ETE;
+ return TRUE;
+}
+
+/*
+ * CreateEdgeTable
+ *
+ * This routine creates the edge table for
+ * scan converting polygons.
+ * The Edge Table (ET) looks like:
+ *
+ * EdgeTable
+ * --------
+ * | ymax | ScanLineLists
+ * |scanline|-->------------>-------------->...
+ * -------- |scanline| |scanline|
+ * |edgelist| |edgelist|
+ * --------- ---------
+ * | |
+ * | |
+ * V V
+ * list of ETEs list of ETEs
+ *
+ * where ETE is an EdgeTableEntry data structure,
+ * and there is one ScanLineList per scanline at
+ * which an edge is initially entered.
+ *
+ */
+
+Bool
+miCreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock)
+ register int count;
+ register DDXPointPtr pts;
+ EdgeTable *ET;
+ EdgeTableEntry *AET;
+ register EdgeTableEntry *pETEs;
+ ScanLineListBlock *pSLLBlock;
+{
+ register DDXPointPtr top, bottom;
+ register DDXPointPtr PrevPt, CurrPt;
+ int iSLLBlock = 0;
+
+ int dy;
+
+ if (count < 2) return TRUE;
+
+ /*
+ * initialize the Active Edge Table
+ */
+ AET->next = (EdgeTableEntry *)NULL;
+ AET->back = (EdgeTableEntry *)NULL;
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ AET->bres.minor = MININT;
+
+ /*
+ * initialize the Edge Table.
+ */
+ ET->scanlines.next = (ScanLineList *)NULL;
+ ET->ymax = MININT;
+ ET->ymin = MAXINT;
+ pSLLBlock->next = (ScanLineListBlock *)NULL;
+
+ PrevPt = &pts[count-1];
+
+ /*
+ * for each vertex in the array of points.
+ * In this loop we are dealing with two vertices at
+ * a time -- these make up one edge of the polygon.
+ */
+ while (count--)
+ {
+ CurrPt = pts++;
+
+ /*
+ * find out which point is above and which is below.
+ */
+ if (PrevPt->y > CurrPt->y)
+ {
+ bottom = PrevPt, top = CurrPt;
+ pETEs->ClockWise = 0;
+ }
+ else
+ {
+ bottom = CurrPt, top = PrevPt;
+ pETEs->ClockWise = 1;
+ }
+
+ /*
+ * don't add horizontal edges to the Edge table.
+ */
+ if (bottom->y != top->y)
+ {
+ pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
+
+ /*
+ * initialize integer edge algorithm
+ */
+ dy = bottom->y - top->y;
+ BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
+
+ if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
+ {
+ miFreeStorage(pSLLBlock->next);
+ return FALSE;
+ }
+
+ ET->ymax = max(ET->ymax, PrevPt->y);
+ ET->ymin = min(ET->ymin, PrevPt->y);
+ pETEs++;
+ }
+
+ PrevPt = CurrPt;
+ }
+ return TRUE;
+}
+
+/*
+ * loadAET
+ *
+ * This routine moves EdgeTableEntries from the
+ * EdgeTable into the Active Edge Table,
+ * leaving them sorted by smaller x coordinate.
+ *
+ */
+
+void
+miloadAET(AET, ETEs)
+ register EdgeTableEntry *AET, *ETEs;
+{
+ register EdgeTableEntry *pPrevAET;
+ register EdgeTableEntry *tmp;
+
+ pPrevAET = AET;
+ AET = AET->next;
+ while (ETEs)
+ {
+ while (AET && (AET->bres.minor < ETEs->bres.minor))
+ {
+ pPrevAET = AET;
+ AET = AET->next;
+ }
+ tmp = ETEs->next;
+ ETEs->next = AET;
+ if (AET)
+ AET->back = ETEs;
+ ETEs->back = pPrevAET;
+ pPrevAET->next = ETEs;
+ pPrevAET = ETEs;
+
+ ETEs = tmp;
+ }
+}
+
+/*
+ * computeWAET
+ *
+ * This routine links the AET by the
+ * nextWETE (winding EdgeTableEntry) link for
+ * use by the winding number rule. The final
+ * Active Edge Table (AET) might look something
+ * like:
+ *
+ * AET
+ * ---------- --------- ---------
+ * |ymax | |ymax | |ymax |
+ * | ... | |... | |... |
+ * |next |->|next |->|next |->...
+ * |nextWETE| |nextWETE| |nextWETE|
+ * --------- --------- ^--------
+ * | | |
+ * V-------------------> V---> ...
+ *
+ */
+void
+micomputeWAET(AET)
+ register EdgeTableEntry *AET;
+{
+ register EdgeTableEntry *pWETE;
+ register int inside = 1;
+ register int isInside = 0;
+
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ pWETE = AET;
+ AET = AET->next;
+ while (AET)
+ {
+ if (AET->ClockWise)
+ isInside++;
+ else
+ isInside--;
+
+ if ((!inside && !isInside) ||
+ ( inside && isInside))
+ {
+ pWETE->nextWETE = AET;
+ pWETE = AET;
+ inside = !inside;
+ }
+ AET = AET->next;
+ }
+ pWETE->nextWETE = (EdgeTableEntry *)NULL;
+}
+
+/*
+ * InsertionSort
+ *
+ * Just a simple insertion sort using
+ * pointers and back pointers to sort the Active
+ * Edge Table.
+ *
+ */
+
+int
+miInsertionSort(AET)
+ register EdgeTableEntry *AET;
+{
+ register EdgeTableEntry *pETEchase;
+ register EdgeTableEntry *pETEinsert;
+ register EdgeTableEntry *pETEchaseBackTMP;
+ register int changed = 0;
+
+ AET = AET->next;
+ while (AET)
+ {
+ pETEinsert = AET;
+ pETEchase = AET;
+ while (pETEchase->back->bres.minor > AET->bres.minor)
+ pETEchase = pETEchase->back;
+
+ AET = AET->next;
+ if (pETEchase != pETEinsert)
+ {
+ pETEchaseBackTMP = pETEchase->back;
+ pETEinsert->back->next = AET;
+ if (AET)
+ AET->back = pETEinsert->back;
+ pETEinsert->next = pETEchase;
+ pETEchase->back->next = pETEinsert;
+ pETEchase->back = pETEinsert;
+ pETEinsert->back = pETEchaseBackTMP;
+ changed = 1;
+ }
+ }
+ return(changed);
+}
+
+/*
+ * Clean up our act.
+ */
+void
+miFreeStorage(pSLLBlock)
+ register ScanLineListBlock *pSLLBlock;
+{
+ register ScanLineListBlock *tmpSLLBlock;
+
+ while (pSLLBlock)
+ {
+ tmpSLLBlock = pSLLBlock->next;
+ free(pSLLBlock);
+ pSLLBlock = tmpSLLBlock;
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mipushpxl.c b/nx-X11/programs/Xserver/mi/mipushpxl.c
new file mode 100644
index 000000000..2bea5ef85
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mipushpxl.c
@@ -0,0 +1,274 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mi.h"
+#include "servermd.h"
+
+#define NPT 128
+
+/* These were stolen from mfb. They don't really belong here. */
+#define LONG2CHARSSAMEORDER(x) ((MiBits)(x))
+#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \
+ | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \
+ | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \
+ | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) )
+
+
+#define PGSZB 4
+#define PPW (PGSZB<<3) /* assuming 8 bits per byte */
+#define PGSZ PPW
+#define PLST (PPW-1)
+#define PIM PLST
+#define PWSH 5
+
+/* miPushPixels -- squeegees the fill style of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+
+WARNING:
+ this code works if the 1-bit deep pixmap format returned by GetSpans
+is the same as the format defined by the mfb code (i.e. 32-bit padding
+per scanline, scanline unit = 32 bits; later, this might mean
+bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
+
+ */
+
+/*
+ * in order to have both (MSB_FIRST and LSB_FIRST) versions of this
+ * in the server, we need to rename one of them
+ */
+void
+miPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ int h, dxDivPPW, ibEnd;
+ MiBits *pwLineStart;
+ register MiBits *pw, *pwEnd;
+ register MiBits msk;
+ register int ib, w;
+ register int ipt; /* index into above arrays */
+ Bool fInBox;
+ DDXPointRec pt[NPT], ptThisLine;
+ int width[NPT];
+#ifdef XFree86Server
+ MiBits startmask;
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ startmask = (MiBits)(-1) ^
+ LONG2CHARSSAMEORDER((MiBits)(-1) << 1);
+ else
+ startmask = (MiBits)(-1) ^
+ LONG2CHARSSAMEORDER((MiBits)(-1) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ startmask = (MiBits)(-1) ^
+ LONG2CHARSDIFFORDER((MiBits)(-1) << 1);
+ else
+ startmask = (MiBits)(-1) ^
+ LONG2CHARSDIFFORDER((MiBits)(-1) >> 1);
+#endif
+
+ pwLineStart = (MiBits *)malloc(BitmapBytePad(dx));
+ if (!pwLineStart)
+ return;
+ ipt = 0;
+ dxDivPPW = dx/PPW;
+
+ for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
+ h < dy;
+ h++, ptThisLine.y++)
+ {
+
+ (*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
+ &ptThisLine, &dx, 1, (char *)pwLineStart);
+
+ pw = pwLineStart;
+ /* Process all words which are fully in the pixmap */
+
+ fInBox = FALSE;
+ pwEnd = pwLineStart + dxDivPPW;
+ while(pw < pwEnd)
+ {
+ w = *pw;
+#ifdef XFree86Server
+ msk = startmask;
+#else
+ msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
+#endif
+ for(ib = 0; ib < PPW; ib++)
+ {
+ if(w & msk)
+ {
+ if(!fInBox)
+ {
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC,
+ NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ /* end box */
+ fInBox = FALSE;
+ }
+ }
+#ifdef XFree86Server
+ /* This is not quite right, but it'll do for now */
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
+ else
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
+ else
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
+#else
+ msk = SCRRIGHT(msk, 1);
+#endif
+ }
+ pw++;
+ }
+ ibEnd = dx & PIM;
+ if(ibEnd)
+ {
+ /* Process final partial word on line */
+ w = *pw;
+#ifdef XFree86Server
+ msk = startmask;
+#else
+ msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
+#endif
+ for(ib = 0; ib < ibEnd; ib++)
+ {
+ if(w & msk)
+ {
+ if(!fInBox)
+ {
+ /* start new box */
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable,
+ pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ fInBox = FALSE;
+ }
+ }
+#ifdef XFree86Server
+ /* This is not quite right, but it'll do for now */
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
+ else
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
+ else
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
+#else
+ msk = SCRRIGHT(msk, 1);
+#endif
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ width[ipt] = dx + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ }
+ }
+ free(pwLineStart);
+ /* Flush any remaining spans */
+ if (ipt)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/miscanfill.h b/nx-X11/programs/Xserver/mi/miscanfill.h
new file mode 100644
index 000000000..e318c45b4
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miscanfill.h
@@ -0,0 +1,147 @@
+/*
+
+Copyright 1987, 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.
+
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SCANFILLINCLUDED
+#define SCANFILLINCLUDED
+/*
+ * scanfill.h
+ *
+ * Written by Brian Kelleher; Jan 1985
+ *
+ * This file contains a few macros to help track
+ * the edge of a filled object. The object is assumed
+ * to be filled in scanline order, and thus the
+ * algorithm used is an extension of Bresenham's line
+ * drawing algorithm which assumes that y is always the
+ * major axis.
+ * Since these pieces of code are the same for any filled shape,
+ * it is more convenient to gather the library in one
+ * place, but since these pieces of code are also in
+ * the inner loops of output primitives, procedure call
+ * overhead is out of the question.
+ * See the author for a derivation if needed.
+ */
+
+
+/*
+ * In scan converting polygons, we want to choose those pixels
+ * which are inside the polygon. Thus, we add .5 to the starting
+ * x coordinate for both left and right edges. Now we choose the
+ * first pixel which is inside the pgon for the left edge and the
+ * first pixel which is outside the pgon for the right edge.
+ * Draw the left pixel, but not the right.
+ *
+ * How to add .5 to the starting x coordinate:
+ * If the edge is moving to the right, then subtract dy from the
+ * error term from the general form of the algorithm.
+ * If the edge is moving to the left, then add dy to the error term.
+ *
+ * The reason for the difference between edges moving to the left
+ * and edges moving to the right is simple: If an edge is moving
+ * to the right, then we want the algorithm to flip immediately.
+ * If it is moving to the left, then we don't want it to flip until
+ * we traverse an entire pixel.
+ */
+#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
+ int dx; /* local storage */ \
+\
+ /* \
+ * if the edge is horizontal, then it is ignored \
+ * and assumed not to be processed. Otherwise, do this stuff. \
+ */ \
+ if ((dy) != 0) { \
+ xStart = (x1); \
+ dx = (x2) - xStart; \
+ if (dx < 0) { \
+ m = dx / (dy); \
+ m1 = m - 1; \
+ incr1 = -2 * dx + 2 * (dy) * m1; \
+ incr2 = -2 * dx + 2 * (dy) * m; \
+ d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
+ } else { \
+ m = dx / (dy); \
+ m1 = m + 1; \
+ incr1 = 2 * dx - 2 * (dy) * m1; \
+ incr2 = 2 * dx - 2 * (dy) * m; \
+ d = -2 * m * (dy) + 2 * dx; \
+ } \
+ } \
+}
+
+#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
+ if (m1 > 0) { \
+ if (d > 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } else {\
+ if (d >= 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } \
+}
+
+
+/*
+ * This structure contains all of the information needed
+ * to run the bresenham algorithm.
+ * The variables may be hardcoded into the declarations
+ * instead of using this structure to make use of
+ * register declarations.
+ */
+typedef struct {
+ int minor; /* minor axis */
+ int d; /* decision variable */
+ int m, m1; /* slope and slope+1 */
+ int incr1, incr2; /* error increments */
+} BRESINFO;
+
+
+#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
+ BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
+ bres.m, bres.m1, bres.incr1, bres.incr2)
+
+#define BRESINCRPGONSTRUCT(bres) \
+ BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
+
+
+#endif
diff --git a/nx-X11/programs/Xserver/mi/miscrinit.c b/nx-X11/programs/Xserver/mi/miscrinit.c
new file mode 100644
index 000000000..e38284c50
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miscrinit.c
@@ -0,0 +1,368 @@
+/*
+
+Copyright 1990, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "servermd.h"
+#include "misc.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "dix.h"
+#include "miline.h"
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+
+/* We use this structure to propogate some information from miScreenInit to
+ * miCreateScreenResources. miScreenInit allocates the structure, fills it
+ * in, and puts it into pScreen->devPrivate. miCreateScreenResources
+ * extracts the info and frees the structure. We could've accomplished the
+ * same thing by adding fields to the screen structure, but they would have
+ * ended up being redundant, and would have exposed this mi implementation
+ * detail to the whole server.
+ */
+
+typedef struct
+{
+ void * pbits; /* pointer to framebuffer */
+ int width; /* delta to add to a framebuffer addr to move one row down */
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+
+/* this plugs into pScreen->ModifyPixmapHeader */
+Bool
+miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
+ pPixData)
+ PixmapPtr pPixmap;
+ int width;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int devKind;
+ void *pPixData;
+{
+ if (!pPixmap)
+ return FALSE;
+
+ /*
+ * If all arguments are specified, reinitialize everything (including
+ * validated state).
+ */
+ if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
+ (devKind > 0) && pPixData) {
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = devKind;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = pPixData;
+ } else {
+ /*
+ * Only modify specified fields, keeping all others intact.
+ */
+
+ if (width > 0)
+ pPixmap->drawable.width = width;
+
+ if (height > 0)
+ pPixmap->drawable.height = height;
+
+ if (depth > 0)
+ pPixmap->drawable.depth = depth;
+
+ if (bitsPerPixel > 0)
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ else if ((bitsPerPixel < 0) && (depth > 0))
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+
+ /*
+ * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for
+ * other purposes.
+ */
+ if (devKind > 0)
+ pPixmap->devKind = devKind;
+ else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+ pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
+ pPixmap->drawable.depth);
+
+ if (pPixData)
+ pPixmap->devPrivate.ptr = pPixData;
+ }
+ return TRUE;
+}
+
+
+/*ARGSUSED*/
+Bool
+miCloseScreen (pScreen)
+ ScreenPtr pScreen;
+{
+ return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
+}
+
+/* With the introduction of pixmap privates, the "screen pixmap" can no
+ * longer be created in miScreenInit, since all the modules that could
+ * possibly ask for pixmap private space have not been initialized at
+ * that time. pScreen->CreateScreenResources is called after all
+ * possible private-requesting modules have been inited; we create the
+ * screen pixmap here.
+ */
+Bool
+miCreateScreenResources(pScreen)
+ ScreenPtr pScreen;
+{
+ miScreenInitParmsPtr pScrInitParms;
+ void * value;
+
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+
+ /* if width is non-zero, pScreen->devPrivate will be a pixmap
+ * else it will just take the value pbits
+ */
+ if (pScrInitParms->width)
+ {
+ PixmapPtr pPixmap;
+
+ /* create a pixmap with no data, then redirect it to point to
+ * the screen
+ */
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
+ if (!pPixmap)
+ return FALSE;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
+ pScreen->height, pScreen->rootDepth,
+ BitsPerPixel(pScreen->rootDepth),
+ PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
+ pScrInitParms->pbits))
+ return FALSE;
+ value = (void *)pPixmap;
+ }
+ else
+ {
+ value = pScrInitParms->pbits;
+ }
+ free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
+ pScreen->devPrivate = value; /* pPixmap or pbits */
+ return TRUE;
+}
+
+Bool
+miScreenDevPrivateInit(pScreen, width, pbits)
+ register ScreenPtr pScreen;
+ int width;
+ void * pbits;
+{
+ miScreenInitParmsPtr pScrInitParms;
+
+ /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
+ * to the screen, until CreateScreenResources can put them in the
+ * screen pixmap.
+ */
+ pScrInitParms = (miScreenInitParmsPtr)malloc(sizeof(miScreenInitParmsRec));
+ if (!pScrInitParms)
+ return FALSE;
+ pScrInitParms->pbits = pbits;
+ pScrInitParms->width = width;
+ pScreen->devPrivate = (void *)pScrInitParms;
+ return TRUE;
+}
+
+Bool
+miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
+ register ScreenPtr pScreen;
+ void * pbits; /* pointer to screen bits */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+ int rootDepth; /* depth of root window */
+ int numDepths; /* number of depths supported */
+ DepthRec *depths; /* supported depths */
+ VisualID rootVisual; /* root visual */
+ int numVisuals; /* number of visuals supported */
+ VisualRec *visuals; /* supported visuals */
+{
+ pScreen->width = xsize;
+ pScreen->height = ysize;
+ pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
+ pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
+ pScreen->numDepths = numDepths;
+ pScreen->rootDepth = rootDepth;
+ pScreen->allowedDepths = depths;
+ pScreen->rootVisual = rootVisual;
+ /* defColormap */
+ pScreen->minInstalledCmaps = 1;
+ pScreen->maxInstalledCmaps = 1;
+ pScreen->backingStoreSupport = NotUseful;
+ pScreen->saveUnderSupport = NotUseful;
+ /* whitePixel, blackPixel */
+ pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
+ pScreen->CreateScreenResources = miCreateScreenResources;
+ pScreen->GetScreenPixmap = miGetScreenPixmap;
+ pScreen->SetScreenPixmap = miSetScreenPixmap;
+ pScreen->numVisuals = numVisuals;
+ pScreen->visuals = visuals;
+ if (width)
+ {
+#ifdef MITSHM
+ ShmRegisterFbFuncs(pScreen);
+#endif
+ pScreen->CloseScreen = miCloseScreen;
+ }
+ /* else CloseScreen */
+ /* QueryBestSize, SaveScreen, GetImage, GetSpans */
+ pScreen->PointerNonInterestBox = (PointerNonInterestBoxProcPtr) 0;
+ pScreen->SourceValidate = (SourceValidateProcPtr) 0;
+ /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
+ /* RealizeWindow, UnrealizeWindow */
+ pScreen->ValidateTree = miValidateTree;
+ pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
+ pScreen->WindowExposures = miWindowExposures;
+ /* PaintWindowBackground, PaintWindowBorder, CopyWindow */
+ pScreen->ClearToBackground = miClearToBackground;
+ pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
+ pScreen->RestackWindow = (RestackWindowProcPtr) 0;
+ /* CreatePixmap, DestroyPixmap */
+ /* RealizeFont, UnrealizeFont */
+ /* CreateGC */
+ /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
+ /* ListInstalledColormaps, StoreColors, ResolveColor */
+#ifdef NEED_SCREEN_REGIONS
+ pScreen->RegionCreate = RegionCreate;
+ pScreen->RegionInit = RegionInit;
+ pScreen->RegionCopy = RegionCopy;
+ pScreen->RegionDestroy = RegionDestroy;
+ pScreen->RegionUninit = RegionUninit;
+ pScreen->Intersect = RegionIntersect;
+ pScreen->Union = RegionUnion;
+ pScreen->Subtract = RegionSubtract;
+ pScreen->Inverse = RegionInverse;
+ pScreen->RegionReset = RegionReset;
+ pScreen->TranslateRegion = RegionTranslate;
+ pScreen->RectIn = RegionContainsRect;
+ pScreen->PointInRegion = RegionContainsPoint;
+ pScreen->RegionNotEmpty = RegionNotEmpty;
+ pScreen->RegionEqual = RegionEqual;
+ pScreen->RegionBroken = RegionBroken;
+ pScreen->RegionBreak = RegionBreak;
+ pScreen->RegionEmpty = RegionEmpty;
+ pScreen->RegionExtents = RegionExtents;
+ pScreen->RegionAppend = RegionAppend;
+ pScreen->RegionValidate = RegionValidate;
+#endif /* NEED_SCREEN_REGIONS */
+ /* BitmapToRegion */
+#ifdef NEED_SCREEN_REGIONS
+ pScreen->RectsToRegion = RegionFromRects;
+#endif /* NEED_SCREEN_REGIONS */
+ pScreen->SendGraphicsExpose = miSendGraphicsExpose;
+ pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
+ pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
+ pScreen->blockData = (void *)0;
+ pScreen->wakeupData = (void *)0;
+ pScreen->MarkWindow = miMarkWindow;
+ pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
+ pScreen->ChangeSaveUnder = miChangeSaveUnder;
+ pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
+ pScreen->MoveWindow = miMoveWindow;
+ pScreen->ResizeWindow = miSlideAndSizeWindow;
+ pScreen->GetLayerWindow = miGetLayerWindow;
+ pScreen->HandleExposures = miHandleValidateExposures;
+ pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
+ pScreen->ChangeBorderWidth = miChangeBorderWidth;
+#ifdef SHAPE
+ pScreen->SetShape = miSetShape;
+#endif
+ pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
+
+ pScreen->SaveDoomedAreas = 0;
+ pScreen->RestoreAreas = 0;
+ pScreen->ExposeCopy = 0;
+ pScreen->TranslateBackingStore = 0;
+ pScreen->ClearBackingStore = 0;
+ pScreen->DrawGuarantee = 0;
+
+ miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
+
+ return miScreenDevPrivateInit(pScreen, width, pbits);
+}
+
+int
+miAllocateGCPrivateIndex()
+{
+ static int privateIndex = -1;
+ static unsigned long miGeneration = 0;
+
+ if (miGeneration != serverGeneration)
+ {
+ privateIndex = AllocateGCPrivateIndex();
+ miGeneration = serverGeneration;
+ }
+ return privateIndex;
+}
+
+int miZeroLineScreenIndex;
+unsigned int miZeroLineGeneration = 0;
+
+void
+miSetZeroLineBias(pScreen, bias)
+ ScreenPtr pScreen;
+ unsigned int bias;
+{
+ if (miZeroLineGeneration != serverGeneration)
+ {
+ miZeroLineScreenIndex = AllocateScreenPrivateIndex();
+ miZeroLineGeneration = serverGeneration;
+ }
+ if (miZeroLineScreenIndex >= 0)
+ pScreen->devPrivates[miZeroLineScreenIndex].uval = bias;
+}
+
+PixmapPtr
+miGetScreenPixmap(pScreen)
+ ScreenPtr pScreen;
+{
+ return (PixmapPtr)(pScreen->devPrivate);
+}
+
+void
+miSetScreenPixmap(pPix)
+ PixmapPtr pPix;
+{
+ if (pPix)
+ pPix->drawable.pScreen->devPrivate = (void *)pPix;
+}
diff --git a/nx-X11/programs/Xserver/mi/mispans.c b/nx-X11/programs/Xserver/mi/mispans.c
new file mode 100644
index 000000000..a8762d323
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mispans.c
@@ -0,0 +1,561 @@
+/***********************************************************
+
+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.
+
+
+Copyright 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "mispans.h"
+
+/*
+
+These routines maintain lists of Spans, in order to implement the
+``touch-each-pixel-once'' rules of wide lines and arcs.
+
+Written by Joel McCormack, Summer 1989.
+
+*/
+
+
+void miInitSpanGroup(spanGroup)
+ SpanGroup *spanGroup;
+{
+ spanGroup->size = 0;
+ spanGroup->count = 0;
+ spanGroup->group = NULL;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+} /* InitSpanGroup */
+
+#define YMIN(spans) (spans->points[0].y)
+#define YMAX(spans) (spans->points[spans->count-1].y)
+
+void miSubtractSpans (spanGroup, sub)
+ SpanGroup *spanGroup;
+ Spans *sub;
+{
+ int i, subCount, spansCount;
+ int ymin, ymax, xmin, xmax;
+ Spans *spans;
+ DDXPointPtr subPt, spansPt;
+ int *subWid, *spansWid;
+ int extra;
+
+ ymin = YMIN(sub);
+ ymax = YMAX(sub);
+ spans = spanGroup->group;
+ for (i = spanGroup->count; i; i--, spans++) {
+ if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) {
+ subCount = sub->count;
+ subPt = sub->points;
+ subWid = sub->widths;
+ spansCount = spans->count;
+ spansPt = spans->points;
+ spansWid = spans->widths;
+ extra = 0;
+ for (;;)
+ {
+ while (spansCount && spansPt->y < subPt->y)
+ {
+ spansPt++; spansWid++; spansCount--;
+ }
+ if (!spansCount)
+ break;
+ while (subCount && subPt->y < spansPt->y)
+ {
+ subPt++; subWid++; subCount--;
+ }
+ if (!subCount)
+ break;
+ if (subPt->y == spansPt->y)
+ {
+ xmin = subPt->x;
+ xmax = xmin + *subWid;
+ if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax)
+ {
+ ;
+ }
+ else if (xmin <= spansPt->x)
+ {
+ if (xmax >= spansPt->x + *spansWid)
+ {
+ memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
+ memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
+ spansPt--;
+ spansWid--;
+ spans->count--;
+ extra++;
+ }
+ else
+ {
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ }
+ else
+ {
+ if (xmax >= spansPt->x + *spansWid)
+ {
+ *spansWid = xmin - spansPt->x;
+ }
+ else
+ {
+ if (!extra) {
+ DDXPointPtr newPt;
+ int *newwid;
+
+#define EXTRA 8
+ newPt = (DDXPointPtr) realloc (spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec));
+ if (!newPt)
+ break;
+ spansPt = newPt + (spansPt - spans->points);
+ spans->points = newPt;
+ newwid = (int *) realloc (spans->widths, (spans->count + EXTRA) * sizeof (int));
+ if (!newwid)
+ break;
+ spansWid = newwid + (spansWid - spans->widths);
+ spans->widths = newwid;
+ extra = EXTRA;
+ }
+ memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
+ memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
+ spans->count++;
+ extra--;
+ *spansWid = xmin - spansPt->x;
+ spansWid++;
+ spansPt++;
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ }
+ }
+ spansPt++; spansWid++; spansCount--;
+ }
+ }
+ }
+}
+
+void miAppendSpans(spanGroup, otherGroup, spans)
+ SpanGroup *spanGroup;
+ SpanGroup *otherGroup;
+ Spans *spans;
+{
+ register int ymin, ymax;
+ register int spansCount;
+
+ spansCount = spans->count;
+ if (spansCount > 0) {
+ if (spanGroup->size == spanGroup->count) {
+ spanGroup->size = (spanGroup->size + 8) * 2;
+ spanGroup->group = (Spans *)
+ realloc(spanGroup->group, sizeof(Spans) * spanGroup->size);
+ }
+
+ spanGroup->group[spanGroup->count] = *spans;
+ (spanGroup->count)++;
+ ymin = spans->points[0].y;
+ if (ymin < spanGroup->ymin) spanGroup->ymin = ymin;
+ ymax = spans->points[spansCount - 1].y;
+ if (ymax > spanGroup->ymax) spanGroup->ymax = ymax;
+ if (otherGroup &&
+ otherGroup->ymin < ymax &&
+ ymin < otherGroup->ymax)
+ {
+ miSubtractSpans (otherGroup, spans);
+ }
+ }
+ else
+ {
+ free (spans->points);
+ free (spans->widths);
+ }
+} /* AppendSpans */
+
+void miFreeSpanGroup(spanGroup)
+ SpanGroup *spanGroup;
+{
+ if (spanGroup->group != NULL) free(spanGroup->group);
+}
+
+static void QuickSortSpansX(
+ register DDXPointRec points[],
+ register int widths[],
+ register int numSpans )
+{
+ register int x;
+ register int i, j, m;
+ register DDXPointPtr r;
+
+/* Always called with numSpans > 1 */
+/* Sorts only by x, as all y should be the same */
+
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ register int tw; \
+ \
+ tpt = points[a]; points[a] = points[b]; points[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+ do {
+ if (numSpans < 9) {
+ /* Do insertion sort */
+ register int xprev;
+
+ xprev = points[0].x;
+ i = 1;
+ do { /* while i != numSpans */
+ x = points[i].x;
+ if (xprev > x) {
+ /* points[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; x >= points[j].x; j++) {}
+ tpt = points[i];
+ tw = widths[i];
+ for (k = i; k != j; k--) {
+ points[k] = points[k-1];
+ widths[k] = widths[k-1];
+ }
+ points[j] = tpt;
+ widths[j] = tw;
+ x = points[i].x;
+ } /* if out of order */
+ xprev = x;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (points[m].x > points[0].x) ExchangeSpans(m, 0);
+ if (points[m].x > points[numSpans-1].x) ExchangeSpans(m, numSpans-1);
+ if (points[m].x > points[0].x) ExchangeSpans(m, 0);
+ x = points[0].x;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do {
+ r = &(points[i]);
+ do {
+ r++;
+ i++;
+ } while (i != numSpans && r->x < x);
+ r = &(points[j]);
+ do {
+ r--;
+ j--;
+ } while (x < r->x);
+ if (i < j) ExchangeSpans(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans(0, j);
+
+ /* Recurse */
+ if (numSpans-j-1 > 1)
+ QuickSortSpansX(&points[j+1], &widths[j+1], numSpans-j-1);
+ numSpans = j;
+ } while (numSpans > 1);
+} /* QuickSortSpans */
+
+
+static int UniquifySpansX(
+ Spans *spans,
+ register DDXPointRec *newPoints,
+ register int *newWidths )
+{
+ register int newx1, newx2, oldpt, i, y;
+ register DDXPointRec *oldPoints;
+ register int *oldWidths;
+ int *startNewWidths;
+
+/* Always called with numSpans > 1 */
+/* Uniquify the spans, and stash them into newPoints and newWidths. Return the
+ number of unique spans. */
+
+
+ startNewWidths = newWidths;
+
+ oldPoints = spans->points;
+ oldWidths = spans->widths;
+
+ y = oldPoints->y;
+ newx1 = oldPoints->x;
+ newx2 = newx1 + *oldWidths;
+
+ for (i = spans->count-1; i != 0; i--) {
+ oldPoints++;
+ oldWidths++;
+ oldpt = oldPoints->x;
+ if (oldpt > newx2) {
+ /* Write current span, start a new one */
+ newPoints->x = newx1;
+ newPoints->y = y;
+ *newWidths = newx2 - newx1;
+ newPoints++;
+ newWidths++;
+ newx1 = oldpt;
+ newx2 = oldpt + *oldWidths;
+ } else {
+ /* extend current span, if old extends beyond new */
+ oldpt = oldpt + *oldWidths;
+ if (oldpt > newx2) newx2 = oldpt;
+ }
+ } /* for */
+
+ /* Write final span */
+ newPoints->x = newx1;
+ *newWidths = newx2 - newx1;
+ newPoints->y = y;
+
+ return (newWidths - startNewWidths) + 1;
+} /* UniquifySpansX */
+
+void
+miDisposeSpanGroup (spanGroup)
+ SpanGroup *spanGroup;
+{
+ int i;
+ Spans *spans;
+
+ for (i = 0; i < spanGroup->count; i++)
+ {
+ spans = spanGroup->group + i;
+ free (spans->points);
+ free (spans->widths);
+ }
+}
+
+void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ SpanGroup *spanGroup;
+{
+ register int i;
+ register Spans *spans;
+ register Spans *yspans;
+ register int *ysizes;
+ register int ymin, ylength;
+
+ /* Outgoing spans for one big call to FillSpans */
+ register DDXPointPtr points;
+ register int *widths;
+ register int count;
+
+ if (spanGroup->count == 0) return;
+
+ if (spanGroup->count == 1) {
+ /* Already should be sorted, unique */
+ spans = spanGroup->group;
+ (*pGC->ops->FillSpans)
+ (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
+ free(spans->points);
+ free(spans->widths);
+ }
+ else
+ {
+ /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */
+ /* This seems to be the fastest thing to do. I've tried sorting on
+ both x and y at the same time rather than creating into all those
+ y buckets, but it was somewhat slower. */
+
+ ymin = spanGroup->ymin;
+ ylength = spanGroup->ymax - ymin + 1;
+
+ /* Allocate Spans for y buckets */
+ yspans = (Spans *) malloc(ylength * sizeof(Spans));
+ ysizes = (int *) malloc(ylength * sizeof (int));
+
+ if (!yspans || !ysizes)
+ {
+ if (yspans)
+ free (yspans);
+ if (ysizes)
+ free (ysizes);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+
+ for (i = 0; i != ylength; i++) {
+ ysizes[i] = 0;
+ yspans[i].count = 0;
+ yspans[i].points = NULL;
+ yspans[i].widths = NULL;
+ }
+
+ /* Go through every single span and put it into the correct bucket */
+ count = 0;
+ for (i = 0, spans = spanGroup->group;
+ i != spanGroup->count;
+ i++, spans++) {
+ int index;
+ int j;
+
+ for (j = 0, points = spans->points, widths = spans->widths;
+ j != spans->count;
+ j++, points++, widths++) {
+ index = points->y - ymin;
+ if (index >= 0 && index < ylength) {
+ Spans *newspans = &(yspans[index]);
+ if (newspans->count == ysizes[index]) {
+ DDXPointPtr newpoints;
+ int *newwidths;
+ ysizes[index] = (ysizes[index] + 8) * 2;
+ newpoints = (DDXPointPtr) realloc(
+ newspans->points,
+ ysizes[index] * sizeof(DDXPointRec));
+ newwidths = (int *) realloc(
+ newspans->widths,
+ ysizes[index] * sizeof(int));
+ if (!newpoints || !newwidths)
+ {
+ int i;
+
+ for (i = 0; i < ylength; i++)
+ {
+ free (yspans[i].points);
+ free (yspans[i].widths);
+ }
+ free (yspans);
+ free (ysizes);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+ newspans->points = newpoints;
+ newspans->widths = newwidths;
+ }
+ newspans->points[newspans->count] = *points;
+ newspans->widths[newspans->count] = *widths;
+ (newspans->count)++;
+ } /* if y value of span in range */
+ } /* for j through spans */
+ count += spans->count;
+ free(spans->points);
+ spans->points = NULL;
+ free(spans->widths);
+ spans->widths = NULL;
+ } /* for i thorough Spans */
+
+ /* Now sort by x and uniquify each bucket into the final array */
+ points = (DDXPointPtr) malloc(count * sizeof(DDXPointRec));
+ widths = (int *) malloc(count * sizeof(int));
+ if (!points || !widths)
+ {
+ int i;
+
+ for (i = 0; i < ylength; i++)
+ {
+ free (yspans[i].points);
+ free (yspans[i].widths);
+ }
+ free (yspans);
+ free (ysizes);
+ if (points)
+ free (points);
+ if (widths)
+ free (widths);
+ return;
+ }
+ count = 0;
+ for (i = 0; i != ylength; i++) {
+ int ycount = yspans[i].count;
+ if (ycount > 0) {
+ if (ycount > 1) {
+ QuickSortSpansX(yspans[i].points, yspans[i].widths, ycount);
+ count += UniquifySpansX
+ (&(yspans[i]), &(points[count]), &(widths[count]));
+ } else {
+ points[count] = yspans[i].points[0];
+ widths[count] = yspans[i].widths[0];
+ count++;
+ }
+ free(yspans[i].points);
+ free(yspans[i].widths);
+ }
+ }
+
+ (*pGC->ops->FillSpans) (pDraw, pGC, count, points, widths, TRUE);
+ free(points);
+ free(widths);
+ free(yspans);
+ free(ysizes);
+ }
+
+ spanGroup->count = 0;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+}
+
+
+void miFillSpanGroup(pDraw, pGC, spanGroup)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ SpanGroup *spanGroup;
+{
+ register int i;
+ register Spans *spans;
+
+ for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
+ (*pGC->ops->FillSpans)
+ (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
+ free(spans->points);
+ free(spans->widths);
+ }
+
+ spanGroup->count = 0;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+} /* FillSpanGroup */
diff --git a/nx-X11/programs/Xserver/mi/mispans.h b/nx-X11/programs/Xserver/mi/mispans.h
new file mode 100644
index 000000000..0f980bff7
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mispans.h
@@ -0,0 +1,115 @@
+/***********************************************************
+
+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.
+
+
+Copyright 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+typedef struct {
+ int count; /* number of spans */
+ DDXPointPtr points; /* pointer to list of start points */
+ int *widths; /* pointer to list of widths */
+} Spans;
+
+typedef struct {
+ int size; /* Total number of *Spans allocated */
+ int count; /* Number of *Spans actually in group */
+ Spans *group; /* List of Spans */
+ int ymin, ymax; /* Min, max y values encountered */
+} SpanGroup;
+
+/* Initialize SpanGroup. MUST BE DONE before use. */
+extern void miInitSpanGroup(
+ SpanGroup * /*spanGroup*/
+);
+
+/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
+extern void miAppendSpans(
+ SpanGroup * /*spanGroup*/,
+ SpanGroup * /*otherGroup*/,
+ Spans * /*spans*/
+);
+
+/* Paint a span group, possibly with some overlap */
+extern void miFillSpanGroup(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ SpanGroup * /*spanGroup*/
+);
+
+/* Paint a span group, insuring that each pixel is painted at most once */
+extern void miFillUniqueSpanGroup(
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ SpanGroup * /*spanGroup*/
+);
+
+/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
+extern void miFreeSpanGroup(
+ SpanGroup * /*spanGroup*/
+);
+
+extern void miSubtractSpans(
+ SpanGroup * /*spanGroup*/,
+ Spans * /*sub*/
+);
+
+extern void miDisposeSpanGroup(
+ SpanGroup * /*spanGroup*/
+);
+
+extern int RegionClipSpans(
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ DDXPointPtr /*pptNew*/,
+ int * /*pwidthNew*/,
+ int /*fSorted*/
+);
+
+/* Rops which must use span groups */
+#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
+#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
+
diff --git a/nx-X11/programs/Xserver/mi/misprite.c b/nx-X11/programs/Xserver/mi/misprite.c
new file mode 100644
index 000000000..151de776d
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/misprite.c
@@ -0,0 +1,828 @@
+/*
+ * misprite.c
+ *
+ * machine independent software sprite routines
+ */
+
+
+/*
+
+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.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# include <nx-X11/X.h>
+# include <nx-X11/Xproto.h>
+# include "misc.h"
+# include "pixmapstr.h"
+# include "input.h"
+# include "mi.h"
+# include "cursorstr.h"
+# include <X11/fonts/font.h>
+# include "scrnintstr.h"
+# include "colormapst.h"
+# include "windowstr.h"
+# include "gcstruct.h"
+# include "mipointer.h"
+# include "mispritest.h"
+# include "dixfontstr.h"
+# include <X11/fonts/fontstruct.h>
+
+#ifdef RENDER
+# include "mipict.h"
+#endif
+# include "damage.h"
+
+#define SPRITE_DEBUG_ENABLE 0
+#if SPRITE_DEBUG_ENABLE
+#define SPRITE_DEBUG(x) ErrorF x
+#else
+#define SPRITE_DEBUG(x)
+#endif
+
+/*
+ * screen wrappers
+ */
+
+static int miSpriteScreenIndex;
+static unsigned long miSpriteGeneration = 0;
+
+static Bool miSpriteCloseScreen(ScreenPtr pScreen);
+static void miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
+ int w, int h, unsigned int format,
+ unsigned long planemask, char *pdstLine);
+static void miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans,
+ char *pdstStart);
+static void miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
+ int width, int height);
+static void miSpriteCopyWindow (WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+static void miSpriteBlockHandler(int i, void * blockData,
+ void * pTimeout,
+ void * pReadMask);
+static void miSpriteInstallColormap(ColormapPtr pMap);
+static void miSpriteStoreColors(ColormapPtr pMap, int ndef,
+ xColorItem *pdef);
+
+static void miSpriteSaveDoomedAreas(WindowPtr pWin,
+ RegionPtr pObscured, int dx,
+ int dy);
+static void miSpriteComputeSaved(ScreenPtr pScreen);
+
+#define SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+/*
+ * void *-sprite method table
+ */
+
+static Bool miSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static Bool miSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+static void miSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCursor,
+ int x, int y);
+static void miSpriteMoveCursor(ScreenPtr pScreen, int x, int y);
+
+miPointerSpriteFuncRec miSpritePointerFuncs = {
+ miSpriteRealizeCursor,
+ miSpriteUnrealizeCursor,
+ miSpriteSetCursor,
+ miSpriteMoveCursor,
+};
+
+/*
+ * other misc functions
+ */
+
+static void miSpriteRemoveCursor(ScreenPtr pScreen);
+static void miSpriteRestoreCursor(ScreenPtr pScreen);
+
+static void
+miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ ScreenPtr pScreen = closure;
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pScreenPriv->isUp &&
+ RegionContainsRect(pRegion, &pScreenPriv->saved) != rgnOUT)
+ {
+ SPRITE_DEBUG(("Damage remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ }
+}
+
+/*
+ * miSpriteInitialize -- called from device-dependent screen
+ * initialization proc after all of the function pointers have
+ * been stored in the screen structure.
+ */
+
+Bool
+miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
+ ScreenPtr pScreen;
+ miSpriteCursorFuncPtr cursorFuncs;
+ miPointerScreenFuncPtr screenFuncs;
+{
+ miSpriteScreenPtr pScreenPriv;
+ VisualPtr pVisual;
+
+ if (!DamageSetup (pScreen))
+ return FALSE;
+
+ if (miSpriteGeneration != serverGeneration)
+ {
+ miSpriteScreenIndex = AllocateScreenPrivateIndex ();
+ if (miSpriteScreenIndex < 0)
+ return FALSE;
+ miSpriteGeneration = serverGeneration;
+ }
+
+ pScreenPriv = (miSpriteScreenPtr) malloc (sizeof (miSpriteScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+
+ pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
+ (DamageDestroyFunc) 0,
+ DamageReportRawRegion,
+ TRUE,
+ pScreen,
+ (void *) pScreen);
+
+ if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
+ {
+ free ((void *) pScreenPriv);
+ return FALSE;
+ }
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+ pScreenPriv->pVisual = pVisual;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreenPriv->SourceValidate = pScreen->SourceValidate;
+
+ pScreenPriv->CopyWindow = pScreen->CopyWindow;
+
+ pScreenPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
+
+ pScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreenPriv->StoreColors = pScreen->StoreColors;
+
+ pScreenPriv->BlockHandler = pScreen->BlockHandler;
+
+ pScreenPriv->pCursor = NULL;
+ pScreenPriv->x = 0;
+ pScreenPriv->y = 0;
+ pScreenPriv->isUp = FALSE;
+ pScreenPriv->shouldBeUp = FALSE;
+ pScreenPriv->pCacheWin = NullWindow;
+ pScreenPriv->isInCacheWin = FALSE;
+ pScreenPriv->checkPixels = TRUE;
+ pScreenPriv->pInstalledMap = NULL;
+ pScreenPriv->pColormap = NULL;
+ pScreenPriv->funcs = cursorFuncs;
+ pScreenPriv->colors[SOURCE_COLOR].red = 0;
+ pScreenPriv->colors[SOURCE_COLOR].green = 0;
+ pScreenPriv->colors[SOURCE_COLOR].blue = 0;
+ pScreenPriv->colors[MASK_COLOR].red = 0;
+ pScreenPriv->colors[MASK_COLOR].green = 0;
+ pScreenPriv->colors[MASK_COLOR].blue = 0;
+ pScreen->devPrivates[miSpriteScreenIndex].ptr = (void *) pScreenPriv;
+
+ pScreen->CloseScreen = miSpriteCloseScreen;
+ pScreen->GetImage = miSpriteGetImage;
+ pScreen->GetSpans = miSpriteGetSpans;
+ pScreen->SourceValidate = miSpriteSourceValidate;
+
+ pScreen->CopyWindow = miSpriteCopyWindow;
+
+ pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas;
+
+ pScreen->InstallColormap = miSpriteInstallColormap;
+ pScreen->StoreColors = miSpriteStoreColors;
+
+ pScreen->BlockHandler = miSpriteBlockHandler;
+
+ return TRUE;
+}
+
+/*
+ * Screen wrappers
+ */
+
+/*
+ * CloseScreen wrapper -- unwrap everything, free the private data
+ * and call the wrapped function
+ */
+
+static Bool
+miSpriteCloseScreen (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->SourceValidate = pScreenPriv->SourceValidate;
+ pScreen->BlockHandler = pScreenPriv->BlockHandler;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+
+ pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
+ miSpriteIsUpFALSE (pScreen, pScreenPriv);
+ DamageDestroy (pScreenPriv->pDamage);
+
+ free ((void *) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+static void
+miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planemask;
+ char *pdstLine;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, GetImage);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ pScreenPriv->isUp &&
+ ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
+ {
+ SPRITE_DEBUG (("GetImage remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+
+ SCREEN_EPILOGUE (pScreen, GetImage, miSpriteGetImage);
+}
+
+static void
+miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
+ DrawablePtr pDrawable;
+ int wMax;
+ DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ char *pdstStart;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, GetSpans);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
+ {
+ register DDXPointPtr pts;
+ register int *widths;
+ register int nPts;
+ register int xorg,
+ yorg;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ for (pts = ppt, widths = pwidth, nPts = nspans;
+ nPts--;
+ pts++, widths++)
+ {
+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
+ pts->x+xorg,*widths))
+ {
+ SPRITE_DEBUG (("GetSpans remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ break;
+ }
+ }
+ }
+
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+
+ SCREEN_EPILOGUE (pScreen, GetSpans, miSpriteGetSpans);
+}
+
+static void
+miSpriteSourceValidate (pDrawable, x, y, width, height)
+ DrawablePtr pDrawable;
+ int x, y, width, height;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, SourceValidate);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
+ ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
+ x, y, width, height))
+ {
+ SPRITE_DEBUG (("SourceValidate remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+
+ SCREEN_EPILOGUE (pScreen, SourceValidate, miSpriteSourceValidate);
+}
+
+static void
+miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, CopyWindow);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ /*
+ * Damage will take care of destination check
+ */
+ if (pScreenPriv->isUp &&
+ RegionContainsRect(prgnSrc, &pScreenPriv->saved) != rgnOUT)
+ {
+ SPRITE_DEBUG (("CopyWindow remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ SCREEN_EPILOGUE (pScreen, CopyWindow, miSpriteCopyWindow);
+}
+
+static void
+miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
+ int i;
+ void * blockData;
+ void * pTimeout;
+ void * pReadmask;
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ miSpriteScreenPtr pPriv;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, BlockHandler);
+
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+ SCREEN_EPILOGUE(pScreen, BlockHandler, miSpriteBlockHandler);
+
+ if (!pPriv->isUp && pPriv->shouldBeUp)
+ {
+ SPRITE_DEBUG (("BlockHandler restore\n"));
+ miSpriteRestoreCursor (pScreen);
+ }
+}
+
+static void
+miSpriteInstallColormap (pMap)
+ ColormapPtr pMap;
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ miSpriteScreenPtr pPriv;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, InstallColormap);
+
+ (*pScreen->InstallColormap) (pMap);
+
+ SCREEN_EPILOGUE(pScreen, InstallColormap, miSpriteInstallColormap);
+
+ pPriv->pInstalledMap = pMap;
+ if (pPriv->pColormap != pMap)
+ {
+ pPriv->checkPixels = TRUE;
+ if (pPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ }
+}
+
+static void
+miSpriteStoreColors (pMap, ndef, pdef)
+ ColormapPtr pMap;
+ int ndef;
+ xColorItem *pdef;
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ miSpriteScreenPtr pPriv;
+ int i;
+ int updated;
+ VisualPtr pVisual;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, StoreColors);
+
+ (*pScreen->StoreColors) (pMap, ndef, pdef);
+
+ SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
+
+ if (pPriv->pColormap == pMap)
+ {
+ updated = 0;
+ pVisual = pMap->pVisual;
+ if (pVisual->class == DirectColor)
+ {
+ /* Direct color - match on any of the subfields */
+
+#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
+
+#define UpdateDAC(plane,dac,mask) {\
+ if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
+ pPriv->colors[plane].dac = pdef[i].dac; \
+ updated = 1; \
+ } \
+}
+
+#define CheckDirect(plane) \
+ UpdateDAC(plane,red,redMask) \
+ UpdateDAC(plane,green,greenMask) \
+ UpdateDAC(plane,blue,blueMask)
+
+ for (i = 0; i < ndef; i++)
+ {
+ CheckDirect (SOURCE_COLOR)
+ CheckDirect (MASK_COLOR)
+ }
+ }
+ else
+ {
+ /* PseudoColor/GrayScale - match on exact pixel */
+ for (i = 0; i < ndef; i++)
+ {
+ if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
+ {
+ pPriv->colors[SOURCE_COLOR] = pdef[i];
+ if (++updated == 2)
+ break;
+ }
+ if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
+ {
+ pPriv->colors[MASK_COLOR] = pdef[i];
+ if (++updated == 2)
+ break;
+ }
+ }
+ }
+ if (updated)
+ {
+ pPriv->checkPixels = TRUE;
+ if (pPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ }
+ }
+}
+
+static void
+miSpriteFindColors (ScreenPtr pScreen)
+{
+ miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
+ pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ CursorPtr pCursor;
+ xColorItem *sourceColor, *maskColor;
+
+ pCursor = pScreenPriv->pCursor;
+ sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
+ maskColor = &pScreenPriv->colors[MASK_COLOR];
+ if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
+ !(pCursor->foreRed == sourceColor->red &&
+ pCursor->foreGreen == sourceColor->green &&
+ pCursor->foreBlue == sourceColor->blue &&
+ pCursor->backRed == maskColor->red &&
+ pCursor->backGreen == maskColor->green &&
+ pCursor->backBlue == maskColor->blue))
+ {
+ pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
+ sourceColor->red = pCursor->foreRed;
+ sourceColor->green = pCursor->foreGreen;
+ sourceColor->blue = pCursor->foreBlue;
+ FakeAllocColor (pScreenPriv->pColormap, sourceColor);
+ maskColor->red = pCursor->backRed;
+ maskColor->green = pCursor->backGreen;
+ maskColor->blue = pCursor->backBlue;
+ FakeAllocColor (pScreenPriv->pColormap, maskColor);
+ /* "free" the pixels right away, don't let this confuse you */
+ FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
+ FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
+ }
+ pScreenPriv->checkPixels = FALSE;
+}
+
+/*
+ * BackingStore wrappers
+ */
+
+static void
+miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pObscured;
+ int dx, dy;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+ BoxRec cursorBox;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ cursorBox = pScreenPriv->saved;
+
+ if (dx || dy)
+ {
+ cursorBox.x1 += dx;
+ cursorBox.y1 += dy;
+ cursorBox.x2 += dx;
+ cursorBox.y2 += dy;
+ }
+ if (RegionContainsRect(pObscured, &cursorBox) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
+
+ SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, miSpriteSaveDoomedAreas);
+}
+
+/*
+ * miPointer interface routines
+ */
+
+#define SPRITE_PAD 8
+
+static Bool
+miSpriteRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pCursor == pScreenPriv->pCursor)
+ pScreenPriv->checkPixels = TRUE;
+ return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miSpriteUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
+}
+
+static void
+miSpriteSetCursor (pScreen, pCursor, x, y)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ int x;
+ int y;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (!pCursor)
+ {
+ pScreenPriv->shouldBeUp = FALSE;
+ if (pScreenPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ pScreenPriv->pCursor = 0;
+ return;
+ }
+ pScreenPriv->shouldBeUp = TRUE;
+ if (pScreenPriv->x == x &&
+ pScreenPriv->y == y &&
+ pScreenPriv->pCursor == pCursor &&
+ !pScreenPriv->checkPixels)
+ {
+ return;
+ }
+ pScreenPriv->x = x;
+ pScreenPriv->y = y;
+ pScreenPriv->pCacheWin = NullWindow;
+ if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
+ {
+ pScreenPriv->pCursor = pCursor;
+ miSpriteFindColors (pScreen);
+ }
+ if (pScreenPriv->isUp) {
+ int sx, sy;
+ /*
+ * check to see if the old saved region
+ * encloses the new sprite, in which case we use
+ * the flicker-free MoveCursor primitive.
+ */
+ sx = pScreenPriv->x - (int)pCursor->bits->xhot;
+ sy = pScreenPriv->y - (int)pCursor->bits->yhot;
+ if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
+ sx < pScreenPriv->saved.x2 &&
+ sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
+ sy < pScreenPriv->saved.y2 &&
+ (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
+ (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1
+ )
+ {
+ DamageDrawInternal (pScreen, TRUE);
+ miSpriteIsUpFALSE (pScreen, pScreenPriv);
+ if (!(sx >= pScreenPriv->saved.x1 &&
+ sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
+ sy >= pScreenPriv->saved.y1 &&
+ sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
+ {
+ int oldx1, oldy1, dx, dy;
+
+ oldx1 = pScreenPriv->saved.x1;
+ oldy1 = pScreenPriv->saved.y1;
+ dx = oldx1 - (sx - SPRITE_PAD);
+ dy = oldy1 - (sy - SPRITE_PAD);
+ pScreenPriv->saved.x1 -= dx;
+ pScreenPriv->saved.y1 -= dy;
+ pScreenPriv->saved.x2 -= dx;
+ pScreenPriv->saved.y2 -= dy;
+ (void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
+ dx, dy);
+ }
+ (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
+ sx - pScreenPriv->saved.x1,
+ sy - pScreenPriv->saved.y1,
+ pScreenPriv->colors[SOURCE_COLOR].pixel,
+ pScreenPriv->colors[MASK_COLOR].pixel);
+ miSpriteIsUpTRUE (pScreen, pScreenPriv);
+ DamageDrawInternal (pScreen, FALSE);
+ }
+ else
+ {
+ SPRITE_DEBUG (("SetCursor remove\n"));
+ miSpriteRemoveCursor (pScreen);
+ }
+ }
+ if (!pScreenPriv->isUp && pScreenPriv->pCursor)
+ {
+ SPRITE_DEBUG (("SetCursor restore\n"));
+ miSpriteRestoreCursor (pScreen);
+ }
+}
+
+static void
+miSpriteMoveCursor (pScreen, x, y)
+ ScreenPtr pScreen;
+ int x, y;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
+}
+
+/*
+ * undraw/draw cursor
+ */
+
+static void
+miSpriteRemoveCursor (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ DamageDrawInternal (pScreen, TRUE);
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ miSpriteIsUpFALSE (pScreen, pScreenPriv);
+ pScreenPriv->pCacheWin = NullWindow;
+ if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
+ {
+ miSpriteIsUpTRUE (pScreen, pScreenPriv);
+ }
+ DamageDrawInternal (pScreen, FALSE);
+}
+
+/*
+ * Called from the block handler, restores the cursor
+ * before waiting for something to do.
+ */
+
+static void
+miSpriteRestoreCursor (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+ int x, y;
+ CursorPtr pCursor;
+
+ DamageDrawInternal (pScreen, TRUE);
+ miSpriteComputeSaved (pScreen);
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pCursor = pScreenPriv->pCursor;
+ x = pScreenPriv->x - (int)pCursor->bits->xhot;
+ y = pScreenPriv->y - (int)pCursor->bits->yhot;
+ if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
+ {
+ if (pScreenPriv->checkPixels)
+ miSpriteFindColors (pScreen);
+ if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
+ pScreenPriv->colors[SOURCE_COLOR].pixel,
+ pScreenPriv->colors[MASK_COLOR].pixel))
+ {
+ miSpriteIsUpTRUE (pScreen, pScreenPriv);
+ }
+ }
+ DamageDrawInternal (pScreen, FALSE);
+}
+
+/*
+ * compute the desired area of the screen to save
+ */
+
+static void
+miSpriteComputeSaved (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+ int x, y, w, h;
+ int wpad, hpad;
+ CursorPtr pCursor;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pCursor = pScreenPriv->pCursor;
+ x = pScreenPriv->x - (int)pCursor->bits->xhot;
+ y = pScreenPriv->y - (int)pCursor->bits->yhot;
+ w = pCursor->bits->width;
+ h = pCursor->bits->height;
+ wpad = SPRITE_PAD;
+ hpad = SPRITE_PAD;
+ pScreenPriv->saved.x1 = x - wpad;
+ pScreenPriv->saved.y1 = y - hpad;
+ pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
+ pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
+}
diff --git a/nx-X11/programs/Xserver/mi/misprite.h b/nx-X11/programs/Xserver/mi/misprite.h
new file mode 100644
index 000000000..5173b7736
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/misprite.h
@@ -0,0 +1,94 @@
+/*
+ * misprite.h
+ *
+ * software-sprite/sprite drawing interface spec
+ *
+ * mi versions of these routines exist.
+ */
+
+
+/*
+
+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.
+*/
+
+typedef struct {
+ Bool (*RealizeCursor)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+);
+ Bool (*UnrealizeCursor)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+);
+ Bool (*PutUpCursor)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned long /*source*/,
+ unsigned long /*mask*/
+);
+ Bool (*SaveUnderCursor)(
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/
+);
+ Bool (*RestoreUnderCursor)(
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/
+);
+ Bool (*MoveCursor)(
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*source*/,
+ unsigned long /*mask*/
+);
+ Bool (*ChangeSave)(
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dx*/,
+ int /*dy*/
+);
+
+} miSpriteCursorFuncRec, *miSpriteCursorFuncPtr;
+
+extern Bool miSpriteInitialize(
+ ScreenPtr /*pScreen*/,
+ miSpriteCursorFuncPtr /*cursorFuncs*/,
+ miPointerScreenFuncPtr /*screenFuncs*/
+);
diff --git a/nx-X11/programs/Xserver/mi/mispritest.h b/nx-X11/programs/Xserver/mi/mispritest.h
new file mode 100644
index 000000000..5075f0580
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mispritest.h
@@ -0,0 +1,132 @@
+/*
+ * mispritest.h
+ *
+ * mi sprite structures
+ */
+
+
+/*
+
+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.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _MISPRITEST_H_
+#define _MISPRITEST_H_
+
+# include "misprite.h"
+#ifdef RENDER
+# include "picturestr.h"
+#endif
+# include "damage.h"
+
+/*
+ * per screen information
+ */
+
+typedef struct {
+ /* screen procedures */
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ SourceValidateProcPtr SourceValidate;
+
+ /* window procedures */
+ CopyWindowProcPtr CopyWindow;
+
+ /* backing store procedures */
+ SaveDoomedAreasProcPtr SaveDoomedAreas;
+
+ /* colormap procedures */
+ InstallColormapProcPtr InstallColormap;
+ StoreColorsProcPtr StoreColors;
+
+ /* os layer procedures */
+ ScreenBlockHandlerProcPtr BlockHandler;
+
+ CursorPtr pCursor;
+ int x; /* cursor hotspot */
+ int y;
+ BoxRec saved; /* saved area from the screen */
+ Bool isUp; /* cursor in frame buffer */
+ Bool shouldBeUp; /* cursor should be displayed */
+ WindowPtr pCacheWin; /* window the cursor last seen in */
+ Bool isInCacheWin;
+ Bool checkPixels; /* check colormap collision */
+ xColorItem colors[2];
+ ColormapPtr pInstalledMap;
+ ColormapPtr pColormap;
+ VisualPtr pVisual;
+ miSpriteCursorFuncPtr funcs;
+ DamagePtr pDamage; /* damage tracking structure */
+} miSpriteScreenRec, *miSpriteScreenPtr;
+
+#define SOURCE_COLOR 0
+#define MASK_COLOR 1
+
+#define miSpriteIsUpTRUE(pScreen, pScreenPriv) if (!pScreenPriv->isUp) { \
+ pScreenPriv->isUp = TRUE; \
+ DamageRegister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
+}
+
+#define miSpriteIsUpFALSE(pScreen, pScreenPriv) if (pScreenPriv->isUp) { \
+ DamageUnregister (&(*pScreen->GetScreenPixmap) (pScreen)->drawable, pScreenPriv->pDamage); \
+ pScreenPriv->isUp = FALSE; \
+}
+
+/*
+ * Overlap BoxPtr and Box elements
+ */
+#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
+ (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
+ ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
+
+/*
+ * Overlap BoxPtr, origins, and rectangle
+ */
+#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
+ BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
+
+/*
+ * Overlap BoxPtr, origins and RectPtr
+ */
+#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
+ ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
+ (int)((pRect)->width), (int)((pRect)->height))
+/*
+ * Overlap BoxPtr and horizontal span
+ */
+#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
+
+#define LINE_SORT(x1,y1,x2,y2) \
+{ int _t; \
+ if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
+ if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
+
+#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
+ BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
+
+#endif /* _MISPRITEST_H_ */
diff --git a/nx-X11/programs/Xserver/mi/mistruct.h b/nx-X11/programs/Xserver/mi/mistruct.h
new file mode 100644
index 000000000..e9cfed5a4
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mistruct.h
@@ -0,0 +1,63 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifndef MISTRUCT_H
+#define MISTRUCT_H
+
+#include "mi.h"
+#include "regionstr.h"
+
+/* information about dashes */
+typedef struct _miDash {
+ DDXPointRec pt;
+ int e1, e2; /* keep these, so we don't have to do it again */
+ int e; /* bresenham error term for this point on line */
+ int which;
+ int newLine;/* 0 if part of same original line as previous dash */
+ } miDashRec;
+
+#endif /* MISTRUCT_H */
diff --git a/nx-X11/programs/Xserver/mi/mivalidate.h b/nx-X11/programs/Xserver/mi/mivalidate.h
new file mode 100644
index 000000000..ef258c0f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mivalidate.h
@@ -0,0 +1,52 @@
+/*
+
+Copyright 1993, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef MIVALIDATE_H
+#define MIVALIDATE_H
+
+#include "regionstr.h"
+
+typedef union _Validate {
+ struct BeforeValidate {
+ DDXPointRec oldAbsCorner; /* old window position */
+ RegionPtr borderVisible; /* visible region of border, */
+ /* non-null when size changes */
+ Bool resized; /* unclipped winSize has changed - */
+ /* don't call SaveDoomedAreas */
+ } before;
+ struct AfterValidate {
+ RegionRec exposed; /* exposed regions, absolute pos */
+ RegionRec borderExposed;
+ } after;
+} ValidateRec;
+
+#endif /* MIVALIDATE_H */
diff --git a/nx-X11/programs/Xserver/mi/mivaltree.c b/nx-X11/programs/Xserver/mi/mivaltree.c
new file mode 100644
index 000000000..0435925ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mivaltree.c
@@ -0,0 +1,823 @@
+/*
+ * mivaltree.c --
+ * Functions for recalculating window clip lists. Main function
+ * is miValidateTree.
+ *
+
+Copyright 1987, 1988, 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.
+
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+ *
+ ******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+
+ /*
+ * Aug '86: Susan Angebranndt -- original code
+ * July '87: Adam de Boor -- substantially modified and commented
+ * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
+ * In particular, much improved code for window mapping and
+ * circulating.
+ * Bob Scheifler -- avoid miComputeClips for unmapped windows,
+ * valdata changes
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+
+#include "globals.h"
+
+#ifdef SHAPE
+/*
+ * Compute the visibility of a shaped window
+ */
+int
+miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
+ ScreenPtr pScreen;
+ RegionPtr universe, bounding;
+ BoxPtr rect;
+ register int x, y;
+{
+ BoxRec box;
+ register BoxPtr boundBox;
+ int nbox;
+ Bool someIn, someOut;
+ register int t, x1, y1, x2, y2;
+
+ nbox = RegionNumRects (bounding);
+ boundBox = RegionRects (bounding);
+ someIn = someOut = FALSE;
+ x1 = rect->x1;
+ y1 = rect->y1;
+ x2 = rect->x2;
+ y2 = rect->y2;
+ while (nbox--)
+ {
+ if ((t = boundBox->x1 + x) < x1)
+ t = x1;
+ box.x1 = t;
+ if ((t = boundBox->y1 + y) < y1)
+ t = y1;
+ box.y1 = t;
+ if ((t = boundBox->x2 + x) > x2)
+ t = x2;
+ box.x2 = t;
+ if ((t = boundBox->y2 + y) > y2)
+ t = y2;
+ box.y2 = t;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ switch (RegionContainsRect(universe, &box))
+ {
+ case rgnIN:
+ if (someOut)
+ return rgnPART;
+ someIn = TRUE;
+ break;
+ case rgnOUT:
+ if (someIn)
+ return rgnPART;
+ someOut = TRUE;
+ break;
+ default:
+ return rgnPART;
+ }
+ boundBox++;
+ }
+ if (someIn)
+ return rgnIN;
+ return rgnOUT;
+}
+#endif
+
+static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
+static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
+
+void
+miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
+ GetRedirectBorderClipProcPtr getBorderClip)
+{
+ miSetRedirectBorderClipProc = setBorderClip;
+ miGetRedirectBorderClipProc = getBorderClip;
+}
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+ HasBorder(w) && \
+ (w)->backgroundState == ParentRelative)
+
+
+/*
+ *-----------------------------------------------------------------------
+ * miComputeClips --
+ * Recompute the clipList, borderClip, exposed and borderExposed
+ * regions for pParent and its children. Only viewable windows are
+ * taken into account.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * clipList, borderClip, exposed and borderExposed are altered.
+ * A VisibilityNotify event may be generated on the parent window.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miComputeClips (
+ register WindowPtr pParent,
+ register ScreenPtr pScreen,
+ register RegionPtr universe,
+ VTKind kind,
+ RegionPtr exposed ) /* for intermediate calculations */
+{
+ int dx,
+ dy;
+ RegionRec childUniverse;
+ register WindowPtr pChild;
+ int oldVis, newVis;
+ BoxRec borderSize;
+ RegionRec childUnion;
+ Bool overlap;
+ RegionPtr borderVisible;
+ Bool resized;
+ /*
+ * Figure out the new visibility of this window.
+ * The extent of the universe should be the same as the extent of
+ * the borderSize region. If the window is unobscured, this rectangle
+ * will be completely inside the universe (the universe will cover it
+ * completely). If the window is completely obscured, none of the
+ * universe will cover the rectangle.
+ */
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
+ if (dx > 32767)
+ dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
+ if (dy > 32767)
+ dy = 32767;
+ borderSize.y2 = dy;
+
+ oldVis = pParent->visibility;
+ switch (RegionContainsRect(universe, &borderSize))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (miShapedWindowIn (pScreen, universe, pBounding,
+ &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ pParent->visibility = newVis;
+ if (oldVis != newVis &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+ SendVisibilityNotify(pParent);
+
+#ifdef COMPOSITE
+ /*
+ * In redirected drawing case, reset universe to borderSize
+ */
+ if (pParent->redirectDraw)
+ {
+ if (miSetRedirectBorderClipProc)
+ (*miSetRedirectBorderClipProc) (pParent, universe);
+ RegionCopy(universe, &pParent->borderSize);
+ }
+#endif
+
+ dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+ dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+ /*
+ * avoid computations when dealing with simple operations
+ */
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (pChild->visibility != VisibilityFullyObscured)
+ {
+ RegionTranslate(&pChild->borderClip,
+ dx, dy);
+ RegionTranslate(&pChild->clipList,
+ dx, dy);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pChild, dx, dy);
+
+ }
+ if (pChild->valdata)
+ {
+ RegionNull(
+ &pChild->valdata->after.borderExposed);
+ if (HasParentRelativeBorder(pChild))
+ {
+ RegionSubtract(
+ &pChild->valdata->after.borderExposed,
+ &pChild->borderClip,
+ &pChild->winSize);
+ }
+ RegionNull(&pChild->valdata->after.exposed);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ /*
+ * To calculate exposures correctly, we have to translate the old
+ * borderClip and clipList regions to the window's new location so there
+ * is a correspondence between pieces of the new and old clipping regions.
+ */
+ if (dx || dy)
+ {
+ /*
+ * We translate the old clipList because that will be exposed or copied
+ * if gravity is right.
+ */
+ RegionTranslate(&pParent->borderClip, dx, dy);
+ RegionTranslate(&pParent->clipList, dx, dy);
+ }
+ break;
+ case VTBroken:
+ RegionEmpty(&pParent->borderClip);
+ RegionEmpty(&pParent->clipList);
+ break;
+ }
+
+ borderVisible = pParent->valdata->before.borderVisible;
+ resized = pParent->valdata->before.resized;
+ RegionNull(&pParent->valdata->after.borderExposed);
+ RegionNull(&pParent->valdata->after.exposed);
+
+ /*
+ * Since the borderClip must not be clipped by the children, we do
+ * the border exposure first...
+ *
+ * 'universe' is the window's borderClip. To figure the exposures, remove
+ * the area that used to be exposed from the new.
+ * This leaves a region of pieces that weren't exposed before.
+ */
+
+ if (HasBorder (pParent))
+ {
+ if (borderVisible)
+ {
+ /*
+ * when the border changes shape, the old visible portions
+ * of the border will be saved by DIX in borderVisible --
+ * use that region and destroy it
+ */
+ RegionSubtract(exposed, universe, borderVisible);
+ RegionDestroy(borderVisible);
+ }
+ else
+ {
+ RegionSubtract(exposed, universe, &pParent->borderClip);
+ }
+ if (HasParentRelativeBorder(pParent) && (dx || dy))
+ RegionSubtract(&pParent->valdata->after.borderExposed,
+ universe,
+ &pParent->winSize);
+ else
+ RegionSubtract(&pParent->valdata->after.borderExposed,
+ exposed, &pParent->winSize);
+
+ RegionCopy(&pParent->borderClip, universe);
+
+ /*
+ * To get the right clipList for the parent, and to make doubly sure
+ * that no child overlaps the parent's border, we remove the parent's
+ * border from the universe before proceeding.
+ */
+
+ RegionIntersect(universe, universe, &pParent->winSize);
+ }
+ else
+ RegionCopy(&pParent->borderClip, universe);
+
+ if ((pChild = pParent->firstChild) && pParent->mapped)
+ {
+ RegionNull(&childUniverse);
+ RegionNull(&childUnion);
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ RegionAppend(&childUnion, &pChild->borderSize);
+ }
+ }
+ else
+ {
+ for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ if (pChild->viewable)
+ RegionAppend(&childUnion, &pChild->borderSize);
+ }
+ }
+ RegionValidate(&childUnion, &overlap);
+
+ for (pChild = pParent->firstChild;
+ pChild;
+ pChild = pChild->nextSib)
+ {
+ if (pChild->viewable) {
+ /*
+ * If the child is viewable, we want to remove its extents
+ * from the current universe, but we only re-clip it if
+ * it's been marked.
+ */
+ if (pChild->valdata) {
+ /*
+ * Figure out the new universe from the child's
+ * perspective and recurse.
+ */
+ RegionIntersect(&childUniverse,
+ universe,
+ &pChild->borderSize);
+ miComputeClips (pChild, pScreen, &childUniverse, kind,
+ exposed);
+ }
+ /*
+ * Once the child has been processed, we remove its extents
+ * from the current universe, thus denying its space to any
+ * other sibling.
+ */
+ if (overlap)
+ RegionSubtract(universe, universe,
+ &pChild->borderSize);
+ }
+ }
+ if (!overlap)
+ RegionSubtract(universe, universe, &childUnion);
+ RegionUninit(&childUnion);
+ RegionUninit(&childUniverse);
+ } /* if any children */
+
+ /*
+ * 'universe' now contains the new clipList for the parent window.
+ *
+ * To figure the exposure of the window we subtract the old clip from the
+ * new, just as for the border.
+ */
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ RegionCopy(&pParent->valdata->after.exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ RegionSubtract(&pParent->valdata->after.exposed,
+ universe, &pParent->clipList);
+ }
+
+ /*
+ * One last thing: backing storage. We have to try to save what parts of
+ * the window are about to be obscured. We can just subtract the universe
+ * from the old clipList and get the areas that were in the old but aren't
+ * in the new and, hence, are about to be obscured.
+ */
+ if (pParent->backStorage && !resized)
+ {
+ RegionSubtract(exposed, &pParent->clipList, universe);
+ (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = pParent->clipList;
+ pParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+#ifdef NOTDEF
+ RegionCopy(&pParent->clipList, universe);
+#endif
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+static void
+miTreeObscured(
+ register WindowPtr pParent )
+{
+ register WindowPtr pChild;
+ register int oldVis;
+
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ oldVis = pChild->visibility;
+ if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
+ ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
+ SendVisibilityNotify(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * miValidateTree --
+ * Recomputes the clip list for pParent and all its inferiors.
+ *
+ * Results:
+ * Always returns 1.
+ *
+ * Side Effects:
+ * The clipList, borderClip, exposed, and borderExposed regions for
+ * each marked window are altered.
+ *
+ * Notes:
+ * This routine assumes that all affected windows have been marked
+ * (valdata created) and their winSize and borderSize regions
+ * adjusted to correspond to their new positions. The borderClip and
+ * clipList regions should not have been touched.
+ *
+ * The top-most level is treated differently from all lower levels
+ * because pParent is unchanged. For the top level, we merge the
+ * regions taken up by the marked children back into the clipList
+ * for pParent, thus forming a region from which the marked children
+ * can claim their areas. For lower levels, where the old clipList
+ * and borderClip are invalid, we can't do this and have to do the
+ * extra operations done in miComputeClips, but this is much faster
+ * e.g. when only one child has moved...
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+int
+miValidateTree (pParent, pChild, kind)
+ WindowPtr pParent; /* Parent to validate */
+ WindowPtr pChild; /* First child of pParent that was
+ * affected */
+ VTKind kind; /* What kind of configuration caused call */
+{
+ RegionRec totalClip; /* Total clipping region available to
+ * the marked children. pParent's clipList
+ * merged with the borderClips of all
+ * the marked children. */
+ RegionRec childClip; /* The new borderClip for the current
+ * child */
+ RegionRec childUnion; /* the space covered by borderSize for
+ * all marked children */
+ RegionRec exposed; /* For intermediate calculations */
+ register ScreenPtr pScreen;
+ register WindowPtr pWin;
+ Bool overlap;
+ int viewvals;
+ Bool forward;
+
+ pScreen = pParent->drawable.pScreen;
+ if (pChild == NullWindow)
+ pChild = pParent->firstChild;
+
+ RegionNull(&childClip);
+ RegionNull(&exposed);
+
+ /*
+ * compute the area of the parent window occupied
+ * by the marked children + the parent itself. This
+ * is the area which can be divied up among the marked
+ * children in their new configuration.
+ */
+ RegionNull(&totalClip);
+ viewvals = 0;
+ if (RegionBroken(&pParent->clipList) &&
+ !RegionBroken(&pParent->borderClip))
+ {
+ kind = VTBroken;
+ /*
+ * When rebuilding clip lists after out of memory,
+ * assume everything is busted.
+ */
+ forward = TRUE;
+ RegionCopy(&totalClip, &pParent->borderClip);
+ RegionIntersect(&totalClip, &totalClip, &pParent->winSize);
+
+ for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
+ {
+ if (pWin->viewable)
+ RegionSubtract(&totalClip, &totalClip, &pWin->borderSize);
+ }
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ if (pWin->valdata && pWin->viewable)
+ viewvals++;
+
+ RegionEmpty(&pParent->clipList);
+ }
+ else
+ {
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ forward = TRUE;
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ {
+ if (pWin->valdata)
+ {
+ RegionPtr pBorderClip = &pWin->borderClip;
+#ifdef COMPOSITE
+ if (pWin->redirectDraw && miGetRedirectBorderClipProc)
+ pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
+#endif
+ RegionAppend(&totalClip, pBorderClip );
+ if (pWin->viewable)
+ viewvals++;
+ }
+ }
+ }
+ else
+ {
+ forward = FALSE;
+ pWin = pParent->lastChild;
+ while (1)
+ {
+ if (pWin->valdata)
+ {
+ RegionPtr pBorderClip = &pWin->borderClip;
+#ifdef COMPOSITE
+ if (pWin->redirectDraw && miGetRedirectBorderClipProc)
+ pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
+#endif
+ RegionAppend(&totalClip, pBorderClip );
+ if (pWin->viewable)
+ viewvals++;
+ }
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+ RegionValidate(&totalClip, &overlap);
+ }
+
+ /*
+ * Now go through the children of the root and figure their new
+ * borderClips from the totalClip, passing that off to miComputeClips
+ * to handle recursively. Once that's done, we remove the child
+ * from the totalClip to clip any siblings below it.
+ */
+
+ overlap = TRUE;
+ if (kind != VTStack)
+ {
+ RegionUnion(&totalClip, &totalClip, &pParent->clipList);
+ if (viewvals > 1)
+ {
+ /*
+ * precompute childUnion to discover whether any of them
+ * overlap. This seems redundant, but performance studies
+ * have demonstrated that the cost of this loop is
+ * lower than the cost of multiple Subtracts in the
+ * loop below.
+ */
+ RegionNull(&childUnion);
+ if (forward)
+ {
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ if (pWin->valdata && pWin->viewable)
+ RegionAppend(&childUnion,
+ &pWin->borderSize);
+ }
+ else
+ {
+ pWin = pParent->lastChild;
+ while (1)
+ {
+ if (pWin->valdata && pWin->viewable)
+ RegionAppend(&childUnion,
+ &pWin->borderSize);
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+ RegionValidate(&childUnion, &overlap);
+ if (overlap)
+ RegionUninit(&childUnion);
+ }
+ }
+
+ for (pWin = pChild;
+ pWin != NullWindow;
+ pWin = pWin->nextSib)
+ {
+ if (pWin->viewable) {
+ if (pWin->valdata) {
+ RegionIntersect(&childClip,
+ &totalClip,
+ &pWin->borderSize);
+ miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+ if (overlap)
+ {
+ RegionSubtract(&totalClip,
+ &totalClip,
+ &pWin->borderSize);
+ }
+ } else if (pWin->visibility == VisibilityNotViewable) {
+ miTreeObscured(pWin);
+ }
+ } else {
+ if (pWin->valdata) {
+ RegionEmpty(&pWin->clipList);
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pWin, 0, 0);
+ RegionEmpty(&pWin->borderClip);
+ pWin->valdata = (ValidatePtr)NULL;
+ }
+ }
+ }
+
+ RegionUninit(&childClip);
+ if (!overlap)
+ {
+ RegionSubtract(&totalClip, &totalClip, &childUnion);
+ RegionUninit(&childUnion);
+ }
+
+ RegionNull(&pParent->valdata->after.exposed);
+ RegionNull(&pParent->valdata->after.borderExposed);
+
+ /*
+ * each case below is responsible for updating the
+ * clipList and serial number for the parent window
+ */
+
+ switch (kind) {
+ case VTStack:
+ break;
+ default:
+ /*
+ * totalClip contains the new clipList for the parent. Figure out
+ * exposures and obscures as per miComputeClips and reset the parent's
+ * clipList.
+ */
+ RegionSubtract(&pParent->valdata->after.exposed,
+ &totalClip, &pParent->clipList);
+ /* fall through */
+ case VTMap:
+ if (pParent->backStorage) {
+ RegionSubtract(&exposed, &pParent->clipList, &totalClip);
+ (* pScreen->SaveDoomedAreas)(pParent, &exposed, 0, 0);
+ }
+
+ RegionCopy(&pParent->clipList, &totalClip);
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ break;
+ }
+
+ RegionUninit(&totalClip);
+ RegionUninit(&exposed);
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pParent, 0, 0);
+ return (1);
+}
diff --git a/nx-X11/programs/Xserver/mi/miwideline.c b/nx-X11/programs/Xserver/mi/miwideline.c
new file mode 100644
index 000000000..8fcf351a7
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miwideline.c
@@ -0,0 +1,2240 @@
+/*
+
+Copyright 1988, 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: Keith Packard, MIT X Consortium */
+
+/*
+ * Mostly integer wideline code. Uses a technique similar to
+ * bresenham zero-width lines, except walks an X edge
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include <nx-X11/X.h>
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "miwideline.h"
+#include "mi.h"
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+static void miLineArc(DrawablePtr pDraw, register GCPtr pGC,
+ unsigned long pixel, SpanDataPtr spanData,
+ register LineFacePtr leftFace,
+ register LineFacePtr rightFace,
+ double xorg, double yorg, Bool isInt);
+
+
+/*
+ * spans-based polygon filler
+ */
+
+void
+miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
+ left, right, left_count, right_count)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ int y; /* start y coordinate */
+ int overall_height; /* height of entire segment */
+ PolyEdgePtr left, right;
+ int left_count, right_count;
+{
+ register int left_x = 0, left_e = 0;
+ int left_stepx = 0;
+ int left_signdx = 0;
+ int left_dy = 0, left_dx = 0;
+
+ register int right_x = 0, right_e = 0;
+ int right_stepx = 0;
+ int right_signdx = 0;
+ int right_dy = 0, right_dx = 0;
+
+ int height = 0;
+ int left_height = 0, right_height = 0;
+
+ register DDXPointPtr ppt;
+ DDXPointPtr pptInit = NULL;
+ register int *pwidth;
+ int *pwidthInit = NULL;
+ XID oldPixel;
+ int xorg;
+ Spans spanRec;
+
+ left_height = 0;
+ right_height = 0;
+
+ if (!spanData)
+ {
+ pptInit = (DDXPointPtr) malloc (overall_height * sizeof(*ppt));
+ if (!pptInit)
+ return;
+ pwidthInit = (int *) malloc (overall_height * sizeof(*pwidth));
+ if (!pwidthInit)
+ {
+ free (pptInit);
+ return;
+ }
+ ppt = pptInit;
+ pwidth = pwidthInit;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.points = (DDXPointPtr) malloc (overall_height * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *) malloc (overall_height * sizeof (int));
+ if (!spanRec.widths)
+ {
+ free (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+ }
+
+ xorg = 0;
+ if (pGC->miTranslate)
+ {
+ y += pDrawable->y;
+ xorg = pDrawable->x;
+ }
+ while ((left_count || left_height) &&
+ (right_count || right_height))
+ {
+ MIPOLYRELOADLEFT
+ MIPOLYRELOADRIGHT
+
+ height = left_height;
+ if (height > right_height)
+ height = right_height;
+
+ left_height -= height;
+ right_height -= height;
+
+ while (--height >= 0)
+ {
+ if (right_x >= left_x)
+ {
+ ppt->y = y;
+ ppt->x = left_x + xorg;
+ ppt++;
+ *pwidth++ = right_x - left_x + 1;
+ }
+ y++;
+
+ MIPOLYSTEPLEFT
+
+ MIPOLYSTEPRIGHT
+ }
+ }
+ if (!spanData)
+ {
+ (*pGC->ops->FillSpans) (pDrawable, pGC, ppt - pptInit, pptInit, pwidthInit, TRUE);
+ free (pwidthInit);
+ free (pptInit);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+static void
+miFillRectPolyHelper (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ unsigned long pixel,
+ SpanDataPtr spanData,
+ int x,
+ int y,
+ int w,
+ int h)
+{
+ register DDXPointPtr ppt;
+ register int *pwidth;
+ XID oldPixel;
+ Spans spanRec;
+ xRectangle rect;
+
+ if (!spanData)
+ {
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &rect);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.points = (DDXPointPtr) malloc (h * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *) malloc (h * sizeof (int));
+ if (!spanRec.widths)
+ {
+ free (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+
+ if (pGC->miTranslate)
+ {
+ y += pDrawable->y;
+ x += pDrawable->x;
+ }
+ while (h--)
+ {
+ ppt->x = x;
+ ppt->y = y;
+ ppt++;
+ *pwidth++ = w;
+ y++;
+ }
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+/* static */ int
+miPolyBuildEdge (x0, y0, k, dx, dy, xi, yi, left, edge)
+ double x0, y0;
+ double k; /* x0 * dy - y0 * dx */
+ register int dx, dy;
+ int xi, yi;
+ int left;
+ register PolyEdgePtr edge;
+{
+ int x, y, e;
+ int xady;
+
+ if (dy < 0)
+ {
+ dy = -dy;
+ dx = -dx;
+ k = -k;
+ }
+
+#ifdef NOTDEF
+ {
+ double realk, kerror;
+ realk = x0 * dy - y0 * dx;
+ kerror = Fabs (realk - k);
+ if (kerror > .1)
+ printf ("realk: %g k: %g\n", realk, k);
+ }
+#endif
+ y = ICEIL (y0);
+ xady = ICEIL (k) + y * dx;
+
+ if (xady <= 0)
+ x = - (-xady / dy) - 1;
+ else
+ x = (xady - 1) / dy;
+
+ e = xady - x * dy;
+
+ if (dx >= 0)
+ {
+ edge->signdx = 1;
+ edge->stepx = dx / dy;
+ edge->dx = dx % dy;
+ }
+ else
+ {
+ edge->signdx = -1;
+ edge->stepx = - (-dx / dy);
+ edge->dx = -dx % dy;
+ e = dy - e + 1;
+ }
+ edge->dy = dy;
+ edge->x = x + left + xi;
+ edge->e = e - dy; /* bias to compare against 0 instead of dy */
+ return y + yi;
+}
+
+#define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr)))
+
+/* static */ int
+miPolyBuildPoly (vertices, slopes, count, xi, yi, left, right, pnleft, pnright, h)
+ register PolyVertexPtr vertices;
+ register PolySlopePtr slopes;
+ int count;
+ int xi, yi;
+ PolyEdgePtr left, right;
+ int *pnleft, *pnright;
+ int *h;
+{
+ int top, bottom;
+ double miny, maxy;
+ register int i;
+ int j;
+ int clockwise;
+ int slopeoff;
+ register int s;
+ register int nright, nleft;
+ int y, lasty = 0, bottomy, topy = 0;
+
+ /* find the top of the polygon */
+ maxy = miny = vertices[0].y;
+ bottom = top = 0;
+ for (i = 1; i < count; i++)
+ {
+ if (vertices[i].y < miny)
+ {
+ top = i;
+ miny = vertices[i].y;
+ }
+ if (vertices[i].y >= maxy)
+ {
+ bottom = i;
+ maxy = vertices[i].y;
+ }
+ }
+ clockwise = 1;
+ slopeoff = 0;
+
+ i = top;
+ j = StepAround (top, -1, count);
+
+ if (slopes[j].dy * slopes[i].dx > slopes[i].dy * slopes[j].dx)
+ {
+ clockwise = -1;
+ slopeoff = -1;
+ }
+
+ bottomy = ICEIL (maxy) + yi;
+
+ nright = 0;
+
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom)
+ {
+ if (slopes[s].dy != 0)
+ {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k,
+ slopes[s].dx, slopes[s].dy,
+ xi, yi, 0,
+ &right[nright]);
+ if (nright != 0)
+ right[nright-1].height = y - lasty;
+ else
+ topy = y;
+ nright++;
+ lasty = y;
+ }
+
+ i = StepAround (i, clockwise, count);
+ s = StepAround (s, clockwise, count);
+ }
+ if (nright != 0)
+ right[nright-1].height = bottomy - lasty;
+
+ if (slopeoff == 0)
+ slopeoff = -1;
+ else
+ slopeoff = 0;
+
+ nleft = 0;
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom)
+ {
+ if (slopes[s].dy != 0)
+ {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k,
+ slopes[s].dx, slopes[s].dy, xi, yi, 1,
+ &left[nleft]);
+
+ if (nleft != 0)
+ left[nleft-1].height = y - lasty;
+ nleft++;
+ lasty = y;
+ }
+ i = StepAround (i, -clockwise, count);
+ s = StepAround (s, -clockwise, count);
+ }
+ if (nleft != 0)
+ left[nleft-1].height = bottomy - lasty;
+ *pnleft = nleft;
+ *pnright = nright;
+ *h = bottomy - topy;
+ return topy;
+}
+
+static void
+miLineOnePoint (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ unsigned long pixel,
+ SpanDataPtr spanData,
+ int x,
+ int y)
+{
+ DDXPointRec pt;
+ int wid;
+ unsigned long oldPixel;
+
+ MILINESETPIXEL (pDrawable, pGC, pixel, oldPixel);
+ if (pGC->fillStyle == FillSolid)
+ {
+ pt.x = x;
+ pt.y = y;
+ (*pGC->ops->PolyPoint) (pDrawable, pGC, CoordModeOrigin, 1, &pt);
+ }
+ else
+ {
+ wid = 1;
+ if (pGC->miTranslate)
+ {
+ x += pDrawable->x;
+ y += pDrawable->y;
+ }
+ pt.x = x;
+ pt.y = y;
+ (*pGC->ops->FillSpans) (pDrawable, pGC, 1, &pt, &wid, TRUE);
+ }
+ MILINERESETPIXEL (pDrawable, pGC, pixel, oldPixel);
+}
+
+static void
+miLineJoin (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ unsigned long pixel,
+ SpanDataPtr spanData,
+ register LineFacePtr pLeft,
+ register LineFacePtr pRight)
+{
+ double mx = 0, my = 0;
+ double denom = 0.0;
+ PolyVertexRec vertices[4];
+ PolySlopeRec slopes[4];
+ int edgecount;
+ PolyEdgeRec left[4], right[4];
+ int nleft, nright;
+ int y, height;
+ int swapslopes;
+ int joinStyle = pGC->joinStyle;
+ int lw = pGC->lineWidth;
+
+ if (lw == 1 && !spanData) {
+ /* See if one of the lines will draw the joining pixel */
+ if (pLeft->dx > 0 || (pLeft->dx == 0 && pLeft->dy > 0))
+ return;
+ if (pRight->dx > 0 || (pRight->dx == 0 && pRight->dy > 0))
+ return;
+ if (joinStyle != JoinRound) {
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+ if (denom == 0)
+ return; /* no join to draw */
+ }
+ if (joinStyle != JoinMiter) {
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, pLeft->x, pLeft->y);
+ return;
+ }
+ } else {
+ if (joinStyle == JoinRound)
+ {
+ miLineArc(pDrawable, pGC, pixel, spanData,
+ pLeft, pRight,
+ (double)0.0, (double)0.0, TRUE);
+ return;
+ }
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+
+ swapslopes = 0;
+ if (denom > 0)
+ {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ pLeft->dx = -pLeft->dx;
+ pLeft->dy = -pLeft->dy;
+ }
+ else
+ {
+ swapslopes = 1;
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ pRight->dx = -pRight->dx;
+ pRight->dy = -pRight->dy;
+ }
+
+ vertices[0].x = pRight->xa;
+ vertices[0].y = pRight->ya;
+ slopes[0].dx = -pRight->dy;
+ slopes[0].dy = pRight->dx;
+ slopes[0].k = 0;
+
+ vertices[1].x = 0;
+ vertices[1].y = 0;
+ slopes[1].dx = pLeft->dy;
+ slopes[1].dy = -pLeft->dx;
+ slopes[1].k = 0;
+
+ vertices[2].x = pLeft->xa;
+ vertices[2].y = pLeft->ya;
+
+ if (joinStyle == JoinMiter)
+ {
+ my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
+ pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx )) /
+ denom;
+ if (pLeft->dy != 0)
+ {
+ mx = pLeft->xa + (my - pLeft->ya) *
+ (double) pLeft->dx / (double) pLeft->dy;
+ }
+ else
+ {
+ mx = pRight->xa + (my - pRight->ya) *
+ (double) pRight->dx / (double) pRight->dy;
+ }
+ /* check miter limit */
+ if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
+ joinStyle = JoinBevel;
+ }
+
+ if (joinStyle == JoinMiter)
+ {
+ slopes[2].dx = pLeft->dx;
+ slopes[2].dy = pLeft->dy;
+ slopes[2].k = pLeft->k;
+ if (swapslopes)
+ {
+ slopes[2].dx = -slopes[2].dx;
+ slopes[2].dy = -slopes[2].dy;
+ slopes[2].k = -slopes[2].k;
+ }
+ vertices[3].x = mx;
+ vertices[3].y = my;
+ slopes[3].dx = pRight->dx;
+ slopes[3].dy = pRight->dy;
+ slopes[3].k = pRight->k;
+ if (swapslopes)
+ {
+ slopes[3].dx = -slopes[3].dx;
+ slopes[3].dy = -slopes[3].dy;
+ slopes[3].k = -slopes[3].k;
+ }
+ edgecount = 4;
+ }
+ else
+ {
+ double scale, dx, dy, adx, ady;
+
+ adx = dx = pRight->xa - pLeft->xa;
+ ady = dy = pRight->ya - pLeft->ya;
+ if (adx < 0)
+ adx = -adx;
+ if (ady < 0)
+ ady = -ady;
+ scale = ady;
+ if (adx > ady)
+ scale = adx;
+ slopes[2].dx = (dx * 65536) / scale;
+ slopes[2].dy = (dy * 65536) / scale;
+ slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
+ (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
+ edgecount = 3;
+ }
+
+ y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
+ left, right, &nleft, &nright, &height);
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, height, left, right, nleft, nright);
+}
+
+static int
+miLineArcI (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xorg,
+ int yorg,
+ DDXPointPtr points,
+ int *widths)
+{
+ register DDXPointPtr tpts, bpts;
+ register int *twids, *bwids;
+ register int x, y, e, ex, slw;
+
+ tpts = points;
+ twids = widths;
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ slw = pGC->lineWidth;
+ if (slw == 1)
+ {
+ tpts->x = xorg;
+ tpts->y = yorg;
+ *twids = 1;
+ return 1;
+ }
+ bpts = tpts + slw;
+ bwids = twids + slw;
+ y = (slw >> 1) + 1;
+ if (slw & 1)
+ e = - ((y << 2) + 3);
+ else
+ e = - (y << 3);
+ ex = -4;
+ x = 0;
+ while (y)
+ {
+ e += (y << 3) - 4;
+ while (e >= 0)
+ {
+ x++;
+ e += (ex = -((x << 3) + 4));
+ }
+ y--;
+ slw = (x << 1) + 1;
+ if ((e == ex) && (slw > 1))
+ slw--;
+ tpts->x = xorg - x;
+ tpts->y = yorg - y;
+ tpts++;
+ *twids++ = slw;
+ if ((y != 0) && ((slw > 1) || (e != ex)))
+ {
+ bpts--;
+ bpts->x = xorg - x;
+ bpts->y = yorg + y;
+ *--bwids = slw;
+ }
+ }
+ return (pGC->lineWidth);
+}
+
+#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
+ if (ybase == edgey) \
+ { \
+ if (edgeleft) \
+ { \
+ if (edge->x > xcl) \
+ xcl = edge->x; \
+ } \
+ else \
+ { \
+ if (edge->x < xcr) \
+ xcr = edge->x; \
+ } \
+ edgey++; \
+ edge->x += edge->stepx; \
+ edge->e += edge->dx; \
+ if (edge->e > 0) \
+ { \
+ edge->x += edge->signdx; \
+ edge->e -= edge->dy; \
+ } \
+ }
+
+static int
+miLineArcD (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ double xorg,
+ double yorg,
+ DDXPointPtr points,
+ int *widths,
+ PolyEdgePtr edge1,
+ int edgey1,
+ Bool edgeleft1,
+ PolyEdgePtr edge2,
+ int edgey2,
+ Bool edgeleft2)
+{
+ register DDXPointPtr pts;
+ register int *wids;
+ double radius, x0, y0, el, er, yk, xlk, xrk, k;
+ int xbase, ybase, y, boty, xl, xr, xcl, xcr;
+ int ymin, ymax;
+ Bool edge1IsMin, edge2IsMin;
+ int ymin1, ymin2;
+
+ pts = points;
+ wids = widths;
+ xbase = floor(xorg);
+ x0 = xorg - xbase;
+ ybase = ICEIL (yorg);
+ y0 = yorg - ybase;
+ if (pGC->miTranslate)
+ {
+ xbase += pDraw->x;
+ ybase += pDraw->y;
+ edge1->x += pDraw->x;
+ edge2->x += pDraw->x;
+ edgey1 += pDraw->y;
+ edgey2 += pDraw->y;
+ }
+ xlk = x0 + x0 + 1.0;
+ xrk = x0 + x0 - 1.0;
+ yk = y0 + y0 - 1.0;
+ radius = ((double)pGC->lineWidth) / 2.0;
+ y = floor(radius - y0 + 1.0);
+ ybase -= y;
+ ymin = ybase;
+ ymax = 65536;
+ edge1IsMin = FALSE;
+ ymin1 = edgey1;
+ if (edge1->dy >= 0)
+ {
+ if (!edge1->dy)
+ {
+ if (edgeleft1)
+ edge1IsMin = TRUE;
+ else
+ ymax = edgey1;
+ edgey1 = 65536;
+ }
+ else
+ {
+ if ((edge1->signdx < 0) == edgeleft1)
+ edge1IsMin = TRUE;
+ }
+ }
+ edge2IsMin = FALSE;
+ ymin2 = edgey2;
+ if (edge2->dy >= 0)
+ {
+ if (!edge2->dy)
+ {
+ if (edgeleft2)
+ edge2IsMin = TRUE;
+ else
+ ymax = edgey2;
+ edgey2 = 65536;
+ }
+ else
+ {
+ if ((edge2->signdx < 0) == edgeleft2)
+ edge2IsMin = TRUE;
+ }
+ }
+ if (edge1IsMin)
+ {
+ ymin = ymin1;
+ if (edge2IsMin && ymin1 > ymin2)
+ ymin = ymin2;
+ } else if (edge2IsMin)
+ ymin = ymin2;
+ el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
+ er = el + xrk;
+ xl = 1;
+ xr = 0;
+ if (x0 < 0.5)
+ {
+ xl = 0;
+ el -= xlk;
+ }
+ boty = (y0 < -0.5) ? 1 : 0;
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty)
+ {
+ k = (y << 1) + yk;
+ er += k;
+ while (er > 0.0)
+ {
+ xr++;
+ er += xrk - (xr << 1);
+ }
+ el += k;
+ while (el >= 0.0)
+ {
+ xl--;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if (xcr >= xcl)
+ {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ er = xrk - (xr << 1) - er;
+ el = (xl << 1) - xlk - el;
+ boty = floor(-y0 - radius + 1.0);
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty)
+ {
+ k = (y << 1) + yk;
+ er -= k;
+ while ((er >= 0.0) && (xr >= 0))
+ {
+ xr--;
+ er += xrk - (xr << 1);
+ }
+ el -= k;
+ while ((el > 0.0) && (xl <= 0))
+ {
+ xl++;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if (xcr >= xcl)
+ {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ return (pts - points);
+}
+
+int
+miRoundJoinFace (face, edge, leftEdge)
+ register LineFacePtr face;
+ register PolyEdgePtr edge;
+ Bool *leftEdge;
+{
+ int y;
+ int dx, dy;
+ double xa, ya;
+ Bool left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ left = 1;
+ if (ya > 0)
+ {
+ ya = 0.0;
+ xa = 0.0;
+ }
+ if (dy < 0 || (dy == 0 && dx > 0))
+ {
+ dx = -dx;
+ dy = -dy;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0)
+ {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ }
+ else
+ {
+ y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+void
+miRoundJoinClip (pLeft, pRight, edge1, edge2, y1, y2, left1, left2)
+ register LineFacePtr pLeft, pRight;
+ PolyEdgePtr edge1, edge2;
+ int *y1, *y2;
+ Bool *left1, *left2;
+{
+ double denom;
+
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+
+ if (denom >= 0)
+ {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ }
+ else
+ {
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ }
+ *y1 = miRoundJoinFace (pLeft, edge1, left1);
+ *y2 = miRoundJoinFace (pRight, edge2, left2);
+}
+
+int
+miRoundCapClip (face, isInt, edge, leftEdge)
+ register LineFacePtr face;
+ Bool isInt;
+ register PolyEdgePtr edge;
+ Bool *leftEdge;
+{
+ int y;
+ register int dx, dy;
+ double xa, ya, k;
+ Bool left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ k = 0.0;
+ if (!isInt)
+ k = face->k;
+ left = 1;
+ if (dy < 0 || (dy == 0 && dx > 0))
+ {
+ dx = -dx;
+ dy = -dy;
+ xa = -xa;
+ ya = -ya;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0)
+ {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ }
+ else
+ {
+ y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+static void
+miLineArc (
+ DrawablePtr pDraw,
+ register GCPtr pGC,
+ unsigned long pixel,
+ SpanDataPtr spanData,
+ register LineFacePtr leftFace,
+ register LineFacePtr rightFace,
+ double xorg,
+ double yorg,
+ Bool isInt)
+{
+ DDXPointPtr points;
+ int *widths;
+ int xorgi = 0, yorgi = 0;
+ XID oldPixel;
+ Spans spanRec;
+ int n;
+ PolyEdgeRec edge1, edge2;
+ int edgey1, edgey2;
+ Bool edgeleft1, edgeleft2;
+
+ if (isInt)
+ {
+ xorgi = leftFace ? leftFace->x : rightFace->x;
+ yorgi = leftFace ? leftFace->y : rightFace->y;
+ }
+ edgey1 = 65536;
+ edgey2 = 65536;
+ edge1.x = 0; /* not used, keep memory checkers happy */
+ edge1.dy = -1;
+ edge2.x = 0; /* not used, keep memory checkers happy */
+ edge2.dy = -1;
+ edgeleft1 = FALSE;
+ edgeleft2 = FALSE;
+ if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) &&
+ ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
+ (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt)))
+ {
+ if (isInt)
+ {
+ xorg = (double) xorgi;
+ yorg = (double) yorgi;
+ }
+ if (leftFace && rightFace)
+ {
+ miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
+ &edgey1, &edgey2, &edgeleft1, &edgeleft2);
+ }
+ else if (leftFace)
+ {
+ edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
+ }
+ else if (rightFace)
+ {
+ edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
+ }
+ isInt = FALSE;
+ }
+ if (!spanData)
+ {
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * pGC->lineWidth);
+ if (!points)
+ return;
+ widths = (int *)malloc(sizeof(int) * pGC->lineWidth);
+ if (!widths)
+ {
+ free(points);
+ return;
+ }
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC(pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDraw, pGC);
+ }
+ }
+ else
+ {
+ points = (DDXPointPtr) malloc (pGC->lineWidth * sizeof (DDXPointRec));
+ if (!points)
+ return;
+ widths = (int *) malloc (pGC->lineWidth * sizeof (int));
+ if (!widths)
+ {
+ free (points);
+ return;
+ }
+ spanRec.points = points;
+ spanRec.widths = widths;
+ }
+ if (isInt)
+ n = miLineArcI(pDraw, pGC, xorgi, yorgi, points, widths);
+ else
+ n = miLineArcD(pDraw, pGC, xorg, yorg, points, widths,
+ &edge1, edgey1, edgeleft1,
+ &edge2, edgey2, edgeleft2);
+
+ if (!spanData)
+ {
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, TRUE);
+ free(widths);
+ free(points);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC(pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDraw, pGC);
+ }
+ }
+ else
+ {
+ spanRec.count = n;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+void
+miLineProjectingCap (pDrawable, pGC, pixel, spanData, face, isLeft, xorg, yorg, isInt)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ register LineFacePtr face;
+ Bool isLeft;
+ double xorg, yorg;
+ Bool isInt;
+{
+ int xorgi = 0, yorgi = 0;
+ int lw;
+ PolyEdgeRec lefts[2], rights[2];
+ int lefty, righty, topy, bottomy;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ double xa,ya;
+ double k;
+ double xap, yap;
+ int dx, dy;
+ double projectXoff, projectYoff;
+ double maxy;
+ int finaly;
+
+ if (isInt)
+ {
+ xorgi = face->x;
+ yorgi = face->y;
+ }
+ lw = pGC->lineWidth;
+ dx = face->dx;
+ dy = face->dy;
+ k = face->k;
+ if (dy == 0)
+ {
+ lefts[0].height = lw;
+ lefts[0].x = xorgi;
+ if (isLeft)
+ lefts[0].x -= (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -lw;
+ lefts[0].dx = 0;
+ lefts[0].dy = lw;
+ rights[0].height = lw;
+ rights[0].x = xorgi;
+ if (!isLeft)
+ rights[0].x += ((lw + 1) >> 1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -lw;
+ rights[0].dx = 0;
+ rights[0].dy = lw;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, yorgi - (lw >> 1), lw,
+ lefts, rights, 1, 1);
+ }
+ else if (dx == 0)
+ {
+ if (dy < 0) {
+ dy = -dy;
+ isLeft = !isLeft;
+ }
+ topy = yorgi;
+ bottomy = yorgi + dy;
+ if (isLeft)
+ topy -= (lw >> 1);
+ else
+ bottomy += (lw >> 1);
+ lefts[0].height = bottomy - topy;
+ lefts[0].x = xorgi - (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -dy;
+ lefts[0].dx = dx;
+ lefts[0].dy = dy;
+
+ rights[0].height = bottomy - topy;
+ rights[0].x = lefts[0].x + (lw-1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -dy;
+ rights[0].dx = dx;
+ rights[0].dy = dy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, bottomy - topy, lefts, rights, 1, 1);
+ }
+ else
+ {
+ xa = face->xa;
+ ya = face->ya;
+ projectXoff = -ya;
+ projectYoff = xa;
+ if (dx < 0)
+ {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ }
+ else
+ {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ if (isLeft)
+ {
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, yorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xa, ya,
+ 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom);
+ maxy = -ya;
+ }
+ else
+ {
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, xorgi, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ }
+ finaly = ICEIL(maxy) + yorgi;
+ if (dx < 0)
+ {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ }
+ else
+ {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+static void
+miWideSegment (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ unsigned long pixel,
+ SpanDataPtr spanData,
+ register int x1,
+ register int y1,
+ register int x2,
+ register int y2,
+ Bool projectLeft,
+ Bool projectRight,
+ register LineFacePtr leftFace,
+ register LineFacePtr rightFace)
+{
+ double l, L, r;
+ double xa, ya;
+ double projectXoff = 0.0, projectYoff = 0.0;
+ double k;
+ double maxy;
+ int x, y;
+ int dx, dy;
+ int finaly;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ int lefty, righty, topy, bottomy;
+ int signdx;
+ PolyEdgeRec lefts[2], rights[2];
+ LineFacePtr tface;
+ int lw = pGC->lineWidth;
+
+ /* draw top-to-bottom always */
+ if (y2 < y1 || (y2 == y1 && x2 < x1))
+ {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+
+ y = y1;
+ y1 = y2;
+ y2 = y;
+
+ x = projectLeft;
+ projectLeft = projectRight;
+ projectRight = x;
+
+ tface = leftFace;
+ leftFace = rightFace;
+ rightFace = tface;
+ }
+
+ dy = y2 - y1;
+ signdx = 1;
+ dx = x2 - x1;
+ if (dx < 0)
+ signdx = -1;
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+
+ if (dy == 0)
+ {
+ rightFace->xa = 0;
+ rightFace->ya = (double) lw / 2.0;
+ rightFace->k = -(double) (lw * dx) / 2.0;
+ leftFace->xa = 0;
+ leftFace->ya = -rightFace->ya;
+ leftFace->k = rightFace->k;
+ x = x1;
+ if (projectLeft)
+ x -= (lw >> 1);
+ y = y1 - (lw >> 1);
+ dx = x2 - x;
+ if (projectRight)
+ dx += ((lw + 1) >> 1);
+ dy = lw;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x, y, dx, dy);
+ }
+ else if (dx == 0)
+ {
+ leftFace->xa = (double) lw / 2.0;
+ leftFace->ya = 0;
+ leftFace->k = (double) (lw * dy) / 2.0;
+ rightFace->xa = -leftFace->xa;
+ rightFace->ya = 0;
+ rightFace->k = leftFace->k;
+ y = y1;
+ if (projectLeft)
+ y -= lw >> 1;
+ x = x1 - (lw >> 1);
+ dy = y2 - y;
+ if (projectRight)
+ dy += ((lw + 1) >> 1);
+ dx = lw;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x, y, dx, dy);
+ }
+ else
+ {
+ l = ((double) lw) / 2.0;
+ L = hypot ((double) dx, (double) dy);
+
+ if (dx < 0)
+ {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ }
+ else
+ {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ r = l / L;
+
+ /* coord of upper bound at integral y */
+ ya = -r * dx;
+ xa = r * dy;
+
+ if (projectLeft | projectRight)
+ {
+ projectXoff = -ya;
+ projectYoff = xa;
+ }
+
+ /* xa * dy - ya * dx */
+ k = l * L;
+
+ leftFace->xa = xa;
+ leftFace->ya = ya;
+ leftFace->k = k;
+ rightFace->xa = -xa;
+ rightFace->ya = -ya;
+ rightFace->k = k;
+
+ if (projectLeft)
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 0, right);
+ else
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 0, right);
+
+ /* coord of lower bound at integral y */
+ ya = -ya;
+ xa = -xa;
+
+ /* xa * dy - ya * dx */
+ k = - k;
+
+ if (projectLeft)
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 1, left);
+ else
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 1, left);
+
+ /* coord of top face at integral y */
+
+ if (signdx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+
+ if (projectLeft)
+ {
+ double xap = xa - projectXoff;
+ double yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x1, y1, dx > 0, top);
+ }
+ else
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top);
+
+ /* coord of bottom face at integral y */
+
+ if (projectRight)
+ {
+ double xap = xa + projectXoff;
+ double yap = ya + projectYoff;
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ }
+ else
+ {
+ bottomy = miPolyBuildEdge (xa, ya,
+ 0.0, -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya;
+ }
+
+ finaly = ICEIL (maxy) + y2;
+
+ if (dx < 0)
+ {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ }
+ else
+ {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+SpanDataPtr
+miSetupSpanData (pGC, spanData, npt)
+ register GCPtr pGC;
+ SpanDataPtr spanData;
+ int npt;
+{
+ if ((npt < 3 && pGC->capStyle != CapRound) || miSpansEasyRop(pGC->alu))
+ return (SpanDataPtr) NULL;
+ if (pGC->lineStyle == LineDoubleDash)
+ miInitSpanGroup (&spanData->bgGroup);
+ miInitSpanGroup (&spanData->fgGroup);
+ return spanData;
+}
+
+void
+miCleanupSpanData (pDrawable, pGC, spanData)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ SpanDataPtr spanData;
+{
+ if (pGC->lineStyle == LineDoubleDash)
+ {
+ XID oldPixel, pixel;
+
+ pixel = pGC->bgPixel;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ miFillUniqueSpanGroup (pDrawable, pGC, &spanData->bgGroup);
+ miFreeSpanGroup (&spanData->bgGroup);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ miFillUniqueSpanGroup (pDrawable, pGC, &spanData->fgGroup);
+ miFreeSpanGroup (&spanData->fgGroup);
+}
+
+void
+miWideLine (pDrawable, pGC, mode, npt, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode;
+ register int npt;
+ register DDXPointPtr pPts;
+{
+ int x1, y1, x2, y2;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ unsigned long pixel;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ register int first;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin;
+
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ pixel = pGC->fgPixel;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (npt > 1)
+ {
+ if (mode == CoordModePrevious)
+ {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp)
+ {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ }
+ else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y)
+ {
+ selfJoin = TRUE;
+ }
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ while (--npt)
+ {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2)
+ {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin)
+ projectRight = TRUE;
+ miWideSegment (pDrawable, pGC, pixel, spanData, x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ if (first)
+ {
+ if (selfJoin)
+ firstFace = leftFace;
+ else if (pGC->capStyle == CapRound)
+ {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, x1, y1);
+ else
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ else
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace,
+ &prevRightFace);
+ }
+ prevRightFace = rightFace;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn)
+ {
+ if (selfJoin)
+ miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace,
+ &rightFace);
+ else if (pGC->capStyle == CapRound)
+ {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, x2, y2);
+ else
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ }
+ /* handle crock where all points are coincedent */
+ if (!somethingDrawn)
+ {
+ projectLeft = pGC->capStyle == CapProjecting;
+ miWideSegment (pDrawable, pGC, pixel, spanData,
+ x2, y2, x2, y2, projectLeft, projectLeft,
+ &leftFace, &rightFace);
+ if (pGC->capStyle == CapRound)
+ {
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,
+ TRUE);
+ rightFace.dx = -1; /* sleezy hack to make it work */
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pDrawable, pGC, spanData);
+}
+
+#define V_TOP 0
+#define V_RIGHT 1
+#define V_BOTTOM 2
+#define V_LEFT 3
+
+static void
+miWideDashSegment (
+ DrawablePtr pDrawable,
+ register GCPtr pGC,
+ SpanDataPtr spanData,
+ int *pDashOffset,
+ int *pDashIndex,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Bool projectLeft,
+ Bool projectRight,
+ LineFacePtr leftFace,
+ LineFacePtr rightFace)
+{
+ int dashIndex, dashRemain;
+ unsigned char *pDash;
+ double L, l;
+ double k;
+ PolyVertexRec vertices[4];
+ PolyVertexRec saveRight, saveBottom;
+ PolySlopeRec slopes[4];
+ PolyEdgeRec left[2], right[2];
+ LineFaceRec lcapFace, rcapFace;
+ int nleft, nright;
+ int h;
+ int y;
+ int dy, dx;
+ unsigned long pixel;
+ double LRemain;
+ double r;
+ double rdx, rdy;
+ double dashDx, dashDy;
+ double saveK = 0.0;
+ Bool first = TRUE;
+ double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0;
+ unsigned long fgPixel, bgPixel;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ dashIndex = *pDashIndex;
+ pDash = pGC->dash;
+ dashRemain = pDash[dashIndex] - *pDashOffset;
+ fgPixel = pGC->fgPixel;
+ bgPixel = pGC->bgPixel;
+ if (pGC->fillStyle == FillOpaqueStippled ||
+ pGC->fillStyle == FillTiled)
+ {
+ bgPixel = fgPixel;
+ }
+
+ l = ((double) pGC->lineWidth) / 2.0;
+ if (dx == 0)
+ {
+ L = dy;
+ rdx = 0;
+ rdy = l;
+ if (dy < 0)
+ {
+ L = -dy;
+ rdy = -l;
+ }
+ }
+ else if (dy == 0)
+ {
+ L = dx;
+ rdx = l;
+ rdy = 0;
+ if (dx < 0)
+ {
+ L = -dx;
+ rdx = -l;
+ }
+ }
+ else
+ {
+ L = hypot ((double) dx, (double) dy);
+ r = l / L;
+
+ rdx = r * dx;
+ rdy = r * dy;
+ }
+ k = l * L;
+ LRemain = L;
+ /* All position comments are relative to a line with dx and dy > 0,
+ * but the code does not depend on this */
+ /* top */
+ slopes[V_TOP].dx = dx;
+ slopes[V_TOP].dy = dy;
+ slopes[V_TOP].k = k;
+ /* right */
+ slopes[V_RIGHT].dx = -dy;
+ slopes[V_RIGHT].dy = dx;
+ slopes[V_RIGHT].k = 0;
+ /* bottom */
+ slopes[V_BOTTOM].dx = -dx;
+ slopes[V_BOTTOM].dy = -dy;
+ slopes[V_BOTTOM].k = k;
+ /* left */
+ slopes[V_LEFT].dx = dy;
+ slopes[V_LEFT].dy = -dx;
+ slopes[V_LEFT].k = 0;
+
+ /* preload the start coordinates */
+ vertices[V_RIGHT].x = vertices[V_TOP].x = rdy;
+ vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx;
+
+ vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy;
+ vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx;
+
+ if (projectLeft)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = rdx * dx + rdy * dy;
+ }
+
+ lcenterx = x1;
+ lcentery = y1;
+
+ if (pGC->capStyle == CapRound)
+ {
+ lcapFace.dx = dx;
+ lcapFace.dy = dy;
+ lcapFace.x = x1;
+ lcapFace.y = y1;
+
+ rcapFace.dx = -dx;
+ rcapFace.dy = -dy;
+ rcapFace.x = x1;
+ rcapFace.y = y1;
+ }
+ while (LRemain > dashRemain)
+ {
+ dashDx = (dashRemain * dx) / L;
+ dashDy = (dashRemain * dy) / L;
+
+ rcenterx = lcenterx + dashDx;
+ rcentery = lcentery + dashDy;
+
+ vertices[V_RIGHT].x += dashDx;
+ vertices[V_RIGHT].y += dashDy;
+
+ vertices[V_BOTTOM].x += dashDx;
+ vertices[V_BOTTOM].y += dashDy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy;
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))
+ {
+ if (pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapProjecting)
+ {
+ saveRight = vertices[V_RIGHT];
+ saveBottom = vertices[V_BOTTOM];
+ saveK = slopes[V_RIGHT].k;
+
+ if (!first)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy -
+ vertices[V_LEFT].y *
+ slopes[V_LEFT].dx;
+ }
+
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy -
+ vertices[V_RIGHT].y *
+ slopes[V_RIGHT].dx;
+ }
+ y = miPolyBuildPoly (vertices, slopes, 4, x1, y1,
+ left, right, &nleft, &nright, &h);
+ pixel = (dashIndex & 1) ? bgPixel : fgPixel;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright);
+
+ if (pGC->lineStyle == LineOnOffDash)
+ {
+ switch (pGC->capStyle)
+ {
+ case CapProjecting:
+ vertices[V_BOTTOM] = saveBottom;
+ vertices[V_RIGHT] = saveRight;
+ slopes[V_RIGHT].k = saveK;
+ break;
+ case CapRound:
+ if (!first)
+ {
+ if (dx < 0)
+ {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ }
+ else
+ {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &lcapFace, (LineFacePtr) NULL,
+ lcenterx, lcentery, FALSE);
+ }
+ if (dx < 0)
+ {
+ rcapFace.xa = vertices[V_BOTTOM].x;
+ rcapFace.ya = vertices[V_BOTTOM].y;
+ rcapFace.k = slopes[V_RIGHT].k;
+ }
+ else
+ {
+ rcapFace.xa = -vertices[V_RIGHT].x;
+ rcapFace.ya = -vertices[V_RIGHT].y;
+ rcapFace.k = -slopes[V_RIGHT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rcapFace,
+ rcenterx, rcentery, FALSE);
+ break;
+ }
+ }
+ }
+ LRemain -= dashRemain;
+ ++dashIndex;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+
+ lcenterx = rcenterx;
+ lcentery = rcentery;
+
+ vertices[V_TOP] = vertices[V_RIGHT];
+ vertices[V_LEFT] = vertices[V_BOTTOM];
+ slopes[V_LEFT].k = -slopes[V_RIGHT].k;
+ first = FALSE;
+ }
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))
+ {
+ vertices[V_TOP].x -= dx;
+ vertices[V_TOP].y -= dy;
+
+ vertices[V_LEFT].x -= dx;
+ vertices[V_LEFT].y -= dy;
+
+ vertices[V_RIGHT].x = rdy;
+ vertices[V_RIGHT].y = -rdx;
+
+ vertices[V_BOTTOM].x = -rdy;
+ vertices[V_BOTTOM].y = rdx;
+
+
+ if (projectRight)
+ {
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy -
+ vertices[V_RIGHT].y *
+ slopes[V_RIGHT].dx;
+ }
+ else
+ slopes[V_RIGHT].k = 0;
+
+ if (!first && pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapProjecting)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy -
+ vertices[V_LEFT].y *
+ slopes[V_LEFT].dx;
+ }
+ else
+ slopes[V_LEFT].k += dx * dx + dy * dy;
+
+
+ y = miPolyBuildPoly (vertices, slopes, 4, x2, y2,
+ left, right, &nleft, &nright, &h);
+
+ pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright);
+ if (!first && pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapRound)
+ {
+ lcapFace.x = x2;
+ lcapFace.y = y2;
+ if (dx < 0)
+ {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ }
+ else
+ {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &lcapFace, (LineFacePtr) NULL,
+ rcenterx, rcentery, FALSE);
+ }
+ }
+ dashRemain = ((double) dashRemain) - LRemain;
+ if (dashRemain == 0)
+ {
+ dashIndex++;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+ }
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+ leftFace->xa = rdy;
+ leftFace->ya = -rdx;
+ leftFace->k = k;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+ rightFace->xa = -rdy;
+ rightFace->ya = rdx;
+ rightFace->k = k;
+
+ *pDashIndex = dashIndex;
+ *pDashOffset = pDash[dashIndex] - dashRemain;
+}
+
+void
+miWideDash (pDrawable, pGC, mode, npt, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode;
+ register int npt;
+ register DDXPointPtr pPts;
+{
+ int x1, y1, x2, y2;
+ unsigned long pixel;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ int first;
+ int dashIndex, dashOffset;
+ register int prevDashIndex;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin;
+ Bool endIsFg = FALSE, startIsFg = FALSE;
+ Bool firstIsFg = FALSE, prevIsFg = FALSE;
+
+#ifndef XFree86Server
+ /* XXX backward compatibility */
+ if (pGC->lineWidth == 0)
+ {
+ miZeroDashLine (pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+#endif
+ if (pGC->lineStyle == LineDoubleDash &&
+ (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled))
+ {
+ miWideLine (pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+ if (npt == 0)
+ return;
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (mode == CoordModePrevious)
+ {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp)
+ {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ }
+ else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y)
+ {
+ selfJoin = TRUE;
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex,
+ pGC->dash, (int)pGC->numInDashList, &dashOffset);
+ while (--npt)
+ {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2)
+ {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting &&
+ (!selfJoin || !firstIsFg))
+ projectRight = TRUE;
+ prevDashIndex = dashIndex;
+ miWideDashSegment (pDrawable, pGC, spanData, &dashOffset, &dashIndex,
+ x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ startIsFg = !(prevDashIndex & 1);
+ endIsFg = (dashIndex & 1) ^ (dashOffset != 0);
+ if (pGC->lineStyle == LineDoubleDash || startIsFg)
+ {
+ pixel = startIsFg ? pGC->fgPixel : pGC->bgPixel;
+ if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg))
+ {
+ if (first && selfJoin)
+ {
+ firstFace = leftFace;
+ firstIsFg = startIsFg;
+ }
+ else if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ else
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace,
+ &prevRightFace);
+ }
+ }
+ prevRightFace = rightFace;
+ prevIsFg = endIsFg;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn)
+ {
+ if (pGC->lineStyle == LineDoubleDash || endIsFg)
+ {
+ pixel = endIsFg ? pGC->fgPixel : pGC->bgPixel;
+ if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg))
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace,
+ &rightFace);
+ }
+ else
+ {
+ if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+ else
+ {
+ /* glue a cap to the start of the line if
+ * we're OnOffDash and ended on odd dash
+ */
+ if (selfJoin && firstIsFg)
+ {
+ pixel = pGC->fgPixel;
+ if (pGC->capStyle == CapProjecting)
+ miLineProjectingCap (pDrawable, pGC, pixel, spanData,
+ &firstFace, TRUE,
+ (double)0.0, (double)0.0, TRUE);
+ else if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &firstFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+ }
+ }
+ /* handle crock where all points are coincident */
+ if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)))
+ {
+ /* not the same as endIsFg computation above */
+ pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel;
+ switch (pGC->capStyle) {
+ case CapRound:
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, (LineFacePtr) NULL,
+ (double)x2, (double)y2,
+ FALSE);
+ break;
+ case CapProjecting:
+ x1 = pGC->lineWidth;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1);
+ break;
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pDrawable, pGC, spanData);
+}
+
+/* these are stubs to allow old ddx ValidateGCs to work without change */
+
+void
+miMiter()
+{
+}
+
+void
+miNotMiter()
+{
+}
diff --git a/nx-X11/programs/Xserver/mi/miwideline.h b/nx-X11/programs/Xserver/mi/miwideline.h
new file mode 100644
index 000000000..8cfa63008
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miwideline.h
@@ -0,0 +1,222 @@
+/*
+
+Copyright 1988, 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: Keith Packard, MIT X Consortium */
+
+#include "mispans.h"
+#include "mifpoly.h" /* for ICEIL */
+
+/*
+ * interface data to span-merging polygon filler
+ */
+
+typedef struct _SpanData {
+ SpanGroup fgGroup, bgGroup;
+} SpanDataRec, *SpanDataPtr;
+
+#define AppendSpanGroup(pGC, pixel, spanPtr, spanData) { \
+ SpanGroup *group, *othergroup = NULL; \
+ if (pixel == pGC->fgPixel) \
+ { \
+ group = &spanData->fgGroup; \
+ if (pGC->lineStyle == LineDoubleDash) \
+ othergroup = &spanData->bgGroup; \
+ } \
+ else \
+ { \
+ group = &spanData->bgGroup; \
+ othergroup = &spanData->fgGroup; \
+ } \
+ miAppendSpans (group, othergroup, spanPtr); \
+}
+
+/*
+ * Polygon edge description for integer wide-line routines
+ */
+
+typedef struct _PolyEdge {
+ int height; /* number of scanlines to process */
+ int x; /* starting x coordinate */
+ int stepx; /* fixed integral dx */
+ int signdx; /* variable dx sign */
+ int e; /* initial error term */
+ int dy;
+ int dx;
+} PolyEdgeRec, *PolyEdgePtr;
+
+#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
+
+/*
+ * types for general polygon routines
+ */
+
+typedef struct _PolyVertex {
+ double x, y;
+} PolyVertexRec, *PolyVertexPtr;
+
+typedef struct _PolySlope {
+ int dx, dy;
+ double k; /* x0 * dy - y0 * dx */
+} PolySlopeRec, *PolySlopePtr;
+
+/*
+ * Line face description for caps/joins
+ */
+
+typedef struct _LineFace {
+ double xa, ya;
+ int dx, dy;
+ int x, y;
+ double k;
+} LineFaceRec, *LineFacePtr;
+
+/*
+ * macros for polygon fillers
+ */
+
+#define MIPOLYRELOADLEFT if (!left_height && left_count) { \
+ left_height = left->height; \
+ left_x = left->x; \
+ left_stepx = left->stepx; \
+ left_signdx = left->signdx; \
+ left_e = left->e; \
+ left_dy = left->dy; \
+ left_dx = left->dx; \
+ --left_count; \
+ ++left; \
+ }
+
+#define MIPOLYRELOADRIGHT if (!right_height && right_count) { \
+ right_height = right->height; \
+ right_x = right->x; \
+ right_stepx = right->stepx; \
+ right_signdx = right->signdx; \
+ right_e = right->e; \
+ right_dy = right->dy; \
+ right_dx = right->dx; \
+ --right_count; \
+ ++right; \
+ }
+
+#define MIPOLYSTEPLEFT left_x += left_stepx; \
+ left_e += left_dx; \
+ if (left_e > 0) \
+ { \
+ left_x += left_signdx; \
+ left_e -= left_dy; \
+ }
+
+#define MIPOLYSTEPRIGHT right_x += right_stepx; \
+ right_e += right_dx; \
+ if (right_e > 0) \
+ { \
+ right_x += right_signdx; \
+ right_e -= right_dy; \
+ }
+
+#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
+ oldPixel = pGC->fgPixel; \
+ if (pixel != oldPixel) { \
+ DoChangeGC (pGC, GCForeground, (XID *) &pixel, FALSE); \
+ ValidateGC (pDrawable, pGC); \
+ } \
+}
+#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
+ if (pixel != oldPixel) { \
+ DoChangeGC (pGC, GCForeground, (XID *) &oldPixel, FALSE); \
+ ValidateGC (pDrawable, pGC); \
+ } \
+}
+
+extern void miFillPolyHelper(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ unsigned long /*pixel*/,
+ SpanDataPtr /*spanData*/,
+ int /*y*/,
+ int /*overall_height*/,
+ PolyEdgePtr /*left*/,
+ PolyEdgePtr /*right*/,
+ int /*left_count*/,
+ int /*right_count*/
+);
+extern int miRoundJoinFace(
+ LineFacePtr /*face*/,
+ PolyEdgePtr /*edge*/,
+ Bool * /*leftEdge*/
+);
+
+extern void miRoundJoinClip(
+ LineFacePtr /*pLeft*/,
+ LineFacePtr /*pRight*/,
+ PolyEdgePtr /*edge1*/,
+ PolyEdgePtr /*edge2*/,
+ int * /*y1*/,
+ int * /*y2*/,
+ Bool * /*left1*/,
+ Bool * /*left2*/
+);
+
+extern int miRoundCapClip(
+ LineFacePtr /*face*/,
+ Bool /*isInt*/,
+ PolyEdgePtr /*edge*/,
+ Bool * /*leftEdge*/
+);
+
+extern void miLineProjectingCap(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ unsigned long /*pixel*/,
+ SpanDataPtr /*spanData*/,
+ LineFacePtr /*face*/,
+ Bool /*isLeft*/,
+ double /*xorg*/,
+ double /*yorg*/,
+ Bool /*isInt*/
+);
+
+extern SpanDataPtr miSetupSpanData(
+ GCPtr /*pGC*/,
+ SpanDataPtr /*spanData*/,
+ int /*npt*/
+);
+
+extern void miCleanupSpanData(
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ SpanDataPtr /*spanData*/
+);
+
+extern int miPolyBuildEdge(double x0, double y0, double k, int dx, int dy,
+ int xi, int yi, int left, PolyEdgePtr edge);
+extern int miPolyBuildPoly(PolyVertexPtr vertices, PolySlopePtr slopes,
+ int count, int xi, int yi, PolyEdgePtr left,
+ PolyEdgePtr right, int *pnleft, int *pnright,
+ int *h);
+
diff --git a/nx-X11/programs/Xserver/mi/miwindow.c b/nx-X11/programs/Xserver/mi/miwindow.c
new file mode 100644
index 000000000..2a583eda7
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/miwindow.c
@@ -0,0 +1,1187 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x,y;
+ int w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ extents = &pWin->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pWin->drawable.pScreen;
+ RegionInit(&reg, &box, 1);
+ if (pWin->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ RegionIntersect(&reg, &reg, &pWin->clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ RegionUninit(&reg);
+ if (pBSReg)
+ RegionDestroy(pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ * Check all the inferiors of a window for coverage by saveUnder
+ * windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ * This code is very inefficient.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+ register WindowPtr pParent, /* Parent to check */
+ WindowPtr pFirst, /* first reconfigured window */
+ RegionPtr pRegion) /* Initial area obscured by saveUnder */
+{
+ register WindowPtr pChild; /* Current child */
+ register ScreenPtr pScreen; /* Screen to use */
+ RegionRec SubRegion; /* Area of children obscured */
+ Bool res = FALSE; /* result */
+ Bool subInited=FALSE;/* SubRegion initialized */
+
+ pScreen = pParent->drawable.pScreen;
+ if ( (pChild = pParent->firstChild) )
+ {
+ /*
+ * build region above first changed window
+ */
+
+ for (; pChild != pFirst; pChild = pChild->nextSib)
+ if (pChild->viewable && pChild->saveUnder)
+ RegionUnion(pRegion, pRegion, &pChild->borderSize);
+
+ /*
+ * check region below and including first changed window
+ */
+
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ {
+ /*
+ * don't save under nephew/niece windows;
+ * use a separate region
+ */
+
+ if (pChild->firstChild)
+ {
+ if (!subInited)
+ {
+ RegionNull(&SubRegion);
+ subInited = TRUE;
+ }
+ RegionCopy(&SubRegion, pRegion);
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ &SubRegion);
+ }
+ else
+ {
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ pRegion);
+ }
+
+ if (pChild->saveUnder)
+ RegionUnion(pRegion, pRegion, &pChild->borderSize);
+ }
+ }
+
+ if (subInited)
+ RegionUninit(&SubRegion);
+ }
+
+ /*
+ * Check the state of this window. DIX save unders are
+ * enabled for viewable windows with some client expressing
+ * exposure interest and which intersect the save under region
+ */
+
+ if (pParent->viewable &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+ RegionNotEmpty(&pParent->borderSize) &&
+ RegionContainsRect(pRegion, RegionExtents(
+ &pParent->borderSize)) != rgnOUT)
+ {
+ if (!pParent->DIXsaveUnder)
+ {
+ pParent->DIXsaveUnder = TRUE;
+ (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+ }
+ }
+ else
+ {
+ if (pParent->DIXsaveUnder)
+ {
+ res = TRUE;
+ pParent->DIXsaveUnder = FALSE;
+ }
+ }
+ return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ * Change the save-under state of a tree of windows. Called when
+ * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed (which
+ * means that PostChangeSaveUnder needs to be called later to
+ * finish the job).
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+ register WindowPtr pWin;
+ WindowPtr first; /* First window to check.
+ * Used when pWin was restacked */
+{
+ RegionRec rgn; /* Area obscured by saveUnder windows */
+ Bool res;
+
+ if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+ return FALSE;
+ numSaveUndersViewable += deltaSaveUndersViewable;
+ deltaSaveUndersViewable = 0;
+ RegionNull(&rgn);
+ res = miCheckSubSaveUnder (pWin->parent,
+ pWin->saveUnder ? first : pWin->nextSib,
+ &rgn);
+ RegionUninit(&rgn);
+ return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ * Actually turn backing-store off for those windows that no longer
+ * need to have it on.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ * windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+{
+ register WindowPtr pParent, pChild;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ if (!(pParent = pWin->parent))
+ return;
+ ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+ if (!pParent->DIXsaveUnder &&
+ (pParent->backingStore == NotUseful) && pParent->backStorage)
+ (*ChangeWindowAttributes)(pParent, CWBackingStore);
+ if (!(pChild = pFirst))
+ return;
+ while (1)
+ {
+ if (!pChild->DIXsaveUnder &&
+ (pChild->backingStore == NotUseful) && pChild->backStorage)
+ (*ChangeWindowAttributes)(pChild, CWBackingStore);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib)
+ {
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ return;
+ }
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMarkWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ValidatePtr val;
+
+ if (pWin->valdata)
+ return;
+ val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+ val->before.oldAbsCorner.x = pWin->drawable.x;
+ val->before.oldAbsCorner.y = pWin->drawable.y;
+ val->before.borderVisible = NullRegion;
+ val->before.resized = FALSE;
+ pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+ WindowPtr *ppLayerWin;
+{
+ register BoxPtr box;
+ register WindowPtr pChild, pLast;
+ Bool anyMarked = FALSE;
+ MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst)
+ {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (RegionBroken(&pChild->winSize))
+ SetWinSize (pChild);
+ if (RegionBroken(&pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if ( (pChild = pFirst) )
+ {
+ box = RegionExtents(&pWin->borderSize);
+ pLast = pChild->parent->lastChild;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (RegionBroken(&pChild->winSize))
+ SetWinSize (pChild);
+ if (RegionBroken(&pChild->borderSize))
+ SetBorderSize (pChild);
+ if (RegionContainsRect(&pChild->borderSize, box))
+ {
+ (* MarkWindow)(pChild);
+ anyMarked = TRUE;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast))
+ pChild = pChild->parent;
+ if (pChild == pLast)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ return anyMarked;
+}
+
+/*****
+ * miHandleValidateExposures(pWin)
+ * starting at pWin, draw background in any windows that have exposure
+ * regions, translate the regions, restore any backing store,
+ * and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+ WindowPtr pWin;
+{
+ register WindowPtr pChild;
+ register ValidatePtr val;
+ WindowExposuresProcPtr WindowExposures;
+
+ pChild = pWin;
+ WindowExposures = pChild->drawable.pScreen->WindowExposures;
+ while (1)
+ {
+ if ( (val = pChild->valdata) )
+ {
+ if (RegionNotEmpty(&val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ RegionUninit(&val->after.borderExposed);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ RegionUninit(&val->after.exposed);
+ free(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+ register WindowPtr pWin;
+ int x,y;
+ WindowPtr pNextSib;
+ VTKind kind;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionPtr oldRegion = NULL;
+ DDXPointRec oldpt;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return ;
+ pScreen = pWin->drawable.pScreen;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable)
+ {
+ oldRegion = RegionCreate(NullBox, 1);
+ RegionCopy(oldRegion, &pWin->borderClip);
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, windowToValidate, (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ RegionDestroy(oldRegion);
+ /* XXX need to retile border if ParentRelative origin */
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+ register WindowPtr pWin,
+ void * value) /* must conform to VisitWindowProcPtr */
+{
+ RegionPtr pValid = (RegionPtr)value;
+
+ if (pWin->valdata)
+ {
+ /*
+ * compute exposed regions of this window
+ */
+ RegionSubtract(&pWin->valdata->after.exposed,
+ &pWin->clipList, pValid);
+ /*
+ * compute exposed regions of the border
+ */
+ RegionSubtract(&pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ RegionSubtract(&pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid);
+ return WT_WALKCHILDREN;
+ }
+ return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+ register WindowPtr pWin;
+ int x,y;
+ unsigned int w, h;
+ WindowPtr pSib;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width,
+ height = pWin->drawable.height;
+ short oldx = pWin->drawable.x,
+ oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion = NULL;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion = NULL;
+ RegionPtr destClip; /* portions of destination already written */
+ RegionPtr oldWinClip = NULL; /* old clip list for window */
+ RegionPtr borderVisible = NullRegion; /* visible area of the border */
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pScreen = pWin->drawable.pScreen;
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ anyMarked = FALSE;
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = RegionCreate(NullBox, 1);
+ RegionCopy(oldRegion, &pWin->winSize);
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = (RegionPtr) NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ g = pChild->winGravity;
+ if (g != UnmapGravity)
+ {
+ if (!gravitate[g])
+ gravitate[g] = RegionCreate(NullBox, 1);
+ RegionUnion(gravitate[g],
+ gravitate[g], &pChild->borderClip);
+ }
+ else
+ {
+ UnmapWindow(pChild, TRUE);
+ anyMarked = TRUE;
+ }
+ }
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+
+ oldWinClip = NULL;
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ oldWinClip = RegionCreate(NullBox, 1);
+ RegionCopy(oldWinClip, &pWin->clipList);
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = RegionCreate(NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ RegionSubtract(borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ RegionCopy(borderVisible,
+ &pWin->borderClip);
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ pRegion = RegionCreate(NullBox, 1);
+ if (pWin->backStorage)
+ RegionCopy(pRegion, &pWin->clipList);
+
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+
+ if (pWin->valdata)
+ {
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ RegionCopy(&pWin->valdata->after.exposed, &pWin->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ {
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+ }
+
+ if (WasViewable)
+ {
+ /* avoid the border */
+ if (HasBorder (pWin))
+ {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy)
+ {
+ RegionTranslate(&pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ RegionIntersect(gravitate[g], gravitate[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ RegionTranslate(&pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ RegionCopy(pRegion, oldWinClip);
+ RegionTranslate(pRegion, nx - oldx, ny - oldy);
+ RegionIntersect(oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+ {
+ if (gravitate[g])
+ RegionSubtract(oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ RegionTranslate(oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else
+ {
+ RegionUnion(gravitate[g], gravitate[g], oldWinClip);
+ RegionDestroy(oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = NULL;
+
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ RegionIntersect(gravitate[g], gravitate[g], oldRegion);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip) {
+ RegionTranslate(destClip, oldpt.x - x, oldpt.y - y);
+ RegionSubtract(gravitate[g], gravitate[g], destClip);
+ RegionTranslate(destClip, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+ || pWin->redirectDraw
+#endif
+ )
+ {
+ (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+ }
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ RegionSubtract(oldRegion, oldRegion, gravitate[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->winGravity != g)
+ continue;
+ RegionIntersect(pRegion,
+ &pChild->borderClip, gravitate[g]);
+ TraverseTree (pChild, miRecomputeExposures, (void *)pRegion);
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity)
+ RegionSubtract(&pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if (!destClip)
+ destClip = gravitate[g];
+ else
+ {
+ RegionUnion(destClip, destClip, gravitate[g]);
+ RegionDestroy(gravitate[g]);
+ }
+ }
+
+ RegionDestroy(oldRegion);
+ RegionDestroy(pRegion);
+ if (destClip)
+ RegionDestroy(destClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ RegionEmpty(valExposed);
+ RegionDestroy(bsExposed);
+ }
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+ VTOther);
+ }
+ else if (bsExposed)
+ {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ RegionDestroy(bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+ WindowPtr pWin;
+{
+ return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ * The border/window shape has changed. Recompute winSize/borderSize
+ * and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+ register WindowPtr pWin;
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool anyMarked = FALSE;
+ RegionPtr pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = RegionCreate(NullBox, 1);
+ RegionSubtract(borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = RegionCreate(NullBox, 1);
+ RegionCopy(pOldClip, &pWin->clipList);
+ }
+
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+
+ /*
+ * Applies to NXAGENT_SERVER builds:
+ *
+ * We got a few, rare, segfaults here after having
+ * started using the backing store. It may be a
+ * different bug but miChangeSaveUnder() calls mi-
+ * CheckSubSaveUnder() that, in turn, can change
+ * the backing store attribute of the window. This
+ * means that we may try to destroy the region
+ * even if it was not created at the beginning of
+ * this function as, at the time, the backing store
+ * was off. miCheckSubSaveUnder() appear to get a
+ * pointer to the parent, so maybe doesn't change
+ * the attribute of the window itself. This is to
+ * be better investigated.
+ */
+
+ if (WasViewable && pOldClip)
+ RegionDestroy(pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ RegionEmpty(valExposed);
+ RegionDestroy(bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+ register WindowPtr pWin;
+ unsigned int width;
+{
+ int oldwidth;
+ Bool anyMarked = FALSE;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ if (WasViewable && width < oldwidth)
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable)
+ {
+ if (width > oldwidth)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ /*
+ * save the old border visible region to correctly compute
+ * borderExposed.
+ */
+ if (pWin->valdata && HadBorder)
+ {
+ RegionPtr borderVisible;
+ borderVisible = RegionCreate(NULL, 1);
+ RegionSubtract(borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+ VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+{
+ if ((pChild != pWin) || fromConfigure)
+ {
+ RegionEmpty(&pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ RegionEmpty(&pChild->borderClip);
+ }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+ WindowPtr pChild;
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->drawable.depth == depth)
+ RegionUnion(pReg, pReg, &pChild->borderClip);
+
+ if (pChild->firstChild)
+ miSegregateChildren(pChild, pReg, depth);
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mizerarc.c b/nx-X11/programs/Xserver/mi/mizerarc.c
new file mode 100644
index 000000000..82832fea0
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mizerarc.c
@@ -0,0 +1,853 @@
+/************************************************************
+
+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: Bob Scheifler, MIT X Consortium
+
+********************************************************/
+
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xprotostr.h>
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#include "mizerarc.h"
+
+#define FULLCIRCLE (360 * 64)
+#define OCTANT (45 * 64)
+#define QUADRANT (90 * 64)
+#define HALFCIRCLE (180 * 64)
+#define QUADRANT3 (270 * 64)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
+ ((d) == HALFCIRCLE ? 0.0 : \
+ ((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
+
+#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
+ ((d) == HALFCIRCLE ? -1.0 : \
+ ((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
+
+#define EPSILON45 64
+
+typedef struct {
+ int skipStart;
+ int haveStart;
+ DDXPointRec startPt;
+ int haveLast;
+ int skipLast;
+ DDXPointRec endPt;
+ int dashIndex;
+ int dashOffset;
+ int dashIndexInit;
+ int dashOffsetInit;
+} DashInfo;
+
+static miZeroArcPtRec oob = {65536, 65536, 0};
+
+/*
+ * (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1
+ *
+ * where l is either 0 or .5
+ *
+ * alpha = 4(W^2)
+ * beta = 4(H^2)
+ * gamma = 0
+ * u = 2(W^2)H
+ * v = 4(H^2)l
+ * k = -4(H^2)(l^2)
+ *
+ */
+
+Bool
+miZeroArcSetup(arc, info, ok360)
+ register xArc *arc;
+ register miZeroArcRec *info;
+ Bool ok360;
+{
+ int l;
+ int angle1, angle2;
+ int startseg, endseg;
+ int startAngle, endAngle;
+ int i, overlap;
+ miZeroArcPtRec start, end;
+
+ l = arc->width & 1;
+ if (arc->width == arc->height)
+ {
+ info->alpha = 4;
+ info->beta = 4;
+ info->k1 = -8;
+ info->k3 = -16;
+ info->b = 12;
+ info->a = (arc->width << 2) - 12;
+ info->d = 17 - (arc->width << 1);
+ if (l)
+ {
+ info->b -= 4;
+ info->a += 4;
+ info->d -= 7;
+ }
+ }
+ else if (!arc->width || !arc->height)
+ {
+ info->alpha = 0;
+ info->beta = 0;
+ info->k1 = 0;
+ info->k3 = 0;
+ info->a = -(int)arc->height;
+ info->b = 0;
+ info->d = -1;
+ }
+ else
+ {
+ /* initial conditions */
+ info->alpha = (arc->width * arc->width) << 2;
+ info->beta = (arc->height * arc->height) << 2;
+ info->k1 = info->beta << 1;
+ info->k3 = info->k1 + (info->alpha << 1);
+ info->b = l ? 0 : -info->beta;
+ info->a = info->alpha * arc->height;
+ info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
+ if (l)
+ info->d -= info->beta >> 2;
+ info->a -= info->b;
+ /* take first step, d < 0 always */
+ info->b -= info->k1;
+ info->a += info->k1;
+ info->d += info->b;
+ /* octant change, b < 0 always */
+ info->k1 = -info->k1;
+ info->k3 = -info->k3;
+ info->b = -info->b;
+ info->d = info->b - info->a - info->d;
+ info->a = info->a - (info->b << 1);
+ }
+ info->dx = 1;
+ info->dy = 0;
+ info->w = (arc->width + 1) >> 1;
+ info->h = arc->height >> 1;
+ info->xorg = arc->x + (arc->width >> 1);
+ info->yorg = arc->y;
+ info->xorgo = info->xorg + l;
+ info->yorgo = info->yorg + arc->height;
+ if (!arc->width)
+ {
+ if (!arc->height)
+ {
+ info->x = 0;
+ info->y = 0;
+ info->initialMask = 0;
+ info->startAngle = 0;
+ info->endAngle = 0;
+ info->start = oob;
+ info->end = oob;
+ return FALSE;
+ }
+ info->x = 0;
+ info->y = 1;
+ }
+ else
+ {
+ info->x = 1;
+ info->y = 0;
+ }
+ angle1 = arc->angle1;
+ angle2 = arc->angle2;
+ if ((angle1 == 0) && (angle2 >= FULLCIRCLE))
+ {
+ startAngle = 0;
+ endAngle = 0;
+ }
+ else
+ {
+ if (angle2 > FULLCIRCLE)
+ angle2 = FULLCIRCLE;
+ else if (angle2 < -FULLCIRCLE)
+ angle2 = -FULLCIRCLE;
+ if (angle2 < 0)
+ {
+ startAngle = angle1 + angle2;
+ endAngle = angle1;
+ }
+ else
+ {
+ startAngle = angle1;
+ endAngle = angle1 + angle2;
+ }
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ if (endAngle < 0)
+ endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
+ if (endAngle >= FULLCIRCLE)
+ endAngle = endAngle % FULLCIRCLE;
+ }
+ info->startAngle = startAngle;
+ info->endAngle = endAngle;
+ if (ok360 && (startAngle == endAngle) && arc->angle2 &&
+ arc->width && arc->height)
+ {
+ info->initialMask = 0xf;
+ info->start = oob;
+ info->end = oob;
+ return TRUE;
+ }
+ startseg = startAngle / OCTANT;
+ if (!arc->height || (((startseg + 1) & 2) && arc->width))
+ {
+ start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
+ if (start.x < 0)
+ start.x = -start.x;
+ start.y = -1;
+ }
+ else
+ {
+ start.y = Dsin(startAngle) * (arc->height / 2.0);
+ if (start.y < 0)
+ start.y = -start.y;
+ start.y = info->h - start.y;
+ start.x = 65536;
+ }
+ endseg = endAngle / OCTANT;
+ if (!arc->height || (((endseg + 1) & 2) && arc->width))
+ {
+ end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
+ if (end.x < 0)
+ end.x = -end.x;
+ end.y = -1;
+ }
+ else
+ {
+ end.y = Dsin(endAngle) * (arc->height / 2.0);
+ if (end.y < 0)
+ end.y = -end.y;
+ end.y = info->h - end.y;
+ end.x = 65536;
+ }
+ info->firstx = start.x;
+ info->firsty = start.y;
+ info->initialMask = 0;
+ overlap = arc->angle2 && (endAngle <= startAngle);
+ for (i = 0; i < 4; i++)
+ {
+ if (overlap ?
+ ((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
+ ((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
+ info->initialMask |= (1 << i);
+ }
+ start.mask = info->initialMask;
+ end.mask = info->initialMask;
+ startseg >>= 1;
+ endseg >>= 1;
+ overlap = overlap && (endseg == startseg);
+ if (start.x != end.x || start.y != end.y || !overlap)
+ {
+ if (startseg & 1)
+ {
+ if (!overlap)
+ info->initialMask &= ~(1 << startseg);
+ if (start.x > end.x || start.y > end.y)
+ end.mask &= ~(1 << startseg);
+ }
+ else
+ {
+ start.mask &= ~(1 << startseg);
+ if (((start.x < end.x || start.y < end.y) ||
+ (start.x == end.x && start.y == end.y && (endseg & 1))) &&
+ !overlap)
+ end.mask &= ~(1 << startseg);
+ }
+ if (endseg & 1)
+ {
+ end.mask &= ~(1 << endseg);
+ if (((start.x > end.x || start.y > end.y) ||
+ (start.x == end.x && start.y == end.y && !(startseg & 1))) &&
+ !overlap)
+ start.mask &= ~(1 << endseg);
+ }
+ else
+ {
+ if (!overlap)
+ info->initialMask &= ~(1 << endseg);
+ if (start.x < end.x || start.y < end.y)
+ start.mask &= ~(1 << endseg);
+ }
+ }
+ /* take care of case when start and stop are both near 45 */
+ /* handle here rather than adding extra code to pixelization loops */
+ if (startAngle &&
+ ((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0)))
+ {
+ i = (startAngle + OCTANT) % OCTANT;
+ if (i < EPSILON45 || i > OCTANT - EPSILON45)
+ {
+ i = (endAngle + OCTANT) % OCTANT;
+ if (i < EPSILON45 || i > OCTANT - EPSILON45)
+ {
+ if (start.y < 0)
+ {
+ i = Dsin(startAngle) * (arc->height / 2.0);
+ if (i < 0)
+ i = -i;
+ if (info->h - i == end.y)
+ start.mask = end.mask;
+ }
+ else
+ {
+ i = Dsin(endAngle) * (arc->height / 2.0);
+ if (i < 0)
+ i = -i;
+ if (info->h - i == start.y)
+ end.mask = start.mask;
+ }
+ }
+ }
+ }
+ if (startseg & 1)
+ {
+ info->start = start;
+ info->end = oob;
+ }
+ else
+ {
+ info->end = start;
+ info->start = oob;
+ }
+ if (endseg & 1)
+ {
+ info->altend = end;
+ if (info->altend.x < info->end.x || info->altend.y < info->end.y)
+ {
+ miZeroArcPtRec tmp;
+ tmp = info->altend;
+ info->altend = info->end;
+ info->end = tmp;
+ }
+ info->altstart = oob;
+ }
+ else
+ {
+ info->altstart = end;
+ if (info->altstart.x < info->start.x ||
+ info->altstart.y < info->start.y)
+ {
+ miZeroArcPtRec tmp;
+ tmp = info->altstart;
+ info->altstart = info->start;
+ info->start = tmp;
+ }
+ info->altend = oob;
+ }
+ if (!info->start.x || !info->start.y)
+ {
+ info->initialMask = info->start.mask;
+ info->start = info->altstart;
+ }
+ if (!arc->width && (arc->height == 1))
+ {
+ /* kludge! */
+ info->initialMask |= info->end.mask;
+ info->initialMask |= info->initialMask << 1;
+ info->end.x = 0;
+ info->end.mask = 0;
+ }
+ return FALSE;
+}
+
+#define Pixelate(xval,yval) \
+ { \
+ pts->x = xval; \
+ pts->y = yval; \
+ pts++; \
+ }
+
+#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
+
+DDXPointPtr
+miZeroArcPts(arc, pts)
+ xArc *arc;
+ register DDXPointPtr pts;
+{
+ miZeroArcRec info;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ Bool do360;
+
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ MIARCSETUP();
+ mask = info.initialMask;
+ if (!(arc->width & 1))
+ {
+ DoPix(1, info.xorgo, info.yorg);
+ DoPix(3, info.xorgo, info.yorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int yorgh = info.yorg + info.h;
+ int xorghp = info.xorg + info.h;
+ int xorghn = info.xorg - info.h;
+
+ while (1)
+ {
+ Pixelate(info.xorg + x, info.yorg + y);
+ Pixelate(info.xorg - x, info.yorg + y);
+ Pixelate(info.xorg - x, info.yorgo - y);
+ Pixelate(info.xorg + x, info.yorgo - y);
+ if (a < 0)
+ break;
+ Pixelate(xorghp - y, yorgh - x);
+ Pixelate(xorghn + y, yorgh - x);
+ Pixelate(xorghn + y, yorgh + x);
+ Pixelate(xorghp - y, yorgh + x);
+ MIARCCIRCLESTEP(;);
+ }
+ if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
+ pts -= 4;
+ x = info.w;
+ y = info.h;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ Pixelate(info.xorg + x, info.yorg + y);
+ Pixelate(info.xorgo - x, info.yorg + y);
+ Pixelate(info.xorgo - x, info.yorgo - y);
+ Pixelate(info.xorg + x, info.yorgo - y);
+ MIARCSTEP(;,;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(;,;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ if (arc->height & 1)
+ {
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ }
+ return pts;
+}
+
+#undef DoPix
+#define DoPix(idx,xval,yval) \
+ if (mask & (1 << idx)) \
+ { \
+ arcPts[idx]->x = xval; \
+ arcPts[idx]->y = yval; \
+ arcPts[idx]++; \
+ }
+
+static void
+miZeroArcDashPts(
+ GCPtr pGC,
+ xArc *arc,
+ DashInfo *dinfo,
+ register DDXPointPtr points,
+ int maxPts,
+ register DDXPointPtr *evenPts,
+ register DDXPointPtr *oddPts )
+{
+ miZeroArcRec info;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ int dashRemaining;
+ DDXPointPtr arcPts[4];
+ DDXPointPtr startPts[5], endPts[5];
+ int deltas[5];
+ DDXPointPtr startPt, pt, lastPt, pts;
+ int i, j, delta, ptsdelta, seg, startseg;
+
+ for (i = 0; i < 4; i++)
+ arcPts[i] = points + (i * maxPts);
+ (void)miZeroArcSetup(arc, &info, FALSE);
+ MIARCSETUP();
+ mask = info.initialMask;
+ startseg = info.startAngle / QUADRANT;
+ startPt = arcPts[startseg];
+ if (!(arc->width & 1))
+ {
+ DoPix(1, info.xorgo, info.yorg);
+ DoPix(3, info.xorgo, info.yorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ if ((x == info.firstx) || (y == info.firsty))
+ startPt = arcPts[startseg];
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(;,;);
+ }
+ if ((x == info.firstx) || (y == info.firsty))
+ startPt = arcPts[startseg];
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ if (arc->height & 1)
+ {
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ }
+ for (i = 0; i < 4; i++)
+ {
+ seg = (startseg + i) & 3;
+ pt = points + (seg * maxPts);
+ if (seg & 1)
+ {
+ startPts[i] = pt;
+ endPts[i] = arcPts[seg];
+ deltas[i] = 1;
+ }
+ else
+ {
+ startPts[i] = arcPts[seg] - 1;
+ endPts[i] = pt - 1;
+ deltas[i] = -1;
+ }
+ }
+ startPts[4] = startPts[0];
+ endPts[4] = startPt;
+ startPts[0] = startPt;
+ if (startseg & 1)
+ {
+ if (startPts[4] != endPts[4])
+ endPts[4]--;
+ deltas[4] = 1;
+ }
+ else
+ {
+ if (startPts[0] > startPts[4])
+ startPts[0]--;
+ if (startPts[4] < endPts[4])
+ endPts[4]--;
+ deltas[4] = -1;
+ }
+ if (arc->angle2 < 0)
+ {
+ DDXPointPtr tmps, tmpe;
+ int tmpd;
+
+ tmpd = deltas[0];
+ tmps = startPts[0] - tmpd;
+ tmpe = endPts[0] - tmpd;
+ startPts[0] = endPts[4] - deltas[4];
+ endPts[0] = startPts[4] - deltas[4];
+ deltas[0] = -deltas[4];
+ startPts[4] = tmpe;
+ endPts[4] = tmps;
+ deltas[4] = -tmpd;
+ tmpd = deltas[1];
+ tmps = startPts[1] - tmpd;
+ tmpe = endPts[1] - tmpd;
+ startPts[1] = endPts[3] - deltas[3];
+ endPts[1] = startPts[3] - deltas[3];
+ deltas[1] = -deltas[3];
+ startPts[3] = tmpe;
+ endPts[3] = tmps;
+ deltas[3] = -tmpd;
+ tmps = startPts[2] - deltas[2];
+ startPts[2] = endPts[2] - deltas[2];
+ endPts[2] = tmps;
+ deltas[2] = -deltas[2];
+ }
+ for (i = 0; i < 5 && startPts[i] == endPts[i]; i++)
+ ;
+ if (i == 5)
+ return;
+ pt = startPts[i];
+ for (j = 4; startPts[j] == endPts[j]; j--)
+ ;
+ lastPt = endPts[j] - deltas[j];
+ if (dinfo->haveLast &&
+ (pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y))
+ {
+ startPts[i] += deltas[i];
+ }
+ else
+ {
+ dinfo->dashIndex = dinfo->dashIndexInit;
+ dinfo->dashOffset = dinfo->dashOffsetInit;
+ }
+ if (!dinfo->skipStart && (info.startAngle != info.endAngle))
+ {
+ dinfo->startPt = *pt;
+ dinfo->haveStart = TRUE;
+ }
+ else if (!dinfo->skipLast && dinfo->haveStart &&
+ (lastPt->x == dinfo->startPt.x) &&
+ (lastPt->y == dinfo->startPt.y) &&
+ (lastPt != startPts[i]))
+ endPts[j] = lastPt;
+ if (info.startAngle != info.endAngle)
+ {
+ dinfo->haveLast = TRUE;
+ dinfo->endPt = *lastPt;
+ }
+ dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
+ for (i = 0; i < 5; i++)
+ {
+ pt = startPts[i];
+ lastPt = endPts[i];
+ delta = deltas[i];
+ while (pt != lastPt)
+ {
+ if (dinfo->dashIndex & 1)
+ {
+ pts = *oddPts;
+ ptsdelta = -1;
+ }
+ else
+ {
+ pts = *evenPts;
+ ptsdelta = 1;
+ }
+ while ((pt != lastPt) && --dashRemaining >= 0)
+ {
+ *pts = *pt;
+ pts += ptsdelta;
+ pt += delta;
+ }
+ if (dinfo->dashIndex & 1)
+ *oddPts = pts;
+ else
+ *evenPts = pts;
+ if (dashRemaining <= 0)
+ {
+ if (++(dinfo->dashIndex) == pGC->numInDashList)
+ dinfo->dashIndex = 0;
+ dashRemaining = pGC->dash[dinfo->dashIndex];
+ }
+ }
+ }
+ dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
+}
+
+void
+miZeroPolyArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ int maxPts = 0;
+ register int n, maxw = 0;
+ register xArc *arc;
+ register int i;
+ DDXPointPtr points, pts, oddPts = NULL;
+ register DDXPointPtr pt;
+ int numPts;
+ Bool dospans;
+ int *widths = NULL;
+ XID fgPixel = pGC->fgPixel;
+ DashInfo dinfo;
+
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (!miCanZeroArc(arc))
+ miPolyArc(pDraw, pGC, 1, arc);
+ else
+ {
+ if (arc->width > arc->height)
+ n = arc->width + (arc->height >> 1);
+ else
+ n = arc->height + (arc->width >> 1);
+ if (n > maxPts)
+ maxPts = n;
+ }
+ }
+ if (!maxPts)
+ return;
+ numPts = maxPts << 2;
+ dospans = (pGC->fillStyle != FillSolid);
+ if (dospans)
+ {
+ widths = (int *)malloc(sizeof(int) * numPts);
+ if (!widths)
+ return;
+ maxw = 0;
+ }
+ if (pGC->lineStyle != LineSolid)
+ {
+ numPts <<= 1;
+ dinfo.haveStart = FALSE;
+ dinfo.skipStart = FALSE;
+ dinfo.haveLast = FALSE;
+ dinfo.dashIndexInit = 0;
+ dinfo.dashOffsetInit = 0;
+ miStepDash((int)pGC->dashOffset, &dinfo.dashIndexInit,
+ (unsigned char *) pGC->dash, (int)pGC->numInDashList,
+ &dinfo.dashOffsetInit);
+ }
+ points = (DDXPointPtr)malloc(sizeof(DDXPointRec) * numPts);
+ if (!points)
+ {
+ if (dospans)
+ {
+ free(widths);
+ }
+ return;
+ }
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miCanZeroArc(arc))
+ {
+ if (pGC->lineStyle == LineSolid)
+ pts = miZeroArcPts(arc, points);
+ else
+ {
+ pts = points;
+ oddPts = &points[(numPts >> 1) - 1];
+ dinfo.skipLast = i;
+ miZeroArcDashPts(pGC, arc, &dinfo,
+ oddPts + 1, maxPts, &pts, &oddPts);
+ dinfo.skipStart = TRUE;
+ }
+ n = pts - points;
+ if (!dospans)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, points);
+ else
+ {
+ if (n > maxw)
+ {
+ while (maxw < n)
+ widths[maxw++] = 1;
+ }
+ if (pGC->miTranslate)
+ {
+ for (pt = points; pt != pts; pt++)
+ {
+ pt->x += pDraw->x;
+ pt->y += pDraw->y;
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, FALSE);
+ }
+ if (pGC->lineStyle != LineDoubleDash)
+ continue;
+ if ((pGC->fillStyle == FillSolid) ||
+ (pGC->fillStyle == FillStippled))
+ {
+ DoChangeGC(pGC, GCForeground, (XID *)&pGC->bgPixel, 0);
+ ValidateGC(pDraw, pGC);
+ }
+ pts = &points[numPts >> 1];
+ oddPts++;
+ n = pts - oddPts;
+ if (!dospans)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, oddPts);
+ else
+ {
+ if (n > maxw)
+ {
+ while (maxw < n)
+ widths[maxw++] = 1;
+ }
+ if (pGC->miTranslate)
+ {
+ for (pt = oddPts; pt != pts; pt++)
+ {
+ pt->x += pDraw->x;
+ pt->y += pDraw->y;
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, oddPts, widths, FALSE);
+ }
+ if ((pGC->fillStyle == FillSolid) ||
+ (pGC->fillStyle == FillStippled))
+ {
+ DoChangeGC(pGC, GCForeground, &fgPixel, 0);
+ ValidateGC(pDraw, pGC);
+ }
+ }
+ }
+ free(points);
+ if (dospans)
+ {
+ free(widths);
+ }
+}
diff --git a/nx-X11/programs/Xserver/mi/mizerarc.h b/nx-X11/programs/Xserver/mi/mizerarc.h
new file mode 100644
index 000000000..8119d885e
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mizerarc.h
@@ -0,0 +1,132 @@
+/************************************************************
+
+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.
+
+********************************************************/
+
+
+typedef struct {
+ int x;
+ int y;
+ int mask;
+} miZeroArcPtRec;
+
+typedef struct {
+ int x, y, k1, k3, a, b, d, dx, dy;
+ int alpha, beta;
+ int xorg, yorg;
+ int xorgo, yorgo;
+ int w, h;
+ int initialMask;
+ miZeroArcPtRec start, altstart, end, altend;
+ int firstx, firsty;
+ int startAngle, endAngle;
+} miZeroArcRec;
+
+#define miCanZeroArc(arc) (((arc)->width == (arc)->height) || \
+ (((arc)->width <= 800) && ((arc)->height <= 800)))
+
+#define MIARCSETUP() \
+ x = info.x; \
+ y = info.y; \
+ k1 = info.k1; \
+ k3 = info.k3; \
+ a = info.a; \
+ b = info.b; \
+ d = info.d; \
+ dx = info.dx; \
+ dy = info.dy
+
+#define MIARCOCTANTSHIFT(clause) \
+ if (a < 0) \
+ { \
+ if (y == info.h) \
+ { \
+ d = -1; \
+ a = b = k1 = 0; \
+ } \
+ else \
+ { \
+ dx = (k1 << 1) - k3; \
+ k1 = dx - k1; \
+ k3 = -k3; \
+ b = b + a - (k1 >> 1); \
+ d = b + ((-a) >> 1) - d + (k3 >> 3); \
+ if (dx < 0) \
+ a = -((-dx) >> 1) - a; \
+ else \
+ a = (dx >> 1) - a; \
+ dx = 0; \
+ dy = 1; \
+ clause \
+ } \
+ }
+
+#define MIARCSTEP(move1,move2) \
+ b -= k1; \
+ if (d < 0) \
+ { \
+ x += dx; \
+ y += dy; \
+ a += k1; \
+ d += b; \
+ move1 \
+ } \
+ else \
+ { \
+ x++; \
+ y++; \
+ a += k3; \
+ d -= a; \
+ move2 \
+ }
+
+#define MIARCCIRCLESTEP(clause) \
+ b -= k1; \
+ x++; \
+ if (d < 0) \
+ { \
+ a += k1; \
+ d += b; \
+ } \
+ else \
+ { \
+ y++; \
+ a += k3; \
+ d -= a; \
+ clause \
+ }
+
+/* mizerarc.c */
+
+extern Bool miZeroArcSetup(
+ xArc * /*arc*/,
+ miZeroArcRec * /*info*/,
+ Bool /*ok360*/
+);
+
+extern DDXPointPtr miZeroArcPts(
+ xArc * /*arc*/,
+ DDXPointPtr /*pts*/
+);
+
diff --git a/nx-X11/programs/Xserver/mi/mizerclip.c b/nx-X11/programs/Xserver/mi/mizerclip.c
new file mode 100644
index 000000000..198a72687
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mizerclip.c
@@ -0,0 +1,635 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "miline.h"
+
+/*
+
+The bresenham error equation used in the mi/mfb/cfb line routines is:
+
+ e = error
+ dx = difference in raw X coordinates
+ dy = difference in raw Y coordinates
+ M = # of steps in X direction
+ N = # of steps in Y direction
+ B = 0 to prefer diagonal steps in a given octant,
+ 1 to prefer axial steps in a given octant
+
+ For X major lines:
+ e = 2Mdy - 2Ndx - dx - B
+ -2dx <= e < 0
+
+ For Y major lines:
+ e = 2Ndx - 2Mdy - dy - B
+ -2dy <= e < 0
+
+At the start of the line, we have taken 0 X steps and 0 Y steps,
+so M = 0 and N = 0:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = -dx - B
+
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = -dy - B
+
+At the end of the line, we have taken dx X steps and dy Y steps,
+so M = dx and N = dy:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = 2dxdy - 2dydx - dx - B
+ = -dx - B
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = 2dydx - 2dxdy - dy - B
+ = -dy - B
+
+Thus, the error term is the same at the start and end of the line.
+
+Let us consider clipping an X coordinate. There are 4 cases which
+represent the two independent cases of clipping the start vs. the
+end of the line and an X major vs. a Y major line. In any of these
+cases, we know the number of X steps (M) and we wish to find the
+number of Y steps (N). Thus, we will solve our error term equation.
+If we are clipping the start of the line, we will find the smallest
+N that satisfies our error term inequality. If we are clipping the
+end of the line, we will find the largest number of Y steps that
+satisfies the inequality. In that case, since we are representing
+the Y steps as (dy - N), we will actually want to solve for the
+smallest N in that equation.
+
+Case 1: X major, starting X coordinate moved by M steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
+ 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
+ N <= (2Mdy + dx - B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dx - B) / 2dx) + 1
+ = floor((2Mdy - dx - B + 2dx) / 2dx)
+ = floor((2Mdy + dx - B) / 2dx)
+
+Case 1b: X major, ending X coordinate moved to M steps
+
+Same derivations as Case 1, but we want the largest N that satisfies
+the equations, so we use the <= inequality:
+
+ N = floor((2Mdy + dx - B) / 2dx)
+
+Case 2: X major, ending X coordinate moved by M steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
+ 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
+ N >= (2Mdy - dx + B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dx + B) / 2dx)
+ = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 2b: X major, starting X coordinate moved to M steps from end
+
+Same derivations as Case 2, but we want the smallest number of Y
+steps, so we want the highest N, so we use the < inequality:
+
+ N = ceiling((2Mdy + dx + B) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 3: Y major, starting X coordinate moved by M steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
+ 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
+ N >= (2Mdy - dy + B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dy + B) / 2dx)
+ = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
+ = floor((2Mdy - dy + B - 1) / 2dx) + 1
+
+Case 3b: Y major, ending X coordinate moved to M steps
+
+Same derivations as Case 3, but we want the largest N that satisfies
+the equations, so we use the < inequality:
+
+ N = ceiling((2Mdy + dy + B) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dy + B - 1) / 2dx)
+
+Case 4: Y major, ending X coordinate moved by M steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
+ 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
+ N <= (2Mdy + dy - B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dy - B) / 2dx) + 1
+
+Case 4b: Y major, starting X coordinate moved to M steps from end
+
+Same analysis as Case 4, but we want the smallest number of Y steps
+which means the largest N, so we use the <= inequality:
+
+ N = floor((2Mdy + dy - B) / 2dx)
+
+Now let's try the Y coordinates, we have the same 4 cases.
+
+Case 5: X major, starting Y coordinate moved by N steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
+ 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
+ M >= (2Ndx - dx + B) / 2dy
+
+Since we are trying to find the smallest M, we use the >= inequality:
+
+ M = ceiling((2Ndx - dx + B) / 2dy)
+ = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
+ = floor((2Ndx - dx + B - 1) / 2dy) + 1
+
+Case 5b: X major, ending Y coordinate moved to N steps
+
+Same derivations as Case 5, but we want the largest M that satisfies
+the equations, so we use the < inequality:
+
+ M = ceiling((2Ndx + dx + B) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dx + B - 1) / 2dy)
+
+Case 6: X major, ending Y coordinate moved by N steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
+ 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
+ M <= (2Ndx + dx - B) / 2dy
+
+Largest # of X steps means smallest M, so use the > inequality:
+
+ M = floor((2Ndx - dx - B) / 2dy) + 1
+
+Case 6b: X major, starting Y coordinate moved to N steps from end
+
+Same derivations as Case 6, but we want the smallest # of X steps
+which means the largest M, so use the <= inequality:
+
+ M = floor((2Ndx + dx - B) / 2dy)
+
+Case 7: Y major, starting Y coordinate moved by N steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
+ 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
+ M <= (2Ndx + dy - B) / 2dy
+
+To find the smallest M, use the > inequality:
+
+ M = floor((2Ndx - dy - B) / 2dy) + 1
+ = floor((2Ndx - dy - B + 2dy) / 2dy)
+ = floor((2Ndx + dy - B) / 2dy)
+
+Case 7b: Y major, ending Y coordinate moved to N steps
+
+Same derivations as Case 7, but we want the largest M that satisfies
+the equations, so use the <= inequality:
+
+ M = floor((2Ndx + dy - B) / 2dy)
+
+Case 8: Y major, ending Y coordinate moved by N steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
+ 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
+ M >= (2Ndx - dy + B) / 2dy
+
+To find the highest X steps, find the smallest M, use the >= inequality:
+
+ M = ceiling((2Ndx - dy + B) / 2dy)
+ = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+Case 8b: Y major, starting Y coordinate moved to N steps from the end
+
+Same derivations as Case 8, but we want to find the smallest # of X
+steps which means the largest M, so we use the < inequality:
+
+ M = ceiling((2Ndx + dy + B) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+So, our equations are:
+
+ 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+ 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+
+ 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
+ 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
+ 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
+ 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
+
+ 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
+ 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
+ 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
+ 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
+
+ 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+ 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+
+We have the following constraints on all of the above terms:
+
+ 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
+ 0 <= dx/dy <= 2^16 - 1
+ 0 <= B <= 1
+
+The floor in all of the above equations can be accomplished with a
+simple C divide operation provided that both numerator and denominator
+are positive.
+
+Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
+and moving a Y coordinate implies dy != 0, we know that the denominators
+are all > 0.
+
+For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
+bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
+or > 0 to prove that the numerators are positive (or zero).
+
+For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
+constraints, the first four equations all have numerators >= 0.
+
+For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
+So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
+or (2Mdy + dy) > 0. So all of their numerators are >= 0.
+
+For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
+>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
+
+For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
+are > 0.
+
+To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
+is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
+ <= 2^16 * (2^16 - 1) + (2^16 - 1)
+ <= 2^32 - 2^16 + 2^16 - 1
+ <= 2^32 - 1
+Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
+the numerator is therefore (2^32 - 1), which does not overflow an unsigned
+32 bit variable.
+
+*/
+
+/* Bit codes for the terms of the 16 clipping equations defined below. */
+
+#define T_2NDX (1 << 0)
+#define T_2MDY (0) /* implicit term */
+#define T_DXNOTY (1 << 1)
+#define T_DYNOTX (0) /* implicit term */
+#define T_SUBDXORY (1 << 2)
+#define T_ADDDX (T_DXNOTY) /* composite term */
+#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
+#define T_ADDDY (T_DYNOTX) /* composite term */
+#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
+#define T_BIASSUBONE (1 << 3)
+#define T_SUBBIAS (0) /* implicit term */
+#define T_DIV2DX (1 << 4)
+#define T_DIV2DY (0) /* implicit term */
+#define T_ADDONE (1 << 5)
+
+/* Bit masks defining the 16 equations used in miZeroClipLine. */
+
+#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+
+#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
+#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
+#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
+#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
+
+#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
+#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
+#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
+#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
+
+#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+
+/* miZeroClipLine
+ *
+ * returns: 1 for partially clipped line
+ * -1 for completely clipped line
+ *
+ */
+int
+miZeroClipLine(xmin, ymin, xmax, ymax,
+ new_x1, new_y1, new_x2, new_y2,
+ adx, ady,
+ pt1_clipped, pt2_clipped, octant, bias, oc1, oc2)
+ int xmin, ymin, xmax, ymax;
+ int *new_x1, *new_y1, *new_x2, *new_y2;
+ int *pt1_clipped, *pt2_clipped;
+ unsigned int adx, ady;
+ int octant;
+ unsigned int bias;
+ int oc1, oc2;
+{
+ int swapped = 0;
+ int clipDone = 0;
+ CARD32 utmp = 0;
+ int clip1, clip2;
+ int x1, y1, x2, y2;
+ int x1_orig, y1_orig, x2_orig, y2_orig;
+ int xmajor;
+ int negslope = 0, anchorval = 0;
+ unsigned int eqn = 0;
+
+ x1 = x1_orig = *new_x1;
+ y1 = y1_orig = *new_y1;
+ x2 = x2_orig = *new_x2;
+ y2 = y2_orig = *new_y2;
+
+ clip1 = 0;
+ clip2 = 0;
+
+ xmajor = IsXMajorOctant(octant);
+ bias = ((bias >> octant) & 1);
+
+ while (1)
+ {
+ if ((oc1 & oc2) != 0) /* trivial reject */
+ {
+ clipDone = -1;
+ clip1 = oc1;
+ clip2 = oc2;
+ break;
+ }
+ else if ((oc1 | oc2) == 0) /* trivial accept */
+ {
+ clipDone = 1;
+ if (swapped)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT(clip1, clip2);
+ }
+ break;
+ }
+ else /* have to clip */
+ {
+ /* only clip one point at a time */
+ if (oc1 == 0)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig);
+ SWAPINT(oc1, oc2);
+ SWAPINT(clip1, clip2);
+ swapped = !swapped;
+ }
+
+ clip1 |= oc1;
+ if (oc1 & OUT_LEFT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = xmin - x1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = x2_orig - xmin;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmin;
+ }
+ else if (oc1 & OUT_ABOVE)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = ymin - y1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = y2_orig - ymin;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymin;
+ }
+ else if (oc1 & OUT_RIGHT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = x1_orig - xmax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * to the right of a clip rectangle.
+ */
+ utmp = xmax - x2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmax;
+ }
+ else if (oc1 & OUT_BELOW)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = y1_orig - ymax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * below the bottom of a clip rectangle.
+ */
+ utmp = ymax - y2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymax;
+ }
+
+ if (swapped)
+ negslope = !negslope;
+
+ utmp <<= 1; /* utmp = 2N or 2M */
+ if (eqn & T_2NDX)
+ utmp = (utmp * adx);
+ else /* (eqn & T_2MDY) */
+ utmp = (utmp * ady);
+ if (eqn & T_DXNOTY)
+ if (eqn & T_SUBDXORY)
+ utmp -= adx;
+ else
+ utmp += adx;
+ else /* (eqn & T_DYNOTX) */
+ if (eqn & T_SUBDXORY)
+ utmp -= ady;
+ else
+ utmp += ady;
+ if (eqn & T_BIASSUBONE)
+ utmp += bias - 1;
+ else /* (eqn & T_SUBBIAS) */
+ utmp -= bias;
+ if (eqn & T_DIV2DX)
+ utmp /= (adx << 1);
+ else /* (eqn & T_DIV2DY) */
+ utmp /= (ady << 1);
+ if (eqn & T_ADDONE)
+ utmp++;
+
+ if (negslope)
+ utmp = -utmp;
+
+ if (eqn & T_2NDX) /* We are calculating X steps */
+ x1 = anchorval + utmp;
+ else /* else, Y steps */
+ y1 = anchorval + utmp;
+
+ oc1 = 0;
+ MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax);
+ }
+ }
+
+ *new_x1 = x1;
+ *new_y1 = y1;
+ *new_x2 = x2;
+ *new_y2 = y2;
+
+ *pt1_clipped = clip1;
+ *pt2_clipped = clip2;
+
+ return clipDone;
+}
diff --git a/nx-X11/programs/Xserver/mi/mizerline.c b/nx-X11/programs/Xserver/mi/mizerline.c
new file mode 100644
index 000000000..49d87edd8
--- /dev/null
+++ b/nx-X11/programs/Xserver/mi/mizerline.c
@@ -0,0 +1,378 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "miline.h"
+
+/* Draw lineSolid, fillStyle-independent zero width lines.
+ *
+ * Must keep X and Y coordinates in "ints" at least until after they're
+ * translated and clipped to accomodate CoordModePrevious lines with very
+ * large coordinates.
+ *
+ * Draws the same pixels regardless of sign(dx) or sign(dy).
+ *
+ * Ken Whaley
+ *
+ */
+
+/* largest positive value that can fit into a component of a point.
+ * Assumes that the point structure is {type x, y;} where type is
+ * a signed type.
+ */
+#define MAX_COORDINATE ((1 << (((sizeof(DDXPointRec) >> 1) << 3) - 1)) - 1)
+
+#define MI_OUTPUT_POINT(xx, yy)\
+{\
+ if ( !new_span && yy == current_y)\
+ {\
+ if (xx < spans->x)\
+ spans->x = xx;\
+ ++*widths;\
+ }\
+ else\
+ {\
+ ++Nspans;\
+ ++spans;\
+ ++widths;\
+ spans->x = xx;\
+ spans->y = yy;\
+ *widths = 1;\
+ current_y = yy;\
+ new_span = FALSE;\
+ }\
+}
+
+void
+miZeroLine(pDraw, pGC, mode, npt, pptInit)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+{
+ int Nspans, current_y = 0;
+ DDXPointPtr ppt;
+ DDXPointPtr pspanInit, spans;
+ int *pwidthInit, *widths, list_len;
+ int xleft, ytop, xright, ybottom;
+ int new_x1, new_y1, new_x2, new_y2;
+ int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
+ int oc1, oc2;
+ int result;
+ int pt1_clipped, pt2_clipped = 0;
+ Bool new_span;
+ int signdx, signdy;
+ int clipdx, clipdy;
+ int width, height;
+ int adx, ady;
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDraw->pScreen);
+ int e, e1, e2, e3; /* Bresenham error terms */
+ int length; /* length of lines == # of pixels on major axis */
+
+ xleft = pDraw->x;
+ ytop = pDraw->y;
+ xright = pDraw->x + pDraw->width - 1;
+ ybottom = pDraw->y + pDraw->height - 1;
+
+ if (!pGC->miTranslate)
+ {
+ /* do everything in drawable-relative coordinates */
+ xleft = 0;
+ ytop = 0;
+ xright -= pDraw->x;
+ ybottom -= pDraw->y;
+ }
+
+ /* it doesn't matter whether we're in drawable or screen coordinates,
+ * FillSpans simply cannot take starting coordinates outside of the
+ * range of a DDXPointRec component.
+ */
+ if (xright > MAX_COORDINATE)
+ xright = MAX_COORDINATE;
+ if (ybottom > MAX_COORDINATE)
+ ybottom = MAX_COORDINATE;
+
+ /* since we're clipping to the drawable's boundaries & coordinate
+ * space boundaries, we're guaranteed that the larger of width/height
+ * is the longest span we'll need to output
+ */
+ width = xright - xleft + 1;
+ height = ybottom - ytop + 1;
+ list_len = (height >= width) ? height : width;
+ pspanInit = (DDXPointPtr)malloc(list_len * sizeof(DDXPointRec));
+ pwidthInit = (int *)malloc(list_len * sizeof(int));
+ if (!pspanInit || !pwidthInit)
+ return;
+
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+ ppt = pptInit;
+
+ xstart = ppt->x;
+ ystart = ppt->y;
+ if (pGC->miTranslate)
+ {
+ xstart += pDraw->x;
+ ystart += pDraw->y;
+ }
+
+ /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
+ * iteration logic
+ */
+ x2 = xstart;
+ y2 = ystart;
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ while (--npt > 0)
+ {
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+
+ x1 = x2;
+ y1 = y2;
+ oc1 = oc2;
+ ++ppt;
+
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (pGC->miTranslate && (mode != CoordModePrevious))
+ {
+ x2 += pDraw->x;
+ y2 += pDraw->y;
+ }
+ else if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ length = adx; /* don't draw endpoint in main loop */
+
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = miZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_x2 - new_x1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdy * e2) + ((clipdx - clipdy) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ y += signdy;
+ e += e3;
+ }
+ x += signdx;
+ }
+ }
+ else /* Y major line */
+ {
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ length = ady; /* don't draw endpoint in main loop */
+
+ SetYMajorOctant(octant);
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = miZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_y2 - new_y1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdx * e2) + ((clipdy - clipdx) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ x += signdx;
+ e += e3;
+ }
+ y += signdy;
+ }
+ }
+ }
+
+ /* only do the capnotlast check on the last segment
+ * and only if the endpoint wasn't clipped. And then, if the last
+ * point is the same as the first point, do not draw it, unless the
+ * line is degenerate
+ */
+ if ( (! pt2_clipped) && (pGC->capStyle != CapNotLast) &&
+ (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1)))
+ {
+ MI_OUTPUT_POINT(x, y);
+ }
+
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+
+ free(pwidthInit);
+ free(pspanInit);
+}
+
+void
+miZeroDashLine(dst, pgc, mode, nptInit, pptInit)
+DrawablePtr dst;
+GCPtr pgc;
+int mode;
+int nptInit; /* number of points in polyline */
+DDXPointRec *pptInit; /* points in the polyline */
+{
+ /* XXX kludge until real zero-width dash code is written */
+ pgc->lineWidth = 1;
+ miWideDash (dst, pgc, mode, nptInit, pptInit);
+ pgc->lineWidth = 0;
+}
diff --git a/nx-X11/programs/Xserver/miext/cw/Imakefile b/nx-X11/programs/Xserver/miext/cw/Imakefile
new file mode 100644
index 000000000..395e60a48
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/cw/Imakefile
@@ -0,0 +1,22 @@
+#include <Server.tmpl>
+
+SRCS = cw.c cw_ops.c cw_render.c
+
+OBJS = cw.o cw_ops.o cw_render.o
+
+ INCLUDES = -I../../mi -I../../fb -I../../render -I../../composite \
+ -I../../include -I$(XINCLUDESRC) $(EXTRAINCLUDES) \
+ -I$(EXTINCSRC) \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../../dix/llib-ldix.ln ../../os/llib-los.ln \
+ ../../mi/llib-lmi.ln
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(cw,$(OBJS))
+LintLibraryTarget(cw,$(SRCS))
+
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(cw.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/miext/cw/cw.c b/nx-X11/programs/Xserver/miext/cw/cw.c
new file mode 100644
index 000000000..d9ca55f7e
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/cw/cw.c
@@ -0,0 +1,701 @@
+/*
+ * Copyright © 2004 Eric Anholt
+ *
+ * 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, and that the name of Eric Anholt not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Eric Anholt makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ERIC ANHOLT 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.
+ */
+/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw.c,v 1.23 2005/10/02 08:28:26 anholt Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "cw.h"
+
+#define CW_DEBUG 1
+
+#if CW_DEBUG
+#define CW_ASSERT(x) do { \
+ if (!(x)) { \
+ ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \
+ __LINE__); \
+ } \
+} while (0)
+#else
+#define CW_ASSERT(x) do {} while (0)
+#endif
+
+int cwGCIndex;
+int cwScreenIndex;
+int cwWindowIndex;
+#ifdef RENDER
+int cwPictureIndex;
+#endif
+static Bool cwDisabled[MAXSCREENS];
+static unsigned long cwGeneration = 0;
+extern GCOps cwGCOps;
+
+static Bool
+cwCloseScreen (ScreenPtr pScreen);
+
+static void
+cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
+static void
+cwChangeGC(GCPtr pGC, unsigned long mask);
+static void
+cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void
+cwDestroyGC(GCPtr pGC);
+static void
+cwChangeClip(GCPtr pGC, int type, void * pvalue, int nrects);
+static void
+cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+static void
+cwDestroyClip(GCPtr pGC);
+
+GCFuncs cwGCFuncs = {
+ cwValidateGC,
+ cwChangeGC,
+ cwCopyGC,
+ cwDestroyGC,
+ cwChangeClip,
+ cwDestroyClip,
+ cwCopyClip,
+};
+
+/* Find the real drawable to draw to, and provide offsets that will translate
+ * window coordinates to backing pixmap coordinates.
+ */
+DrawablePtr
+cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
+{
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ (pPixmap = getCwPixmap ((WindowPtr) pDrawable)))
+ {
+ *x_off = pDrawable->x - pPixmap->screen_x;
+ *y_off = pDrawable->y - pPixmap->screen_y;
+ return &pPixmap->drawable;
+ } else {
+ *x_off = *y_off = 0;
+ return pDrawable;
+ }
+}
+
+#define FUNC_PROLOGUE(pGC, pPriv) do { \
+ (pGC)->funcs = (pPriv)->wrapFuncs; \
+ (pGC)->ops = (pPriv)->wrapOps; \
+} while (0)
+
+#define FUNC_EPILOGUE(pGC, pPriv) do { \
+ (pPriv)->wrapFuncs = (pGC)->funcs; \
+ (pPriv)->wrapOps = (pGC)->ops; \
+ (pGC)->funcs = &cwGCFuncs; \
+ (pGC)->ops = &cwGCOps; \
+} while (0)
+
+
+static Bool
+cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable)
+{
+ cwGCRec *pPriv = getCwGC(pGC);
+ int status, x_off, y_off;
+ XID noexpose = xFalse;
+ DrawablePtr pBackingDrawable;
+
+ pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
+ pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
+ &noexpose, &status);
+ if (status != Success)
+ return FALSE;
+
+ pPriv->serialNumber = 0;
+ pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
+
+ return TRUE;
+}
+
+static void
+cwDestroyBackingGC(GCPtr pGC)
+{
+ cwGCPtr pPriv;
+
+ pPriv = (cwGCPtr) getCwGC (pGC);
+
+ if (pPriv->pBackingGC) {
+ FreeGC(pPriv->pBackingGC, (XID)0);
+ pPriv->pBackingGC = NULL;
+ }
+}
+
+static void
+cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
+{
+ GCPtr pBackingGC;
+ cwGCPtr pPriv;
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off;
+
+ pPriv = (cwGCPtr) getCwGC (pGC);
+
+ FUNC_PROLOGUE(pGC, pPriv);
+
+ /*
+ * Must call ValidateGC to ensure pGC->pCompositeClip is valid
+ */
+ (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
+
+ if (!cwDrawableIsRedirWindow(pDrawable)) {
+ cwDestroyBackingGC(pGC);
+ FUNC_EPILOGUE(pGC, pPriv);
+ return;
+ } else {
+ if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
+ FUNC_EPILOGUE(pGC, pPriv);
+ return;
+ }
+ }
+
+ pBackingGC = pPriv->pBackingGC;
+ pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
+
+ pPriv->stateChanges |= stateChanges;
+
+ /*
+ * Copy the composite clip into the backing GC if either
+ * the drawable clip list has changed or the client has changed
+ * the client clip data
+ */
+ if (pDrawable->serialNumber != pPriv->serialNumber ||
+ (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
+ {
+ XID vals[2];
+ RegionPtr pCompositeClip;
+
+ pCompositeClip = RegionCreate(NULL, 0);
+ RegionCopy(pCompositeClip, pGC->pCompositeClip);
+
+ /* Either the drawable has changed, or the clip list in the drawable has
+ * changed. Copy the new clip list over and set the new translated
+ * offset for it.
+ */
+
+ (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION,
+ (void *) pCompositeClip, 0);
+
+ vals[0] = x_off - pDrawable->x;
+ vals[1] = y_off - pDrawable->y;
+ dixChangeGC(NullClient, pBackingGC,
+ (GCClipXOrigin | GCClipYOrigin), vals, NULL);
+
+ pPriv->serialNumber = pDrawable->serialNumber;
+ /*
+ * Mask off any client clip changes to make sure
+ * the clip list set above remains in effect
+ */
+ pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ }
+
+ if (pPriv->stateChanges) {
+ CopyGC(pGC, pBackingGC, pPriv->stateChanges);
+ pPriv->stateChanges = 0;
+ }
+
+ if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
+ (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
+ {
+ XID vals[2];
+ vals[0] = pGC->patOrg.x + x_off;
+ vals[1] = pGC->patOrg.y + y_off;
+ dixChangeGC(NullClient, pBackingGC,
+ (GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
+ }
+
+ ValidateGC(pBackingDrawable, pBackingGC);
+
+ FUNC_EPILOGUE(pGC, pPriv);
+}
+
+static void
+cwChangeGC(GCPtr pGC, unsigned long mask)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pGC, pPriv);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ FUNC_EPILOGUE(pGC, pPriv);
+}
+
+static void
+cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pGCDst)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pGCDst, pPriv);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ FUNC_EPILOGUE(pGCDst, pPriv);
+}
+
+static void
+cwDestroyGC(GCPtr pGC)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pGC, pPriv);
+
+ cwDestroyBackingGC(pGC);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ /* leave it unwrapped */
+}
+
+static void
+cwChangeClip(GCPtr pGC, int type, void * pvalue, int nrects)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pGC, pPriv);
+
+ (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
+
+ FUNC_EPILOGUE(pGC, pPriv);
+}
+
+static void
+cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pgcDst)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pgcDst, pPriv);
+
+ (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ FUNC_EPILOGUE(pgcDst, pPriv);
+}
+
+static void
+cwDestroyClip(GCPtr pGC)
+{
+ cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
+
+ FUNC_PROLOGUE(pGC, pPriv);
+
+ (*pGC->funcs->DestroyClip)(pGC);
+
+ FUNC_EPILOGUE(pGC, pPriv);
+}
+
+/*
+ * Screen wrappers.
+ */
+
+#define SCREEN_PROLOGUE(pScreen, field) \
+ ((pScreen)->field = getCwScreen(pScreen)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \
+ getCwScreen(pScreen)->field = (pScreen)->field; \
+ (pScreen)->field = (wrapper); \
+} while (0)
+
+static Bool
+cwCreateGC(GCPtr pGC)
+{
+ cwGCPtr pPriv = getCwGC(pGC);
+ ScreenPtr pScreen = pGC->pScreen;
+ Bool ret;
+
+ bzero(pPriv, sizeof(cwGCRec));
+ SCREEN_PROLOGUE(pScreen, CreateGC);
+
+ if ( (ret = (*pScreen->CreateGC)(pGC)) )
+ FUNC_EPILOGUE(pGC, pPriv);
+
+ SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
+
+ return ret;
+}
+
+static void
+cwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format,
+ unsigned long planemask, char *pdstLine)
+{
+ ScreenPtr pScreen = pSrc->pScreen;
+ DrawablePtr pBackingDrawable;
+ int src_off_x, src_off_y;
+
+ SCREEN_PROLOGUE(pScreen, GetImage);
+
+ pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y);
+
+ CW_OFFSET_XY_SRC(x, y);
+
+ (*pScreen->GetImage)(pBackingDrawable, x, y, w, h, format, planemask,
+ pdstLine);
+
+ SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
+}
+
+static void
+cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth,
+ int nspans, char *pdstStart)
+{
+ ScreenPtr pScreen = pSrc->pScreen;
+ DrawablePtr pBackingDrawable;
+ int i;
+ int src_off_x, src_off_y;
+
+ SCREEN_PROLOGUE(pScreen, GetSpans);
+
+ pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y);
+
+ for (i = 0; i < nspans; i++)
+ CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y);
+
+ (*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans,
+ pdstStart);
+
+ SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
+}
+
+static void
+cwFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, unsigned long pixel)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ GCPtr pGC;
+ BoxPtr pBox;
+ int nbox, i;
+ ChangeGCVal v[3];
+
+ pGC = GetScratchGC(pDrawable->depth, pScreen);
+ v[0].val = GXcopy;
+ v[1].val = pixel;
+ v[2].val = FillSolid;
+ dixChangeGC(NullClient, pGC, (GCFunction | GCForeground | GCFillStyle),
+ NULL, v);
+ ValidateGC(pDrawable, pGC);
+
+ pBox = RegionRects(pRegion);
+ nbox = RegionNumRects(pRegion);
+
+ for (i = 0; i < nbox; i++, pBox++) {
+ xRectangle rect;
+ rect.x = pBox->x1;
+ rect.y = pBox->y1;
+ rect.width = pBox->x2 - pBox->x1;
+ rect.height = pBox->y2 - pBox->y1;
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &rect);
+ }
+
+ FreeScratchGC(pGC);
+}
+
+static void
+cwFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ int x_off, int y_off)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ GCPtr pGC;
+ BoxPtr pBox;
+ int nbox, i;
+ ChangeGCVal v[5];
+
+ pGC = GetScratchGC(pDrawable->depth, pScreen);
+ v[0].val = GXcopy;
+ v[1].val = FillTiled;
+ v[2].ptr = (void *) pTile;
+ v[3].val = x_off;
+ v[4].val = y_off;
+ dixChangeGC(NullClient, pGC, (GCFunction | GCFillStyle | GCTile |
+ GCTileStipXOrigin | GCTileStipYOrigin), NULL, v);
+
+ ValidateGC(pDrawable, pGC);
+
+ pBox = RegionRects(pRegion);
+ nbox = RegionNumRects(pRegion);
+
+ for (i = 0; i < nbox; i++, pBox++) {
+ xRectangle rect;
+ rect.x = pBox->x1;
+ rect.y = pBox->y1;
+ rect.width = pBox->x2 - pBox->x1;
+ rect.height = pBox->y2 - pBox->y1;
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &rect);
+ }
+
+ FreeScratchGC(pGC);
+}
+
+static void
+cwPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE(pScreen, PaintWindowBackground);
+
+ if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
+ (*pScreen->PaintWindowBackground)(pWin, pRegion, what);
+ } else {
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off, x_screen, y_screen;
+
+ while (pWin && pWin->backgroundState == ParentRelative)
+ pWin = pWin->parent;
+
+ pBackingDrawable = cwGetBackingDrawable((DrawablePtr)pWin, &x_off,
+ &y_off);
+
+ x_screen = x_off - pWin->drawable.x;
+ y_screen = y_off - pWin->drawable.y;
+
+ if (pWin && (pWin->backgroundState == BackgroundPixel ||
+ pWin->backgroundState == BackgroundPixmap))
+ {
+ RegionTranslate(pRegion, x_screen, y_screen);
+
+ if (pWin->backgroundState == BackgroundPixel) {
+ cwFillRegionSolid(pBackingDrawable, pRegion,
+ pWin->background.pixel);
+ } else {
+ cwFillRegionTiled(pBackingDrawable, pRegion,
+ pWin->background.pixmap, x_off, y_off);
+ }
+
+ RegionTranslate(pRegion, -x_screen, -y_screen);
+ }
+ }
+
+ SCREEN_EPILOGUE(pScreen, PaintWindowBackground, cwPaintWindowBackground);
+}
+
+static void
+cwPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE(pScreen, PaintWindowBorder);
+
+ if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
+ (*pScreen->PaintWindowBorder)(pWin, pRegion, what);
+ } else {
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off, x_screen, y_screen;
+
+ pBackingDrawable = cwGetBackingDrawable((DrawablePtr)pWin, &x_off,
+ &y_off);
+
+ x_screen = x_off - pWin->drawable.x;
+ y_screen = y_off - pWin->drawable.y;
+
+ RegionTranslate(pRegion, x_screen, y_screen);
+
+ if (pWin->borderIsPixel) {
+ cwFillRegionSolid(pBackingDrawable, pRegion, pWin->border.pixel);
+ } else {
+ cwFillRegionTiled(pBackingDrawable, pRegion, pWin->border.pixmap,
+ x_off, y_off);
+ }
+
+ RegionTranslate(pRegion, -x_screen, -y_screen);
+ }
+
+ SCREEN_EPILOGUE(pScreen, PaintWindowBorder, cwPaintWindowBorder);
+}
+
+static void
+cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE(pScreen, CopyWindow);
+
+ if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) {
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+ } else {
+ GCPtr pGC;
+ BoxPtr pExtents;
+ int x_off, y_off;
+ int dx, dy;
+ PixmapPtr pBackingPixmap;
+ RegionPtr pClip;
+ int src_x, src_y, dst_x, dst_y, w, h;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+
+ pExtents = RegionExtents(prgnSrc);
+
+ pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin,
+ &x_off, &y_off);
+
+ src_x = pExtents->x1 - pBackingPixmap->screen_x;
+ src_y = pExtents->y1 - pBackingPixmap->screen_y;
+ w = pExtents->x2 - pExtents->x1;
+ h = pExtents->y2 - pExtents->y1;
+ dst_x = src_x - dx;
+ dst_y = src_y - dy;
+
+ /* Translate region (as required by API) */
+ RegionTranslate(prgnSrc, -dx, -dy);
+
+ pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen);
+ /*
+ * Copy region to GC as clip, aligning as dest clip
+ */
+ pClip = RegionCreate(NULL, 0);
+ RegionIntersect(pClip, &pWin->borderClip, prgnSrc);
+ RegionTranslate(pClip,
+ -pBackingPixmap->screen_x,
+ -pBackingPixmap->screen_y);
+
+ (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
+
+ ValidateGC(&pBackingPixmap->drawable, pGC);
+
+ (*pGC->ops->CopyArea) (&pBackingPixmap->drawable,
+ &pBackingPixmap->drawable, pGC,
+ src_x, src_y, w, h, dst_x, dst_y);
+
+ (*pGC->funcs->DestroyClip) (pGC);
+
+ FreeScratchGC(pGC);
+ }
+
+ SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
+}
+
+static PixmapPtr
+cwGetWindowPixmap (WindowPtr pWin)
+{
+ PixmapPtr pPixmap = getCwPixmap (pWin);
+
+ if (!pPixmap)
+ {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SCREEN_PROLOGUE(pScreen, GetWindowPixmap);
+ if (pScreen->GetWindowPixmap)
+ pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap);
+ }
+ return pPixmap;
+}
+
+static void
+cwSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+
+ if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen))
+ pPixmap = NULL;
+ setCwPixmap (pWindow, pPixmap);
+}
+
+/* Screen initialization/teardown */
+void
+miInitializeCompositeWrapper(ScreenPtr pScreen)
+{
+ cwScreenPtr pScreenPriv;
+
+ if (cwDisabled[pScreen->myNum])
+ return;
+
+ if (cwGeneration != serverGeneration)
+ {
+ cwScreenIndex = AllocateScreenPrivateIndex();
+ if (cwScreenIndex < 0)
+ return;
+ cwGCIndex = AllocateGCPrivateIndex();
+ cwWindowIndex = AllocateWindowPrivateIndex();
+#ifdef RENDER
+ cwPictureIndex = AllocatePicturePrivateIndex();
+#endif
+ cwGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate(pScreen, cwGCIndex, sizeof(cwGCRec)))
+ return;
+ if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0))
+ return;
+#ifdef RENDER
+ if (!AllocatePicturePrivate(pScreen, cwPictureIndex, 0))
+ return;
+#endif
+ pScreenPriv = (cwScreenPtr)malloc(sizeof(cwScreenRec));
+ if (!pScreenPriv)
+ return;
+
+ pScreen->devPrivates[cwScreenIndex].ptr = (void *)pScreenPriv;
+
+ SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen);
+ SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
+ SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
+ SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
+ SCREEN_EPILOGUE(pScreen, PaintWindowBackground, cwPaintWindowBackground);
+ SCREEN_EPILOGUE(pScreen, PaintWindowBorder, cwPaintWindowBorder);
+ SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow);
+
+ SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap);
+ SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap);
+
+#ifdef RENDER
+ if (GetPictureScreen (pScreen))
+ cwInitializeRender(pScreen);
+#endif
+}
+
+void
+miDisableCompositeWrapper(ScreenPtr pScreen)
+{
+ cwDisabled[pScreen->myNum] = TRUE;
+}
+
+static Bool
+cwCloseScreen (ScreenPtr pScreen)
+{
+ cwScreenPtr pScreenPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ pScreenPriv = (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+ pScreen->CopyWindow = pScreenPriv->CopyWindow;
+
+#ifdef RENDER
+ if (ps)
+ cwFiniRender(pScreen);
+#endif
+
+ free((void *)pScreenPriv);
+
+ return (*pScreen->CloseScreen)(pScreen);
+}
diff --git a/nx-X11/programs/Xserver/miext/cw/cw.h b/nx-X11/programs/Xserver/miext/cw/cw.h
new file mode 100644
index 000000000..de4746be6
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/cw/cw.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright © 2004 Eric Anholt
+ *
+ * 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, and that the name of Eric Anholt not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Eric Anholt makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ERIC ANHOLT 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.
+ */
+/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw.h,v 1.14 2005/12/09 18:32:46 ajax Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "gcstruct.h"
+#include "picturestr.h"
+
+/*
+ * One of these structures is allocated per GC that gets used with a window with
+ * backing pixmap.
+ */
+
+typedef struct {
+ GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
+ * set FALSE and the clientClip set to
+ * clip output to the valid regions of the
+ * backing pixmap. */
+ unsigned long serialNumber; /* clientClip computed time */
+ unsigned long stateChanges; /* changes in parent gc since last copy */
+ GCOps *wrapOps; /* wrapped ops */
+ GCFuncs *wrapFuncs; /* wrapped funcs */
+} cwGCRec, *cwGCPtr;
+
+extern int cwGCIndex;
+
+#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
+#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (void *) (p))
+
+/*
+ * One of these structures is allocated per Picture that gets used with a
+ * window with a backing pixmap
+ */
+
+typedef struct {
+ PicturePtr pBackingPicture;
+ unsigned long serialNumber;
+ unsigned long stateChanges;
+} cwPictureRec, *cwPicturePtr;
+
+#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
+#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (void *) (p))
+
+extern int cwPictureIndex;
+
+extern int cwWindowIndex;
+
+#define cwWindowPrivate(pWindow) ((pWindow)->devPrivates[cwWindowIndex].ptr)
+#define getCwPixmap(pWindow) ((PixmapPtr) cwWindowPrivate(pWindow))
+#define setCwPixmap(pWindow,pPixmap) (cwWindowPrivate(pWindow) = (void *) (pPixmap))
+
+#define cwDrawableIsRedirWindow(pDraw) \
+ ((pDraw)->type == DRAWABLE_WINDOW && \
+ getCwPixmap((WindowPtr) (pDraw)) != NULL)
+
+typedef struct {
+ /*
+ * screen func wrappers
+ */
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ CreateGCProcPtr CreateGC;
+
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+
+ GetWindowPixmapProcPtr GetWindowPixmap;
+ SetWindowPixmapProcPtr SetWindowPixmap;
+
+#ifdef RENDER
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ CompositeRectsProcPtr CompositeRects;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+#endif
+} cwScreenRec, *cwScreenPtr;
+
+extern int cwScreenIndex;
+
+#define getCwScreen(pScreen) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr)
+#define setCwScreen(pScreen,p) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr = (p))
+
+#define CW_OFFSET_XYPOINTS(ppt, npt) do { \
+ DDXPointPtr _ppt = (DDXPointPtr)(ppt); \
+ int _i; \
+ for (_i = 0; _i < npt; _i++) { \
+ _ppt[_i].x += dst_off_x; \
+ _ppt[_i].y += dst_off_y; \
+ } \
+} while (0)
+
+#define CW_OFFSET_RECTS(prect, nrect) do { \
+ int _i; \
+ for (_i = 0; _i < nrect; _i++) { \
+ (prect)[_i].x += dst_off_x; \
+ (prect)[_i].y += dst_off_y; \
+ } \
+} while (0)
+
+#define CW_OFFSET_ARCS(parc, narc) do { \
+ int _i; \
+ for (_i = 0; _i < narc; _i++) { \
+ (parc)[_i].x += dst_off_x; \
+ (parc)[_i].y += dst_off_y; \
+ } \
+} while (0)
+
+#define CW_OFFSET_XY_DST(x, y) do { \
+ (x) = (x) + dst_off_x; \
+ (y) = (y) + dst_off_y; \
+} while (0)
+
+#define CW_OFFSET_XY_SRC(x, y) do { \
+ (x) = (x) + src_off_x; \
+ (y) = (y) + src_off_y; \
+} while (0)
+
+/* cw.c */
+DrawablePtr
+cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off);
+
+/* cw_render.c */
+
+void
+cwInitializeRender (ScreenPtr pScreen);
+
+void
+cwFiniRender (ScreenPtr pScreen);
+
+/* cw.c */
+
+void
+miInitializeCompositeWrapper(ScreenPtr pScreen);
+
+/* Must be called before miInitializeCompositeWrapper */
+void
+miDisableCompositeWrapper(ScreenPtr pScreen);
diff --git a/nx-X11/programs/Xserver/miext/cw/cw_ops.c b/nx-X11/programs/Xserver/miext/cw/cw_ops.c
new file mode 100644
index 000000000..826a0eeca
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/cw/cw_ops.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright © 2004 Eric Anholt
+ *
+ * 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, and that the name of Eric Anholt not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Eric Anholt makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ERIC ANHOLT 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.
+ */
+/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw_ops.c,v 1.9 2005/07/03 07:02:01 daniels Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "gcstruct.h"
+#include "cw.h"
+
+#define SETUP_BACKING_DST(_pDst, _pGC) \
+ cwGCPtr pGCPrivate = getCwGC (_pGC); \
+ int dst_off_x, dst_off_y; \
+ DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
+ &dst_off_y); \
+ GCPtr pBackingGC = pGCPrivate->pBackingGC ? pGCPrivate->pBackingGC : _pGC
+
+#define SETUP_BACKING_SRC(pSrc, pGC) \
+ int src_off_x, src_off_y; \
+ DrawablePtr pBackingSrc = cwGetBackingDrawable(pSrc, &src_off_x, \
+ &src_off_y)
+
+#define PROLOGUE(pGC) do { \
+ pGC->funcs = pGCPrivate->wrapFuncs;\
+ pGC->ops = pGCPrivate->wrapOps;\
+} while (0)
+
+#define EPILOGUE(pGC) do { \
+ pGCPrivate->wrapFuncs = (pGC)->funcs; \
+ pGCPrivate->wrapOps = (pGC)->ops; \
+ (pGC)->funcs = &cwGCFuncs; \
+ (pGC)->ops = &cwGCOps; \
+} while (0)
+
+extern GCFuncs cwGCFuncs;
+
+/*
+ * GC ops -- wrap each GC operation with our own function
+ */
+
+static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit, int fSorted);
+static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pBits);
+static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty);
+static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long plane);
+static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ xPoint *pptInit);
+static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
+static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg,
+ xSegment *pSegs);
+static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC,
+ int nrects, xRectangle *pRects);
+static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs);
+static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode,
+ int count, DDXPointPtr pPts);
+static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC,
+ int narcs, xArc *parcs);
+static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, char *chars);
+static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ void * pglyphBase);
+static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
+ unsigned int nglyph, CharInfoPtr *ppci,
+ void * pglyphBase);
+static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y);
+
+GCOps cwGCOps = {
+ cwFillSpans,
+ cwSetSpans,
+ cwPutImage,
+ cwCopyArea,
+ cwCopyPlane,
+ cwPolyPoint,
+ cwPolylines,
+ cwPolySegment,
+ cwPolyRectangle,
+ cwPolyArc,
+ cwFillPolygon,
+ cwPolyFillRect,
+ cwPolyFillArc,
+ cwPolyText8,
+ cwPolyText16,
+ cwImageText8,
+ cwImageText16,
+ cwImageGlyphBlt,
+ cwPolyGlyphBlt,
+ cwPushPixels
+};
+
+static void
+cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt,
+ int *pwidth, int fSorted)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XYPOINTS(ppt, nspans);
+
+ (*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC, nspans, ppt,
+ pwidth, fSorted);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt,
+ int *pwidth, int nspans, int fSorted)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XYPOINTS(ppt, nspans);
+
+ (*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc, ppt, pwidth,
+ nspans, fSorted);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, x, y, w, h,
+ leftPad, format, pBits);
+
+ EPILOGUE(pGC);
+}
+
+static RegionPtr
+cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty)
+{
+ int odstx, odsty;
+ RegionPtr exposed = NULL;
+ SETUP_BACKING_DST(pDst, pGC);
+ SETUP_BACKING_SRC(pSrc, pGC);
+
+ PROLOGUE(pGC);
+
+ odstx = dstx;
+ odsty = dsty;
+ CW_OFFSET_XY_DST(dstx, dsty);
+ CW_OFFSET_XY_SRC(srcx, srcy);
+
+ exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
+ pBackingGC, srcx, srcy, w, h,
+ dstx, dsty);
+
+ if (exposed != NULL)
+ RegionTranslate(exposed, odstx - dstx, odsty - dsty);
+
+ EPILOGUE(pGC);
+
+ return exposed;
+}
+
+static RegionPtr
+cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty, unsigned long plane)
+{
+ int odstx, odsty;
+ RegionPtr exposed = NULL;
+ SETUP_BACKING_DST(pDst, pGC);
+ SETUP_BACKING_SRC(pSrc, pGC);
+
+ PROLOGUE(pGC);
+
+ odstx = dstx;
+ odsty = dsty;
+ CW_OFFSET_XY_DST(dstx, dsty);
+ CW_OFFSET_XY_SRC(srcx, srcy);
+
+ exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
+ pBackingGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ if (exposed != NULL)
+ RegionTranslate(exposed, odstx - dstx, odsty - dsty);
+
+ EPILOGUE(pGC);
+
+ return exposed;
+}
+
+static void
+cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if (mode == CoordModeOrigin)
+ CW_OFFSET_XYPOINTS(ppt, npt);
+ else
+ CW_OFFSET_XYPOINTS(ppt, 1);
+
+ (*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt, ppt);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if (mode == CoordModeOrigin)
+ CW_OFFSET_XYPOINTS(ppt, npt);
+ else
+ CW_OFFSET_XYPOINTS(ppt, 1);
+
+ (*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt, ppt);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XYPOINTS(pSegs, nseg * 2);
+
+ (*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg, pSegs);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_RECTS(pRects, nrects);
+
+ (*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects, pRects);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_RECTS(pArcs, narcs);
+
+ (*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs, pArcs);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if (mode == CoordModeOrigin)
+ CW_OFFSET_XYPOINTS(ppt, npt);
+ else
+ CW_OFFSET_XYPOINTS(ppt, 1);
+
+ (*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode, npt,
+ ppt);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_RECTS(pRects, nrects);
+
+ (*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects, pRects);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_RECTS(parcs, narcs);
+
+ (*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs, parcs);
+
+ EPILOGUE(pGC);
+}
+
+static int
+cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int result;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, x, y,
+ count, chars);
+
+ EPILOGUE(pGC);
+
+ return result;
+}
+
+static int
+cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ int result;
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, x, y,
+ count, chars);
+
+ EPILOGUE(pGC);
+ return result;
+}
+
+static void
+cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, x, y, count,
+ chars);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, x, y, count,
+ chars);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void * pglyphBase)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph,
+ ppci, pglyphBase);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, void * pglyphBase)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph,
+ ppci, pglyphBase);
+
+ EPILOGUE(pGC);
+}
+
+static void
+cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h,
+ int x, int y)
+{
+ SETUP_BACKING_DST(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ CW_OFFSET_XY_DST(x, y);
+
+ (*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h,
+ x, y);
+
+ EPILOGUE(pGC);
+}
+
diff --git a/nx-X11/programs/Xserver/miext/cw/cw_render.c b/nx-X11/programs/Xserver/miext/cw/cw_render.c
new file mode 100644
index 000000000..a44d7c4d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/cw/cw_render.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright © 2004 Eric Anholt
+ *
+ * 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, and that the name of Eric Anholt not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Eric Anholt makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ERIC ANHOLT 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.
+ */
+/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw_render.c,v 1.14 2005/07/03 07:02:01 daniels Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "cw.h"
+
+#ifdef RENDER
+
+#define cwPsDecl(pScreen) \
+ PictureScreenPtr ps = GetPictureScreen (pScreen); \
+ cwScreenPtr pCwScreen = getCwScreen (pScreen)
+
+#define cwPicturePrivate \
+ cwPicturePtr pPicturePrivate = getCwPicture(pPicture)
+
+#define cwSrcPictureDecl \
+ int src_picture_x_off, src_picture_y_off; \
+ PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \
+ &src_picture_x_off,\
+ &src_picture_y_off)
+
+#define cwDstPictureDecl \
+ int dst_picture_x_off, dst_picture_y_off; \
+ PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \
+ &dst_picture_x_off,\
+ &dst_picture_y_off)
+
+#define cwMskPictureDecl \
+ int msk_picture_x_off = 0, msk_picture_y_off = 0; \
+ PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \
+ cwGetBackingPicture(pMskPicture, \
+ &msk_picture_x_off,\
+ &msk_picture_y_off))
+
+#define cwPsUnwrap(elt) { \
+ ps->elt = pCwScreen->elt; \
+}
+
+#define cwPsWrap(elt,func) { \
+ pCwScreen->elt = ps->elt; \
+ ps->elt = func; \
+}
+
+static cwPicturePtr
+cwCreatePicturePrivate (PicturePtr pPicture)
+{
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PixmapPtr pPixmap = getCwPixmap (pWindow);
+ int error;
+ cwPicturePtr pPicturePrivate;
+
+ pPicturePrivate = malloc (sizeof (cwPictureRec));
+ if (!pPicturePrivate)
+ return NULL;
+
+ pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable,
+ pPicture->pFormat,
+ 0, 0, serverClient,
+ &error);
+ if (!pPicturePrivate->pBackingPicture)
+ {
+ free (pPicturePrivate);
+ return NULL;
+ }
+
+ /*
+ * Ensure that this serial number does not match the window's
+ */
+ pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
+ pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
+
+ setCwPicture(pPicture, pPicturePrivate);
+
+ return pPicturePrivate;
+}
+
+static void
+cwDestroyPicturePrivate (PicturePtr pPicture)
+{
+ cwPicturePrivate;
+
+ if (pPicturePrivate)
+ {
+ if (pPicturePrivate->pBackingPicture)
+ FreePicture (pPicturePrivate->pBackingPicture, 0);
+ free (pPicturePrivate);
+ setCwPicture(pPicture, NULL);
+ }
+}
+
+static PicturePtr
+cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
+{
+ cwPicturePrivate;
+
+ if (pPicturePrivate)
+ {
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ PixmapPtr pPixmap = getCwPixmap (pWindow);
+
+ *x_off = pDrawable->x - pPixmap->screen_x;
+ *y_off = pDrawable->y - pPixmap->screen_y;
+
+ return pPicturePrivate->pBackingPicture;
+ }
+ else
+ {
+ *x_off = *y_off = 0;
+ return pPicture;
+ }
+}
+
+static void
+cwDestroyPicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+
+ cwPsUnwrap(DestroyPicture);
+ cwDestroyPicturePrivate (pPicture);
+ (*ps->DestroyPicture) (pPicture);
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+}
+
+static void
+cwChangePicture (PicturePtr pPicture, Mask mask)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPicturePtr pPicturePrivate = getCwPicture(pPicture);
+
+ cwPsUnwrap(ChangePicture);
+ (*ps->ChangePicture) (pPicture, mask);
+ if (pPicturePrivate)
+ pPicturePrivate->stateChanges |= mask;
+ cwPsWrap(ChangePicture, cwChangePicture);
+}
+
+
+static void
+cwValidatePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwPicturePrivate;
+
+ cwPsUnwrap(ValidatePicture);
+
+ /*
+ * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid
+ */
+ (*ps->ValidatePicture) (pPicture, mask);
+
+ if (!cwDrawableIsRedirWindow (pDrawable))
+ {
+ if (pPicturePrivate)
+ cwDestroyPicturePrivate (pPicture);
+ }
+ else
+ {
+ PicturePtr pBackingPicture;
+ DrawablePtr pBackingDrawable;
+ int x_off, y_off;
+
+ pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
+
+ if (pPicturePrivate &&
+ pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
+ {
+ cwDestroyPicturePrivate (pPicture);
+ pPicturePrivate = 0;
+ }
+
+ if (!pPicturePrivate)
+ {
+ pPicturePrivate = cwCreatePicturePrivate (pPicture);
+ if (!pPicturePrivate)
+ {
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ return;
+ }
+ }
+
+ pBackingPicture = pPicturePrivate->pBackingPicture;
+
+ /*
+ * Always copy transform and filters because there's no
+ * indication of when they've changed
+ */
+ SetPictureTransform(pBackingPicture, pPicture->transform);
+
+ if (pBackingPicture->filter != pPicture->filter ||
+ pPicture->filter_nparams > 0)
+ {
+ char *filter = PictureGetFilterName (pPicture->filter);
+
+ SetPictureFilter(pBackingPicture,
+ filter, strlen (filter),
+ pPicture->filter_params,
+ pPicture->filter_nparams);
+ }
+
+ pPicturePrivate->stateChanges |= mask;
+
+ if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
+ (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
+ {
+ SetPictureClipRegion (pBackingPicture,
+ x_off - pDrawable->x,
+ y_off - pDrawable->y,
+ pPicture->pCompositeClip);
+
+ pPicturePrivate->serialNumber = pDrawable->serialNumber;
+ pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
+ }
+
+ CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
+
+ ValidatePicture (pBackingPicture);
+ }
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+}
+
+static void
+cwComposite (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMskPicture,
+ PicturePtr pDstPicture,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMsk,
+ INT16 yMsk,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwMskPictureDecl;
+ cwDstPictureDecl;
+
+ cwPsUnwrap(Composite);
+ (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
+ xDst + dst_picture_x_off, yDst + dst_picture_y_off,
+ width, height);
+ cwPsWrap(Composite, cwComposite);
+}
+
+static void
+cwCompositeRects (CARD8 op,
+ PicturePtr pDstPicture,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(CompositeRects);
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x += dst_picture_x_off;
+ rects[i].y += dst_picture_y_off;
+ }
+ (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
+ cwPsWrap(CompositeRects, cwCompositeRects);
+}
+
+static void
+cwTrapezoids (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(Trapezoids);
+ if (dst_picture_x_off || dst_picture_y_off) {
+ for (i = 0; i < ntrap; i++)
+ {
+ traps[i].top += dst_picture_y_off << 16;
+ traps[i].bottom += dst_picture_y_off << 16;
+ traps[i].left.p1.x += dst_picture_x_off << 16;
+ traps[i].left.p1.y += dst_picture_y_off << 16;
+ traps[i].left.p2.x += dst_picture_x_off << 16;
+ traps[i].left.p2.y += dst_picture_y_off << 16;
+ traps[i].right.p1.x += dst_picture_x_off << 16;
+ traps[i].right.p1.y += dst_picture_y_off << 16;
+ traps[i].right.p2.x += dst_picture_x_off << 16;
+ traps[i].right.p2.y += dst_picture_y_off << 16;
+ }
+ }
+ (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ ntrap, traps);
+ cwPsWrap(Trapezoids, cwTrapezoids);
+}
+
+static void
+cwTriangles (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(Triangles);
+ if (dst_picture_x_off || dst_picture_y_off) {
+ for (i = 0; i < ntri; i++)
+ {
+ tris[i].p1.x += dst_picture_x_off << 16;
+ tris[i].p1.y += dst_picture_y_off << 16;
+ tris[i].p2.x += dst_picture_x_off << 16;
+ tris[i].p2.y += dst_picture_y_off << 16;
+ tris[i].p3.x += dst_picture_x_off << 16;
+ tris[i].p3.y += dst_picture_y_off << 16;
+ }
+ }
+ (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ ntri, tris);
+ cwPsWrap(Triangles, cwTriangles);
+}
+
+static void
+cwTriStrip (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(TriStrip);
+ if (dst_picture_x_off || dst_picture_y_off) {
+ for (i = 0; i < npoint; i++)
+ {
+ points[i].x += dst_picture_x_off << 16;
+ points[i].y += dst_picture_y_off << 16;
+ }
+ }
+ (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ npoint, points);
+ cwPsWrap(TriStrip, cwTriStrip);
+}
+
+static void
+cwTriFan (CARD8 op,
+ PicturePtr pSrcPicture,
+ PicturePtr pDstPicture,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
+ cwPsDecl(pScreen);
+ cwSrcPictureDecl;
+ cwDstPictureDecl;
+ int i;
+
+ cwPsUnwrap(TriFan);
+ if (dst_picture_x_off || dst_picture_y_off) {
+ for (i = 0; i < npoint; i++)
+ {
+ points[i].x += dst_picture_x_off << 16;
+ points[i].y += dst_picture_y_off << 16;
+ }
+ }
+ (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
+ xSrc + src_picture_x_off, ySrc + src_picture_y_off,
+ npoint, points);
+ cwPsWrap(TriFan, cwTriFan);
+}
+
+void
+cwInitializeRender (ScreenPtr pScreen)
+{
+ cwPsDecl (pScreen);
+
+ cwPsWrap(DestroyPicture, cwDestroyPicture);
+ cwPsWrap(ChangePicture, cwChangePicture);
+ cwPsWrap(ValidatePicture, cwValidatePicture);
+ cwPsWrap(Composite, cwComposite);
+ cwPsWrap(CompositeRects, cwCompositeRects);
+ cwPsWrap(Trapezoids, cwTrapezoids);
+ cwPsWrap(Triangles, cwTriangles);
+ cwPsWrap(TriStrip, cwTriStrip);
+ cwPsWrap(TriFan, cwTriFan);
+ /* There is no need to wrap AddTraps as far as we can tell. AddTraps can
+ * only be done on alpha-only pictures, and we won't be getting
+ * alpha-only window pictures, so there's no need to translate.
+ */
+}
+
+void
+cwFiniRender (ScreenPtr pScreen)
+{
+ cwPsDecl (pScreen);
+
+ cwPsUnwrap(DestroyPicture);
+ cwPsUnwrap(ChangePicture);
+ cwPsUnwrap(ValidatePicture);
+ cwPsUnwrap(Composite);
+ cwPsUnwrap(CompositeRects);
+ cwPsUnwrap(Trapezoids);
+ cwPsUnwrap(Triangles);
+ cwPsUnwrap(TriStrip);
+ cwPsUnwrap(TriFan);
+}
+
+#endif /* RENDER */
diff --git a/nx-X11/programs/Xserver/miext/damage/Imakefile b/nx-X11/programs/Xserver/miext/damage/Imakefile
new file mode 100644
index 000000000..34d3fcf5a
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/damage/Imakefile
@@ -0,0 +1,29 @@
+#define IHaveModules
+#include <Server.tmpl>
+
+#if BuildRootless
+DEFINES = -DROOTLESS_WORKAROUND
+#endif
+
+#if (!(defined(NXAgentServer) && NXAgentServer))
+SRCS = damage.c
+
+OBJS = damage.o
+
+ INCLUDES = -I. -I../shadow -I../../mi -I../../fb -I../../include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/common $(EXTRAINCLUDES) \
+ -I../../render -I../cw -I$(EXTINCSRC) \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../../dix/llib-ldix.ln ../../os/llib-los.ln \
+ ../../mi/llib-lmi.ln
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(damage,$(OBJS))
+LintLibraryTarget(damage,$(SRCS))
+
+NormalLintTarget($(SRCS))
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(damage.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/miext/damage/damage.c b/nx-X11/programs/Xserver/miext/damage/damage.c
new file mode 100644
index 000000000..9c9161d36
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/damage/damage.c
@@ -0,0 +1,1980 @@
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <nx-X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <X11/fonts/font.h>
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS_XFONT2 */
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "damage.h"
+#include "damagestr.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+ ((a)->x1 == (b)->x1 && \
+ (a)->y1 == (b)->y1 && \
+ (a)->x2 == (b)->x2 && \
+ (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x) ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+ ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap) damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ pPixmap = 0;
+ if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+ && ((WindowPtr)pDrawable)->viewable
+#endif
+ )
+ pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+ if (!pPixmap)
+ {
+ damageScrPriv(pScreen);
+
+ return &pScrPriv->pScreenDamage;
+ }
+ }
+ else
+ pPixmap = (PixmapPtr) pDrawable;
+ return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable) (*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin) getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable) \
+ DamagePtr pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin) drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+ DamagePtr *pPrev = (DamagePtr *) \
+ &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+ int subWindowMode)
+#endif
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ damageScrPriv(pScreen);
+ drawableDamage(pDrawable);
+ DamagePtr pNext;
+ RegionRec clippedRec;
+ RegionPtr pDamageRegion;
+ RegionRec pixClip;
+ Bool was_empty;
+ RegionRec tmpRegion;
+ BoxRec tmpBox;
+ int draw_x, draw_y;
+#ifdef COMPOSITE
+ int screen_x = 0, screen_y = 0;
+#endif
+
+ /* short circuit for empty regions */
+ if (!RegionNotEmpty(pRegion))
+ return;
+
+#ifdef COMPOSITE
+ /*
+ * When drawing to a pixmap which is storing window contents,
+ * the region presented is in pixmap relative coordinates which
+ * need to be converted to screen relative coordinates
+ */
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ {
+ screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+ screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+ }
+ if (screen_x || screen_y)
+ RegionTranslate(pRegion, screen_x, screen_y);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)(pDrawable))->backingStore == NotUseful)
+ {
+ if (subWindowMode == ClipByChildren)
+ {
+ RegionIntersect(pRegion, pRegion,
+ &((WindowPtr)(pDrawable))->clipList);
+ }
+ else if (subWindowMode == IncludeInferiors)
+ {
+ RegionPtr pTempRegion =
+ NotClippedByChildren((WindowPtr)(pDrawable));
+ RegionIntersect(pRegion, pRegion, pTempRegion);
+ RegionDestroy(pTempRegion);
+ }
+ /* If subWindowMode is set to an invalid value, don't perform
+ * any drawable-based clipping. */
+ }
+
+
+ RegionNull(&clippedRec);
+ for (; pDamage; pDamage = pNext)
+ {
+ pNext = pDamage->pNext;
+ /*
+ * Check for internal damage and don't send events
+ */
+ if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+ {
+ DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+ pScrPriv->internalLevel));
+ continue;
+ }
+ /*
+ * Check for unrealized windows
+ */
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr) (pDamage->pDrawable))->realized)
+ {
+#if 0
+ DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+ continue;
+ }
+
+ draw_x = pDamage->pDrawable->x;
+ draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+ /*
+ * Need to move everyone to screen coordinates
+ * XXX what about off-screen pixmaps with non-zero x/y?
+ */
+ if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+ {
+ draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+ draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+ }
+#endif
+
+ /*
+ * Clip against border or pixmap bounds
+ */
+
+ pDamageRegion = pRegion;
+ if (clip || pDamage->pDrawable != pDrawable)
+ {
+ pDamageRegion = &clippedRec;
+ if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+ RegionIntersect(pDamageRegion, pRegion,
+ &((WindowPtr)(pDamage->pDrawable))->borderClip);
+ } else {
+ BoxRec box;
+ box.x1 = draw_x;
+ box.y1 = draw_y;
+ box.x2 = draw_x + pDamage->pDrawable->width;
+ box.y2 = draw_y + pDamage->pDrawable->height;
+ RegionInit(&pixClip, &box, 1);
+ RegionIntersect(pDamageRegion, pRegion, &pixClip);
+ RegionUninit(&pixClip);
+ }
+ /*
+ * Short circuit empty results
+ */
+ if (!RegionNotEmpty(pDamageRegion))
+ continue;
+ }
+
+ DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+ where,
+ pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+ pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+ pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+ pDrawable->id, pDamage->pDrawable->id));
+
+ /*
+ * Move region to target coordinate space
+ */
+ if (draw_x || draw_y)
+ RegionTranslate(pDamageRegion, -draw_x, -draw_y);
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ RegionNull(&tmpRegion);
+ RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage);
+ if (RegionNotEmpty(&tmpRegion))
+ {
+ RegionUnion(&pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ RegionUninit(&tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *RegionExtents(&pDamage->damage);
+ RegionUnion(&pDamage->damage,
+ &pDamage->damage, pDamageRegion);
+ if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage)))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !RegionNotEmpty(&pDamage->damage);
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && RegionNotEmpty(&pDamage->damage))
+ (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+ break;
+ case DamageReportNone:
+ RegionUnion(&pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+ /*
+ * translate original region back
+ */
+ if (pDamageRegion == pRegion && (draw_x || draw_y))
+ RegionTranslate(pDamageRegion, draw_x, draw_y);
+ }
+#ifdef COMPOSITE
+ if (screen_x || screen_y)
+ RegionTranslate(pRegion, -screen_x, -screen_y);
+#endif
+
+ RegionUninit(&clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+ RegionRec region;
+
+ RegionInit(&region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+ _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+ damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+ RegionUninit(&region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, void *, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+ damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+ damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ damageScrPriv(pScreen);
+ damageGCPriv(pGC);
+ Bool ret;
+
+ pGC->pCompositeClip = 0;
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+ return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+ damageGCPriv(pGC);
+
+ pGC->funcs = pGCPriv->funcs;
+ if (pGCPriv->ops)
+ pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+ damageGCPriv(pGC); \
+ GCFuncs *oldFuncs = pGC->funcs; \
+ unwrap(pGCPriv, pGC, funcs); \
+ unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+ damageGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &damageGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr pGC,
+ int type,
+ void *pvalue,
+ int nrects)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+ DAMAGE_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+ box.x1 += pDrawable->x; \
+ box.x2 += pDrawable->x; \
+ box.y1 += pDrawable->y; \
+ box.y2 += pDrawable->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+ TRANSLATE_BOX(box, pDrawable); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g) (getDrawableDamage(d) && \
+ (!g->pCompositeClip ||\
+ RegionNotEmpty(\
+ g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+ BoxPtr extents = &pDst->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define checkPictureDamage(p) (getDrawableDamage(p->pDrawable) && \
+ RegionNotEmpty(p->pCompositeClip))
+
+static void
+damageComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ BoxRec box;
+
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ TRIM_PICTURE_BOX(box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ damageScrPriv(pScreen);
+
+ if (checkPictureDamage (pDst))
+ {
+ int nlistTmp = nlist;
+ GlyphListPtr listTmp = list;
+ GlyphPtr *glyphsTmp = glyphs;
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ BoxRec box;
+ int x1, y1, x2, y2;
+
+ box.x1 = 32767;
+ box.y1 = 32767;
+ box.x2 = -32767;
+ box.y2 = -32767;
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+ while (nlistTmp--)
+ {
+ x += listTmp->xOff;
+ y += listTmp->yOff;
+ n = listTmp->len;
+ while (n--)
+ {
+ glyph = *glyphsTmp++;
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+ x2 = x1 + glyph->info.width;
+ y2 = y1 + glyph->info.height;
+ if (x1 < box.x1)
+ box.x1 = x1;
+ if (y1 < box.y1)
+ box.y1 = y1;
+ if (x2 > box.x2)
+ box.x2 = x2;
+ if (y2 > box.y2)
+ box.y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ listTmp++;
+ }
+ TRIM_PICTURE_BOX (box, pDst);
+ if (BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+ }
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+ GC *pGC,
+ int npt,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int npt,
+ int fSorted)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int *pwidthTmp = pwidth;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x1 = pptTmp->x;
+ box.x2 = box.x1 + *pwidthTmp;
+ box.y2 = box.y1 = pptTmp->y;
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ pwidthTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ if(box.x2 < (pptTmp->x + *pwidthTmp))
+ box.x2 = pptTmp->x + *pwidthTmp;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDrawable);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = x + pDrawable->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDrawable->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+ /* The driver will only call SourceValidate() when pSrc != pDst,
+ * but the software sprite (misprite.c) always need to know when a
+ * drawable is copied so it can remove the sprite. See #1030. */
+ if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+ pSrc->type == DRAWABLE_WINDOW &&
+ ((WindowPtr)pSrc)->viewable)
+ {
+ (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+ }
+
+ if (checkGCDamage (pDst, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDst, &box, pGC->subWindowMode);
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+ return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nptTmp = npt;
+ xPoint *pptTmp = ppt;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt && checkGCDamage (pDrawable, pGC))
+ {
+ int nptTmp = npt;
+ DDXPointPtr pptTmp = ppt;
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(nptTmp > 1)
+ {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSeg,
+ xSegment *pSeg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nSeg && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+ int nsegTmp = nSeg;
+ xSegment *pSegTmp = pSeg;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSegTmp->x2 > pSegTmp->x1) {
+ box.x1 = pSegTmp->x1;
+ box.x2 = pSegTmp->x2;
+ } else {
+ box.x2 = pSegTmp->x1;
+ box.x1 = pSegTmp->x2;
+ }
+
+ if(pSegTmp->y2 > pSegTmp->y1) {
+ box.y1 = pSegTmp->y1;
+ box.y2 = pSegTmp->y2;
+ } else {
+ box.y2 = pSegTmp->y1;
+ box.y1 = pSegTmp->y2;
+ }
+
+ while(--nsegTmp)
+ {
+ pSegTmp++;
+ if(pSegTmp->x2 > pSegTmp->x1)
+ {
+ if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+ if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+ }
+ else
+ {
+ if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+ if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+ }
+ if(pSegTmp->y2 > pSegTmp->y1)
+ {
+ if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+ if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+ }
+ else
+ {
+ if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+ if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+ int nRectsTmp = nRects;
+ xRectangle *pRectsTmp = pRects;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRectsTmp--)
+ {
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+ box.y1 = pRectsTmp->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRectsTmp->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ box.x1 = pRectsTmp->x - offset1;
+ box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+ box.x2 = box.x1 + pRectsTmp->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+ pRectsTmp++;
+ }
+ }
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ if(extra)
+ {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (npt > 2 && checkGCDamage (pDrawable, pGC))
+ {
+ DDXPointPtr pptTmp = ppt;
+ int nptTmp = npt;
+ BoxRec box;
+
+ box.x2 = box.x1 = pptTmp->x;
+ box.y2 = box.y1 = pptTmp->y;
+
+ if(mode != CoordModeOrigin)
+ {
+ int x = box.x1;
+ int y = box.y1;
+ while(--nptTmp)
+ {
+ pptTmp++;
+ x += pptTmp->x;
+ y += pptTmp->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ }
+ else
+ {
+ while(--nptTmp)
+ {
+ pptTmp++;
+ if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+ else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+ if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+ else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if (nRects && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ xRectangle *pRectsTmp = pRects;
+ int nRectsTmp = nRects;
+
+ box.x1 = pRectsTmp->x;
+ box.x2 = box.x1 + pRectsTmp->width;
+ box.y1 = pRectsTmp->y;
+ box.y2 = box.y1 + pRectsTmp->height;
+
+ while(--nRectsTmp)
+ {
+ pRectsTmp++;
+ if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+ if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+ box.x2 = pRectsTmp->x + pRectsTmp->width;
+ if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+ if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+ box.y2 = pRectsTmp->y + pRectsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (nArcs && checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+ int nArcsTmp = nArcs;
+ xArc *pArcsTmp = pArcs;
+
+ box.x1 = pArcsTmp->x;
+ box.x2 = box.x1 + pArcsTmp->width;
+ box.y1 = pArcsTmp->y;
+ box.y2 = box.y1 + pArcsTmp->height;
+
+ while(--nArcsTmp)
+ {
+ pArcsTmp++;
+ if(box.x1 > pArcsTmp->x)
+ box.x1 = pArcsTmp->x;
+ if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+ box.x2 = pArcsTmp->x + pArcsTmp->width;
+ if(box.y1 > pArcsTmp->y)
+ box.y1 = pArcsTmp->y;
+ if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+ box.y2 = pArcsTmp->y + pArcsTmp->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr pDrawable,
+ FontPtr font,
+ int x,
+ int y,
+ unsigned int n,
+ CharInfoPtr *charinfo,
+ Bool imageblt,
+ int subWindowMode)
+{
+ ExtentInfoRec extents;
+ BoxRec box;
+
+#ifdef HAS_XFONT2
+ xfont2_query_glyph_extents(font, charinfo, n, &extents);
+#else
+ QueryGlyphExtents(font, charinfo, n, &extents);
+#endif /* HAS_XFONT2 */
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ box.x1 = x + extents.overallLeft;
+ box.y1 = y - extents.overallAscent;
+ box.x2 = x + extents.overallRight;
+ box.y2 = y + extents.overallDescent;
+ damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+#ifndef NXAGENT_SERVER
+
+static int
+damageText (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned long count,
+ char *chars,
+ FontEncoding fontEncoding,
+ Bool textType)
+{
+ CharInfoPtr *charinfo;
+ CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) malloc(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ charinfo, imageblt, pGC->subWindowMode);
+ if (imageblt)
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ else
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ FONTGLYPHS(pGC->font));
+ }
+ free(charinfo);
+ return x + w;
+}
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_POLY8);
+ else
+ x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static int
+damagePolyText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_POLY16);
+ else
+ x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ return x;
+}
+
+static void
+damageImageText8(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+ Linear8Bit, TT_IMAGE8);
+ else
+ (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+ if (checkGCDamage (pDrawable, pGC))
+ damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+ FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+ TT_IMAGE16);
+ else
+ (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#endif /* NXAGENT_SERVER */
+
+static void
+damageImageGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void * pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, TRUE, pGC->subWindowMode);
+ (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ void * pglyphBase)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+ nglyph, ppci, FALSE, pGC->subWindowMode);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+ if(checkGCDamage (pDrawable, pGC))
+ {
+ BoxRec box;
+
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDrawable->x;
+ box.y1 += pDrawable->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+ }
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNext;
+ return;
+ }
+ pPrev = &(*pPrev)->pNext;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ ErrorF ("Damage not on list\n");
+ abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNext = *pPrev;
+ *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (pPixmap->refcnt == 1)
+ {
+ DamagePtr *pPrev = getPixmapDamageRef (pPixmap);
+ DamagePtr pDamage;
+
+ while ((pDamage = *pPrev))
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ if (!pDamage->isWindow)
+ DamageDestroy (pDamage);
+ }
+ }
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+ RegionPtr prgn,
+ int what)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ /*
+ * Painting background none doesn't actually *do* anything, so
+ * no damage is recorded
+ */
+ if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+ getWindowDamage (pWindow))
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ if(what == PW_BACKGROUND) {
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ } else {
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ }
+}
+
+
+static void
+damageCopyWindow(WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if (getWindowDamage (pWindow))
+ {
+ int dx = pWindow->drawable.x - ptOldOrg.x;
+ int dy = pWindow->drawable.y - ptOldOrg.y;
+
+ /*
+ * The region comes in source relative, but the damage occurs
+ * at the destination location. Translate back and forth.
+ */
+ RegionTranslate(prgnSrc, dx, dy);
+ damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+ RegionTranslate(prgnSrc, -dx, -dy);
+ }
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+ damageFillSpans, damageSetSpans,
+ damagePutImage, damageCopyArea,
+ damageCopyPlane, damagePolyPoint,
+ damagePolylines, damagePolySegment,
+ damagePolyRectangle, damagePolyArc,
+ damageFillPolygon, damagePolyFillRect,
+ damagePolyFillArc, damagePolyText8,
+ damagePolyText16, damageImageText8,
+ damageImageText16, damageImageGlyphBlt,
+ damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+ xorg, yorg, pWindow);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ damageScrPriv(pScreen);
+
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ PixmapPtr pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+ DamagePtr *pPrev = getPixmapDamageRef(pOldPixmap);
+
+ while (pDamage)
+ {
+ damageRemoveDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+ unwrap (pScrPriv, pScreen, SetWindowPixmap);
+ (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ if ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamagePtr *pPrev = getPixmapDamageRef(pPixmap);
+
+ while (pDamage)
+ {
+ damageInsertDamage (pPrev, pDamage);
+ pDamage = pDamage->pNextWin;
+ }
+ }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+ DamagePtr pDamage;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ Bool ret;
+ damageScrPriv(pScreen);
+
+ while ((pDamage = damageGetWinPriv(pWindow)))
+ {
+ DamageUnregister (&pWindow->drawable, pDamage);
+ DamageDestroy (pDamage);
+ }
+ unwrap (pScrPriv, pScreen, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ return ret;
+}
+
+static Bool
+damageCloseScreen (ScreenPtr pScreen)
+{
+ damageScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, DestroyPixmap);
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ free (pScrPriv);
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+ DamageScrPrivPtr pScrPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ if (damageGeneration != serverGeneration)
+ {
+ damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (damageScrPrivateIndex == -1)
+ return FALSE;
+ damageGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (damageGCPrivateIndex == -1)
+ return FALSE;
+ damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+ if (damagePixPrivateIndex == -1)
+ return FALSE;
+ damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (damageWinPrivateIndex == -1)
+ return FALSE;
+ damageGeneration = serverGeneration;
+ }
+ if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+ return TRUE;
+
+ if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+ return FALSE;
+ if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+ return FALSE;
+
+ pScrPriv = (DamageScrPrivPtr) malloc (sizeof (DamageScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+#ifdef COMPOSITE
+ /* This is a kludge to ensure wrapping order with the composite wrapper.
+ * If it's done from compinit.c, then DamageSetup may be called before the
+ * extension init phase, so that cw will be higher in the wrapping chain and
+ * rewrite drawables before damage gets to it, causing confusion.
+ */
+ if (!noCompositeExtension)
+ miInitializeCompositeWrapper (pScreen);
+#endif
+
+ pScrPriv->internalLevel = 0;
+ pScrPriv->pScreenDamage = 0;
+
+ wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+ wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+ wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+ wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+ wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ damageRestoreAreas);
+#ifdef RENDER
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+ wrap (pScrPriv, ps, Composite, damageComposite);
+ }
+#endif
+
+ pScreen->devPrivates[damageScrPrivateIndex].ptr = (void *) pScrPriv;
+ return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void *closure)
+{
+ DamagePtr pDamage;
+
+ pDamage = malloc (sizeof (DamageRec));
+ if (!pDamage)
+ return 0;
+ pDamage->pNext = 0;
+ pDamage->pNextWin = 0;
+ RegionNull(&pDamage->damage);
+
+ pDamage->damageLevel = damageLevel;
+ pDamage->isInternal = isInternal;
+ pDamage->closure = closure;
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = 0;
+
+ pDamage->damageReport = damageReport;
+ pDamage->damageDestroy = damageDestroy;
+ return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+ DamagePtr pOld;
+
+ for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+ if (pOld == pDamage) {
+ ErrorF ("Damage already on window list\n");
+ abort ();
+ }
+#endif
+ pDamage->pNextWin = *pPrev;
+ *pPrev = pDamage;
+ pDamage->isWindow = TRUE;
+ }
+ else
+ pDamage->isWindow = FALSE;
+ pDamage->pDrawable = pDrawable;
+ damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+ damageScrPriv (pScreen);
+
+ pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pDrawable;
+ winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+ int found = 0;
+#endif
+
+ while (*pPrev)
+ {
+ if (*pPrev == pDamage)
+ {
+ *pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+ found = 1;
+#endif
+ break;
+ }
+ pPrev = &(*pPrev)->pNextWin;
+ }
+#if DAMAGE_VALIDATE_ENABLE
+ if (!found) {
+ ErrorF ("Damage not on window list\n");
+ abort ();
+ }
+#endif
+ }
+ pDamage->pDrawable = 0;
+ damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr pDamage)
+{
+ if (pDamage->damageDestroy)
+ (*pDamage->damageDestroy) (pDamage, pDamage->closure);
+ RegionUninit(&pDamage->damage);
+ free (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion)
+{
+ RegionPtr pClip;
+ RegionRec pixmapClip;
+ DrawablePtr pDrawable = pDamage->pDrawable;
+
+ RegionSubtract(&pDamage->damage, &pDamage->damage, pRegion);
+ if (pDrawable)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pClip = &((WindowPtr) pDrawable)->borderClip;
+ else
+ {
+ BoxRec box;
+
+ box.x1 = pDrawable->x;
+ box.y1 = pDrawable->y;
+ box.x2 = pDrawable->x + pDrawable->width;
+ box.y2 = pDrawable->y + pDrawable->height;
+ RegionInit(&pixmapClip, &box, 1);
+ pClip = &pixmapClip;
+ }
+ RegionTranslate(&pDamage->damage, pDrawable->x, pDrawable->y);
+ RegionIntersect(&pDamage->damage, &pDamage->damage, pClip);
+ RegionTranslate(&pDamage->damage, -pDrawable->x, -pDrawable->y);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ RegionUninit(&pixmapClip);
+ }
+ return RegionNotEmpty(&pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr pDamage)
+{
+ RegionEmpty(&pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr pDamage)
+{
+ return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ RegionPtr pRegion)
+{
+ damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/miext/damage/damage.h b/nx-X11/programs/Xserver/miext/damage/damage.h
new file mode 100644
index 000000000..a363e09bb
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/damage/damage.h
@@ -0,0 +1,84 @@
+/*
+ * $Id: damage.h,v 1.4 2005/07/03 07:02:01 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DAMAGE_H_
+#define _DAMAGE_H_
+
+typedef struct _damage *DamagePtr;
+
+typedef enum _damageReportLevel {
+ DamageReportRawRegion,
+ DamageReportDeltaRegion,
+ DamageReportBoundingBox,
+ DamageReportNonEmpty,
+ DamageReportNone
+} DamageReportLevel;
+
+typedef void (*DamageReportFunc) (DamagePtr pDamage, RegionPtr pRegion, void *closure);
+typedef void (*DamageDestroyFunc) (DamagePtr pDamage, void *closure);
+
+Bool
+DamageSetup (ScreenPtr pScreen);
+
+DamagePtr
+DamageCreate (DamageReportFunc damageReport,
+ DamageDestroyFunc damageDestroy,
+ DamageReportLevel damageLevel,
+ Bool isInternal,
+ ScreenPtr pScreen,
+ void * closure);
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable);
+
+void
+DamageRegister (DrawablePtr pDrawable,
+ DamagePtr pDamage);
+
+void
+DamageUnregister (DrawablePtr pDrawable,
+ DamagePtr pDamage);
+
+void
+DamageDestroy (DamagePtr pDamage);
+
+Bool
+DamageSubtract (DamagePtr pDamage,
+ const RegionPtr pRegion);
+
+void
+DamageEmpty (DamagePtr pDamage);
+
+RegionPtr
+DamageRegion (DamagePtr pDamage);
+
+void
+DamageDamageRegion (DrawablePtr pDrawable,
+ const RegionPtr pRegion);
+
+#endif /* _DAMAGE_H_ */
diff --git a/nx-X11/programs/Xserver/miext/damage/damagestr.h b/nx-X11/programs/Xserver/miext/damage/damagestr.h
new file mode 100644
index 000000000..62b384167
--- /dev/null
+++ b/nx-X11/programs/Xserver/miext/damage/damagestr.h
@@ -0,0 +1,113 @@
+/*
+ * $Id: damagestr.h,v 1.6 2005/07/03 07:02:01 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _DAMAGESTR_H_
+#define _DAMAGESTR_H_
+
+#include "damage.h"
+#ifdef RENDER
+# include "picturestr.h"
+#endif
+
+typedef struct _damage {
+ DamagePtr pNext;
+ DamagePtr pNextWin;
+ RegionRec damage;
+
+ DamageReportLevel damageLevel;
+ Bool isInternal;
+ void *closure;
+ Bool isWindow;
+ DrawablePtr pDrawable;
+
+ DamageReportFunc damageReport;
+ DamageDestroyFunc damageDestroy;
+} DamageRec;
+
+typedef struct _damageScrPriv {
+ int internalLevel;
+
+ /*
+ * For DDXen which don't provide GetScreenPixmap, this provides
+ * a place to hook damage for windows on the screen
+ */
+ DamagePtr pScreenDamage;
+
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ CloseScreenProcPtr CloseScreen;
+ CreateGCProcPtr CreateGC;
+ DestroyPixmapProcPtr DestroyPixmap;
+ SetWindowPixmapProcPtr SetWindowPixmap;
+ DestroyWindowProcPtr DestroyWindow;
+#ifdef RENDER
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+#endif
+ BSFuncRec BackingStoreFuncs;
+} DamageScrPrivRec, *DamageScrPrivPtr;
+
+typedef struct _damageGCPriv {
+ GCOps *ops;
+ GCFuncs *funcs;
+} DamageGCPrivRec, *DamageGCPrivPtr;
+
+extern int damageScrPrivateIndex;
+extern int damagePixPrivateIndex;
+extern int damageGCPrivateIndex;
+extern int damageWinPrivateIndex;
+
+#define damageGetScrPriv(pScr) \
+ ((DamageScrPrivPtr) (pScr)->devPrivates[damageScrPrivateIndex].ptr)
+
+#define damageScrPriv(pScr) \
+ DamageScrPrivPtr pScrPriv = damageGetScrPriv(pScr)
+
+#define damageGetPixPriv(pPix) \
+ ((DamagePtr) (pPix)->devPrivates[damagePixPrivateIndex].ptr)
+
+#define damgeSetPixPriv(pPix,v) \
+ ((pPix)->devPrivates[damagePixPrivateIndex].ptr = (void * ) (v))
+
+#define damagePixPriv(pPix) \
+ DamagePtr pDamage = damageGetPixPriv(pPix)
+
+#define damageGetGCPriv(pGC) \
+ ((DamageGCPrivPtr) (pGC)->devPrivates[damageGCPrivateIndex].ptr)
+
+#define damageGCPriv(pGC) \
+ DamageGCPrivPtr pGCPriv = damageGetGCPriv(pGC)
+
+#define damageGetWinPriv(pWin) \
+ ((DamagePtr) (pWin)->devPrivates[damageWinPrivateIndex].ptr)
+
+#define damageSetWinPriv(pWin,d) \
+ ((pWin)->devPrivates[damageWinPrivateIndex].ptr = (d))
+
+#endif /* _DAMAGESTR_H_ */
diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile
new file mode 100644
index 000000000..7932e32cd
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/Imakefile
@@ -0,0 +1,262 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <Server.tmpl>
+
+NULL =
+
+/*
+ * If you have any extra files to be put into the library, define them here.
+ */
+
+ZONEID_DEFINES = -UHAVE_GETZONEID
+
+#if NXLibraries
+
+NX_INCLUDES = -I../../../../nxcomp
+
+NX_DEFINES = -DNX_TRANS_SOCKET \
+ -DNX_TRANS_AUTH \
+ -DNX_TRANS_FOPEN \
+ -DNX_TRANS_SLEEP \
+ -DNX_TRANS_EXIT \
+ -DNX_TRANS_WAKEUP=1000 \
+ -DNXAGENT_SERVER \
+ $(NULL)
+
+# -DNX_TRANS_WARN \
+# -DNX_TRANS_INFO \
+# -DNX_TRANS_TEST \
+# -DNX_TRANS_DEBUG \
+
+#endif
+
+/*
+ * do not modify the following two definitions
+ */
+
+#ifndef OtherSources
+#define OtherSources
+#endif
+
+#ifndef OtherObjects
+#define OtherObjects
+#endif
+
+#if HasXdmAuth
+XDMAUTHDEFS = -DHASXDMAUTH
+XDMAUTHOBJS = xdmauth.o
+XDMAUTHSRCS = xdmauth.c
+#else
+XDMAUTHDEFS =
+XDMAUTHOBJS =
+XDMAUTHSCRS =
+#endif
+
+#if HasSecureRPC
+RPCDEFS = -DSECURE_RPC
+RPCOBJS = rpcauth.o
+RPCSRCS = rpcauth.c
+#else
+RPCDEFS =
+RPCOBJS =
+RPCSRCS =
+#endif
+
+#if HasBSD44Sockets
+ SOCK_DEFINES = -DBSD44SOCKETS
+#endif
+
+#if HasGetIfAddrs
+ IFADDRS_DEFINES = -DHAS_GETIFADDRS
+#endif
+
+#if !defined(DDXOsColor)
+COLOR_SRCS=oscolor.c
+COLOR_OBJS=oscolor.o
+#endif
+
+#if !HasSnprintf
+SNPRINTF_SRCS = snprintf.c
+SNPRINTF_OBJS = snprintf.o
+#endif
+
+#if !HasStrlcat
+STRLCAT_SRCS = strlcat.c strlcpy.c
+STRLCAT_OBJS = strlcat.o strlcpy.o
+#endif
+
+#if !HasReallocarray
+REALLOCARRAY_SRCS = reallocarray.c
+REALLOCARRAY_OBJS = reallocarray.o
+#endif
+
+#if HasGetpeerucred
+GETPEER_DEFINES = -DHAS_GETPEERUCRED
+#else
+# if HasGetpeereid
+GETPEER_DEFINES = -DHAS_GETPEEREID
+# endif
+#endif
+
+#if !HasTimingsafeMemcmp
+TMEMCMP_SRCS = timingsafe_memcmp.c
+TMEMCMP_OBJS = timingsafe_memcmp.o
+#endif
+
+BOOTSTRAPCFLAGS =
+ SRCS = WaitFor.c \
+ access.c \
+ client.c \
+ connection.c \
+ io.c \
+ $(COLOR_SRCS) \
+ osinit.c \
+ utils.c \
+ log.c \
+ auth.c \
+ mitauth.c \
+ secauth.c \
+ $(XDMAUTHSRCS) \
+ $(RPCSRCS) \
+ xdmcp.c \
+ OtherSources \
+ xstrans.c \
+ $(SNPRINTF_SRCS) \
+ $(STRLCAT_SRCS) \
+ $(REALLOCARRAY_SRCS) \
+ xprintf.c \
+ $(TMEMCMP_SRCS) \
+ $(NULL)
+
+ OBJS = WaitFor.o \
+ access.o \
+ client.o \
+ connection.o \
+ io.o \
+ $(COLOR_OBJS) \
+ osinit.o \
+ utils.o \
+ log.o \
+ auth.o \
+ mitauth.o \
+ secauth.o \
+ $(XDMAUTHOBJS) \
+ $(RPCOBJS) \
+ xdmcp.o \
+ OtherObjects \
+ xstrans.o \
+ $(SNPRINTF_OBJS) \
+ $(STRLCAT_OBJS) \
+ $(REALLOCARRAY_OBJS) \
+ xprintf.o \
+ $(TMEMCMP_OBJS) \
+ $(NULL)
+
+#if UseMemLeak
+ MEM_DEFINES = -DMEMBUG
+#endif
+ ADM_DEFINES = -DADMPATH=\"$(ADMDIR)/X\%smsgs\"
+ XDMCP_DEFINES = ServerXdmcpDefines
+ ERROR_DEFINES = ServerErrorDefines
+#if HasPam && HasPamMisc
+ PAM_DEFINES = -DUSE_PAM
+#endif
+ XTRANS_DEFINES = -DXTRANS_SEND_FDS=0
+
+ DEFINES = $(CONNECTION_FLAGS) \
+ $(MEM_DEFINES) \
+ $(XDMAUTHDEFS) \
+ $(RPCDEFS) \
+ $(SIGNAL_DEFINES) \
+ $(OS_DEFINES) \
+ $(GETPEER_DEFINES) \
+ $(RANDOM_DEFINES) \
+ $(BUGMSG) \
+ $(XTRANS_FAILDEFINES) \
+ $(XTRANS_DEFINES) \
+ $(NX_DEFINES) \
+ $(NULL)
+
+ INCLUDES = -I. \
+ -I../include \
+ -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/render \
+ -I$(TOP)/lib/Xau \
+ $(NX_INCLUDES) \
+ `pkg-config --cflags-only-I pixman-1` \
+ $(NULL)
+
+ DEPEND_DEFINES = $(XDMCP_DEFINES) \
+ $(EXT_DEFINES) \
+ $(TRANS_INCLUDES) \
+ $(CONNECTION_FLAGS) \
+ $(GETPEER_DEFINES) \
+ DependDefines \
+ $(NULL)
+
+ LINTLIBS = ../dix/llib-ldix.ln
+
+#ifdef NEED_ALLOCA_FROM_LIBPW
+ PWLIB = /lib/libPW.a
+#endif /* NEED_ALLOCA_FROM_LIBPW */
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(os,$(OBJS))
+LintLibraryTarget(os,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#ifdef NEED_ALLOCA_FROM_LIBPW
+XCOMM
+XCOMM And this one is to get the version of alloca that lives in /lib/libPW.a
+XCOMM without getting all of the rest of the stuff in there.
+XCOMM
+alloca.o: $(PWLIB)
+ rm -f alloca.o
+ ar x $(PWLIB) alloca.o
+#endif /* NEED_ALLOCA_FROM_LIBPW */
+
+SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES) $(ZONEID_DEFINES))
+SpecialCObjectRule(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
+SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
+SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
+SpecialCObjectRule(connection,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
+SpecialCObjectRule(osinit,$(ICONFIGFILES),$(ADM_DEFINES))
+SpecialCObjectRule(WaitFor,$(ICONFIGFILES),$(EXT_DEFINES))
+SpecialCObjectRule(io,$(ICONFIGFILES),$(EXT_DEFINES))
+SpecialCObjectRule(utils,$(ICONFIGFILES),$(XDMCP_DEFINES) $(EXT_DEFINES) $(ERROR_DEFINES) $(PAM_DEFINES))
+#if defined(SparcArchitecture) && HasGcc && !HasGcc2
+oscolor.o: oscolor.c $(ICONFIGFILES)
+ $(RM) $@
+ cc -c $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
+#endif
+
+#if !HasSnprintf
+LinkSourceFile(snprintf.c,$(LIBSRC)/misc)
+#endif
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c
new file mode 100644
index 000000000..76e5da5f2
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/WaitFor.c
@@ -0,0 +1,829 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+/*****************************************************************
+ * OS Dependent input routines:
+ *
+ * WaitForSomething
+ * TimerForce, TimerSet, TimerCheck, TimerFree
+ *
+ *****************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef WIN32
+#include <nx-X11/Xwinsock.h>
+#endif
+#include <nx-X11/Xos.h> /* for strings, fcntl, time */
+#include <errno.h>
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include "misc.h"
+
+#include "osdep.h"
+#include <nx-X11/Xpoll.h>
+#include "dixstruct.h"
+#include "opaque.h"
+#ifdef DPMSExtension
+#include "dpmsproc.h"
+#endif
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
+
+static unsigned long startTimeInMillis;
+
+#endif
+
+#ifdef WIN32
+/* Error codes from windows sockets differ from fileio error codes */
+#undef EINTR
+#define EINTR WSAEINTR
+#undef EINVAL
+#define EINVAL WSAEINVAL
+#undef EBADF
+#define EBADF WSAENOTSOCK
+/* Windows select does not set errno. Use GetErrno as wrapper for
+ WSAGetLastError */
+#define GetErrno WSAGetLastError
+#else
+/* This is just a fallback to errno to hide the differences between unix and
+ Windows in the code */
+#define GetErrno() errno
+#endif
+
+/* modifications by raphael */
+int
+mffs(fd_mask mask)
+{
+ int i;
+
+ if (!mask) return 0;
+ i = 1;
+ while (!(mask & 1))
+ {
+ i++;
+ mask >>= 1;
+ }
+ return i;
+}
+
+#ifdef DPMSExtension
+#define DPMS_SERVER
+#include <nx-X11/extensions/dpms.h>
+#endif
+
+#ifdef XTESTEXT1
+/*
+ * defined in xtestext1dd.c
+ */
+extern int playback_on;
+#endif /* XTESTEXT1 */
+
+struct _OsTimerRec {
+ OsTimerPtr next;
+ CARD32 expires;
+ OsTimerCallback callback;
+ void * arg;
+};
+
+static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev);
+static OsTimerPtr timers = NULL;
+
+/*****************
+ * WaitForSomething:
+ * Make the server suspend until there is
+ * 1. data from clients or
+ * 2. input events available or
+ * 3. ddx notices something of interest (graphics
+ * queue ready, etc.) or
+ * 4. clients that have buffered replies/events are ready
+ *
+ * If the time between INPUT events is
+ * greater than ScreenSaverTime, the display is turned off (or
+ * saved, depending on the hardware). So, WaitForSomething()
+ * has to handle this also (that's why the select() has a timeout.
+ * For more info on ClientsWithInput, see ReadRequestFromClient().
+ * pClientsReady is an array to store ready client->index values into.
+ *****************/
+
+int
+WaitForSomething(int *pClientsReady)
+{
+ int i;
+ struct timeval waittime, *wt;
+ INT32 timeout = 0;
+ fd_set clientsReadable;
+ fd_set clientsWritable;
+ int curclient;
+ int selecterr;
+ int nready;
+ CARD32 now = 0;
+ Bool someReady = FALSE;
+ Bool someNotifyWriteReady = FALSE;
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Got called.\n");
+#endif
+
+ FD_ZERO(&clientsReadable);
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
+
+ startTimeInMillis = GetTimeInMillis();
+
+#endif
+
+ /* We need a while loop here to handle
+ crashed connections and the screen saver timeout */
+ while (1)
+ {
+ /* deal with any blocked jobs */
+ if (workQueue)
+ ProcessWorkQueue();
+ if (XFD_ANYSET (&ClientsWithInput))
+ {
+ someReady = TRUE;
+ waittime.tv_sec = 0;
+ waittime.tv_usec = 0;
+ wt = &waittime;
+ }
+ if (someReady)
+ {
+ XFD_COPYSET(&AllSockets, &LastSelectMask);
+ XFD_UNSET(&LastSelectMask, &ClientsWithInput);
+ }
+ else
+ {
+ wt = NULL;
+ if (timers)
+ {
+ now = GetTimeInMillis();
+ timeout = timers->expires - now;
+ if (timeout < 0)
+ timeout = 0;
+ waittime.tv_sec = timeout / MILLI_PER_SECOND;
+ waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ wt = &waittime;
+ }
+ XFD_COPYSET(&AllSockets, &LastSelectMask);
+ }
+ SmartScheduleStopTimer ();
+
+ BlockHandler((void *)&wt, (void *)&LastSelectMask);
+ if (NewOutputPending)
+ FlushAllOutput();
+#ifdef XTESTEXT1
+ /* XXX how does this interact with new write block handling? */
+ if (playback_on) {
+ wt = &waittime;
+ XTestComputeWaitTime (&waittime);
+ }
+#endif /* XTESTEXT1 */
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
+
+ /*
+ * If caller has marked the first element of pClientsReady[],
+ * bail out of select after a short timeout. We need this to
+ * let the NX agent remove the splash screen when the timeout
+ * is expired. A better option would be to use the existing
+ * screen-saver timeout but it can be modified by clients, so
+ * we would need a special handling. This hack is trivial and
+ * keeps WaitForSomething() backward compatible with the exis-
+ * ting servers.
+ */
+
+ if (pClientsReady[0] == -1)
+ {
+ unsigned long timeoutInMillis;
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: pClientsReady[0] is [%d], pClientsReady[1] is [%d].\n",
+ pClientsReady[0], pClientsReady[1]);
+#endif
+
+ timeoutInMillis = GetTimeInMillis();
+
+ if (timeoutInMillis - startTimeInMillis >= NX_TRANS_WAKEUP)
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Returning 0 because of wakeup timeout.\n");
+#endif
+ return 0;
+ }
+
+ timeoutInMillis = NX_TRANS_WAKEUP - (timeoutInMillis - startTimeInMillis);
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Milliseconds to next wakeup are %ld.\n",
+ timeoutInMillis);
+#endif
+ if (wt == NULL || (wt -> tv_sec * MILLI_PER_SECOND +
+ wt -> tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
+ {
+ if ((waittime.tv_sec * MILLI_PER_SECOND +
+ waittime.tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
+ {
+ waittime.tv_sec = timeoutInMillis / MILLI_PER_SECOND;
+ waittime.tv_usec = (timeoutInMillis * MILLI_PER_SECOND) %
+ (MILLI_PER_SECOND * 1000);
+ wt = &waittime;
+ }
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Next wakeup timeout set to %ld milliseconds.\n",
+ (waittime.tv_sec * MILLI_PER_SECOND) +
+ (waittime.tv_usec / MILLI_PER_SECOND));
+#endif
+ }
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
+ else
+ {
+ fprintf(stderr, "WaitForSomething: Using existing timeout of %ld milliseconds.\n",
+ (waittime.tv_sec * MILLI_PER_SECOND) +
+ (waittime.tv_usec / MILLI_PER_SECOND));
+ }
+#endif
+ }
+#endif
+
+ /* keep this check close to select() call to minimize race */
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ if (dispatchException)
+ {
+ i = -1;
+
+ fprintf(stderr, "WaitForSomething: Value of dispatchException is true. Set i = -1.\n");
+ }
+#else
+ if (dispatchException)
+ i = -1;
+#endif
+ else if (AnyWritesPending)
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ if (wt == NULL)
+ {
+ fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and "
+ "clientsWritable and null timeout.\n");
+ }
+ else
+ {
+ fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, "
+ "clientsWritable, %ld secs and %ld usecs.\n",
+ wt -> tv_sec, wt -> tv_usec);
+ }
+#endif
+ XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask);
+ XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask);
+ i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt);
+ }
+ else
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ if (wt == NULL)
+ {
+ fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and null timeout.\n");
+ }
+ else
+ {
+ fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, %ld secs and %ld usecs.\n",
+ wt -> tv_sec, wt -> tv_usec);
+ }
+#endif
+ i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
+ }
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Bailed out with i = [%d] and errno = [%d].\n", i, errno);
+
+ if (i < 0)
+ {
+ fprintf(stderr, "WaitForSomething: Error is [%s].\n", strerror(errno));
+ }
+#endif
+ selecterr = GetErrno();
+ WakeupHandler(i, (void *)&LastSelectMask);
+#ifdef XTESTEXT1
+ if (playback_on) {
+ i = XTestProcessInputAction (i, &waittime);
+ }
+#endif /* XTESTEXT1 */
+ SmartScheduleStartTimer ();
+
+ if (i <= 0) /* An error or timeout occurred */
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ if (dispatchException)
+ {
+ fprintf(stderr, "WaitForSomething: Returning 0 because of (dispatchException).\n");
+ return 0;
+ }
+#else
+ if (dispatchException)
+ return 0;
+#endif
+ if (i < 0)
+ {
+ if (selecterr == EBADF) /* Some client disconnected */
+ {
+ CheckConnections ();
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ if (! XFD_ANYSET (&AllClients))
+ {
+ fprintf(stderr, "WaitForSomething: Returning 0 because of (! XFD_ANYSET (&AllClients)).\n");
+ return 0;
+ }
+#else
+ if (! XFD_ANYSET (&AllClients))
+ return 0;
+#endif
+ }
+ else if (selecterr == EINVAL)
+ {
+ FatalError("WaitForSomething(): select: errno=%d\n",
+ selecterr);
+ }
+ else if (selecterr != EINTR)
+ {
+ ErrorF("WaitForSomething(): select: errno=%d\n",
+ selecterr);
+ }
+ }
+ else if (someReady)
+ {
+ /*
+ * If no-one else is home, bail quickly
+ */
+ XFD_COPYSET(&ClientsWithInput, &LastSelectMask);
+ XFD_COPYSET(&ClientsWithInput, &clientsReadable);
+ break;
+ }
+#if defined(NX_TRANS_SOCKET)
+ if (*checkForInput[0] != *checkForInput[1])
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Returning 0 because of (*checkForInput[0] != *checkForInput[1]).\n");
+#endif
+ return 0;
+ }
+#else
+ if (*checkForInput[0] != *checkForInput[1])
+ return 0;
+#endif
+
+ if (timers)
+ {
+ int expired = 0;
+ now = GetTimeInMillis();
+ if ((int) (timers->expires - now) <= 0)
+ expired = 1;
+
+ while (timers && (int) (timers->expires - now) <= 0)
+ DoTimer(timers, now, &timers);
+
+ if (expired)
+ return 0;
+ }
+ }
+ else
+ {
+ fd_set tmp_set;
+
+ if (*checkForInput[0] == *checkForInput[1]) {
+ if (timers)
+ {
+ int expired = 0;
+ now = GetTimeInMillis();
+ if ((int) (timers->expires - now) <= 0)
+ expired = 1;
+
+ while (timers && (int) (timers->expires - now) <= 0)
+ DoTimer(timers, now, &timers);
+
+ if (expired)
+ return 0;
+ }
+ }
+ if (someReady)
+ XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
+ if (AnyWritesPending) {
+ XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked);
+ if (XFD_ANYSET(&clientsWritable)) {
+ NewOutputPending = TRUE;
+ XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
+ XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
+ if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+ AnyWritesPending = FALSE;
+ }
+ if (NumNotifyWriteFd != 0) {
+ XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds);
+ if (XFD_ANYSET(&tmp_set))
+ someNotifyWriteReady = TRUE;
+ }
+ }
+
+ XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
+
+ XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
+ if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
+ HandleNotifyFds();
+
+ if (XFD_ANYSET (&clientsReadable))
+ break;
+#ifdef WIN32
+ /* Windows keyboard and mouse events are added to the input queue
+ in Block- and WakupHandlers. There is no device to check if
+ data is ready. So check here if new input is available */
+#if defined(NX_TRANS_SOCKET)
+ if (*checkForInput[0] != *checkForInput[1])
+ {
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Returning 0 because of (*checkForInput[0] != *checkForInput[1]).\n");
+#endif
+ return 0;
+ }
+#else
+ if (*checkForInput[0] != *checkForInput[1])
+ return 0;
+#endif
+#endif
+ }
+ }
+
+ nready = 0;
+ if (XFD_ANYSET (&clientsReadable))
+ {
+#ifndef WIN32
+ for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
+ {
+ while (clientsReadable.fds_bits[i])
+ {
+ int client_index;
+
+ curclient = ffs (clientsReadable.fds_bits[i]) - 1;
+ client_index = /* raphael: modified */
+ ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))];
+#else
+ fd_set savedClientsReadable;
+ XFD_COPYSET(&clientsReadable, &savedClientsReadable);
+ for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++)
+ {
+ int client_priority, client_index;
+
+ curclient = XFD_FD(&savedClientsReadable, i);
+ client_index = GetConnectionTranslation(curclient);
+#endif
+ pClientsReady[nready++] = client_index;
+#ifndef WIN32
+ clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
+ }
+#else
+ FD_CLR(curclient, &clientsReadable);
+#endif
+ }
+ }
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ fprintf(stderr, "WaitForSomething: Returning nready.\n");
+#endif
+ return nready;
+}
+
+#if 0
+/*
+ * This is not always a macro.
+ */
+ANYSET(FdMask *src)
+{
+ int i;
+
+ for (i=0; i<mskcnt; i++)
+ if (src[ i ])
+ return (TRUE);
+ return (FALSE);
+}
+#endif
+
+
+static void
+DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
+{
+ CARD32 newTime;
+
+ *prev = timer->next;
+ timer->next = NULL;
+ newTime = (*timer->callback)(timer, now, timer->arg);
+ if (newTime)
+ TimerSet(timer, 0, newTime, timer->callback, timer->arg);
+}
+
+OsTimerPtr
+TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
+ OsTimerCallback func, void * arg)
+{
+ register OsTimerPtr *prev;
+ CARD32 now = GetTimeInMillis();
+
+ if (!timer)
+ {
+ timer = (OsTimerPtr)malloc(sizeof(struct _OsTimerRec));
+ if (!timer)
+ return NULL;
+ }
+ else
+ {
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ *prev = timer->next;
+ if (flags & TimerForceOld)
+ (void)(*timer->callback)(timer, now, timer->arg);
+ break;
+ }
+ }
+ }
+ if (!millis)
+ return timer;
+ if (!(flags & TimerAbsolute))
+ millis += now;
+ timer->expires = millis;
+ timer->callback = func;
+ timer->arg = arg;
+ if ((int) (millis - now) <= 0)
+ {
+ timer->next = NULL;
+ millis = (*timer->callback)(timer, now, timer->arg);
+ if (!millis)
+ return timer;
+ }
+ for (prev = &timers;
+ *prev && (int) ((*prev)->expires - millis) <= 0;
+ prev = &(*prev)->next)
+ ;
+ timer->next = *prev;
+ *prev = timer;
+ return timer;
+}
+
+Bool
+TimerForce(OsTimerPtr timer)
+{
+ OsTimerPtr *prev;
+
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ DoTimer(timer, GetTimeInMillis(), prev);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void
+TimerCancel(OsTimerPtr timer)
+{
+ OsTimerPtr *prev;
+
+ if (!timer)
+ return;
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ *prev = timer->next;
+ break;
+ }
+ }
+}
+
+void
+TimerFree(OsTimerPtr timer)
+{
+ if (!timer)
+ return;
+ TimerCancel(timer);
+ free(timer);
+}
+
+void
+TimerCheck(void)
+{
+ CARD32 now = GetTimeInMillis();
+
+ while (timers && (int) (timers->expires - now) <= 0)
+ DoTimer(timers, now, &timers);
+}
+
+void
+TimerInit(void)
+{
+ OsTimerPtr timer;
+
+ while ((timer = timers))
+ {
+ timers = timer->next;
+ free(timer);
+ }
+}
+
+static CARD32
+ScreenSaverTimeoutExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+ INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+ if (timeout < ScreenSaverTime) {
+ return ScreenSaverTime - timeout;
+ }
+
+ ResetOsBuffers(); /* not ideal, but better than nothing */
+ SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
+
+#ifdef DPMSExtension
+ if (ScreenSaverInterval > 0 && DPMSPowerLevel == DPMSModeOn)
+#else
+ if (ScreenSaverInterval > 0)
+#endif /* DPMSExtension */
+ return ScreenSaverInterval;
+
+ return 0;
+}
+
+static OsTimerPtr ScreenSaverTimer = NULL;
+
+void
+FreeScreenSaverTimer(void)
+{
+ if (ScreenSaverTimer) {
+ TimerFree(ScreenSaverTimer);
+ ScreenSaverTimer = NULL;
+ }
+}
+
+void
+SetScreenSaverTimer(void)
+{
+ if (ScreenSaverTime > 0) {
+ ScreenSaverTimer = TimerSet(ScreenSaverTimer, 0, ScreenSaverTime,
+ ScreenSaverTimeoutExpire, NULL);
+ } else if (ScreenSaverTimer) {
+ FreeScreenSaverTimer();
+ }
+}
+
+#ifdef DPMSExtension
+
+static OsTimerPtr DPMSStandbyTimer = NULL;
+static OsTimerPtr DPMSSuspendTimer = NULL;
+static OsTimerPtr DPMSOffTimer = NULL;
+
+static CARD32
+DPMSStandbyTimerExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+ INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+ if (timeout < DPMSStandbyTime) {
+ return DPMSStandbyTime - timeout;
+ }
+ if (DPMSPowerLevel < DPMSModeStandby) {
+ if (DPMSEnabled)
+ DPMSSet(DPMSModeStandby);
+ }
+ return DPMSStandbyTime;
+}
+
+static CARD32
+DPMSSuspendTimerExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+ INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+ if (timeout < DPMSSuspendTime) {
+ return DPMSSuspendTime - timeout;
+ }
+ if (DPMSPowerLevel < DPMSModeSuspend) {
+ if (DPMSEnabled)
+ DPMSSet(DPMSModeSuspend);
+ }
+ return DPMSSuspendTime;
+}
+
+static CARD32
+DPMSOffTimerExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+ INT32 timeout = now - lastDeviceEventTime.milliseconds;
+
+ if (timeout < DPMSOffTime) {
+ return DPMSOffTime - timeout;
+ }
+ if (DPMSPowerLevel < DPMSModeOff) {
+ if (DPMSEnabled)
+ DPMSSet(DPMSModeOff);
+ }
+ return DPMSOffTime;
+}
+
+void
+FreeDPMSTimers(void)
+{
+ if (DPMSStandbyTimer) {
+ TimerFree(DPMSStandbyTimer);
+ DPMSStandbyTimer = NULL;
+ }
+ if (DPMSSuspendTimer) {
+ TimerFree(DPMSSuspendTimer);
+ DPMSSuspendTimer = NULL;
+ }
+ if (DPMSOffTimer) {
+ TimerFree(DPMSOffTimer);
+ DPMSOffTimer = NULL;
+ }
+}
+
+void
+SetDPMSTimers(void)
+{
+ if (!DPMSEnabled)
+ return;
+
+ DPMSStandbyTimer = TimerSet(DPMSStandbyTimer, 0, DPMSStandbyTime,
+ DPMSStandbyTimerExpire, NULL);
+ DPMSSuspendTimer = TimerSet(DPMSSuspendTimer, 0, DPMSSuspendTime,
+ DPMSSuspendTimerExpire, NULL);
+ DPMSOffTimer = TimerSet(DPMSOffTimer, 0, DPMSOffTime,
+ DPMSOffTimerExpire, NULL);
+}
+#endif
diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c
new file mode 100644
index 000000000..d8d035ade
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/access.c
@@ -0,0 +1,2285 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+Copyright 2004 Sun Microsystems, Inc.
+
+All rights reserved.
+
+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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+X Window System is a trademark of The Open Group.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef WIN32
+#include <nx-X11/Xwinsock.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#include <nx-X11/Xauth.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "site.h"
+#include <errno.h>
+#include <sys/types.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+
+#if defined(TCPCONN) || defined(ISC) || defined(__SCO__)
+#include <netinet/in.h>
+#endif /* TCPCONN || ISC || __SCO__ */
+
+#ifdef HAS_GETPEERUCRED
+# include <ucred.h>
+# ifdef sun
+# include <zone.h>
+# endif
+#endif
+
+#if defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(__GNU__)
+# include <sys/utsname.h>
+#endif
+#if defined(SYSV) && defined(i386)
+# include <sys/stream.h>
+# ifdef ISC
+# include <sys/stropts.h>
+# include <sys/sioctl.h>
+# endif /* ISC */
+#endif
+#ifdef __GNU__
+#undef SIOCGIFCONF
+#include <netdb.h>
+#else /*!__GNU__*/
+# include <net/if.h>
+#endif /*__GNU__ */
+
+#ifdef SVR4
+#include <sys/sockio.h>
+#include <sys/stropts.h>
+#endif
+
+#include <netdb.h>
+
+#ifdef CSRG_BASED
+#include <sys/param.h>
+#if (BSD >= 199103)
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#ifdef BSD44SOCKETS
+#ifndef VARIABLE_IFREQ
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#ifdef HAS_GETIFADDRS
+#include <ifaddrs.h>
+#endif
+
+/* Solaris provides an extended interface SIOCGLIFCONF. Other systems
+ * may have this as well, but the code has only been tested on Solaris
+ * so far, so we only enable it there. Other platforms may be added as
+ * needed.
+ *
+ * Test for Solaris commented out -- TSI @ UQV 2003.06.13
+ */
+#ifdef SIOCGLIFCONF
+/* #if defined(sun) */
+#define USE_SIOCGLIFCONF
+/* #endif */
+#endif
+
+#endif /* WIN32 */
+
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+#ifdef __SCO__
+/* The system defined value is wrong. MAXPATHLEN is set in sco5.cf. */
+#undef PATH_MAX
+#endif
+
+#define X_INCLUDE_NETDB_H
+#include <nx-X11/Xos_r.h>
+
+#include "dixstruct.h"
+#include "osdep.h"
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+Bool defeatAccessControl = FALSE;
+
+#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
+#define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
+#define addrEqual(fam, address, length, host) \
+ ((fam) == (host)->family &&\
+ (length) == (host)->len &&\
+ !acmp (address, (host)->addr, length))
+
+static int ConvertAddr(struct sockaddr * /*saddr*/,
+ int * /*len*/,
+ void ** /*addr*/);
+
+static int CheckAddr(int /*family*/,
+ void * /*pAddr*/,
+ unsigned /*length*/);
+
+static Bool NewHost(int /*family*/,
+ void * /*addr*/,
+ int /*len*/,
+ int /* addingLocalHosts */);
+
+/* XFree86 bug #156: To keep track of which hosts were explicitly requested in
+ /etc/X<display>.hosts, we've added a requested field to the HOST struct,
+ and a LocalHostRequested variable. These default to FALSE, but are set
+ to TRUE in ResetHosts when reading in /etc/X<display>.hosts. They are
+ checked in DisableLocalHost(), which is called to disable the default
+ local host entries when stronger authentication is turned on. */
+
+typedef struct _host {
+ short family;
+ short len;
+ unsigned char *addr;
+ struct _host *next;
+ int requested;
+} HOST;
+
+#define MakeHost(h,l) (h)=(HOST *) malloc(sizeof *(h)+(l));\
+ if (h) { \
+ (h)->addr=(unsigned char *) ((h) + 1);\
+ (h)->requested = FALSE; \
+ }
+#define FreeHost(h) free(h)
+static HOST *selfhosts = NULL;
+static HOST *validhosts = NULL;
+static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
+static int LocalHostEnabled = FALSE;
+static int LocalHostRequested = FALSE;
+static int UsingXdmcp = FALSE;
+
+/* FamilyServerInterpreted implementation */
+static Bool siAddrMatch(int family, void * addr, int len, HOST *host,
+ ClientPtr client);
+static int siCheckAddr(const char *addrString, int length);
+static void siTypesInitialize(void);
+
+/*
+ * called when authorization is not enabled to add the
+ * local host to the access list
+ */
+
+void
+EnableLocalHost (void)
+{
+ if (!UsingXdmcp)
+ {
+ LocalHostEnabled = TRUE;
+ AddLocalHosts ();
+ }
+}
+
+/*
+ * called when authorization is enabled to keep us secure
+ */
+void
+DisableLocalHost (void)
+{
+ HOST *self;
+
+ if (!LocalHostRequested) /* Fix for XFree86 bug #156 */
+ LocalHostEnabled = FALSE;
+ for (self = selfhosts; self; self = self->next) {
+ if (!self->requested) /* Fix for XFree86 bug #156 */
+ (void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (void *)self->addr);
+ }
+}
+
+/*
+ * called at init time when XDMCP will be used; xdmcp always
+ * adds local hosts manually when needed
+ */
+
+void
+AccessUsingXdmcp (void)
+{
+ UsingXdmcp = TRUE;
+ LocalHostEnabled = FALSE;
+}
+
+
+#if ((defined(SVR4) && !defined(SCO325) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
+
+/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
+
+static int
+ifioctl (int fd, int cmd, char *arg)
+{
+ struct strioctl ioc;
+ int ret;
+
+ bzero((char *) &ioc, sizeof(ioc));
+ ioc.ic_cmd = cmd;
+ ioc.ic_timout = 0;
+ if (cmd == SIOCGIFCONF)
+ {
+ ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
+ ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
+#ifdef ISC
+ /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
+ * buffer must contain the ifconf structure as header. Ifc_req
+ * is also not a pointer but a one element array of ifreq
+ * structures. On return this array is extended by enough
+ * ifreq fields to hold all interfaces. The return buffer length
+ * is placed in the buffer header.
+ */
+ ((struct ifconf *) ioc.ic_dp)->ifc_len =
+ ioc.ic_len - sizeof(struct ifconf);
+#endif
+ }
+ else
+ {
+ ioc.ic_len = sizeof(struct ifreq);
+ ioc.ic_dp = arg;
+ }
+ ret = ioctl(fd, I_STR, (char *) &ioc);
+ if (ret >= 0 && cmd == SIOCGIFCONF)
+#ifdef SVR4
+ ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
+#endif
+#ifdef ISC
+ {
+ ((struct ifconf *) arg)->ifc_len =
+ ((struct ifconf *)ioc.ic_dp)->ifc_len;
+ ((struct ifconf *) arg)->ifc_buf =
+ (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
+ }
+#endif
+ return(ret);
+}
+#else /* Case sun, SCO325 NCR and others */
+#define ifioctl ioctl
+#endif /* ((SVR4 && !sun !SCO325 !NCR) || ISC) && SIOCGIFCONF */
+
+/*
+ * DefineSelf (fd):
+ *
+ * Define this host for access control. Find all the hosts the OS knows about
+ * for this fd and add them to the selfhosts list.
+ */
+
+#ifdef WINTCP /* NCR Wollongong based TCP */
+
+#include <sys/un.h>
+#include <stropts.h>
+#include <tiuser.h>
+
+#include <sys/stream.h>
+#include <net/if.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+void
+DefineSelf (int fd)
+{
+ /*
+ * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
+ * socket IO calls that most other drivers seem to like. Because of
+ * this, this routine must be special cased for NCR. Eventually,
+ * this will be cleared up.
+ */
+
+ struct ipb ifnet;
+ struct in_ifaddr ifaddr;
+ struct strioctl str;
+ unsigned char *addr;
+ register HOST *host;
+ int family, len;
+
+ if ((fd = open ("/dev/ip", O_RDWR, 0 )) < 0)
+ Error ("Getting interface configuration (1)");
+
+ /* Indicate that we want to start at the begining */
+ ifnet.ib_next = (struct ipb *) 1;
+
+ while (ifnet.ib_next)
+ {
+ str.ic_cmd = IPIOC_GETIPB;
+ str.ic_timout = 0;
+ str.ic_len = sizeof (struct ipb);
+ str.ic_dp = (char *) &ifnet;
+
+ if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
+ {
+ close (fd);
+ Error ("Getting interface configuration (2)");
+ }
+
+ ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
+ str.ic_cmd = IPIOC_GETINADDR;
+ str.ic_timout = 0;
+ str.ic_len = sizeof (struct in_ifaddr);
+ str.ic_dp = (char *) &ifaddr;
+
+ if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
+ {
+ close (fd);
+ Error ("Getting interface configuration (3)");
+ }
+
+ len = sizeof(struct sockaddr_in);
+ family = ConvertAddr (IA_SIN(&ifaddr), &len, (void **)&addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next)
+ ;
+ if (host)
+ continue;
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ {
+ struct sockaddr broad_addr;
+
+ /*
+ * If this isn't an Internet Address, don't register it.
+ */
+ if (family != FamilyInternet)
+ continue;
+
+ /*
+ * Ignore 'localhost' entries as they're not useful
+ * on the other end of the wire.
+ */
+ if (len == 4 &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ continue;
+
+ /*
+ * Ignore '0.0.0.0' entries as they are
+ * returned by some OSes for unconfigured NICs but they are
+ * not useful on the other end of the wire.
+ */
+ if (len == 4 &&
+ addr[0] == 0 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 0)
+ continue;
+
+ XdmcpRegisterConnection (family, (char *)addr, len);
+
+
+#define IA_BROADADDR(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_broadaddr))
+
+ XdmcpRegisterBroadcastAddress (
+ (struct sockaddr_in *) IA_BROADADDR(&ifaddr));
+
+#undef IA_BROADADDR
+ }
+#endif /* XDMCP */
+ }
+
+ close(fd);
+
+ /*
+ * add something of FamilyLocalHost
+ */
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+}
+
+#else /* WINTCP */
+
+#if !defined(SIOCGIFCONF)
+void
+DefineSelf (int fd)
+{
+#if !defined(TCPCONN) && !defined(UNIXCONN)
+ return;
+#else
+ register int n;
+ int len;
+ caddr_t addr;
+ int family;
+ register HOST *host;
+
+#ifndef WIN32
+ struct utsname name;
+#else
+ struct {
+ char nodename[512];
+ } name;
+#endif
+
+ register struct hostent *hp;
+
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_in6 in6;
+#endif
+ } saddr;
+
+ struct sockaddr_in *inetaddr;
+ struct sockaddr_in6 *inet6addr;
+ struct sockaddr_in broad_addr;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+ _Xgethostbynameparams hparams;
+#endif
+
+ /* Why not use gethostname()? Well, at least on my system, I've had to
+ * make an ugly kernel patch to get a name longer than 8 characters, and
+ * uname() lets me access to the whole string (it smashes release, you
+ * see), whereas gethostname() kindly truncates it for me.
+ */
+#ifndef WIN32
+ uname(&name);
+#else
+ gethostname(name.nodename, sizeof(name.nodename));
+#endif
+
+ hp = _XGethostbyname(name.nodename, hparams);
+ if (hp != NULL)
+ {
+ saddr.sa.sa_family = hp->h_addrtype;
+ switch (hp->h_addrtype) {
+ case AF_INET:
+ inetaddr = (struct sockaddr_in *) (&(saddr.sa));
+ acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
+ len = sizeof(saddr.sa);
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
+ acopy ( hp->h_addr, &(inet6addr->sin6_addr), hp->h_length);
+ len = sizeof(saddr.in6);
+ break;
+#endif
+ default:
+ goto DefineLocalHost;
+ }
+ family = ConvertAddr ( &(saddr.sa), &len, (void **)&addr);
+ if ( family != -1 && family != FamilyLocal )
+ {
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next) ;
+ if (!host)
+ {
+ /* add this host to the host list. */
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy ( addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ /*
+ * If this is an Internet Address, but not the localhost
+ * address (127.0.0.1), nor the bogus address (0.0.0.0),
+ * register it.
+ */
+ if (family == FamilyInternet &&
+ !(len == 4 &&
+ ((addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1) ||
+ (addr[0] == 0 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 0)))
+ )
+ {
+ XdmcpRegisterConnection (family, (char *)addr, len);
+ broad_addr = *inetaddr;
+ ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+ htonl (INADDR_BROADCAST);
+ XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
+ &broad_addr);
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if (family == FamilyInternet6 &&
+ !(IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)))
+ {
+ XdmcpRegisterConnection (family, (char *)addr, len);
+ }
+#endif
+
+#endif /* XDMCP */
+ }
+ }
+ }
+ /*
+ * now add a host of family FamilyLocalHost...
+ */
+DefineLocalHost:
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+#endif /* !TCPCONN && !UNIXCONN */
+}
+
+#else
+
+#ifdef USE_SIOCGLIFCONF
+#define ifr_type struct lifreq
+#else
+#define ifr_type struct ifreq
+#endif
+
+#ifdef VARIABLE_IFREQ
+#define ifr_size(p) (sizeof (struct ifreq) + \
+ (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
+ p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
+#define ifraddr_size(a) (a.sa_len)
+#else
+#define ifr_size(p) (sizeof (ifr_type))
+#define ifraddr_size(a) (sizeof (a))
+#endif
+
+#if defined(DEF_SELF_DEBUG) || (defined(IPv6) && defined(AF_INET6))
+#include <arpa/inet.h>
+#endif
+
+#if defined(IPv6) && defined(AF_INET6)
+static void
+in6_fillscopeid(struct sockaddr_in6 *sin6)
+{
+#if defined(__KAME__)
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sin6->sin6_scope_id =
+ ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
+ sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
+ }
+#endif
+}
+#endif
+
+void
+DefineSelf (int fd)
+{
+#ifndef HAS_GETIFADDRS
+ char buf[2048], *cp, *cplim;
+ void * bufptr = buf;
+#ifdef USE_SIOCGLIFCONF
+ struct lifconf ifc;
+ register struct lifreq *ifr;
+#ifdef SIOCGLIFNUM
+ struct lifnum ifn;
+#endif
+#else
+ struct ifconf ifc;
+ register struct ifreq *ifr;
+#endif
+#else
+ struct ifaddrs * ifap, *ifr;
+#endif
+ int len;
+ unsigned char * addr;
+ int family;
+ register HOST *host;
+
+#ifndef HAS_GETIFADDRS
+
+ len = sizeof(buf);
+
+#ifdef USE_SIOCGLIFCONF
+
+#ifdef SIOCGLIFNUM
+ ifn.lifn_family = AF_UNSPEC;
+ ifn.lifn_flags = 0;
+ if (ioctl (fd, SIOCGLIFNUM, (char *) &ifn) < 0)
+ Error ("Getting interface count");
+ if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
+ len = ifn.lifn_count * sizeof(struct lifreq);
+ bufptr = malloc(len);
+ }
+#endif
+
+ ifc.lifc_family = AF_UNSPEC;
+ ifc.lifc_flags = 0;
+ ifc.lifc_len = len;
+ ifc.lifc_buf = bufptr;
+
+#define IFC_IOCTL_REQ SIOCGLIFCONF
+#define IFC_IFC_REQ ifc.lifc_req
+#define IFC_IFC_LEN ifc.lifc_len
+#define IFR_IFR_ADDR ifr->lifr_addr
+#define IFR_IFR_NAME ifr->lifr_name
+
+#else /* Use SIOCGIFCONF */
+ ifc.ifc_len = len;
+ ifc.ifc_buf = bufptr;
+
+#define IFC_IOCTL_REQ SIOCGIFCONF
+#ifdef ISC
+#define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
+#else
+#define IFC_IFC_REQ ifc.ifc_req
+#endif /* ISC */
+#define IFC_IFC_LEN ifc.ifc_len
+#define IFR_IFR_ADDR ifr->ifr_addr
+#define IFR_IFR_NAME ifr->ifr_name
+#endif
+
+ if (ifioctl (fd, IFC_IOCTL_REQ, (void *) &ifc) < 0)
+ Error ("Getting interface configuration (4)");
+
+ cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
+
+ for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
+ {
+ ifr = (ifr_type *) cp;
+ len = ifraddr_size (IFR_IFR_ADDR);
+ family = ConvertAddr ((struct sockaddr *) &IFR_IFR_ADDR,
+ &len, (void **)&addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+#if defined(IPv6) && defined(AF_INET6)
+ if (family == FamilyInternet6)
+ in6_fillscopeid((struct sockaddr_in6 *)&IFR_IFR_ADDR);
+#endif
+#ifdef DEF_SELF_DEBUG
+ if (family == FamilyInternet)
+ ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
+ IFR_IFR_NAME, addr[0], addr[1], addr[2], addr[3]);
+#if defined(IPv6) && defined(AF_INET6)
+ else if (family == FamilyInternet6) {
+ char cp[INET6_ADDRSTRLEN] = "";
+ inet_ntop(AF_INET6, addr, cp, sizeof(cp));
+ ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %s\n",
+ IFR_IFR_NAME, cp);
+ }
+#endif
+#endif /* DEF_SELF_DEBUG */
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next)
+ ;
+ if (host)
+ continue;
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ {
+#ifdef USE_SIOCGLIFCONF
+ struct sockaddr_storage broad_addr;
+#else
+ struct sockaddr broad_addr;
+#endif
+
+ /*
+ * If this isn't an Internet Address, don't register it.
+ */
+ if (family != FamilyInternet
+#if defined(IPv6) && defined(AF_INET6)
+ && family != FamilyInternet6
+#endif
+ )
+ continue;
+
+ /*
+ * ignore 'localhost' entries as they're not useful
+ * on the other end of the wire
+ */
+ if (family == FamilyInternet &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ continue;
+#if defined(IPv6) && defined(AF_INET6)
+ else if (family == FamilyInternet6 &&
+ IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
+ continue;
+#endif
+
+ /*
+ * Ignore '0.0.0.0' entries as they are
+ * returned by some OSes for unconfigured NICs but they are
+ * not useful on the other end of the wire.
+ */
+ if (len == 4 &&
+ addr[0] == 0 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 0)
+ continue;
+
+ XdmcpRegisterConnection (family, (char *)addr, len);
+
+#if defined(IPv6) && defined(AF_INET6)
+ /* IPv6 doesn't support broadcasting, so we drop out here */
+ if (family == FamilyInternet6)
+ continue;
+#endif
+
+ broad_addr = IFR_IFR_ADDR;
+
+ ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+ htonl (INADDR_BROADCAST);
+#if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
+ {
+ struct lifreq broad_req;
+
+ broad_req = *ifr;
+ if (ioctl (fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
+ (broad_req.lifr_flags & IFF_BROADCAST) &&
+ (broad_req.lifr_flags & IFF_UP)
+ )
+ {
+ broad_req = *ifr;
+ if (ioctl (fd, SIOCGLIFBRDADDR, &broad_req) != -1)
+ broad_addr = broad_req.lifr_broadaddr;
+ else
+ continue;
+ }
+ else
+ continue;
+ }
+
+#elif defined(SIOCGIFBRDADDR)
+ {
+ struct ifreq broad_req;
+
+ broad_req = *ifr;
+ if (ifioctl (fd, SIOCGIFFLAGS, (void *) &broad_req) != -1 &&
+ (broad_req.ifr_flags & IFF_BROADCAST) &&
+ (broad_req.ifr_flags & IFF_UP)
+ )
+ {
+ broad_req = *ifr;
+ if (ifioctl (fd, SIOCGIFBRDADDR, (void *) &broad_req) != -1)
+ broad_addr = broad_req.ifr_addr;
+ else
+ continue;
+ }
+ else
+ continue;
+ }
+#endif /* SIOCGIFBRDADDR */
+#ifdef DEF_SELF_DEBUG
+ ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
+ IFR_IFR_NAME,
+ inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
+#endif /* DEF_SELF_DEBUG */
+ XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
+ }
+#endif /* XDMCP */
+ }
+ if (bufptr != buf)
+ free(bufptr);
+#else /* HAS_GETIFADDRS */
+ if (getifaddrs(&ifap) < 0) {
+ ErrorF("Warning: getifaddrs returns %s\n", strerror(errno));
+ return;
+ }
+ for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
+ if (!ifr->ifa_addr)
+ continue;
+ len = sizeof(*(ifr->ifa_addr));
+ family = ConvertAddr(ifr->ifa_addr, &len, (void **)&addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+#if defined(IPv6) && defined(AF_INET6)
+ if (family == FamilyInternet6)
+ in6_fillscopeid((struct sockaddr_in6 *)ifr->ifa_addr);
+#endif
+
+#ifdef DEF_SELF_DEBUG
+ if (family == FamilyInternet)
+ ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
+ ifr->ifa_name, addr[0], addr[1], addr[2], addr[3]);
+#if defined(IPv6) && defined(AF_INET6)
+ else if (family == FamilyInternet6) {
+ char cp[INET6_ADDRSTRLEN];
+
+ inet_ntop(AF_INET6, addr, cp, sizeof(cp));
+ ErrorF("Xserver: DefineSelf(): ifname = %s addr = %s\n",
+ ifr->ifa_name, cp);
+ }
+#endif
+#endif /* DEF_SELF_DEBUG */
+ for (host = selfhosts;
+ host != NULL && !addrEqual(family, addr, len, host);
+ host = host->next)
+ ;
+ if (host != NULL)
+ continue;
+ MakeHost(host, len);
+ if (host != NULL) {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ {
+ struct sockaddr broad_addr;
+ /*
+ * If this isn't an Internet Address, don't register it.
+ */
+ if (family != FamilyInternet
+#if defined(IPv6) && defined(AF_INET6)
+ && family != FamilyInternet6
+#endif
+ )
+ continue;
+
+ /*
+ * ignore 'localhost' entries as they're not useful
+ * on the other end of the wire
+ */
+ if (ifr->ifa_flags & IFF_LOOPBACK)
+ continue;
+
+ if (family == FamilyInternet &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ continue;
+
+ /*
+ * Ignore '0.0.0.0' entries as they are
+ * returned by some OSes for unconfigured NICs but they are
+ * not useful on the other end of the wire.
+ */
+ if (len == 4 &&
+ addr[0] == 0 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 0)
+ continue;
+#if defined(IPv6) && defined(AF_INET6)
+ else if (family == FamilyInternet6 &&
+ IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
+ continue;
+#endif
+ XdmcpRegisterConnection(family, (char *)addr, len);
+#if defined(IPv6) && defined(AF_INET6)
+ if (family == FamilyInternet6)
+ /* IPv6 doesn't support broadcasting, so we drop out here */
+ continue;
+#endif
+ if ((ifr->ifa_flags & IFF_BROADCAST) &&
+ (ifr->ifa_flags & IFF_UP))
+ broad_addr = *ifr->ifa_broadaddr;
+ else
+ continue;
+#ifdef DEF_SELF_DEBUG
+ ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
+ ifr->ifa_name,
+ inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
+#endif /* DEF_SELF_DEBUG */
+ XdmcpRegisterBroadcastAddress((struct sockaddr_in *)
+ &broad_addr);
+ }
+#endif /* XDMCP */
+
+ } /* for */
+ freeifaddrs(ifap);
+#endif /* HAS_GETIFADDRS */
+
+ /*
+ * add something of FamilyLocalHost
+ */
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+}
+#endif /* !SIOCGIFCONF */
+#endif /* WINTCP */
+
+#ifdef XDMCP
+void
+AugmentSelf(void * from, int len)
+{
+ int family;
+ void * addr;
+ register HOST *host;
+
+ family = ConvertAddr(from, &len, (void **)&addr);
+ if (family == -1 || family == FamilyLocal)
+ return;
+ for (host = selfhosts; host; host = host->next)
+ {
+ if (addrEqual(family, addr, len, host))
+ return;
+ }
+ MakeHost(host,len)
+ if (!host)
+ return;
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+}
+#endif
+
+void
+AddLocalHosts (void)
+{
+ HOST *self;
+
+ for (self = selfhosts; self; self = self->next)
+ /* Fix for XFree86 bug #156: pass addingLocal = TRUE to
+ * NewHost to tell that we are adding the default local
+ * host entries and not to flag the entries as being
+ * explicitely requested */
+ (void) NewHost (self->family, self->addr, self->len, TRUE);
+}
+
+/* Reset access control list to initial hosts */
+void
+ResetHosts (char *display)
+{
+ register HOST *host;
+ char lhostname[120], ohostname[120];
+ char *hostname = ohostname;
+ char fname[PATH_MAX + 1];
+ int fnamelen;
+ FILE *fd;
+ char *ptr;
+ int i, hostlen;
+#if (defined(TCPCONN) && (!defined(IPv6) || !defined(AF_INET6)))
+ union {
+ struct sockaddr sa;
+#if defined(TCPCONN)
+ struct sockaddr_in in;
+#endif /* TCPCONN */
+ } saddr;
+#endif
+ int family = 0;
+ void *addr = NULL;
+ int len;
+
+ siTypesInitialize();
+ AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
+ LocalHostEnabled = FALSE;
+ while ((host = validhosts) != 0)
+ {
+ validhosts = host->next;
+ FreeHost (host);
+ }
+
+#define ETC_HOST_PREFIX "/etc/X"
+#define ETC_HOST_SUFFIX ".hosts"
+ fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
+ strlen(display) + 1;
+ if (fnamelen > sizeof(fname))
+ FatalError("Display name `%s' is too long\n", display);
+ sprintf(fname, ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, display);
+
+ if ((fd = fopen (fname, "r")) != 0)
+ {
+ while (fgets (ohostname, sizeof (ohostname), fd))
+ {
+ family = FamilyWild;
+ if (*ohostname == '#')
+ continue;
+ if ((ptr = strchr(ohostname, '\n')) != 0)
+ *ptr = 0;
+ hostlen = strlen(ohostname) + 1;
+ for (i = 0; i < hostlen; i++)
+ lhostname[i] = tolower(ohostname[i]);
+ hostname = ohostname;
+ if (!strncmp("local:", lhostname, 6))
+ {
+ family = FamilyLocalHost;
+ NewHost(family, "", 0, FALSE);
+ LocalHostRequested = TRUE; /* Fix for XFree86 bug #156 */
+ }
+#if defined(TCPCONN)
+ else if (!strncmp("inet:", lhostname, 5))
+ {
+ family = FamilyInternet;
+ hostname = ohostname + 5;
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if (!strncmp("inet6:", lhostname, 6))
+ {
+ family = FamilyInternet6;
+ hostname = ohostname + 6;
+ }
+#endif
+#endif
+#ifdef SECURE_RPC
+ else if (!strncmp("nis:", lhostname, 4))
+ {
+ family = FamilyNetname;
+ hostname = ohostname + 4;
+ }
+#endif
+ else if (!strncmp("si:", lhostname, 3))
+ {
+ family = FamilyServerInterpreted;
+ hostname = ohostname + 3;
+ hostlen -= 3;
+ }
+
+
+ if (family == FamilyServerInterpreted)
+ {
+ len = siCheckAddr(hostname, hostlen);
+ if (len >= 0) {
+ NewHost(family, hostname, len, FALSE);
+ }
+ }
+ else
+#ifdef SECURE_RPC
+ if ((family == FamilyNetname) || (strchr(hostname, '@')))
+ {
+ SecureRPCInit ();
+ (void) NewHost (FamilyNetname, hostname, strlen (hostname), FALSE);
+ }
+ else
+#endif /* SECURE_RPC */
+#if defined(TCPCONN)
+ {
+#if defined(IPv6) && defined(AF_INET6)
+ if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
+ (family == FamilyWild) )
+ {
+ struct addrinfo *addresses;
+ struct addrinfo *a;
+ int f;
+
+ if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
+ for (a = addresses ; a != NULL ; a = a->ai_next) {
+ len = a->ai_addrlen;
+ f = ConvertAddr(a->ai_addr,&len,(void **)&addr);
+ if (addr && ((family == f) ||
+ ((family == FamilyWild) && (f != -1)))) {
+ NewHost(f, addr, len, FALSE);
+ }
+ }
+ freeaddrinfo(addresses);
+ }
+ }
+#else
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+ _Xgethostbynameparams hparams;
+#endif
+ register struct hostent *hp;
+
+ /* host name */
+ if ((family == FamilyInternet &&
+ ((hp = _XGethostbyname(hostname, hparams)) != 0)) ||
+ ((hp = _XGethostbyname(hostname, hparams)) != 0))
+ {
+ saddr.sa.sa_family = hp->h_addrtype;
+ len = sizeof(saddr.sa);
+ if ((family = ConvertAddr (&saddr.sa, &len, (void **)&addr)) != -1)
+ {
+#ifdef h_addr /* new 4.3bsd version of gethostent */
+ char **list;
+
+ /* iterate over the addresses */
+ for (list = hp->h_addr_list; *list; list++)
+ (void) NewHost (family, (void *)*list, len, FALSE);
+#else
+ (void) NewHost (family, (void *)hp->h_addr, len, FALSE);
+#endif
+ }
+ }
+#endif /* IPv6 */
+ }
+#endif /* TCPCONN */
+ family = FamilyWild;
+ }
+ fclose (fd);
+ }
+}
+
+/* Is client on the local host */
+Bool
+ComputeLocalClient(ClientPtr client)
+{
+ int alen, family, notused;
+ Xtransaddr *from = NULL;
+ void *addr;
+ register HOST *host;
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+
+ if (!oc->trans_conn)
+ return FALSE;
+
+#ifdef XCSECURITY
+ /* untrusted clients can't change host access */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to change host access\n",
+ client->index);
+ return FALSE;
+ }
+#endif
+ if (!_XSERVTransGetPeerAddr (oc->trans_conn, &notused, &alen, &from))
+ {
+ family = ConvertAddr ((struct sockaddr *) from,
+ &alen, (void **)&addr);
+ if (family == -1)
+ {
+ free(from);
+ return FALSE;
+ }
+ if (family == FamilyLocal)
+ {
+ free(from);
+ return TRUE;
+ }
+ for (host = selfhosts; host; host = host->next)
+ {
+ if (addrEqual (family, addr, alen, host)) {
+ free(from);
+ return TRUE;
+ }
+ }
+ free(from);
+ }
+ return FALSE;
+}
+
+/*
+ * Return the uid and gid of a connected local client
+ *
+ * Used by XShm to test access rights to shared memory segments
+ */
+int
+LocalClientCred(ClientPtr client, int *pUid, int *pGid)
+{
+ LocalClientCredRec *lcc;
+ int ret = GetLocalClientCreds(client, &lcc);
+
+ if (ret == 0) {
+#ifdef HAVE_GETZONEID /* only local if in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+#endif
+ if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
+ *pUid = lcc->euid;
+ if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
+ *pGid = lcc->egid;
+ FreeLocalClientCreds(lcc);
+ }
+ return ret;
+}
+
+/*
+ * Return the uid and all gids of a connected local client
+ * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds
+ *
+ * Used by localuser & localgroup ServerInterpreted access control forms below
+ * Used by AuthAudit to log where local connections came from
+ */
+int
+GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
+{
+#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
+ int fd;
+ XtransConnInfo ci;
+ LocalClientCredRec *lcc;
+#ifdef HAS_GETPEEREID
+ uid_t uid;
+ gid_t gid;
+#elif defined(HAS_GETPEERUCRED)
+ ucred_t *peercred = NULL;
+ const gid_t *gids;
+#elif defined(SO_PEERCRED)
+ struct ucred peercred;
+ socklen_t so_len = sizeof(peercred);
+#endif
+
+ if (client == NULL)
+ return -1;
+ ci = ((OsCommPtr)client->osPrivate)->trans_conn;
+#if !(defined(sun) && defined(HAS_GETPEERUCRED))
+ /* Most implementations can only determine peer credentials for Unix
+ * domain sockets - Solaris getpeerucred can work with a bit more, so
+ * we just let it tell us if the connection type is supported or not
+ */
+ if (!_XSERVTransIsLocal(ci)) {
+ return -1;
+ }
+#endif
+
+ *lccp = calloc(1, sizeof(LocalClientCredRec));
+ if (*lccp == NULL)
+ return -1;
+ lcc = *lccp;
+
+ fd = _XSERVTransGetConnectionNumber(ci);
+#ifdef HAS_GETPEEREID
+ if (getpeereid(fd, &uid, &gid) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = uid;
+ lcc->egid = gid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
+ return 0;
+#elif defined(HAS_GETPEERUCRED)
+ if (getpeerucred(fd, &peercred) < 0) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ lcc->euid = ucred_geteuid(peercred);
+ if (lcc->euid != -1)
+ lcc->fieldsSet |= LCC_UID_SET;
+ lcc->egid = ucred_getegid(peercred);
+ if (lcc->egid != -1)
+ lcc->fieldsSet |= LCC_GID_SET;
+ lcc->pid = ucred_getpid(peercred);
+ if (lcc->pid != -1)
+ lcc->fieldsSet |= LCC_PID_SET;
+#ifdef HAVE_GETZONEID
+ lcc->zoneid = ucred_getzoneid(peercred);
+ if (lcc->zoneid != -1)
+ lcc->fieldsSet |= LCC_ZID_SET;
+#endif
+ lcc->nSuppGids = ucred_getgroups(peercred, &gids);
+ if (lcc->nSuppGids > 0) {
+ lcc->pSuppGids = calloc((lcc->nSuppGids), sizeof(int));
+ if (lcc->pSuppGids == NULL) {
+ lcc->nSuppGids = 0;
+ } else {
+ int i;
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ (lcc->pSuppGids)[i] = (int) gids[i];
+ }
+ }
+ } else {
+ lcc->nSuppGids = 0;
+ }
+ ucred_free(peercred);
+ return 0;
+#elif defined(SO_PEERCRED)
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
+ FreeLocalClientCreds(lcc);
+ return -1;
+ }
+ lcc->euid = peercred.uid;
+ lcc->egid = peercred.gid;
+ lcc->pid = peercred.pid;
+ lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
+ return 0;
+#endif
+#else
+ /* No system call available to get the credentials of the peer */
+#define NO_LOCAL_CLIENT_CRED
+ return -1;
+#endif
+}
+
+void
+FreeLocalClientCreds(LocalClientCredRec *lcc)
+{
+ if (lcc != NULL) {
+ if (lcc->nSuppGids > 0) {
+ free(lcc->pSuppGids);
+ }
+ free(lcc);
+ }
+}
+
+static Bool
+AuthorizedClient(ClientPtr client)
+{
+ if (!client || defeatAccessControl)
+ return TRUE;
+ return client->local ? Success : BadAccess;
+}
+
+/* Add a host to the access control list. This is the external interface
+ * called from the dispatcher */
+
+int
+AddHost (ClientPtr client,
+ int family,
+ unsigned length, /* of bytes in pAddr */
+ void *pAddr)
+{
+ int len;
+
+ if (!AuthorizedClient(client))
+ return(BadAccess);
+ switch (family) {
+ case FamilyLocalHost:
+ len = length;
+ LocalHostEnabled = TRUE;
+ break;
+#ifdef SECURE_RPC
+ case FamilyNetname:
+ len = length;
+ SecureRPCInit ();
+ break;
+#endif
+ case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+#endif
+ case FamilyChaos:
+ case FamilyServerInterpreted:
+ if ((len = CheckAddr (family, pAddr, length)) < 0)
+ {
+ client->errorValue = length;
+ return (BadValue);
+ }
+ break;
+ case FamilyLocal:
+ default:
+ client->errorValue = family;
+ return (BadValue);
+ }
+ if (NewHost (family, pAddr, len, FALSE))
+ return Success;
+ return BadAlloc;
+}
+
+Bool
+ForEachHostInFamily (int family,
+ Bool (*func)(
+ unsigned char * /* addr */,
+ short /* len */,
+ void * /* closure */),
+ void * closure)
+{
+ HOST *host;
+
+ for (host = validhosts; host; host = host->next)
+ if (family == host->family && func (host->addr, host->len, closure))
+ return TRUE;
+ return FALSE;
+}
+
+/* Add a host to the access control list. This is the internal interface
+ * called when starting or resetting the server */
+static Bool
+NewHost (int family,
+ void *addr,
+ int len,
+ int addingLocalHosts)
+{
+ register HOST *host;
+
+ for (host = validhosts; host; host = host->next)
+ {
+ if (addrEqual (family, addr, len, host))
+ return TRUE;
+ }
+ if (!addingLocalHosts) { /* Fix for XFree86 bug #156 */
+ for (host = selfhosts; host; host = host->next) {
+ if (addrEqual (family, addr, len, host)) {
+ host->requested = TRUE;
+ break;
+ }
+ }
+ }
+ MakeHost(host,len)
+ if (!host)
+ return FALSE;
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = validhosts;
+ validhosts = host;
+ return TRUE;
+}
+
+/* Remove a host from the access control list */
+
+int
+RemoveHost (
+ ClientPtr client,
+ int family,
+ unsigned length, /* of bytes in pAddr */
+ void *pAddr)
+{
+ int len;
+ register HOST *host, **prev;
+
+ if (!AuthorizedClient(client))
+ return(BadAccess);
+ switch (family) {
+ case FamilyLocalHost:
+ len = length;
+ LocalHostEnabled = FALSE;
+ break;
+#ifdef SECURE_RPC
+ case FamilyNetname:
+ len = length;
+ break;
+#endif
+ case FamilyInternet:
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+#endif
+ case FamilyChaos:
+ case FamilyServerInterpreted:
+ if ((len = CheckAddr (family, pAddr, length)) < 0)
+ {
+ client->errorValue = length;
+ return(BadValue);
+ }
+ break;
+ case FamilyLocal:
+ default:
+ client->errorValue = family;
+ return(BadValue);
+ }
+ for (prev = &validhosts;
+ (host = *prev) && (!addrEqual (family, pAddr, len, host));
+ prev = &host->next)
+ ;
+ if (host)
+ {
+ *prev = host->next;
+ FreeHost (host);
+ }
+ return (Success);
+}
+
+/* Get all hosts in the access control list */
+int
+GetHosts (
+ void * *data,
+ int *pnHosts,
+ int *pLen,
+ BOOL *pEnabled)
+{
+ int len;
+ register int n = 0;
+ register unsigned char *ptr;
+ register HOST *host;
+ int nHosts = 0;
+
+ *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
+ for (host = validhosts; host; host = host->next)
+ {
+ nHosts++;
+ n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
+ /* Could check for INT_MAX, but in reality having more than 1mb of
+ hostnames in the access list is ridiculous */
+ if (n >= 1024*1024)
+ break;
+ }
+ if (n)
+ {
+ *data = ptr = (void *) malloc (n);
+ if (!ptr)
+ {
+ return(BadAlloc);
+ }
+ for (host = validhosts; host; host = host->next)
+ {
+ len = host->len;
+ if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n))
+ break;
+ ((xHostEntry *)ptr)->family = host->family;
+ ((xHostEntry *)ptr)->length = len;
+ ptr += sizeof(xHostEntry);
+ acopy (host->addr, ptr, len);
+ ptr += ((len + 3) >> 2) << 2;
+ }
+ } else {
+ *data = NULL;
+ }
+ *pnHosts = nHosts;
+ *pLen = n;
+ return(Success);
+}
+
+/* Check for valid address family and length, and return address length. */
+
+/*ARGSUSED*/
+static int
+CheckAddr (
+ int family,
+ void * pAddr,
+ unsigned length)
+{
+ int len;
+
+ switch (family)
+ {
+#if defined(TCPCONN)
+ case FamilyInternet:
+ if (length == sizeof (struct in_addr))
+ len = length;
+ else
+ len = -1;
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case FamilyInternet6:
+ if (length == sizeof (struct in6_addr))
+ len = length;
+ else
+ len = -1;
+ break;
+#endif
+#endif
+ case FamilyServerInterpreted:
+ len = siCheckAddr(pAddr, length);
+ break;
+ default:
+ len = -1;
+ }
+ return (len);
+}
+
+/* Check if a host is not in the access control list.
+ * Returns 1 if host is invalid, 0 if we've found it. */
+
+int
+InvalidHost (
+ register struct sockaddr *saddr,
+ int len,
+ ClientPtr client)
+{
+ int family;
+ void *addr = NULL;
+ register HOST *selfhost, *host;
+
+ if (!AccessEnabled) /* just let them in */
+ return(0);
+ family = ConvertAddr (saddr, &len, (void **)&addr);
+ if (family == -1)
+ return 1;
+ if (family == FamilyLocal)
+ {
+ if (!LocalHostEnabled)
+ {
+ /*
+ * check to see if any local address is enabled. This
+ * implicitly enables local connections.
+ */
+ for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
+ {
+ for (host = validhosts; host; host=host->next)
+ {
+ if (addrEqual (selfhost->family, selfhost->addr,
+ selfhost->len, host))
+ return 0;
+ }
+ }
+ } else
+ return 0;
+ }
+ for (host = validhosts; host; host = host->next)
+ {
+ if ((host->family == FamilyServerInterpreted)) {
+ if (siAddrMatch (family, addr, len, host, client)) {
+ return (0);
+ }
+ } else {
+ if (addr && addrEqual (family, addr, len, host))
+ return (0);
+ }
+
+ }
+ return (1);
+}
+
+static int
+ConvertAddr (
+ register struct sockaddr *saddr,
+ int *len,
+ void **addr)
+{
+ if (*len == 0)
+ return (FamilyLocal);
+ switch (saddr->sa_family)
+ {
+ case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN)
+ case AF_UNIX:
+#endif
+ return FamilyLocal;
+#if defined(TCPCONN)
+ case AF_INET:
+#ifdef WIN32
+ if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr)
+ return FamilyLocal;
+#endif
+ *len = sizeof (struct in_addr);
+ *addr = (void *) &(((struct sockaddr_in *) saddr)->sin_addr);
+ return FamilyInternet;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
+ if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
+ *len = sizeof (struct in_addr);
+ *addr = (void *) &(saddr6->sin6_addr.s6_addr[12]);
+ return FamilyInternet;
+ } else {
+ *len = sizeof (struct in6_addr);
+ *addr = (void *) &(saddr6->sin6_addr);
+ return FamilyInternet6;
+ }
+ }
+#endif
+#endif
+#ifdef CHAOSCONN
+ case AF_CHAOS:
+ {
+ not implemented
+ }
+ return FamilyChaos;
+#endif
+ default:
+ return -1;
+ }
+}
+
+int
+ChangeAccessControl(
+ ClientPtr client,
+ int fEnabled)
+{
+ if (!AuthorizedClient(client))
+ return BadAccess;
+ AccessEnabled = fEnabled;
+ return Success;
+}
+
+/* returns FALSE if xhost + in effect, else TRUE */
+int
+GetAccessControl(void)
+{
+ return AccessEnabled;
+}
+
+/*****************************************************************************
+ * FamilyServerInterpreted host entry implementation
+ *
+ * Supports an extensible system of host types which the server can interpret
+ * See the IPv6 extensions to the X11 protocol spec for the definition.
+ *
+ * Currently supported schemes:
+ *
+ * hostname - hostname as defined in IETF RFC 2396
+ * ipv6 - IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
+ *
+ * See xc/doc/specs/SIAddresses for formal definitions of each type.
+ */
+
+/* These definitions and the siTypeAdd function could be exported in the
+ * future to enable loading additional host types, but that was not done for
+ * the initial implementation.
+ */
+typedef Bool (*siAddrMatchFunc)(int family, void * addr, int len,
+ const char *siAddr, int siAddrlen, ClientPtr client, void *siTypePriv);
+typedef int (*siCheckAddrFunc)(const char *addrString, int length,
+ void *siTypePriv);
+
+struct siType {
+ struct siType * next;
+ const char * typeName;
+ siAddrMatchFunc addrMatch;
+ siCheckAddrFunc checkAddr;
+ void * typePriv; /* Private data for type routines */
+};
+
+static struct siType *siTypeList;
+
+static int
+siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
+ siCheckAddrFunc checkAddr, void *typePriv)
+{
+ struct siType *s, *p;
+
+ if ((typeName == NULL) || (addrMatch == NULL) || (checkAddr == NULL))
+ return BadValue;
+
+ for (s = siTypeList, p = NULL; s != NULL ; p = s, s = s->next) {
+ if (strcmp(typeName, s->typeName) == 0) {
+ s->addrMatch = addrMatch;
+ s->checkAddr = checkAddr;
+ s->typePriv = typePriv;
+ return Success;
+ }
+ }
+
+ s = (struct siType *) malloc(sizeof(struct siType));
+ if (s == NULL)
+ return BadAlloc;
+
+ if (p == NULL)
+ siTypeList = s;
+ else
+ p->next = s;
+
+ s->next = NULL;
+ s->typeName = typeName;
+ s->addrMatch = addrMatch;
+ s->checkAddr = checkAddr;
+ s->typePriv = typePriv;
+ return Success;
+}
+
+/* Checks to see if a host matches a server-interpreted host entry */
+static Bool
+siAddrMatch(int family, void * addr, int len, HOST *host, ClientPtr client)
+{
+ Bool matches = FALSE;
+ struct siType *s;
+ const char *valueString;
+ int addrlen;
+
+ valueString = (const char *) memchr(host->addr, '\0', host->len);
+ if (valueString != NULL) {
+ for (s = siTypeList; s != NULL ; s = s->next) {
+ if (strcmp((char *) host->addr, s->typeName) == 0) {
+ addrlen = host->len - (strlen((char *)host->addr) + 1);
+ matches = s->addrMatch(family, addr, len,
+ valueString + 1, addrlen, client, s->typePriv);
+ break;
+ }
+ }
+#ifdef FAMILY_SI_DEBUG
+ ErrorF(
+ "Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
+ host->addr, addrlen, addrlen, valueString + 1,
+ (matches) ? "accepted" : "rejected");
+#endif
+ }
+ return matches;
+}
+
+static int
+siCheckAddr(const char *addrString, int length)
+{
+ const char *valueString;
+ int addrlen, typelen;
+ int len = -1;
+ struct siType *s;
+
+ /* Make sure there is a \0 byte inside the specified length
+ to separate the address type from the address value. */
+ valueString = (const char *) memchr(addrString, '\0', length);
+ if (valueString != NULL) {
+ /* Make sure the first string is a recognized address type,
+ * and the second string is a valid address of that type.
+ */
+ typelen = strlen(addrString) + 1;
+ addrlen = length - typelen;
+
+ for (s = siTypeList; s != NULL ; s = s->next) {
+ if (strcmp(addrString, s->typeName) == 0) {
+ len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
+ if (len >= 0) {
+ len += typelen;
+ }
+ break;
+ }
+ }
+#ifdef FAMILY_SI_DEBUG
+ {
+ const char *resultMsg;
+
+ if (s == NULL) {
+ resultMsg = "type not registered";
+ } else {
+ if (len == -1)
+ resultMsg = "rejected";
+ else
+ resultMsg = "accepted";
+ }
+
+ ErrorF("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
+ addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
+ }
+#endif
+ }
+ return len;
+}
+
+
+/***
+ * Hostname server-interpreted host type
+ *
+ * Stored as hostname string, explicitly defined to be resolved ONLY
+ * at access check time, to allow for hosts with dynamic addresses
+ * but static hostnames, such as found in some DHCP & mobile setups.
+ *
+ * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
+ * hostname = *( domainlabel "." ) toplabel [ "." ]
+ * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
+ * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ */
+
+#ifdef NI_MAXHOST
+# define SI_HOSTNAME_MAXLEN NI_MAXHOST
+#else
+# ifdef MAXHOSTNAMELEN
+# define SI_HOSTNAME_MAXLEN MAXHOSTNAMELEN
+# else
+# define SI_HOSTNAME_MAXLEN 256
+# endif
+#endif
+
+static Bool
+siHostnameAddrMatch(int family, void * addr, int len,
+ const char *siAddr, int siAddrLen, ClientPtr client, void *typePriv)
+{
+ Bool res = FALSE;
+
+/* Currently only supports checking against IPv4 & IPv6 connections, but
+ * support for other address families, such as DECnet, could be added if
+ * desired.
+ */
+#if defined(IPv6) && defined(AF_INET6)
+ if ((family == FamilyInternet) || (family == FamilyInternet6)) {
+ char hostname[SI_HOSTNAME_MAXLEN];
+ struct addrinfo *addresses;
+ struct addrinfo *a;
+ int f, hostaddrlen;
+ void * hostaddr = NULL;
+
+ if (siAddrLen >= sizeof(hostname))
+ return FALSE;
+
+ strncpy(hostname, siAddr, siAddrLen);
+ hostname[siAddrLen] = '\0';
+
+ if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
+ for (a = addresses ; a != NULL ; a = a->ai_next) {
+ hostaddrlen = a->ai_addrlen;
+ f = ConvertAddr(a->ai_addr,&hostaddrlen,&hostaddr);
+ if ((f == family) && (len == hostaddrlen) && hostaddr &&
+ (acmp (addr, hostaddr, len) == 0) ) {
+ res = TRUE;
+ break;
+ }
+ }
+ freeaddrinfo(addresses);
+ }
+ }
+#else /* IPv6 not supported, use gethostbyname instead for IPv4 */
+ if (family == FamilyInternet) {
+ register struct hostent *hp;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+ _Xgethostbynameparams hparams;
+#endif
+ char hostname[SI_HOSTNAME_MAXLEN];
+ int f, hostaddrlen;
+ void * hostaddr;
+ const char **addrlist;
+
+ if (siAddrLen >= sizeof(hostname))
+ return FALSE;
+
+ strncpy(hostname, siAddr, siAddrLen);
+ hostname[siAddrLen] = '\0';
+
+ if ((hp = _XGethostbyname(hostname, hparams)) != NULL) {
+#ifdef h_addr /* new 4.3bsd version of gethostent */
+ /* iterate over the addresses */
+ for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
+#else
+ addrlist = &hp->h_addr;
+#endif
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_family = hp->h_addrtype;
+ acopy ( *addrlist, &(sin.sin_addr), hp->h_length);
+ hostaddrlen = sizeof(sin);
+ f = ConvertAddr ((struct sockaddr *)&sin,
+ &hostaddrlen, &hostaddr);
+ if ((f == family) && (len == hostaddrlen) &&
+ (acmp (addr, hostaddr, len) == 0) ) {
+ res = TRUE;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ return res;
+}
+
+
+static int
+siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
+{
+ /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
+ * We do not use ctype functions here to avoid locale-specific
+ * character sets. Hostnames must be pure ASCII.
+ */
+ int len = length;
+ int i;
+ Bool dotAllowed = FALSE;
+ Bool dashAllowed = FALSE;
+
+ if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN)) {
+ len = -1;
+ } else {
+ for (i = 0; i < length; i++) {
+ char c = valueString[i];
+
+ if (c == 0x2E) { /* '.' */
+ if (dotAllowed == FALSE) {
+ len = -1;
+ break;
+ } else {
+ dotAllowed = FALSE;
+ dashAllowed = FALSE;
+ }
+ } else if (c == 0x2D) { /* '-' */
+ if (dashAllowed == FALSE) {
+ len = -1;
+ break;
+ } else {
+ dotAllowed = FALSE;
+ }
+ } else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
+ ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
+ ((c >= 0x41) && (c <= 0x5A)) /* A-Z */) {
+ dotAllowed = TRUE;
+ dashAllowed = TRUE;
+ } else { /* Invalid character */
+ len = -1;
+ break;
+ }
+ }
+ }
+ return len;
+}
+
+#if defined(IPv6) && defined(AF_INET6)
+/***
+ * "ipv6" server interpreted type
+ *
+ * Currently supports only IPv6 literal address as specified in IETF RFC 3513
+ *
+ * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be
+ * added for the scoped address format it specifies.
+ */
+
+/* Maximum length of an IPv6 address string - increase when adding support
+ * for scoped address qualifiers. Includes room for trailing NUL byte.
+ */
+#define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
+
+static Bool
+siIPv6AddrMatch(int family, void * addr, int len,
+ const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
+{
+ struct in6_addr addr6;
+ char addrbuf[SI_IPv6_MAXLEN];
+
+ if ((family != FamilyInternet6) || (len != sizeof(addr6)))
+ return FALSE;
+
+ memcpy(addrbuf, siAddr, siAddrlen);
+ addrbuf[siAddrlen] = '\0';
+
+ if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
+ perror("inet_pton");
+ return FALSE;
+ }
+
+ if (memcmp(addr, &addr6, len) == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+static int
+siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
+{
+ int len;
+
+ /* Minimum length is 3 (smallest legal address is "::1") */
+ if (length < 3) {
+ /* Address is too short! */
+ len = -1;
+ } else if (length >= SI_IPv6_MAXLEN) {
+ /* Address is too long! */
+ len = -1;
+ } else {
+ /* Assume inet_pton is sufficient validation */
+ struct in6_addr addr6;
+ char addrbuf[SI_IPv6_MAXLEN];
+
+ memcpy(addrbuf, addrString, length);
+ addrbuf[length] = '\0';
+
+ if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
+ perror("inet_pton");
+ len = -1;
+ } else {
+ len = length;
+ }
+ }
+ return len;
+}
+#endif /* IPv6 */
+
+#if !defined(NO_LOCAL_CLIENT_CRED)
+/***
+ * "localuser" & "localgroup" server interpreted types
+ *
+ * Allows local connections from a given local user or group
+ */
+
+#include <pwd.h>
+#include <grp.h>
+
+#define LOCAL_USER 1
+#define LOCAL_GROUP 2
+
+typedef struct {
+ int credType;
+} siLocalCredPrivRec, *siLocalCredPrivPtr;
+
+static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
+static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
+
+static Bool
+siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
+{
+ Bool parsedOK = FALSE;
+ char *addrbuf = malloc(len + 1);
+
+ if (addrbuf == NULL) {
+ return FALSE;
+ }
+
+ memcpy(addrbuf, addr, len);
+ addrbuf[len] = '\0';
+
+ if (addr[0] == '#') { /* numeric id */
+ char *cp;
+ errno = 0;
+ *id = strtol(addrbuf + 1, &cp, 0);
+ if ((errno == 0) && (cp != (addrbuf+1))) {
+ parsedOK = TRUE;
+ }
+ } else { /* non-numeric name */
+ if (lcPriv->credType == LOCAL_USER) {
+ struct passwd *pw = getpwnam(addrbuf);
+
+ if (pw != NULL) {
+ *id = (int) pw->pw_uid;
+ parsedOK = TRUE;
+ }
+ } else { /* group */
+ struct group *gr = getgrnam(addrbuf);
+
+ if (gr != NULL) {
+ *id = (int) gr->gr_gid;
+ parsedOK = TRUE;
+ }
+ }
+ }
+
+ free(addrbuf);
+ return parsedOK;
+}
+
+static Bool
+siLocalCredAddrMatch(int family, void * addr, int len,
+ const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
+{
+ int siAddrId;
+ LocalClientCredRec *lcc;
+ siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
+
+ if (GetLocalClientCreds(client, &lcc) == -1) {
+ return FALSE;
+ }
+
+#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */
+ if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
+ FreeLocalClientCreds(lcc);
+ return FALSE;
+ }
+#endif
+
+ if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
+ FreeLocalClientCreds(lcc);
+ return FALSE;
+ }
+
+ if (lcPriv->credType == LOCAL_USER) {
+ if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
+ return TRUE;
+ }
+ } else {
+ if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
+ FreeLocalClientCreds(lcc);
+ return TRUE;
+ }
+ if (lcc->pSuppGids != NULL) {
+ int i;
+
+ for (i = 0 ; i < lcc->nSuppGids; i++) {
+ if (lcc->pSuppGids[i] == siAddrId) {
+ FreeLocalClientCreds(lcc);
+ return TRUE;
+ }
+ }
+ }
+ }
+ FreeLocalClientCreds(lcc);
+ return FALSE;
+}
+
+static int
+siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
+{
+ int len = length;
+ int id;
+
+ if (siLocalCredGetId(addrString, length,
+ (siLocalCredPrivPtr)typePriv, &id) == FALSE) {
+ len = -1;
+ }
+ return len;
+}
+#endif /* localuser */
+
+static void
+siTypesInitialize(void)
+{
+ siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL);
+#if defined(IPv6) && defined(AF_INET6)
+ siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
+#endif
+#if !defined(NO_LOCAL_CLIENT_CRED)
+ siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
+ &siLocalUserPriv);
+ siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
+ &siLocalGroupPriv);
+#endif
+}
diff --git a/nx-X11/programs/Xserver/os/auth.c b/nx-X11/programs/Xserver/os/auth.c
new file mode 100644
index 000000000..84bc5c3c6
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/auth.c
@@ -0,0 +1,602 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1988, 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.
+
+*/
+
+/*
+ * authorization hooks for the server
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# include <nx-X11/X.h>
+# include <nx-X11/Xauth.h>
+# include "misc.h"
+# include "osdep.h"
+# include "dixstruct.h"
+# include <sys/types.h>
+# include <sys/stat.h>
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+# include <nx-X11/extensions/security.h>
+#endif
+#ifdef WIN32
+#include <nx-X11/Xw32defs.h>
+#endif
+
+struct protocol {
+ unsigned short name_length;
+ char *name;
+ AuthAddCFunc Add; /* new authorization data */
+ AuthCheckFunc Check; /* verify client authorization data */
+ AuthRstCFunc Reset; /* delete all authorization data entries */
+ AuthToIDFunc ToID; /* convert cookie to ID */
+ AuthFromIDFunc FromID; /* convert ID to cookie */
+ AuthRemCFunc Remove; /* remove a specific cookie */
+#ifdef XCSECURITY
+ AuthGenCFunc Generate;
+#endif
+};
+
+static struct protocol protocols[] = {
+{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
+ MitAddCookie, MitCheckCookie, MitResetCookie,
+ MitToID, MitFromID, MitRemoveCookie,
+#ifdef XCSECURITY
+ MitGenerateCookie
+#endif
+},
+#ifdef HASXDMAUTH
+{ (unsigned short) 19, "XDM-AUTHORIZATION-1",
+ XdmAddCookie, XdmCheckCookie, XdmResetCookie,
+ XdmToID, XdmFromID, XdmRemoveCookie,
+#ifdef XCSECURITY
+ NULL
+#endif
+},
+#endif
+#ifdef SECURE_RPC
+{ (unsigned short) 9, "SUN-DES-1",
+ SecureRPCAdd, SecureRPCCheck, SecureRPCReset,
+ SecureRPCToID, SecureRPCFromID,SecureRPCRemove,
+#ifdef XCSECURITY
+ NULL
+#endif
+},
+#endif
+#ifdef XCSECURITY
+{ (unsigned short) XSecurityAuthorizationNameLen,
+ XSecurityAuthorizationName,
+ NULL, AuthSecurityCheck, NULL,
+ NULL, NULL, NULL,
+ NULL
+},
+#endif
+};
+
+# define NUM_AUTHORIZATION (sizeof (protocols) /\
+ sizeof (struct protocol))
+
+/*
+ * Initialize all classes of authorization by reading the
+ * specified authorization file
+ */
+
+static char *authorization_file = (char *)NULL;
+
+static Bool ShouldLoadAuth = TRUE;
+
+void
+InitAuthorization (char *file_name)
+{
+#ifdef __sun
+ char * envBuffer;
+#endif
+ authorization_file = file_name;
+#ifdef NX_TRANS_AUTH
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "InitAuthorization: Going to propagate auth file '%s' to the environment.\n",
+ authorization_file);
+#endif
+#ifdef __sun
+ envBuffer = malloc(15+strlen(authorization_file));
+ sprintf(envBuffer,"NX_XAUTHORITY=%s",authorization_file);
+ putenv(envBuffer);
+#else
+ setenv("NX_XAUTHORITY", authorization_file, 1);
+#endif
+#endif
+
+}
+
+static int
+LoadAuthorization (void)
+{
+ FILE *f;
+ Xauth *auth;
+ int i;
+ int count = 0;
+
+ ShouldLoadAuth = FALSE;
+ if (!authorization_file)
+ return 0;
+
+#ifdef NX_TRANS_AUTH
+
+ /*
+ * We think that the way LoadAuthorization() is working is wrong.
+ * It doesn't reset the list of stored authorizations before reading
+ * the new cookies. Our take is that if a new auth file is to be
+ * read, the only cookies that are to be accepted are those that are
+ * in the new file, not those in the file -plus- those that have
+ * been in the file in the past. Furthermore, if the list can't be
+ * read or it is empty, it should assume that it ignores which co-
+ * okies are valid and thus it should disable any access. Your mile-
+ * age can vary. A less draconian approach could be to leave the old
+ * cookies if the file can't be read and remove them only if the
+ * file is empty.
+ *
+ * Adding the cookies without removing the old values for the same
+ * protocol has an important implication. If an user shares the co-
+ * okie with somebody and later wants to revoke the access to the
+ * display, changing the cookie will not work. This is especially
+ * important with NX. For security reasons, after reconnecting the
+ * session to a different display, it is advisable to generate a
+ * new set of cookies, but doing that it is useless with the current
+ * code, as the old cookies are going to be still accepted. On the
+ * same topic, consider that once an user has got access to the X
+ * server, he/she can freely enable host authentication from any
+ * host, so the safe behaviour should be to reset the host based
+ * authenthication at least at reconnection, and keep as valid only
+ * the cookies that are actually in the file. This behaviour would
+ * surely break many applications, among them a SSH connection run
+ * inside a NX session, as ssh -X reads the cookie for the display
+ * only at session startup and does not read the cookies again
+ * when the auth file is changed.
+ *
+ * Another bug (or feature, depending on how you want to consider
+ * it) is that if the authority file contains entries for different
+ * displays (as it is the norm when the authority file is the default
+ * .Xauthority in the user's home), the server will match -any- of
+ * the cookies, even cookies that are not for its own display. This
+ * means that you have be careful when passing an authority file to
+ * nxagent or Xnest and maybe keep separate files for letting nxagent
+ * find the cookie to be used to connect to the remote display and
+ * for letting it find what cookies to accept. If the file is the
+ * same, clients will be able to connect to nxagent with both the
+ * cookies.
+ */
+
+#ifdef NX_TRANS_AUTH_RESET
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "LoadAuthorization: Resetting authorization info.\n");
+ #endif
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].Reset) {
+ (*protocols[i].Reset) ();
+ }
+ }
+
+#endif
+
+#endif /* #ifdef NX_TRANS_AUTH */
+
+ f = Fopen (authorization_file, "r");
+ if (!f)
+ return -1;
+
+ while ((auth = XauReadAuth (f)) != 0) {
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == auth->name_length &&
+ memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
+ protocols[i].Add)
+ {
+#ifdef NX_TRANS_AUTH
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "LoadAuthorization: Adding new record from file [%s].\n",
+ authorization_file);
+ #endif
+
+#endif
+ ++count;
+ (*protocols[i].Add) (auth->data_length, auth->data,
+ FakeClientID(0));
+ }
+ }
+ XauDisposeAuth (auth);
+ }
+
+#ifdef NX_TRANS_AUTH
+
+ if (count == 0)
+ {
+ fprintf(stderr, "Warning: No authorization record could be read from file '%s'.\n",
+ authorization_file);
+
+ fprintf(stderr, "Warning: Please, create a valid authorization cookie using the command\n"
+ "Warning: 'xauth -f %s add <display> MIT-MAGIC-COOKIE-1 <cookie>'.\n",
+ authorization_file);
+ }
+
+#endif
+
+#ifdef NX_TRANS_AUTH
+ if (Fclose (f) != 0)
+ {
+ /*
+ * If the Fclose() fails, for example because of a signal,
+ * it's advisable to return the number of protocols read,
+ * if any, or otherwise the server would believe that no
+ * cookie is valid and eventually fall back to host based
+ * authentication. Note anyway that the new code in Check-
+ * Authorization() doesn't care the return value and gives
+ * a chance to the function to check the file at the next
+ * connection.
+ */
+
+ if (count > 0)
+ {
+ return count;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+#else
+ Fclose (f);
+#endif
+ return count;
+}
+
+#ifdef XDMCP
+/*
+ * XdmcpInit calls this function to discover all authorization
+ * schemes supported by the display
+ */
+void
+RegisterAuthorizations (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++)
+ XdmcpRegisterAuthorization (protocols[i].name,
+ (int)protocols[i].name_length);
+}
+#endif
+
+XID
+CheckAuthorization (
+ unsigned int name_length,
+ char *name,
+ unsigned int data_length,
+ char *data,
+ ClientPtr client,
+ char **reason) /* failure message. NULL for default msg */
+{
+ int i;
+ struct stat buf;
+ static time_t lastmod = 0;
+
+ #ifndef NX_TRANS_AUTH
+ static Bool loaded = FALSE;
+ #endif
+
+ if (!authorization_file || stat(authorization_file, &buf))
+ {
+ if (lastmod != 0) {
+ lastmod = 0;
+ ShouldLoadAuth = TRUE; /* stat lost, so force reload */
+ }
+ }
+ else if (buf.st_mtime > lastmod)
+ {
+ lastmod = buf.st_mtime;
+ ShouldLoadAuth = TRUE;
+ }
+ if (ShouldLoadAuth)
+ {
+ int loadauth = LoadAuthorization();
+
+ /*
+ * If the authorization file has at least one entry for this server,
+ * disable local host access. (loadauth > 0)
+ *
+ * If there are zero entries (either initially or when the
+ * authorization file is later reloaded), or if a valid
+ * authorization file was never loaded, enable local host access.
+ * (loadauth == 0 || !loaded)
+ *
+ * If the authorization file was loaded initially (with valid
+ * entries for this server), and reloading it later fails, don't
+ * change anything. (loadauth == -1 && loaded)
+ */
+
+#ifdef NX_TRANS_AUTH
+
+ /*
+ * The implementation of CheckAuthorization() was changed. The way
+ * the auth file was handled previously was questionable and could
+ * open the way to a vast array of security problems. There might be
+ * ways for an attacker to prevent the server from reading the file
+ * and it was enough for the server to fail reading the file once
+ * (because of a not blocked signal, for example) to leave the dis-
+ * play open to all the users running a session on the same terminal
+ * server.
+ *
+ * In NX we want to have only two cases: either we have to check an
+ * authorization file or we don't. In the first case we need to do our
+ * best to read the file at any new client access and never fall back
+ * to host based authentication. Falling back to local host access has
+ * no way back, as it will always take precedence over the auth cookie
+ * (unless the user explicitly disables, one by one, all the rules
+ * allowing local access, if and only if he/she becomes aware of the
+ * problem). In the second case we assume that user doesn't care secu-
+ * rity and so allow unrestricted access from the local machine.
+ */
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "CheckAuthorization: Going to set authorization with loadauth [%d].\n",
+ loadauth);
+ #endif
+
+ if (authorization_file)
+ {
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "CheckAuthorization: Disabling local host access.\n");
+ #endif
+
+ DisableLocalHost();
+ }
+ else
+ {
+ /*
+ * Enable host-based authentication only if
+ * the authorization file was not specified
+ * either on the command line or in the env-
+ * ironment.
+ */
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "CheckAuthorization: Enabling local host access.\n");
+ #endif
+
+ EnableLocalHost();
+ }
+
+ /*
+ * Avoid the 'unused variable' warning.
+ */
+
+ loadauth = loadauth;
+
+#else /* #ifdef NX_TRANS_AUTH */
+
+ if (loadauth > 0)
+ {
+ DisableLocalHost(); /* got at least one */
+ loaded = TRUE;
+ }
+ else if (loadauth == 0 || !loaded)
+ EnableLocalHost ();
+
+#endif /* #ifdef NX_TRANS_AUTH */
+ }
+ if (name_length) {
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0)
+ {
+ return (*protocols[i].Check) (data_length, data, client, reason);
+ }
+ *reason = "Protocol not supported by server\n";
+ }
+ } else *reason = "No protocol specified\n";
+ return (XID) ~0L;
+}
+
+void
+ResetAuthorization (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++)
+ if (protocols[i].Reset)
+ (*protocols[i].Reset)();
+ ShouldLoadAuth = TRUE;
+}
+
+XID
+AuthorizationToID (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].ToID)
+ {
+ return (*protocols[i].ToID) (data_length, data);
+ }
+ }
+ return (XID) ~0L;
+}
+
+int
+AuthorizationFromID (
+ XID id,
+ unsigned short *name_lenp,
+ char **namep,
+ unsigned short *data_lenp,
+ char **datap)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].FromID &&
+ (*protocols[i].FromID) (id, data_lenp, datap)) {
+ *name_lenp = protocols[i].name_length;
+ *namep = protocols[i].name;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+RemoveAuthorization (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Remove)
+ {
+ return (*protocols[i].Remove) (data_length, data);
+ }
+ }
+ return 0;
+}
+
+int
+AddAuthorization (unsigned name_length, char *name, unsigned data_length, char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Add)
+ {
+ return (*protocols[i].Add) (data_length, data, FakeClientID(0));
+ }
+ }
+ return 0;
+}
+
+#ifdef XCSECURITY
+
+XID
+GenerateAuthorization(
+ unsigned name_length,
+ char *name,
+ unsigned data_length,
+ char *data,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Generate)
+ {
+ return (*protocols[i].Generate) (data_length, data,
+ FakeClientID(0), data_length_return, data_return);
+ }
+ }
+ return -1;
+}
+
+/* A random number generator that is more unpredictable
+ than that shipped with some systems.
+ This code is taken from the C standard. */
+
+static unsigned long int next = 1;
+
+static int
+xdm_rand(void)
+{
+ next = next * 1103515245 + 12345;
+ return (unsigned int)(next/65536) % 32768;
+}
+
+static void
+xdm_srand(unsigned int seed)
+{
+ next = seed;
+}
+
+void
+GenerateRandomData (int len, char *buf)
+{
+ static int seed;
+ int value;
+ int i;
+
+ seed += GetTimeInMillis();
+ xdm_srand (seed);
+ for (i = 0; i < len; i++)
+ {
+ value = xdm_rand ();
+ buf[i] ^= (value & 0xff00) >> 8;
+ }
+
+ /* XXX add getrusage, popen("ps -ale") */
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/os/client.c b/nx-X11/programs/Xserver/os/client.c
new file mode 100644
index 000000000..ef5e3935d
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/client.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All
+ * rights reserved.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * 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 THE
+ * AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+/**
+ * @file
+ *
+ * This file contains functionality for identifying clients by various
+ * means. The primary purpose of identification is to simply aid in
+ * finding out which clients are using X server and how they are using
+ * it. For example, it's often necessary to monitor what requests
+ * clients are executing (to spot bad behaviour) and how they are
+ * allocating resources in X server (to spot excessive resource
+ * usage).
+ *
+ * This framework automatically allocates information, that can be
+ * used for client identification, when a client connects to the
+ * server. The information is freed when the client disconnects. The
+ * allocated information is just a collection of various IDs, such as
+ * PID and process name for local clients, that are likely to be
+ * useful in analyzing X server usage.
+ *
+ * Users of the framework can query ID information about clients at
+ * any time. To avoid repeated polling of IDs the users can also
+ * subscribe for notifications about the availability of ID
+ * information. IDs have been allocated before ClientStateCallback is
+ * called with ClientStateInitial state. Similarly the IDs will be
+ * released after ClientStateCallback is called with ClientStateGone
+ * state.
+ *
+ * Author: Rami Ylimäki <rami.ylimaki@vincit.fi>
+ */
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "client.h"
+#include "os.h"
+#include "dixstruct.h"
+
+#ifdef __sun
+#include <errno.h>
+#include <procfs.h>
+#endif
+
+#ifdef __OpenBSD__
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <kvm.h>
+#include <limits.h>
+#endif
+
+/**
+ * Try to determine a PID for a client from its connection
+ * information. This should be called only once when new client has
+ * connected, use GetClientPid to determine the PID at other times.
+ *
+ * @param[in] client Connection linked to some process.
+ *
+ * @return PID of the client. Error (-1) if PID can't be determined
+ * for the client.
+ *
+ * @see GetClientPid
+ */
+pid_t
+DetermineClientPid(struct _Client * client)
+{
+ LocalClientCredRec *lcc = NULL;
+ pid_t pid = -1;
+
+ if (client == NullClient)
+ return pid;
+
+ if (client == serverClient)
+ return getpid();
+
+ if (GetLocalClientCreds(client, &lcc) != -1) {
+ if (lcc->fieldsSet & LCC_PID_SET)
+ pid = lcc->pid;
+ FreeLocalClientCreds(lcc);
+ }
+
+ return pid;
+}
+
+/**
+ * Try to determine a command line string for a client based on its
+ * PID. Note that mapping PID to a command hasn't been implemented for
+ * some operating systems. This should be called only once when a new
+ * client has connected, use GetClientCmdName/Args to determine the
+ * string at other times.
+ *
+ * @param[in] pid Process ID of a client.
+
+ * @param[out] cmdname Client process name without arguments. You must
+ * release this by calling free. On error NULL is
+ * returned. Pass NULL if you aren't interested in
+ * this value.
+ * @param[out] cmdargs Arguments to client process. Useful for
+ * identifying a client that is executed from a
+ * launcher program. You must release this by
+ * calling free. On error NULL is returned. Pass
+ * NULL if you aren't interested in this value.
+ *
+ * @see GetClientCmdName/Args
+ */
+void
+DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
+{
+ char path[PATH_MAX + 1];
+ int totsize = 0;
+ int fd = 0;
+
+ if (cmdname)
+ *cmdname = NULL;
+ if (cmdargs)
+ *cmdargs = NULL;
+
+ if (pid == -1)
+ return;
+
+#ifdef __sun /* Solaris */
+ /* Solaris does not support /proc/pid/cmdline, but makes information
+ * similar to what ps shows available in a binary structure in the
+ * /proc/pid/psinfo file. */
+ if (snprintf(path, sizeof(path), "/proc/%d/psinfo", pid) < 0)
+ return;
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ ErrorF("Failed to open %s: %s\n", path, strerror(errno));
+ return;
+ }
+ else {
+ psinfo_t psinfo = { 0 };
+ char *sp;
+
+ totsize = read(fd, &psinfo, sizeof(psinfo_t));
+ close(fd);
+ if (totsize <= 0)
+ return;
+
+ /* pr_psargs is the first PRARGSZ (80) characters of the command
+ * line string - assume up to the first space is the command name,
+ * since it's not delimited. While there is also pr_fname, that's
+ * more limited, giving only the first 16 chars of the basename of
+ * the file that was exec'ed, thus cutting off many long gnome
+ * command names, or returning "isapython2.6" for all python scripts.
+ */
+ psinfo.pr_psargs[PRARGSZ - 1] = '\0';
+ sp = strchr(psinfo.pr_psargs, ' ');
+ if (sp)
+ *sp++ = '\0';
+
+ if (cmdname)
+ *cmdname = strdup(psinfo.pr_psargs);
+
+ if (cmdargs && sp)
+ *cmdargs = strdup(sp);
+ }
+#elif defined(__OpenBSD__)
+ /* on OpenBSD use kvm_getargv() */
+ {
+ kvm_t *kd;
+ char errbuf[_POSIX2_LINE_MAX];
+ char **argv;
+ struct kinfo_proc *kp;
+ size_t len = 0;
+ int i, n;
+
+ kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
+ if (kd == NULL)
+ return;
+ kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc),
+ &n);
+ if (n != 1)
+ return;
+ argv = kvm_getargv(kd, kp, 0);
+ *cmdname = strdup(argv[0]);
+ i = 1;
+ while (argv[i] != NULL) {
+ len += strlen(argv[i]) + 1;
+ i++;
+ }
+ *cmdargs = calloc(1, len);
+ i = 1;
+ while (argv[i] != NULL) {
+ strlcat(*cmdargs, argv[i], len);
+ strlcat(*cmdargs, " ", len);
+ i++;
+ }
+ kvm_close(kd);
+ }
+#else /* Linux using /proc/pid/cmdline */
+
+ /* Check if /proc/pid/cmdline exists. It's not supported on all
+ * operating systems. */
+ if (snprintf(path, sizeof(path), "/proc/%d/cmdline", pid) < 0)
+ return;
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return;
+
+ /* Read the contents of /proc/pid/cmdline. It should contain the
+ * process name and arguments. */
+ totsize = read(fd, path, sizeof(path));
+ close(fd);
+ if (totsize <= 0)
+ return;
+ path[totsize - 1] = '\0';
+
+ /* Contruct the process name without arguments. */
+ if (cmdname) {
+ *cmdname = strdup(path);
+ }
+
+ /* Construct the arguments for client process. */
+ if (cmdargs) {
+ int cmdsize = strlen(path) + 1;
+ int argsize = totsize - cmdsize;
+ char *args = NULL;
+
+ if (argsize > 0)
+ args = malloc(argsize);
+ if (args) {
+ int i = 0;
+
+ for (i = 0; i < (argsize - 1); ++i) {
+ const char c = path[cmdsize + i];
+
+ args[i] = (c == '\0') ? ' ' : c;
+ }
+ args[argsize - 1] = '\0';
+ *cmdargs = args;
+ }
+ }
+#endif
+}
+
+/**
+ * Called when a new client connects. Allocates client ID information.
+ *
+ * @param[in] client Recently connected client.
+ */
+void
+ReserveClientIds(struct _Client *client)
+{
+#ifdef CLIENTIDS
+ if (client == NullClient)
+ return;
+
+ assert(!client->clientIds);
+ client->clientIds = calloc(1, sizeof(ClientIdRec));
+ if (!client->clientIds)
+ return;
+
+ client->clientIds->pid = DetermineClientPid(client);
+ if (client->clientIds->pid != -1)
+ DetermineClientCmd(client->clientIds->pid, &client->clientIds->cmdname,
+ &client->clientIds->cmdargs);
+
+ DebugF("client(%lx): Reserved pid(%d).\n",
+ (unsigned long) client->clientAsMask, client->clientIds->pid);
+ DebugF("client(%lx): Reserved cmdname(%s) and cmdargs(%s).\n",
+ (unsigned long) client->clientAsMask,
+ client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
+ client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
+#endif /* CLIENTIDS */
+}
+
+/**
+ * Called when an existing client disconnects. Frees client ID
+ * information.
+ *
+ * @param[in] client Recently disconnected client.
+ */
+void
+ReleaseClientIds(struct _Client *client)
+{
+#ifdef CLIENTIDS
+ if (client == NullClient)
+ return;
+
+ if (!client->clientIds)
+ return;
+
+ DebugF("client(%lx): Released pid(%d).\n",
+ (unsigned long) client->clientAsMask, client->clientIds->pid);
+ DebugF("client(%lx): Released cmdline(%s) and cmdargs(%s).\n",
+ (unsigned long) client->clientAsMask,
+ client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
+ client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
+
+ free((void *) client->clientIds->cmdname); /* const char * */
+ free((void *) client->clientIds->cmdargs); /* const char * */
+ free(client->clientIds);
+ client->clientIds = NULL;
+#endif /* CLIENTIDS */
+}
+
+/**
+ * Get cached PID of a client.
+ *
+ * param[in] client Client whose PID has been already cached.
+ *
+ * @return Cached client PID. Error (-1) if called:
+ * - before ClientStateInitial client state notification
+ * - after ClientStateGone client state notification
+ * - for remote clients
+ *
+ * @see DetermineClientPid
+ */
+pid_t
+GetClientPid(struct _Client *client)
+{
+ if (client == NullClient)
+ return -1;
+
+ if (!client->clientIds)
+ return -1;
+
+ return client->clientIds->pid;
+}
+
+/**
+ * Get cached command name string of a client.
+ *
+ * param[in] client Client whose command line string has been already
+ * cached.
+ *
+ * @return Cached client command name. Error (NULL) if called:
+ * - before ClientStateInitial client state notification
+ * - after ClientStateGone client state notification
+ * - for remote clients
+ * - on OS that doesn't support mapping of PID to command line
+ *
+ * @see DetermineClientCmd
+ */
+const char *
+GetClientCmdName(struct _Client *client)
+{
+ if (client == NullClient)
+ return NULL;
+
+ if (!client->clientIds)
+ return NULL;
+
+ return client->clientIds->cmdname;
+}
+
+/**
+ * Get cached command arguments string of a client.
+ *
+ * param[in] client Client whose command line string has been already
+ * cached.
+ *
+ * @return Cached client command arguments. Error (NULL) if called:
+ * - before ClientStateInitial client state notification
+ * - after ClientStateGone client state notification
+ * - for remote clients
+ * - on OS that doesn't support mapping of PID to command line
+ *
+ * @see DetermineClientCmd
+ */
+const char *
+GetClientCmdArgs(struct _Client *client)
+{
+ if (client == NullClient)
+ return NULL;
+
+ if (!client->clientIds)
+ return NULL;
+
+ return client->clientIds->cmdargs;
+}
diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c
new file mode 100644
index 000000000..c5ebeea1e
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/connection.c
@@ -0,0 +1,1377 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+/*****************************************************************
+ * Stuff to create connections --- OS dependent
+ *
+ * EstablishNewConnections, CreateWellKnownSockets, ResetWellKnownSockets,
+ * CloseDownConnection, CheckConnections,
+ * OnlyListToOneClient,
+ * ListenToAllClients,
+ *
+ * (WaitForSomething is in its own file)
+ *
+ * In this implementation, a client socket table is not kept.
+ * Instead, what would be the index into the table is just the
+ * file descriptor of the socket. This won't work for if the
+ * socket ids aren't small nums (0 - 2^8)
+ *
+ *****************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef WIN32
+#include <nx-X11/Xwinsock.h>
+#endif
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#include <nx-X11/Xtrans/Xtransint.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifndef WIN32
+#include <sys/socket.h>
+
+#if defined(TCPCONN)
+# include <netinet/in.h>
+# include <arpa/inet.h>
+
+/* FIXME: correct indentation levels after ancient platform support clean-up */
+
+# ifdef apollo
+# ifndef NO_TCP_H
+# include <netinet/tcp.h>
+# endif
+# else
+# ifdef CSRG_BASED
+# include <sys/param.h>
+# endif
+# include <netinet/tcp.h>
+# endif
+# include <arpa/inet.h>
+#endif
+
+#include <sys/uio.h>
+#endif /* WIN32 */
+#include "misc.h"
+#include "osdep.h"
+#include <nx-X11/Xpoll.h>
+#include "opaque.h"
+#include "dixstruct.h"
+#include "list.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#ifdef X_NOT_POSIX
+#define Pid_t int
+#else
+#define Pid_t pid_t
+#endif
+
+int lastfdesc; /* maximum file descriptor */
+
+fd_set NotifyReadFds; /* mask for other file descriptors */
+fd_set NotifyWriteFds; /* mask for other write file descriptors */
+fd_set AllSockets; /* select on this */
+fd_set AllClients; /* available clients */
+fd_set LastSelectMask; /* mask returned from last select call */
+fd_set LastSelectWriteMask; /* mask returned from last select call */
+fd_set ClientsWithInput; /* clients with FULL requests in buffer */
+fd_set ClientsWriteBlocked; /* clients who cannot receive output */
+fd_set OutputPending; /* clients with reply/event data ready to go */
+int MaxClients = 0;
+int NumNotifyWriteFd; /* Number of NotifyFd members with write set */
+Bool NewOutputPending; /* not yet attempted to write some new output */
+Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */
+Bool NoListenAll; /* Don't establish any listening sockets */
+Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
+static char dynamic_display[7]; /* display name */
+Bool PartialNetwork; /* continue even if unable to bind all addrs */
+static Pid_t ParentProcess;
+
+static Bool debug_conns = FALSE;
+
+fd_set IgnoredClientsWithInput;
+static fd_set GrabImperviousClients;
+static fd_set SavedAllClients;
+static fd_set SavedAllSockets;
+static fd_set SavedClientsWithInput;
+int GrabInProgress = 0;
+
+static void
+QueueNewConnections(int curconn, int ready, void *data);
+
+#if !defined(WIN32)
+int *ConnectionTranslation = NULL;
+#else
+/*
+ * On NT fds are not between 0 and MAXSOCKS, they are unrelated, and there is
+ * not even a known maximum value, so use something quite arbitrary for now.
+ * Do storage is a hash table of size 256. Collisions are handled in a linked
+ * list.
+ */
+
+#undef MAXSOCKS
+#define MAXSOCKS 500
+#undef MAXSELECT
+#define MAXSELECT 500
+#define MAXFD 500
+
+struct _ct_node {
+ struct _ct_node *next;
+ int key;
+ int value;
+};
+
+struct _ct_node *ct_head[256];
+
+void InitConnectionTranslation(void)
+{
+ bzero(ct_head, sizeof(ct_head));
+}
+
+int GetConnectionTranslation(int conn)
+{
+ struct _ct_node *node = ct_head[conn & 0xff];
+ while (node != NULL)
+ {
+ if (node->key == conn)
+ return node->value;
+ node = node->next;
+ }
+ return 0;
+}
+
+void SetConnectionTranslation(int conn, int client)
+{
+ struct _ct_node **node = ct_head + (conn & 0xff);
+ if (client == 0) /* remove entry */
+ {
+ while (*node != NULL)
+ {
+ if ((*node)->key == conn)
+ {
+ struct _ct_node *temp = *node;
+ *node = (*node)->next;
+ free(temp);
+ return;
+ }
+ node = &((*node)->next);
+ }
+ return;
+ } else
+ {
+ while (*node != NULL)
+ {
+ if ((*node)->key == conn)
+ {
+ (*node)->value = client;
+ return;
+ }
+ node = &((*node)->next);
+ }
+ *node = (struct _ct_node*)malloc(sizeof(struct _ct_node));
+ (*node)->next = NULL;
+ (*node)->key = conn;
+ (*node)->value = client;
+ return;
+ }
+}
+
+void ClearConnectionTranslation(void)
+{
+ unsigned i;
+ for (i = 0; i < 256; i++)
+ {
+ struct _ct_node *node = ct_head[i];
+ while (node != NULL)
+ {
+ struct _ct_node *temp = node;
+ node = node->next;
+ free(temp);
+ }
+ }
+}
+#endif
+
+XtransConnInfo *ListenTransConns = NULL;
+int *ListenTransFds = NULL;
+int ListenTransCount;
+
+static void ErrorConnMax(XtransConnInfo /* trans_conn */);
+
+static
+void CloseDownFileDescriptor(
+ OsCommPtr /*oc*/
+);
+
+
+static XtransConnInfo
+lookup_trans_conn (int fd)
+{
+ if (ListenTransFds)
+ {
+ int i;
+ for (i = 0; i < ListenTransCount; i++)
+ if (ListenTransFds[i] == fd)
+ return ListenTransConns[i];
+ }
+
+ return (NULL);
+}
+
+/* Set MaxClients and lastfdesc, and allocate ConnectionTranslation */
+
+void
+InitConnectionLimits(void)
+{
+ lastfdesc = -1;
+
+#ifndef __CYGWIN__
+
+#if !defined(XNO_SYSCONF) && defined(_SC_OPEN_MAX)
+ lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
+#endif
+
+#ifdef HAS_GETDTABLESIZE
+ if (lastfdesc < 0)
+ lastfdesc = getdtablesize() - 1;
+#endif
+
+#ifdef _NFILE
+ if (lastfdesc < 0)
+ lastfdesc = _NFILE - 1;
+#endif
+
+#endif /* __CYGWIN__ */
+
+ /* This is the fallback */
+ if (lastfdesc < 0)
+ lastfdesc = MAXSOCKS;
+
+ if (lastfdesc > MAXSELECT)
+ lastfdesc = MAXSELECT;
+
+ if (lastfdesc > MAXCLIENTS)
+ {
+ lastfdesc = MAXCLIENTS;
+ if (debug_conns)
+ ErrorF( "REACHED MAXIMUM CLIENTS LIMIT %d\n", MAXCLIENTS);
+ }
+ MaxClients = lastfdesc;
+
+#ifdef DEBUG
+ ErrorF("InitConnectionLimits: MaxClients = %d\n", MaxClients);
+#endif
+
+#if !defined(WIN32)
+ ConnectionTranslation = (int *)xnfalloc(sizeof(int)*(lastfdesc + 1));
+#else
+ InitConnectionTranslation();
+#endif
+}
+
+/*
+ * If SIGUSR1 was set to SIG_IGN when the server started, assume that either
+ *
+ * a- The parent process is ignoring SIGUSR1
+ *
+ * or
+ *
+ * b- The parent process is expecting a SIGUSR1
+ * when the server is ready to accept connections
+ *
+ * In the first case, the signal will be harmless, in the second case,
+ * the signal will be quite useful.
+ */
+static void
+InitParentProcess(void)
+{
+#if !defined(WIN32)
+ OsSigHandlerPtr handler;
+ handler = OsSignal (SIGUSR1, SIG_IGN);
+ if ( handler == SIG_IGN)
+ RunFromSmartParent = TRUE;
+ OsSignal(SIGUSR1, handler);
+ ParentProcess = getppid ();
+#ifdef __UNIXOS2__
+ /*
+ * fg030505: under OS/2, xinit is not the parent process but
+ * the "grant parent" process of the server because execvpe()
+ * presents us an additional process number;
+ * GetPPID(pid) is part of libemxfix
+ */
+ ParentProcess = GetPPID (ParentProcess);
+#endif /* __UNIXOS2__ */
+#endif
+}
+
+void
+NotifyParentProcess(void)
+{
+#if !defined(WIN32)
+ if (displayfd >= 0) {
+#ifdef NXAGENT_SERVER
+ if (displayfd == STDERR_FILENO)
+ {
+ const char *msg = "Auto-detected display number is: DISPLAY=:";
+ if (write(displayfd, msg, strlen(msg)) != strlen(msg))
+ FatalError("Cannot write display number to fd %d\n", displayfd);
+ }
+#endif
+ if (write(displayfd, display, strlen(display)) != strlen(display))
+ FatalError("Cannot write display number to fd %d\n", displayfd);
+ if (write(displayfd, "\n", 1) != 1)
+ FatalError("Cannot write display number to fd %d\n", displayfd);
+ close(displayfd);
+ displayfd = -1;
+ }
+ if (RunFromSmartParent) {
+ if (ParentProcess > 1) {
+ kill (ParentProcess, SIGUSR1);
+ }
+ }
+#endif
+}
+
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+ char port[20];
+
+ snprintf(port, sizeof(port), "%d", num);
+
+ return (_XSERVTransMakeAllCOTSServerListeners(port, partial,
+ &ListenTransCount,
+ &ListenTransConns) >= 0);
+}
+
+/*****************
+ * CreateWellKnownSockets
+ * At initialization, create the sockets to listen on for new clients.
+ *****************/
+
+void
+CreateWellKnownSockets(void)
+{
+ int i;
+ int partial;
+
+ FD_ZERO(&AllSockets);
+ FD_ZERO(&AllClients);
+ FD_ZERO(&LastSelectMask);
+ FD_ZERO(&ClientsWithInput);
+
+#if !defined(WIN32)
+ for (i=0; i<MaxClients; i++) ConnectionTranslation[i] = 0;
+#else
+ ClearConnectionTranslation();
+#endif
+
+ /* display is initialized to "0" by main(). It is then set to the display
+ * number if specified on the command line. */
+ if (NoListenAll) {
+ ListenTransCount = 0;
+ }
+#ifndef NXAGENT_SERVER
+ else if ((displayfd < 0) || explicit_display) {
+#else
+ else if (displayfd < 0) {
+#endif /* ! NXAGENT_SERVER */
+ if (TryCreateSocket(atoi(display), &partial) &&
+ ListenTransCount >= 1)
+ if (!PartialNetwork && partial)
+ FatalError ("Failed to establish all listening sockets");
+ }
+ else { /* -displayfd and no explicit display number */
+ Bool found = 0;
+ int i_offset = 0;
+#ifdef NXAGENT_SERVER
+ if (explicit_display)
+ i_offset = atoi(display);
+#endif /* NXAGENT_SERVER */
+ for (i = i_offset; i < 65536 - X_TCP_PORT; i++) {
+ if (TryCreateSocket(i, &partial) && !partial) {
+ found = 1;
+ break;
+ }
+ else
+ CloseWellKnownConnections();
+ }
+ if (!found)
+ FatalError("Failed to find a socket to listen on");
+ snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
+ display = dynamic_display;
+ LogSetDisplay();
+ }
+
+ ListenTransFds = malloc(ListenTransCount * sizeof (int));
+
+ for (i = 0; i < ListenTransCount; i++) {
+ int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
+
+ ListenTransFds[i] = fd;
+ SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
+
+ if (!_XSERVTransIsLocal(ListenTransConns[i]))
+ DefineSelf (fd);
+ }
+
+ if (ListenTransCount == 0 && !NoListenAll)
+ FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running");
+#if !defined(WIN32)
+ OsSignal (SIGPIPE, SIG_IGN);
+ OsSignal (SIGHUP, AutoResetServer);
+#endif
+ OsSignal (SIGINT, GiveUp);
+ OsSignal (SIGTERM, GiveUp);
+ ResetHosts(display);
+
+ InitParentProcess();
+
+#ifdef XDMCP
+ XdmcpInit ();
+#endif
+}
+
+#ifdef NX_TRANS_SOCKET
+
+/*
+ * The following block is now defined also
+ * under Cygwin to support this environment.
+ */
+
+#ifndef __DARWIN__
+
+/*
+ * This is defined in Xtranssock.c and must
+ * be called explicitly as it doesn't share
+ * a pointer in the transport function table.
+ */
+
+extern void _XSERVTransSocketRejectConnection(XtransConnInfo);
+
+void
+RejectWellKnownSockets ()
+{
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ _XSERVTransSocketRejectConnection(ListenTransConns[i]);
+ }
+}
+
+#endif /* #ifndef __DARWIN__ */
+
+#else /* #ifdef NX_TRANS_SOCKET */
+
+void
+RejectWellKnownSockets ()
+{
+}
+
+#endif /* #ifdef NX_TRANS_SOCKET */
+
+void
+ResetWellKnownSockets (void)
+{
+ int i;
+
+ ResetOsBuffers();
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int status = _XSERVTransResetListener (ListenTransConns[i]);
+
+ if (status != TRANS_RESET_NOOP)
+ {
+ if (status == TRANS_RESET_FAILURE)
+ {
+ /*
+ * ListenTransConns[i] freed by xtrans.
+ * Remove it from out list.
+ */
+
+ RemoveNotifyFd(ListenTransFds[i]);
+ ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
+ ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
+ ListenTransCount -= 1;
+ i -= 1;
+ }
+ else if (status == TRANS_RESET_NEW_FD)
+ {
+ /*
+ * A new file descriptor was allocated (the old one was closed)
+ */
+
+ int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
+
+ ListenTransFds[i] = newfd;
+ }
+ }
+ }
+
+ for (i = 0; i < ListenTransCount; i++)
+ SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL);
+
+ ResetAuthorization ();
+ ResetHosts(display);
+ /*
+ * restart XDMCP
+ */
+#ifdef XDMCP
+ XdmcpReset ();
+#endif
+}
+
+void
+CloseWellKnownConnections(void)
+{
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++) {
+ if (ListenTransConns[i] != NULL) {
+ _XSERVTransClose(ListenTransConns[i]);
+ ListenTransConns[i] = NULL;
+ if (ListenTransFds != NULL)
+ RemoveNotifyFd(ListenTransFds[i]);
+ }
+ }
+ ListenTransCount = 0;
+}
+
+static void
+AuthAudit (ClientPtr client, Bool letin,
+ struct sockaddr *saddr, int len,
+ unsigned int proto_n, char *auth_proto, int auth_id)
+{
+ char addr[128];
+ char *out = addr;
+
+ char client_uid_string[64];
+ LocalClientCredRec *lcc;
+
+ if (!len)
+ strcpy(out, "local host");
+ else
+ switch (saddr->sa_family)
+ {
+ case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN)
+ case AF_UNIX:
+#endif
+ strcpy(out, "local host");
+ break;
+#if defined(TCPCONN)
+ case AF_INET:
+ sprintf(out, "IP %s",
+ inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr));
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6: {
+ char ipaddr[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &((struct sockaddr_in6 *) saddr)->sin6_addr,
+ ipaddr, sizeof(ipaddr));
+ sprintf(out, "IP %s", ipaddr);
+ }
+ break;
+#endif
+#endif
+ default:
+ strcpy(out, "unknown address");
+ }
+
+ if (GetLocalClientCreds(client, &lcc) != -1) {
+ int slen; /* length written to client_uid_string */
+
+ strcpy(client_uid_string, " ( ");
+ slen = 3;
+
+ if (lcc->fieldsSet & LCC_UID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "uid=%ld ", (long) lcc->euid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_GID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "gid=%ld ", (long) lcc->egid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_PID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "pid=%ld ", (long) lcc->pid);
+ slen = strlen(client_uid_string);
+ }
+
+ if (lcc->fieldsSet & LCC_ZID_SET) {
+ snprintf(client_uid_string + slen,
+ sizeof(client_uid_string) - slen,
+ "zoneid=%ld ", (long) lcc->zoneid);
+ slen = strlen(client_uid_string);
+ }
+
+ snprintf(client_uid_string + slen, sizeof(client_uid_string) - slen, ")");
+ FreeLocalClientCreds(lcc);
+ }
+ else {
+ client_uid_string[0] = '\0';
+ }
+
+ if (proto_n)
+ AuditF("client %d %s from %s%s\n Auth name: %.*s ID: %d\n",
+ client->index, letin ? "connected" : "rejected", addr,
+ client_uid_string, (int)proto_n, auth_proto, auth_id);
+ else
+ AuditF("client %d %s from %s%s\n",
+ client->index, letin ? "connected" : "rejected", addr,
+ client_uid_string);
+}
+
+XID
+AuthorizationIDOfClient(ClientPtr client)
+{
+ if (client->osPrivate)
+ return ((OsCommPtr)client->osPrivate)->auth_id;
+ else
+ return None;
+}
+
+
+/*****************************************************************
+ * ClientAuthorized
+ *
+ * Sent by the client at connection setup:
+ * typedef struct _xConnClientPrefix {
+ * CARD8 byteOrder;
+ * BYTE pad;
+ * CARD16 majorVersion, minorVersion;
+ * CARD16 nbytesAuthProto;
+ * CARD16 nbytesAuthString;
+ * } xConnClientPrefix;
+ *
+ * It is hoped that eventually one protocol will be agreed upon. In the
+ * mean time, a server that implements a different protocol than the
+ * client expects, or a server that only implements the host-based
+ * mechanism, will simply ignore this information.
+ *
+ *****************************************************************/
+
+char *
+ClientAuthorized(ClientPtr client,
+ unsigned int proto_n, char *auth_proto,
+ unsigned int string_n, char *auth_string)
+{
+ OsCommPtr priv;
+ Xtransaddr *from = NULL;
+ int family;
+ int fromlen;
+ XID auth_id;
+ char *reason = NULL;
+ XtransConnInfo trans_conn;
+
+ priv = (OsCommPtr)client->osPrivate;
+ trans_conn = priv->trans_conn;
+
+ auth_id = CheckAuthorization (proto_n, auth_proto,
+ string_n, auth_string, client, &reason);
+
+ if (auth_id == (XID) ~0L)
+ {
+ if (
+#ifdef XCSECURITY
+ (proto_n == 0 ||
+ strncmp (auth_proto, XSecurityAuthorizationName, proto_n) != 0) &&
+#endif
+ _XSERVTransGetPeerAddr (trans_conn,
+ &family, &fromlen, &from) != -1)
+ {
+ if (
+ InvalidHost ((struct sockaddr *) from, fromlen, client))
+ AuthAudit(client, FALSE, (struct sockaddr *) from,
+ fromlen, proto_n, auth_proto, auth_id);
+ else
+ {
+ auth_id = (XID) 0;
+ if (auditTrailLevel > 1)
+ AuthAudit(client, TRUE,
+ (struct sockaddr *) from, fromlen,
+ proto_n, auth_proto, auth_id);
+ }
+
+ free ((char *) from);
+ }
+
+ if (auth_id == (XID) ~0L) {
+ if (reason)
+ return reason;
+ else
+ return "Client is not authorized to connect to Server";
+ }
+ }
+ else if (auditTrailLevel > 1)
+ {
+ if (_XSERVTransGetPeerAddr (trans_conn,
+ &family, &fromlen, &from) != -1)
+ {
+ AuthAudit(client, TRUE, (struct sockaddr *) from, fromlen,
+ proto_n, auth_proto, auth_id);
+
+ free ((char *) from);
+ }
+ }
+ priv->auth_id = auth_id;
+ priv->conn_time = 0;
+
+#ifdef XDMCP
+ /* indicate to Xdmcp protocol that we've opened new client */
+ XdmcpOpenDisplay(priv->fd);
+#endif /* XDMCP */
+ /* At this point, if the client is authorized to change the access control
+ * list, we should getpeername() information, and add the client to
+ * the selfhosts list. It's not really the host machine, but the
+ * true purpose of the selfhosts list is to see who may change the
+ * access control list.
+ */
+ return((char *)NULL);
+}
+
+static ClientPtr
+AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
+{
+ OsCommPtr oc;
+ ClientPtr client;
+
+ if (
+#ifndef WIN32
+ fd >= lastfdesc
+#else
+ XFD_SETCOUNT(&AllClients) >= MaxClients
+#endif
+ )
+ return NullClient;
+ oc = (OsCommPtr)malloc(sizeof(OsCommRec));
+ if (!oc)
+ return NullClient;
+ oc->trans_conn = trans_conn;
+ oc->fd = fd;
+ oc->input = (ConnectionInputPtr)NULL;
+ oc->output = (ConnectionOutputPtr)NULL;
+ oc->auth_id = None;
+ oc->conn_time = conn_time;
+ if (!(client = NextAvailableClient((void *)oc)))
+ {
+ free (oc);
+ return NullClient;
+ }
+ client->local = ComputeLocalClient(client);
+ {
+#if !defined(WIN32)
+ ConnectionTranslation[fd] = client->index;
+#else
+ SetConnectionTranslation(fd, client->index);
+#endif
+ if (GrabInProgress)
+ {
+ FD_SET(fd, &SavedAllClients);
+ FD_SET(fd, &SavedAllSockets);
+ }
+ else
+ {
+ FD_SET(fd, &AllClients);
+ FD_SET(fd, &AllSockets);
+ }
+ }
+
+#ifdef DEBUG
+ ErrorF("AllocNewConnection: client index = %d, socket fd = %d\n",
+ client->index, fd);
+#endif
+
+ return client;
+}
+
+/*****************
+ * EstablishNewConnections
+ * If anyone is waiting on listened sockets, accept them.
+ * Returns a mask with indices of new clients. Updates AllClients
+ * and AllSockets.
+ *****************/
+
+static Bool
+EstablishNewConnections(ClientPtr clientUnused, void * closure)
+{
+ int curconn = (int) (intptr_t) closure;
+ int newconn; /* fd of new client */
+ CARD32 connect_time;
+ int i;
+ ClientPtr client;
+ OsCommPtr oc;
+ XtransConnInfo trans_conn, new_trans_conn;
+ int status;
+
+ connect_time = GetTimeInMillis();
+ /* kill off stragglers */
+ for (i=1; i<currentMaxClients; i++)
+ {
+ if ((client = clients[i]))
+ {
+ oc = (OsCommPtr)(client->osPrivate);
+ if ((oc && (oc->conn_time != 0) &&
+ (connect_time - oc->conn_time) >= TimeOutValue) ||
+ (client->noClientException != Success && !client->clientGone))
+ CloseDownClient(client);
+ }
+ }
+ if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
+ return TRUE;
+
+ if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
+ return TRUE;
+
+ newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
+
+ if (newconn < lastfdesc) {
+ int clientid;
+
+#if !defined(WIN32)
+ clientid = ConnectionTranslation[newconn];
+#else
+ clientid = GetConnectionTranslation(newconn);
+#endif
+ if (clientid && (client = clients[clientid]))
+ CloseDownClient(client);
+ }
+
+ _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
+
+ if (trans_conn->flags & TRANS_NOXAUTH)
+ new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
+
+ if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
+ ErrorConnMax(new_trans_conn);
+ }
+
+ return TRUE;
+}
+
+static void
+QueueNewConnections(int fd, int ready, void *data)
+{
+ QueueWorkProc(EstablishNewConnections, NULL, (void *) (intptr_t) fd);
+}
+
+#define NOROOM "Maximum number of clients reached"
+
+/************
+ * ErrorConnMax
+ * Fail a connection due to lack of client or file descriptor space
+ ************/
+
+static void
+ConnMaxNotify(int fd, int events, void *data)
+{
+ XtransConnInfo trans_conn = data;
+ char order = 0;
+
+ /* try to read the byte-order of the connection */
+ (void)_XSERVTransRead(trans_conn, &order, 1);
+ if (order == 'l' || order == 'B' || order == 'r' || order == 'R')
+ {
+
+ xConnSetupPrefix csp;
+ char pad[3] = { 0, 0, 0 };
+ int whichbyte = 1;
+ struct iovec iov[3];
+
+ csp.success = xFalse;
+ csp.lengthReason = sizeof(NOROOM) - 1;
+ csp.length = (sizeof(NOROOM) + 2) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
+ {
+ swaps(&csp.majorVersion);
+ swaps(&csp.minorVersion);
+ swaps(&csp.length);
+ }
+ iov[0].iov_len = sz_xConnSetupPrefix;
+ iov[0].iov_base = (char *) &csp;
+ iov[1].iov_len = csp.lengthReason;
+ iov[1].iov_base = NOROOM;
+ iov[2].iov_len = (4 - (csp.lengthReason & 3)) & 3;
+ iov[2].iov_base = pad;
+ (void)_XSERVTransWritev(trans_conn, iov, 3);
+ }
+ RemoveNotifyFd(trans_conn->fd);
+ _XSERVTransClose(trans_conn);
+}
+
+static void
+ErrorConnMax(XtransConnInfo trans_conn)
+{
+ if (!SetNotifyFd(trans_conn->fd, ConnMaxNotify, X_NOTIFY_READ, trans_conn))
+ _XSERVTransClose(trans_conn);
+}
+
+/************
+ * CloseDownFileDescriptor:
+ * Remove this file descriptor and it's I/O buffers, etc.
+ ************/
+
+static void
+CloseDownFileDescriptor(OsCommPtr oc)
+{
+ int connection = oc->fd;
+
+ if (oc->trans_conn) {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ }
+ FreeOsBuffers(oc);
+ free(oc);
+#ifndef WIN32
+ ConnectionTranslation[connection] = 0;
+#else
+ SetConnectionTranslation(connection, 0);
+#endif
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ FD_CLR(connection, &ClientsWithInput);
+ FD_CLR(connection, &GrabImperviousClients);
+ if (GrabInProgress)
+ {
+ FD_CLR(connection, &SavedAllSockets);
+ FD_CLR(connection, &SavedAllClients);
+ FD_CLR(connection, &SavedClientsWithInput);
+ }
+ FD_CLR(connection, &ClientsWriteBlocked);
+ if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+ AnyWritesPending = FALSE;
+ FD_CLR(connection, &OutputPending);
+}
+
+/*****************
+ * CheckConnections
+ * Some connection has died, go find which one and shut it down
+ * The file descriptor has been closed, but is still in AllClients.
+ * If would truly be wonderful if select() would put the bogus
+ * file descriptors in the exception mask, but nooooo. So we have
+ * to check each and every socket individually.
+ *****************/
+
+void
+CheckConnections(void)
+{
+#ifndef WIN32
+ fd_mask mask;
+#endif
+ fd_set tmask;
+ int curclient, curoff;
+ int i;
+ struct timeval notime;
+ int r;
+#ifdef WIN32
+ fd_set savedAllClients;
+#endif
+
+ notime.tv_sec = 0;
+ notime.tv_usec = 0;
+
+#ifndef WIN32
+ for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
+ {
+ mask = AllClients.fds_bits[i];
+ while (mask)
+ {
+ curoff = ffs (mask) - 1;
+ curclient = curoff + (i * (sizeof(fd_mask)*8));
+ FD_ZERO(&tmask);
+ FD_SET(curclient, &tmask);
+ r = Select (curclient + 1, &tmask, NULL, NULL, &notime);
+ if (r < 0)
+ CloseDownClient(clients[ConnectionTranslation[curclient]]);
+ mask &= ~((fd_mask)1 << curoff);
+ }
+ }
+#else
+ XFD_COPYSET(&AllClients, &savedAllClients);
+ for (i = 0; i < XFD_SETCOUNT(&savedAllClients); i++)
+ {
+ curclient = XFD_FD(&savedAllClients, i);
+ FD_ZERO(&tmask);
+ FD_SET(curclient, &tmask);
+ r = Select (curclient + 1, &tmask, NULL, NULL, &notime);
+ if (r < 0)
+ CloseDownClient(clients[GetConnectionTranslation(curclient)]);
+ }
+#endif
+}
+
+
+/*****************
+ * CloseDownConnection
+ * Delete client from AllClients and free resources
+ *****************/
+
+void
+CloseDownConnection(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+
+ if (FlushCallback)
+ CallCallbacks(&FlushCallback, client);
+
+ if (oc->output && oc->output->count)
+ FlushClient(client, oc, (char *)NULL, 0);
+#ifdef XDMCP
+ XdmcpCloseDisplay(oc->fd);
+#endif
+ CloseDownFileDescriptor(oc);
+ client->osPrivate = (void *)NULL;
+ if (auditTrailLevel > 1)
+ AuditF("client %d disconnected\n", client->index);
+}
+
+struct notify_fd {
+ struct xorg_list list;
+ int fd;
+ int mask;
+ NotifyFdProcPtr notify;
+ void *data;
+};
+
+static struct xorg_list notify_fds;
+
+void
+InitNotifyFds(void)
+{
+ struct notify_fd *s, *next;
+ static int been_here;
+
+ if (been_here)
+ xorg_list_for_each_entry_safe(s, next, &notify_fds, list)
+ RemoveNotifyFd(s->fd);
+
+ xorg_list_init(&notify_fds);
+ NumNotifyWriteFd = 0;
+ been_here = 1;
+}
+
+/*****************
+ * SetNotifyFd
+ * Registers a callback to be invoked when the specified
+ * file descriptor becomes readable.
+ *****************/
+
+Bool
+SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
+{
+ struct notify_fd *n;
+ int changes;
+
+ xorg_list_for_each_entry(n, &notify_fds, list)
+ if (n->fd == fd)
+ break;
+
+ if (&n->list == &notify_fds) {
+ if (mask == 0)
+ return TRUE;
+
+ n = calloc(1, sizeof (struct notify_fd));
+ if (!n)
+ return FALSE;
+ n->fd = fd;
+ xorg_list_add(&n->list, &notify_fds);
+ }
+
+ changes = n->mask ^ mask;
+
+ if (changes & X_NOTIFY_READ) {
+ if (mask & X_NOTIFY_READ) {
+ FD_SET(fd, &NotifyReadFds);
+ FD_SET(fd, &AllSockets);
+ if (GrabInProgress)
+ FD_SET(fd, &SavedAllSockets);
+ } else {
+ FD_CLR(fd, &AllSockets);
+ if (GrabInProgress)
+ FD_CLR(fd, &SavedAllSockets);
+ FD_CLR(fd, &NotifyReadFds);
+ }
+ }
+
+ if (changes & X_NOTIFY_WRITE) {
+ if (mask & X_NOTIFY_WRITE) {
+ FD_SET(fd, &NotifyWriteFds);
+ if (!NumNotifyWriteFd++)
+ AnyWritesPending = TRUE;
+ } else {
+ FD_CLR(fd, &NotifyWriteFds);
+ if (!--NumNotifyWriteFd)
+ if (!XFD_ANYSET(&ClientsWriteBlocked))
+ AnyWritesPending = FALSE;
+ }
+ }
+
+ if (mask == 0) {
+ xorg_list_del(&n->list);
+ free(n);
+ } else {
+ n->mask = mask;
+ n->data = data;
+ n->notify = notify;
+ }
+
+ return TRUE;
+}
+
+/*****************
+ * HandlNotifyFds
+ * A WorkProc to be called when any of the registered
+ * file descriptors are readable.
+ *****************/
+
+void
+HandleNotifyFds(void)
+{
+ struct notify_fd *n, *next;
+
+ xorg_list_for_each_entry_safe(n, next, &notify_fds, list) {
+ int ready = 0;
+ if ((n->mask & X_NOTIFY_READ) && FD_ISSET(n->fd, &LastSelectMask))
+ ready |= X_NOTIFY_READ;
+ if ((n->mask & X_NOTIFY_WRITE) & FD_ISSET(n->fd, &LastSelectWriteMask))
+ ready |= X_NOTIFY_WRITE;
+ if (ready != 0)
+ n->notify(n->fd, ready, n->data);
+ }
+}
+
+/*****************
+ * OnlyListenToOneClient:
+ * Only accept requests from one client. Continue to handle new
+ * connections, but don't take any protocol requests from the new
+ * ones. Note that if GrabInProgress is set, EstablishNewConnections
+ * needs to put new clients into SavedAllSockets and SavedAllClients.
+ * Note also that there is no timeout for this in the protocol.
+ * This routine is "undone" by ListenToAllClients()
+ *****************/
+
+void
+OnlyListenToOneClient(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ if (! GrabInProgress)
+ {
+ XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput);
+ XFD_ANDSET(&ClientsWithInput,
+ &ClientsWithInput, &GrabImperviousClients);
+ if (FD_ISSET(connection, &SavedClientsWithInput))
+ {
+ FD_CLR(connection, &SavedClientsWithInput);
+ FD_SET(connection, &ClientsWithInput);
+ }
+ XFD_UNSET(&SavedClientsWithInput, &GrabImperviousClients);
+ XFD_COPYSET(&AllSockets, &SavedAllSockets);
+ XFD_COPYSET(&AllClients, &SavedAllClients);
+ XFD_UNSET(&AllSockets, &AllClients);
+ XFD_ANDSET(&AllClients, &AllClients, &GrabImperviousClients);
+ FD_SET(connection, &AllClients);
+ XFD_ORSET(&AllSockets, &AllSockets, &AllClients);
+ GrabInProgress = client->index;
+ }
+}
+
+/****************
+ * ListenToAllClients:
+ * Undoes OnlyListentToOneClient()
+ ****************/
+
+void
+ListenToAllClients(void)
+{
+ if (GrabInProgress)
+ {
+ XFD_ORSET(&AllSockets, &AllSockets, &SavedAllSockets);
+ XFD_ORSET(&AllClients, &AllClients, &SavedAllClients);
+ XFD_ORSET(&ClientsWithInput, &ClientsWithInput, &SavedClientsWithInput);
+ GrabInProgress = 0;
+ }
+}
+
+/****************
+ * IgnoreClient
+ * Removes one client from input masks.
+ * Must have cooresponding call to AttendClient.
+ ****************/
+
+void
+IgnoreClient (ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ isItTimeToYield = TRUE;
+ if (!GrabInProgress || FD_ISSET(connection, &AllClients))
+ {
+ if (FD_ISSET (connection, &ClientsWithInput))
+ FD_SET(connection, &IgnoredClientsWithInput);
+ else
+ FD_CLR(connection, &IgnoredClientsWithInput);
+ FD_CLR(connection, &ClientsWithInput);
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ FD_CLR(connection, &LastSelectMask);
+ }
+ else
+ {
+ if (FD_ISSET (connection, &SavedClientsWithInput))
+ FD_SET(connection, &IgnoredClientsWithInput);
+ else
+ FD_CLR(connection, &IgnoredClientsWithInput);
+ FD_CLR(connection, &SavedClientsWithInput);
+ FD_CLR(connection, &SavedAllSockets);
+ FD_CLR(connection, &SavedAllClients);
+ }
+}
+
+/****************
+ * AttendClient
+ * Adds one client back into the input masks.
+ ****************/
+
+void
+AttendClient (ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+ if (!GrabInProgress || GrabInProgress == client->index ||
+ FD_ISSET(connection, &GrabImperviousClients))
+ {
+ FD_SET(connection, &AllClients);
+ FD_SET(connection, &AllSockets);
+ FD_SET(connection, &LastSelectMask);
+ if (FD_ISSET (connection, &IgnoredClientsWithInput))
+ FD_SET(connection, &ClientsWithInput);
+ }
+ else
+ {
+ FD_SET(connection, &SavedAllClients);
+ FD_SET(connection, &SavedAllSockets);
+ if (FD_ISSET(connection, &IgnoredClientsWithInput))
+ FD_SET(connection, &SavedClientsWithInput);
+ }
+}
+
+/* make client impervious to grabs; assume only executing client calls this */
+
+void
+MakeClientGrabImpervious(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ FD_SET(connection, &GrabImperviousClients);
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = CLIENT_IMPERVIOUS;
+ CallCallbacks(&ServerGrabCallback, &grabinfo);
+ }
+}
+
+/* make client pervious to grabs; assume only executing client calls this */
+
+void
+MakeClientGrabPervious(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ FD_CLR(connection, &GrabImperviousClients);
+ if (GrabInProgress && (GrabInProgress != client->index))
+ {
+ if (FD_ISSET(connection, &ClientsWithInput))
+ {
+ FD_SET(connection, &SavedClientsWithInput);
+ FD_CLR(connection, &ClientsWithInput);
+ }
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ isItTimeToYield = TRUE;
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = CLIENT_PERVIOUS;
+ CallCallbacks(&ServerGrabCallback, &grabinfo);
+ }
+}
+
diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c
new file mode 100644
index 000000000..07399438e
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/io.c
@@ -0,0 +1,1293 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+
+******************************************************************/
+/*****************************************************************
+ * i/o functions
+ *
+ * WriteToClient, ReadRequestFromClient
+ * InsertFakeRequest, ResetCurrentRequest
+ *
+ *****************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#if 0
+#define DEBUG_COMMUNICATION
+#endif
+#ifdef WIN32
+#include <nx-X11/Xwinsock.h>
+#endif
+#include <stdio.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#include <nx-X11/Xmd.h>
+#include <errno.h>
+#if !defined(WIN32)
+#include <sys/uio.h>
+#endif
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "os.h"
+#include "osdep.h"
+#include <nx-X11/Xpoll.h>
+#include "opaque.h"
+#include "dixstruct.h"
+#include "misc.h"
+
+CallbackListPtr ReplyCallback;
+CallbackListPtr FlushCallback;
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifndef WIN32
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST(err) (err == EAGAIN)
+#else
+#define ETEST(err) (err == EWOULDBLOCK)
+#endif
+#endif
+#else /* WIN32 The socket errorcodes differ from the normal errors*/
+#define ETEST(err) (err == EAGAIN || err == WSAEWOULDBLOCK)
+#endif
+
+Bool CriticalOutputPending;
+int timesThisConnection = 0;
+ConnectionInputPtr FreeInputs = (ConnectionInputPtr)NULL;
+ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr)NULL;
+OsCommPtr AvailableInput = (OsCommPtr)NULL;
+
+#define get_req_len(req,cli) ((cli)->swapped ? \
+ lswaps((req)->length) : (req)->length)
+
+#ifdef BIGREQS
+#include <nx-X11/extensions/bigreqstr.h>
+
+#define get_big_req_len(req,cli) ((cli)->swapped ? \
+ lswapl(((xBigReq *)(req))->length) : \
+ ((xBigReq *)(req))->length)
+#endif
+
+#define MAX_TIMES_PER 10
+
+/*
+ * A lot of the code in this file manipulates a ConnectionInputPtr:
+ *
+ * -----------------------------------------------
+ * |------- bufcnt ------->| | |
+ * | |- gotnow ->| | |
+ * | |-------- needed ------>| |
+ * |-----------+--------- size --------+---------->|
+ * -----------------------------------------------
+ * ^ ^
+ * | |
+ * buffer bufptr
+ *
+ * buffer is a pointer to the start of the buffer.
+ * bufptr points to the start of the current request.
+ * bufcnt counts how many bytes are in the buffer.
+ * size is the size of the buffer in bytes.
+ *
+ * In several of the functions, gotnow and needed are local variables
+ * that do the following:
+ *
+ * gotnow is the number of bytes of the request that we're
+ * trying to read that are currently in the buffer.
+ * Typically, gotnow = (buffer + bufcnt) - bufptr
+ *
+ * needed = the length of the request that we're trying to
+ * read. Watch out: needed sometimes counts bytes and sometimes
+ * counts CARD32's.
+ */
+
+
+/*****************************************************************
+ * ReadRequestFromClient
+ * Returns one request in client->requestBuffer. The request
+ * length will be in client->req_len. Return status is:
+ *
+ * > 0 if successful, specifies length in bytes of the request
+ * = 0 if entire request is not yet available
+ * < 0 if client should be terminated
+ *
+ * The request returned must be contiguous so that it can be
+ * cast in the dispatcher to the correct request type. Because requests
+ * are variable length, ReadRequestFromClient() must look at the first 4
+ * or 8 bytes of a request to determine the length (the request length is
+ * in the 3rd and 4th bytes of the request unless it is a Big Request
+ * (see the Big Request Extension), in which case the 3rd and 4th bytes
+ * are zero and the following 4 bytes are the request length.
+ *
+ * Note: in order to make the server scheduler (WaitForSomething())
+ * "fair", the ClientsWithInput mask is used. This mask tells which
+ * clients have FULL requests left in their buffers. Clients with
+ * partial requests require a read. Basically, client buffers
+ * are drained before select() is called again. But, we can't keep
+ * reading from a client that is sending buckets of data (or has
+ * a partial request) because others clients need to be scheduled.
+ *****************************************************************/
+
+#define YieldControl() \
+ { isItTimeToYield = TRUE; \
+ timesThisConnection = 0; }
+#define YieldControlNoInput() \
+ { YieldControl(); \
+ FD_CLR(fd, &ClientsWithInput); }
+#define YieldControlDeath() \
+ { timesThisConnection = 0; }
+
+int
+ReadRequestFromClient(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ unsigned int gotnow, needed;
+ int result;
+ register xReq *request;
+ Bool need_header;
+#ifdef BIGREQS
+ Bool move_header;
+#endif
+
+ /* If an input buffer was empty, either free it if it is too big
+ * or link it into our list of free input buffers. This means that
+ * different clients can share the same input buffer (at different
+ * times). This was done to save memory.
+ */
+
+ if (AvailableInput)
+ {
+ if (AvailableInput != oc)
+ {
+ register ConnectionInputPtr aci = AvailableInput->input;
+ if (aci->size > BUFWATERMARK)
+ {
+ free(aci->buffer);
+ free(aci);
+ }
+ else
+ {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr)NULL;
+ }
+ AvailableInput = (OsCommPtr)NULL;
+ }
+
+ /* make sure we have an input buffer */
+
+ if (!oci)
+ {
+ if ((oci = FreeInputs))
+ {
+ FreeInputs = oci->next;
+ }
+ else if (!(oci = AllocateInputBuffer()))
+ {
+ YieldControlDeath();
+ return -1;
+ }
+ oc->input = oci;
+ }
+
+ /* advance to start of next request */
+
+ oci->bufptr += oci->lenLastReq;
+
+ need_header = FALSE;
+#ifdef BIGREQS
+ move_header = FALSE;
+#endif
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+
+ if (oci->ignoreBytes > 0) {
+ if (oci->ignoreBytes > oci->size)
+ needed = oci->size;
+ else
+ needed = oci->ignoreBytes;
+ }
+ else if (gotnow < sizeof(xReq))
+ {
+ /* We don't have an entire xReq yet. Can't tell how big
+ * the request will be until we get the whole xReq.
+ */
+ needed = sizeof(xReq);
+ need_header = TRUE;
+ }
+ else
+ {
+ /* We have a whole xReq. We can tell how big the whole
+ * request will be unless it is a Big Request.
+ */
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ /* It's a Big Request. */
+ move_header = TRUE;
+ if (gotnow < sizeof(xBigReq))
+ {
+ /* Still need more data to tell just how big. */
+ needed = sizeof(xBigReq) >> 2; /* needed is in CARD32s now */
+ need_header = TRUE;
+ }
+ else
+ needed = get_big_req_len(request, client);
+ }
+#endif
+ client->req_len = needed;
+ needed <<= 2; /* needed is in bytes now */
+ }
+ if (gotnow < needed)
+ {
+ /* Need to read more data, either so that we can get a
+ * complete xReq (if need_header is TRUE), a complete
+ * xBigReq (if move_header is TRUE), or the rest of the
+ * request (if need_header and move_header are both FALSE).
+ */
+
+ oci->lenLastReq = 0;
+ if (needed > MAXBUFSIZE)
+ {
+ /* request is too big for us to handle */
+ /*
+ * Mark the rest of it as needing to be ignored, and then return
+ * the full size. Dispatch() will turn it into a BadLength error.
+ */
+ oci->ignoreBytes = needed - gotnow;
+ oci->lenLastReq = gotnow;
+ return needed;
+ }
+ if ((gotnow == 0) ||
+ ((oci->bufptr - oci->buffer + needed) > oci->size))
+ {
+ /* no data, or the request is too big to fit in the buffer */
+
+ if ((gotnow > 0) && (oci->bufptr != oci->buffer))
+ /* save the data we've already read */
+ memmove(oci->buffer, oci->bufptr, gotnow);
+ if (needed > oci->size)
+ {
+ /* make buffer bigger to accomodate request */
+ char *ibuf;
+
+ ibuf = (char *)realloc(oci->buffer, needed);
+ if (!ibuf)
+ {
+ YieldControlDeath();
+ return -1;
+ }
+ oci->size = needed;
+ oci->buffer = ibuf;
+ }
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = gotnow;
+ }
+ /* XXX this is a workaround. This function is sometimes called
+ * after the trans_conn has been freed. In this case trans_conn
+ * will be null. Really ought to restructure things so that we
+ * never get here in those circumstances.
+ */
+ if (!oc->trans_conn)
+ {
+ /* treat as if an error occured on the read, which is what
+ * used to happen
+ */
+ YieldControlDeath();
+ return -1;
+ }
+ result = _XSERVTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
+ oci->size - oci->bufcnt);
+ if (result <= 0)
+ {
+ if ((result < 0) && ETEST(errno))
+ {
+#if defined(SVR4) && defined(i386) && !defined(sun)
+ if (0)
+#endif
+ {
+ YieldControlNoInput();
+ return 0;
+ }
+ }
+ YieldControlDeath();
+ return -1;
+ }
+ oci->bufcnt += result;
+ gotnow += result;
+ /* free up some space after huge requests */
+ if ((oci->size > BUFWATERMARK) &&
+ (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE))
+ {
+ char *ibuf;
+
+ ibuf = (char *)realloc(oci->buffer, BUFSIZE);
+ if (ibuf)
+ {
+ oci->size = BUFSIZE;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ }
+ if (need_header && gotnow >= needed)
+ {
+ /* We wanted an xReq, now we've gotten it. */
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ move_header = TRUE;
+ if (gotnow < sizeof(xBigReq))
+ needed = sizeof(xBigReq) >> 2;
+ else
+ needed = get_big_req_len(request, client);
+ }
+#endif
+ client->req_len = needed;
+ needed <<= 2;
+ }
+ if (gotnow < needed)
+ {
+ /* Still don't have enough; punt. */
+ YieldControlNoInput();
+ return 0;
+ }
+ }
+ if (needed == 0)
+ {
+#ifdef BIGREQS
+ if (client->big_requests)
+ needed = sizeof(xBigReq);
+ else
+#endif
+ needed = sizeof(xReq);
+ }
+
+ /* If there are bytes to ignore, ignore them now. */
+
+ if (oci->ignoreBytes > 0) {
+ assert(needed == oci->ignoreBytes || needed == oci->size);
+ oci->ignoreBytes -= gotnow;
+ needed = gotnow = 0;
+ /*
+ * The _XSERVTransRead call above may return more or fewer bytes than we
+ * want to ignore. Ignore the smaller of the two sizes.
+ */
+ if (gotnow < needed) {
+ oci->ignoreBytes -= gotnow;
+ oci->bufptr += gotnow;
+ gotnow = 0;
+ } else {
+ oci->ignoreBytes -= needed;
+ oci->bufptr += needed;
+ gotnow -= needed;
+ }
+ needed = 0;
+ }
+
+ oci->lenLastReq = needed;
+
+ /*
+ * Check to see if client has at least one whole request in the
+ * buffer beyond the request we're returning to the caller.
+ * If there is only a partial request, treat like buffer
+ * is empty so that select() will be called again and other clients
+ * can get into the queue.
+ */
+
+ gotnow -= needed;
+ if (gotnow >= sizeof(xReq))
+ {
+ request = (xReq *)(oci->bufptr + needed);
+ if (gotnow >= (result = (get_req_len(request, client) << 2))
+#ifdef BIGREQS
+ && (result ||
+ (client->big_requests &&
+ (gotnow >= sizeof(xBigReq) &&
+ gotnow >= (get_big_req_len(request, client) << 2))))
+#endif
+ )
+ FD_SET(fd, &ClientsWithInput);
+ else
+ {
+ FD_CLR(fd, &ClientsWithInput);
+ }
+ }
+ else
+ {
+ if (!gotnow)
+ AvailableInput = oc;
+ FD_CLR(fd, &ClientsWithInput);
+ }
+#ifdef BIGREQS
+ if (move_header)
+ {
+ request = (xReq *)oci->bufptr;
+ oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));
+ *(xReq *)oci->bufptr = *request;
+ oci->lenLastReq -= (sizeof(xBigReq) - sizeof(xReq));
+ client->req_len -= (sizeof(xBigReq) - sizeof(xReq)) >> 2;
+ }
+#endif
+ client->requestBuffer = (void *)oci->bufptr;
+#ifdef DEBUG_COMMUNICATION
+ {
+ xReq *req = client->requestBuffer;
+ ErrorF("REQUEST: ClientIDX: %i, type: 0x%x data: 0x%x len: %i\n",
+ client->index,req->reqType,req->data,req->length);
+ }
+#endif
+ return needed;
+}
+
+/*****************************************************************
+ * InsertFakeRequest
+ * Splice a consed up (possibly partial) request in as the next request.
+ *
+ **********************/
+
+Bool
+InsertFakeRequest(ClientPtr client, char *data, int count)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ int gotnow, moveup;
+
+ if (AvailableInput)
+ {
+ if (AvailableInput != oc)
+ {
+ ConnectionInputPtr aci = AvailableInput->input;
+ if (aci->size > BUFWATERMARK)
+ {
+ free(aci->buffer);
+ free(aci);
+ }
+ else
+ {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr)NULL;
+ }
+ AvailableInput = (OsCommPtr)NULL;
+ }
+ if (!oci)
+ {
+ if ((oci = FreeInputs))
+ FreeInputs = oci->next;
+ else if (!(oci = AllocateInputBuffer()))
+ return FALSE;
+ oc->input = oci;
+ }
+ oci->bufptr += oci->lenLastReq;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if ((gotnow + count) > oci->size)
+ {
+ char *ibuf;
+
+ ibuf = (char *)realloc(oci->buffer, gotnow + count);
+ if (!ibuf)
+ return(FALSE);
+ oci->size = gotnow + count;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ moveup = count - (oci->bufptr - oci->buffer);
+ if (moveup > 0)
+ {
+ if (gotnow > 0)
+ memmove(oci->bufptr + moveup, oci->bufptr, gotnow);
+ oci->bufptr += moveup;
+ oci->bufcnt += moveup;
+ }
+ memmove(oci->bufptr - count, data, count);
+ oci->bufptr -= count;
+ gotnow += count;
+ if ((gotnow >= sizeof(xReq)) &&
+ (gotnow >= (int)(get_req_len((xReq *)oci->bufptr, client) << 2)))
+ FD_SET(fd, &ClientsWithInput);
+ else
+ YieldControlNoInput();
+ return(TRUE);
+}
+
+/*****************************************************************
+ * ResetRequestFromClient
+ * Reset to reexecute the current request, and yield.
+ *
+ **********************/
+
+void
+ResetCurrentRequest(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ register xReq *request;
+ int gotnow, needed;
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr)NULL;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if (gotnow < sizeof(xReq))
+ {
+ YieldControlNoInput();
+ }
+ else
+ {
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ oci->bufptr -= sizeof(xBigReq) - sizeof(xReq);
+ *(xReq *)oci->bufptr = *request;
+ ((xBigReq *)oci->bufptr)->length = client->req_len;
+ if (client->swapped)
+ {
+ swapl(&((xBigReq *)oci->bufptr)->length);
+ }
+ }
+#endif
+ if (gotnow >= (needed << 2))
+ {
+ if (FD_ISSET(fd, &AllClients))
+ {
+ FD_SET(fd, &ClientsWithInput);
+ }
+ else
+ {
+ FD_SET(fd, &IgnoredClientsWithInput);
+ }
+ YieldControl();
+ }
+ else
+ YieldControlNoInput();
+ }
+}
+
+
+
+/*****************************************************************
+ * PeekNextRequest and SkipRequests were implemented to support DBE
+ * idioms, but can certainly be used outside of DBE. There are two
+ * related macros in os.h, ReqLen and CastxReq. See the porting
+ * layer document for more details.
+ *
+ **********************/
+
+
+/*****************************************************************
+ * PeekNextRequest
+ * lets you look ahead at the unexecuted requests in a
+ * client's request buffer.
+ *
+ * Note: this implementation of PeekNextRequest ignores the
+ * readmore parameter.
+ *
+ **********************/
+
+xReqPtr
+PeekNextRequest(
+ xReqPtr req, /* request we're starting from */
+ ClientPtr client, /* client whose requests we're skipping */
+ Bool readmore) /* attempt to read more if next request isn't there? */
+{
+ register ConnectionInputPtr oci = ((OsCommPtr)client->osPrivate)->input;
+ xReqPtr pnextreq;
+ int needed, gotnow, reqlen;
+
+ if (!oci) return NULL;
+
+ if (!req)
+ {
+ /* caller wants the request after the one currently being executed */
+ pnextreq = (xReqPtr)
+ (((CARD32 *)client->requestBuffer) + client->req_len);
+ }
+ else
+ {
+ /* caller wants the request after the one specified by req */
+ reqlen = get_req_len(req, client);
+#ifdef BIGREQS
+ if (!reqlen) reqlen = get_big_req_len(req, client);
+#endif
+ pnextreq = (xReqPtr)(((char *)req) + (reqlen << 2));
+ }
+
+ /* see how much of the next request we have available */
+
+ gotnow = oci->bufcnt - (((char *)pnextreq) - oci->buffer);
+
+ if (gotnow < sizeof(xReq))
+ return NULL;
+
+ needed = get_req_len(pnextreq, client) << 2;
+#ifdef BIGREQS
+ if (!needed)
+ {
+ /* it's a big request */
+ if (gotnow < sizeof(xBigReq))
+ return NULL;
+ needed = get_big_req_len(pnextreq, client) << 2;
+ }
+#endif
+
+ /* if we have less than we need, return NULL */
+
+ return (gotnow < needed) ? NULL : pnextreq;
+}
+
+/*****************************************************************
+ * SkipRequests
+ * lets you skip over some of the requests in a client's
+ * request buffer. Presumably the caller has used PeekNextRequest
+ * to examine the requests being skipped and has performed whatever
+ * actions they dictate.
+ *
+ **********************/
+
+CallbackListPtr SkippedRequestsCallback = NULL;
+
+void
+SkipRequests(
+ xReqPtr req, /* last request being skipped */
+ ClientPtr client, /* client whose requests we're skipping */
+ int numskipped) /* how many requests we're skipping */
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int reqlen;
+
+ /* see if anyone wants to snoop the skipped requests */
+
+ if (SkippedRequestsCallback)
+ {
+ SkippedRequestInfoRec skipinfo;
+ skipinfo.req = req;
+ skipinfo.client = client;
+ skipinfo.numskipped = numskipped;
+ CallCallbacks(&SkippedRequestsCallback, &skipinfo);
+ }
+
+ /* adjust the sequence number */
+ client->sequence += numskipped;
+
+ /* twiddle the oci to skip over the requests */
+
+ reqlen = get_req_len(req, client);
+#ifdef BIGREQS
+ if (!reqlen) reqlen = get_big_req_len(req, client);
+#endif
+ reqlen <<= 2;
+ oci->bufptr = (char *)req;
+ oci->lenLastReq = reqlen;
+
+ /* see if any requests left in the buffer */
+
+ if ( ((char *)req + reqlen) == (oci->buffer + oci->bufcnt) )
+ {
+ /* no requests; mark input buffer as available and client
+ * as having no input
+ */
+ int fd = oc->fd;
+ AvailableInput = oc;
+ YieldControlNoInput();
+ }
+}
+
+
+ /* lookup table for adding padding bytes to data that is read from
+ or written to the X socket. */
+static int padlength[4] = {0, 3, 2, 1};
+
+ /********************
+ * FlushAllOutput()
+ * Flush all clients with output. However, if some client still
+ * has input in the queue (more requests), then don't flush. This
+ * will prevent the output queue from being flushed every time around
+ * the round robin queue. Now, some say that it SHOULD be flushed
+ * every time around, but...
+ *
+ **********************/
+
+void
+FlushAllOutput(void)
+{
+ register int index, base;
+ register fd_mask mask; /* raphael */
+ OsCommPtr oc;
+ register ClientPtr client;
+ Bool newoutput = NewOutputPending;
+#if defined(WIN32)
+ fd_set newOutputPending;
+#endif
+
+ if (!newoutput)
+ return;
+
+ /*
+ * It may be that some client still has critical output pending,
+ * but he is not yet ready to receive it anyway, so we will
+ * simply wait for the select to tell us when he's ready to receive.
+ */
+ CriticalOutputPending = FALSE;
+ NewOutputPending = FALSE;
+
+#ifndef WIN32
+ for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++)
+ {
+ mask = OutputPending.fds_bits[ base ];
+ OutputPending.fds_bits[ base ] = 0;
+ while (mask)
+ {
+ index = ffs(mask) - 1;
+ mask &= ~lowbit(mask);
+ if ((index = ConnectionTranslation[(base * (sizeof(fd_mask)*8)) + index]) == 0)
+ continue;
+ client = clients[index];
+ if (client->clientGone)
+ continue;
+ oc = (OsCommPtr)client->osPrivate;
+ if (
+ FD_ISSET(oc->fd, &ClientsWithInput))
+ {
+ FD_SET(oc->fd, &OutputPending); /* set the bit again */
+ NewOutputPending = TRUE;
+ }
+ else
+ (void)FlushClient(client, oc, (char *)NULL, 0);
+ }
+ }
+#else /* WIN32 */
+ FD_ZERO(&newOutputPending);
+ for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++)
+ {
+ index = XFD_FD(&OutputPending, base);
+ if ((index = GetConnectionTranslation(index)) == 0)
+ continue;
+ client = clients[index];
+ if (client->clientGone)
+ continue;
+ oc = (OsCommPtr)client->osPrivate;
+ if (
+ FD_ISSET(oc->fd, &ClientsWithInput))
+ {
+ FD_SET(oc->fd, &newOutputPending); /* set the bit again */
+ NewOutputPending = TRUE;
+ }
+ else
+ (void)FlushClient(client, oc, (char *)NULL, 0);
+ }
+ XFD_COPYSET(&newOutputPending, &OutputPending);
+#endif /* WIN32 */
+}
+
+void
+FlushIfCriticalOutputPending(void)
+{
+ if (CriticalOutputPending)
+ FlushAllOutput();
+}
+
+void
+SetCriticalOutputPending(void)
+{
+ CriticalOutputPending = TRUE;
+}
+
+/*****************
+ * WriteToClient
+ * Copies buf into ClientPtr.buf if it fits (with padding), else
+ * flushes ClientPtr.buf and buf to client. As of this writing,
+ * every use of WriteToClient is cast to void, and the result
+ * is ignored. Potentially, this could be used by requests
+ * that are sending several chunks of data and want to break
+ * out of a loop on error. Thus, we will leave the type of
+ * this routine as int.
+ *****************/
+
+int
+WriteToClient (ClientPtr who, int count, const void *__buf)
+{
+ OsCommPtr oc;
+ ConnectionOutputPtr oco;
+ int padBytes;
+ const char *buf = __buf;
+#ifdef DEBUG_COMMUNICATION
+ Bool multicount = FALSE;
+#endif
+ if (!count || !who || who == serverClient || who->clientGone)
+ return(0);
+ oc = who->osPrivate;
+ oco = oc->output;
+#ifdef DEBUG_COMMUNICATION
+ {
+ char info[128];
+ xError *err;
+ xGenericReply *rep;
+ xEvent *ev;
+
+ if (!who->replyBytesRemaining) {
+ switch(buf[0]) {
+ case X_Reply:
+ rep = (xGenericReply*)buf;
+ if (rep->sequenceNumber == who->sequence) {
+ snprintf(info,127,"Xreply: type: 0x%x data: 0x%x "
+ "len: %i seq#: 0x%x", rep->type, rep->data1,
+ rep->length, rep->sequenceNumber);
+ multicount = TRUE;
+ }
+ break;
+ case X_Error:
+ err = (xError*)buf;
+ snprintf(info,127,"Xerror: Code: 0x%x resID: 0x%x maj: 0x%x "
+ "min: %x", err->errorCode,err->resourceID,
+ err->minorCode,err->majorCode);
+ break;
+ default:
+ if ((buf[0] & 0x7f) == KeymapNotify)
+ snprintf(info,127,"KeymapNotifyEvent: %i",buf[0]);
+ else {
+ ev = (xEvent*)buf;
+ snprintf(info,127,"XEvent: type: 0x%x detail: 0x%x "
+ "seq#: 0x%x", ev->u.u.type, ev->u.u.detail,
+ ev->u.u.sequenceNumber);
+ }
+ }
+ ErrorF("REPLY: ClientIDX: %i %s\n",who->index, info);
+ } else
+ multicount = TRUE;
+ }
+#endif
+
+ if (!oco)
+ {
+ if ((oco = FreeOutputs))
+ {
+ FreeOutputs = oco->next;
+ }
+ else if (!(oco = AllocateOutputBuffer()))
+ {
+ if (oc->trans_conn) {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ }
+ MarkClientException(who);
+ return -1;
+ }
+ oc->output = oco;
+ }
+
+ padBytes = padlength[count & 3];
+
+ if(ReplyCallback)
+ {
+ ReplyInfoRec replyinfo;
+
+ replyinfo.client = who;
+ replyinfo.replyData = buf;
+ replyinfo.dataLenBytes = count + padBytes;
+ if (who->replyBytesRemaining)
+ { /* still sending data of an earlier reply */
+ who->replyBytesRemaining -= count + padBytes;
+ replyinfo.startOfReply = FALSE;
+ replyinfo.bytesRemaining = who->replyBytesRemaining;
+ CallCallbacks((&ReplyCallback), (void *)&replyinfo);
+ }
+ else if (who->clientState == ClientStateRunning
+ && buf[0] == X_Reply)
+ { /* start of new reply */
+ CARD32 replylen;
+ unsigned long bytesleft;
+
+ replylen = ((xGenericReply *)buf)->length;
+ if (who->swapped)
+ swapl(&replylen);
+ bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes;
+ replyinfo.startOfReply = TRUE;
+ replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft;
+ CallCallbacks((&ReplyCallback), (void *)&replyinfo);
+ }
+ }
+#ifdef DEBUG_COMMUNICATION
+ else if (multicount) {
+ if (who->replyBytesRemaining) {
+ who->replyBytesRemaining -= (count + padBytes);
+ } else {
+ CARD32 replylen;
+ replylen = ((xGenericReply *)buf)->length;
+ who->replyBytesRemaining =
+ (replylen * 4) + SIZEOF(xReply) - count - padBytes;
+ }
+ }
+#endif
+ if (oco->count == 0 || oco->count + count + padBytes > oco->size)
+ {
+ FD_CLR(oc->fd, &OutputPending);
+ if(!XFD_ANYSET(&OutputPending)) {
+ CriticalOutputPending = FALSE;
+ NewOutputPending = FALSE;
+ }
+ return FlushClient(who, oc, buf, count);
+ }
+
+ NewOutputPending = TRUE;
+ FD_SET(oc->fd, &OutputPending);
+ memmove((char *)oco->buf + oco->count, buf, count);
+ oco->count += count;
+ if (padBytes) {
+ memset(oco->buf + oco->count, '\0', padBytes);
+ oco->count += padBytes;
+ }
+ return(count);
+}
+
+ /********************
+ * FlushClient()
+ * If the client isn't keeping up with us, then we try to continue
+ * buffering the data and set the apropriate bit in ClientsWritable
+ * (which is used by WaitFor in the select). If the connection yields
+ * a permanent error, or we can't allocate any more space, we then
+ * close the connection.
+ *
+ **********************/
+
+int
+FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
+{
+ ConnectionOutputPtr oco = oc->output;
+ int connection = oc->fd;
+ XtransConnInfo trans_conn = oc->trans_conn;
+ struct iovec iov[3];
+ static char padBuffer[3];
+ const char *extraBuf = __extraBuf;
+ long written;
+ long padsize;
+ long notWritten;
+ long todo;
+
+ if (!oco)
+ return 0;
+ written = 0;
+ padsize = padlength[extraCount & 3];
+ notWritten = oco->count + extraCount + padsize;
+
+ if (!notWritten)
+ return 0;
+
+ if (FlushCallback)
+ CallCallbacks(&FlushCallback, who);
+
+ todo = notWritten;
+ while (notWritten) {
+ long before = written; /* amount of whole thing written */
+ long remain = todo; /* amount to try this time, <= notWritten */
+ int i = 0;
+ long len;
+
+ /* You could be very general here and have "in" and "out" iovecs
+ * and write a loop without using a macro, but what the heck. This
+ * translates to:
+ *
+ * how much of this piece is new?
+ * if more new then we are trying this time, clamp
+ * if nothing new
+ * then bump down amount already written, for next piece
+ * else put new stuff in iovec, will need all of next piece
+ *
+ * Note that todo had better be at least 1 or else we'll end up
+ * writing 0 iovecs.
+ */
+#define InsertIOV(pointer, length) \
+ len = (length) - before; \
+ if (len > remain) \
+ len = remain; \
+ if (len <= 0) { \
+ before = (-len); \
+ } else { \
+ iov[i].iov_len = len; \
+ iov[i].iov_base = (pointer) + before; \
+ i++; \
+ remain -= len; \
+ before = 0; \
+ }
+
+ InsertIOV ((char *)oco->buf, oco->count)
+ InsertIOV ((char *)extraBuf, extraCount)
+ InsertIOV (padBuffer, padsize)
+
+ errno = 0;
+ if (trans_conn && (len = _XSERVTransWritev(trans_conn, iov, i)) >= 0)
+ {
+ written += len;
+ notWritten -= len;
+ todo = notWritten;
+ }
+ else if (ETEST(errno)
+#ifdef SUNSYSV /* check for another brain-damaged OS bug */
+ || (errno == 0)
+#endif
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ || ((errno == EMSGSIZE) && (todo == 1))
+#endif
+ )
+ {
+ /* If we've arrived here, then the client is stuffed to the gills
+ and not ready to accept more. Make a note of it and buffer
+ the rest. */
+ FD_SET(connection, &ClientsWriteBlocked);
+ AnyWritesPending = TRUE;
+
+ if (written < oco->count)
+ {
+ if (written > 0)
+ {
+ oco->count -= written;
+ memmove((char *)oco->buf,
+ (char *)oco->buf + written,
+ oco->count);
+ written = 0;
+ }
+ }
+ else
+ {
+ written -= oco->count;
+ oco->count = 0;
+ }
+
+ if (notWritten > oco->size)
+ {
+ unsigned char *obuf = NULL;
+
+ if (notWritten + BUFSIZE <= INT_MAX) {
+ obuf = realloc(oco->buf, notWritten + BUFSIZE);
+ }
+ if (!obuf)
+ {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ MarkClientException(who);
+ oco->count = 0;
+ return(-1);
+ }
+ oco->size = notWritten + BUFSIZE;
+ oco->buf = obuf;
+ }
+
+ /* If the amount written extended into the padBuffer, then the
+ difference "extraCount - written" may be less than 0 */
+ if ((len = extraCount - written) > 0)
+ memmove ((char *)oco->buf + oco->count,
+ extraBuf + written,
+ len);
+
+ oco->count = notWritten; /* this will include the pad */
+ /* return only the amount explicitly requested */
+ return extraCount;
+ }
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ else if (errno == EMSGSIZE)
+ {
+ todo >>= 1;
+ }
+#endif
+ else
+ {
+ if (oc->trans_conn)
+ {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ }
+ MarkClientException(who);
+ oco->count = 0;
+ return(-1);
+ }
+ }
+
+ /* everything was flushed out */
+ oco->count = 0;
+ /* check to see if this client was write blocked */
+ if (AnyWritesPending)
+ {
+ FD_CLR(oc->fd, &ClientsWriteBlocked);
+ if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+ AnyWritesPending = FALSE;
+
+ }
+ if (oco->size > BUFWATERMARK)
+ {
+ free(oco->buf);
+ free(oco);
+ }
+ else
+ {
+ oco->next = FreeOutputs;
+ FreeOutputs = oco;
+ }
+ oc->output = (ConnectionOutputPtr)NULL;
+ return extraCount; /* return only the amount explicitly requested */
+}
+
+ConnectionInputPtr
+AllocateInputBuffer(void)
+{
+ ConnectionInputPtr oci;
+
+ oci = (ConnectionInputPtr)malloc(sizeof(ConnectionInput));
+ if (!oci)
+ return (ConnectionInputPtr)NULL;
+ oci->buffer = (char *)malloc(BUFSIZE);
+ if (!oci->buffer)
+ {
+ free(oci);
+ return (ConnectionInputPtr)NULL;
+ }
+ oci->size = BUFSIZE;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ oci->ignoreBytes = 0;
+ return oci;
+}
+
+ConnectionOutputPtr
+AllocateOutputBuffer(void)
+{
+ ConnectionOutputPtr oco;
+
+ oco = (ConnectionOutputPtr)malloc(sizeof(ConnectionOutput));
+ if (!oco)
+ return (ConnectionOutputPtr)NULL;
+ oco->buf = (unsigned char *) malloc(BUFSIZE);
+ if (!oco->buf)
+ {
+ free(oco);
+ return (ConnectionOutputPtr)NULL;
+ }
+ oco->size = BUFSIZE;
+ oco->count = 0;
+ return oco;
+}
+
+void
+FreeOsBuffers(OsCommPtr oc)
+{
+ ConnectionInputPtr oci;
+ ConnectionOutputPtr oco;
+
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr)NULL;
+ if ((oci = oc->input))
+ {
+ if (FreeInputs)
+ {
+ free(oci->buffer);
+ free(oci);
+ }
+ else
+ {
+ FreeInputs = oci;
+ oci->next = (ConnectionInputPtr)NULL;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ oci->ignoreBytes = 0;
+ }
+ }
+ if ((oco = oc->output))
+ {
+ if (FreeOutputs)
+ {
+ free(oco->buf);
+ free(oco);
+ }
+ else
+ {
+ FreeOutputs = oco;
+ oco->next = (ConnectionOutputPtr)NULL;
+ oco->count = 0;
+ }
+ }
+}
+
+void
+ResetOsBuffers(void)
+{
+ ConnectionInputPtr oci;
+ ConnectionOutputPtr oco;
+
+ while ((oci = FreeInputs))
+ {
+ FreeInputs = oci->next;
+ free(oci->buffer);
+ free(oci);
+ }
+ while ((oco = FreeOutputs))
+ {
+ FreeOutputs = oco->next;
+ free(oco->buf);
+ free(oco);
+ }
+}
diff --git a/nx-X11/programs/Xserver/os/log.c b/nx-X11/programs/Xserver/os/log.c
new file mode 100644
index 000000000..0ead6e9f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/log.c
@@ -0,0 +1,779 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 Quarterdeck Office Systems.
+
+ 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 and
+Quarterdeck not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+DIGITAL AND QUARTERDECK DISCLAIM 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.
+
+*/
+
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 copyright holder(s)
+ * and author(s) 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 copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/Xos.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <stdlib.h> /* for malloc() */
+#include <errno.h>
+
+#include "input.h"
+#include "site.h"
+#include "opaque.h"
+
+#ifdef WIN32
+#include <process.h>
+#define getpid(x) _getpid(x)
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+#include <nx/NX.h>
+
+#endif
+
+#ifdef DDXOSVERRORF
+void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
+#ifdef NX_TRANS_EXIT
+int OsVendorVErrorFFatal = 0;
+#endif
+#endif
+
+static FILE *logFile = NULL;
+static Bool logFlush = FALSE;
+static Bool logSync = FALSE;
+static int logVerbosity = DEFAULT_LOG_VERBOSITY;
+static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY;
+
+/* Buffer to information logged before the log file is opened. */
+static char *saveBuffer = NULL;
+static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
+static Bool needBuffer = TRUE;
+
+/* Prefix strings for log messages. */
+#ifndef X_UNKNOWN_STRING
+#define X_UNKNOWN_STRING "(\?\?)"
+#endif
+#ifndef X_PROBE_STRING
+#define X_PROBE_STRING "(--)"
+#endif
+#ifndef X_CONFIG_STRING
+#define X_CONFIG_STRING "(**)"
+#endif
+#ifndef X_DEFAULT_STRING
+#define X_DEFAULT_STRING "(==)"
+#endif
+#ifndef X_CMDLINE_STRING
+#define X_CMDLINE_STRING "(++)"
+#endif
+#ifndef X_NOTICE_STRING
+#define X_NOTICE_STRING "(!!)"
+#endif
+#ifndef X_ERROR_STRING
+#define X_ERROR_STRING "(EE)"
+#endif
+#ifndef X_WARNING_STRING
+#define X_WARNING_STRING "(WW)"
+#endif
+#ifndef X_INFO_STRING
+#define X_INFO_STRING "(II)"
+#endif
+#ifndef X_NOT_IMPLEMENTED_STRING
+#define X_NOT_IMPLEMENTED_STRING "(NI)"
+#endif
+
+/*
+ * LogFilePrep is called to setup files for logging, including getting
+ * an old file out of the way, but it doesn't actually open the file,
+ * since it may be used for renaming a file we're already logging to.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static char *
+LogFilePrep(const char *fname, const char *backup, const char *idstring)
+{
+ char *logFileName = NULL;
+
+ if (asprintf(&logFileName, fname, idstring) == -1)
+ FatalError("Cannot allocate space for the log file name\n");
+
+ if (backup && *backup) {
+ struct stat buf;
+
+ if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
+ char *suffix;
+ char *oldLog;
+
+ if ((asprintf(&suffix, backup, idstring) == -1) ||
+ (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) {
+ FatalError("Cannot allocate space for the log file name\n");
+ }
+ free(suffix);
+
+ if (rename(logFileName, oldLog) == -1) {
+ FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
+ logFileName, oldLog);
+ }
+ free(oldLog);
+ }
+ }
+ else {
+ if (remove(logFileName) != 0) {
+ FatalError("Cannot remove old log file \"%s\": %s\n",
+ logFileName, strerror(errno));
+ }
+ }
+
+ return logFileName;
+}
+#pragma GCC diagnostic pop
+
+/*
+ * LogInit is called to start logging to a file. It is also called (with
+ * NULL arguments) when logging to a file is not wanted. It must always be
+ * called, otherwise log messages will continue to accumulate in a buffer.
+ *
+ * %s, if present in the fname or backup strings, is expanded to the display
+ * string (or to a string containing the pid if the display is not yet set).
+ */
+
+static char *saved_log_fname;
+static char *saved_log_backup;
+static char *saved_log_tempname;
+
+const char *
+LogInit(const char *fname, const char *backup)
+{
+ char *logFileName = NULL;
+
+ if (fname && *fname) {
+ if (displayfd != -1) {
+ /* Display isn't set yet, so we can't use it in filenames yet. */
+ char pidstring[32];
+ snprintf(pidstring, sizeof(pidstring), "pid-%ld",
+ (unsigned long) getpid());
+ logFileName = LogFilePrep(fname, backup, pidstring);
+ saved_log_tempname = logFileName;
+
+ /* Save the patterns for use when the display is named. */
+ saved_log_fname = strdup(fname);
+ if (backup == NULL)
+ saved_log_backup = NULL;
+ else
+ saved_log_backup = strdup(backup);
+ } else
+ logFileName = LogFilePrep(fname, backup, display);
+ if ((logFile = fopen(logFileName, "w")) == NULL)
+ FatalError("Cannot open log file \"%s\"\n", logFileName);
+ setvbuf(logFile, NULL, _IONBF, 0);
+
+ /* Flush saved log information. */
+ if (saveBuffer && bufferSize > 0) {
+ fwrite(saveBuffer, bufferPos, 1, logFile);
+ fflush(logFile);
+#ifndef WIN32
+ fsync(fileno(logFile));
+#endif
+ }
+ }
+
+ /*
+ * Unconditionally free the buffer, and flag that the buffer is no longer
+ * needed.
+ */
+ if (saveBuffer && bufferSize > 0) {
+ free(saveBuffer); /* Must be free(), not free() */
+ saveBuffer = NULL;
+ bufferSize = 0;
+ }
+ needBuffer = FALSE;
+
+ return logFileName;
+}
+
+void
+LogSetDisplay(void)
+{
+ if (saved_log_fname) {
+ char *logFileName;
+
+ logFileName = LogFilePrep(saved_log_fname, saved_log_backup, display);
+
+ if (rename(saved_log_tempname, logFileName) == 0) {
+ LogMessageVerb(X_PROBED, 0,
+ "Log file renamed from \"%s\" to \"%s\"\n",
+ saved_log_tempname, logFileName);
+
+ if (strlen(saved_log_tempname) >= strlen(logFileName))
+ strncpy(saved_log_tempname, logFileName,
+ strlen(saved_log_tempname));
+ }
+ else {
+ ErrorF("Failed to rename log file \"%s\" to \"%s\": %s\n",
+ saved_log_tempname, logFileName, strerror(errno));
+ }
+
+ /* free newly allocated string - can't free old one since existing
+ pointers to it may exist in DDX callers. */
+ free(logFileName);
+ free(saved_log_fname);
+ free(saved_log_backup);
+ }
+}
+
+void
+LogClose()
+{
+ if (logFile) {
+ fclose(logFile);
+ logFile = NULL;
+ }
+}
+
+Bool
+LogSetParameter(LogParameter param, int value)
+{
+ switch (param) {
+ case XLOG_FLUSH:
+ logFlush = value ? TRUE : FALSE;
+ return TRUE;
+ case XLOG_SYNC:
+ logSync = value ? TRUE : FALSE;
+ return TRUE;
+ case XLOG_VERBOSITY:
+ logVerbosity = value;
+ return TRUE;
+ case XLOG_FILE_VERBOSITY:
+ logFileVerbosity = value;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* This function does the actual log message writes. */
+
+void
+LogVWrite(int verb, const char *f, va_list args)
+{
+ static char tmpBuffer[1024];
+ int len = 0;
+
+ /*
+ * Since a va_list can only be processed once, write the string to a
+ * buffer, and then write the buffer out to the appropriate output
+ * stream(s).
+ */
+ if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
+ vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
+#ifdef NX_TRANS_EXIT
+ /*
+ * Beautify the message. Make the
+ * first letter uppercase.
+ */
+
+ *tmpBuffer = toupper(*tmpBuffer);
+
+ /*
+ * Remove the trailing newline.
+ */
+
+ if (strlen(tmpBuffer) > 0 &&
+ *(tmpBuffer + strlen(tmpBuffer) - 1) == '\n') {
+ *(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
+ }
+
+ /*
+ * Remove the trailing full-stop.
+ */
+
+ if (strlen(tmpBuffer) > 0 &&
+ *(tmpBuffer + strlen(tmpBuffer) - 1) == '.') {
+ *(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
+ }
+#endif /* #ifdef NX_TRANS_EXIT */
+ len = strlen(tmpBuffer);
+ }
+ if ((verb < 0 || logVerbosity >= verb) && len > 0)
+ fwrite(tmpBuffer, len, 1, stderr);
+ if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
+ if (logFile) {
+ fwrite(tmpBuffer, len, 1, logFile);
+ if (logFlush) {
+ fflush(logFile);
+#ifndef WIN32
+ if (logSync)
+ fsync(fileno(logFile));
+#endif
+ }
+ } else if (needBuffer) {
+ /*
+ * Note, this code is used before OsInit() has been called, so
+ * malloc() and friends can't be used.
+ */
+ if (len > bufferUnused) {
+ bufferSize += 1024;
+ bufferUnused += 1024;
+ if (saveBuffer)
+ saveBuffer = realloc(saveBuffer, bufferSize);
+ else
+ saveBuffer = malloc(bufferSize);
+ if (!saveBuffer)
+ FatalError("realloc() failed while saving log messages\n");
+ }
+ bufferUnused -= len;
+ memcpy(saveBuffer + bufferPos, tmpBuffer, len);
+ bufferPos += len;
+ }
+ }
+}
+
+void
+LogWrite(int verb, const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ LogVWrite(verb, f, args);
+ va_end(args);
+}
+
+void
+LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
+{
+ const char *s = X_UNKNOWN_STRING;
+ char *tmpBuf = NULL;
+
+ /* Ignore verbosity for X_ERROR */
+ if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
+ switch (type) {
+ case X_PROBED:
+ s = X_PROBE_STRING;
+ break;
+ case X_CONFIG:
+ s = X_CONFIG_STRING;
+ break;
+ case X_DEFAULT:
+ s = X_DEFAULT_STRING;
+ break;
+ case X_CMDLINE:
+ s = X_CMDLINE_STRING;
+ break;
+ case X_NOTICE:
+ s = X_NOTICE_STRING;
+ break;
+ case X_ERROR:
+ s = X_ERROR_STRING;
+ if (verb > 0)
+ verb = 0;
+ break;
+ case X_WARNING:
+ s = X_WARNING_STRING;
+ break;
+ case X_INFO:
+ s = X_INFO_STRING;
+ break;
+ case X_NOT_IMPLEMENTED:
+ s = X_NOT_IMPLEMENTED_STRING;
+ break;
+ case X_UNKNOWN:
+ s = X_UNKNOWN_STRING;
+ break;
+ case X_NONE:
+ s = NULL;
+ break;
+ }
+
+ /*
+ * Prefix the format string with the message type. We do it this way
+ * so that LogVWrite() is only called once per message.
+ */
+ if (s) {
+ tmpBuf = malloc(strlen(format) + strlen(s) + 1 + 1);
+ /* Silently return if malloc fails here. */
+ if (!tmpBuf)
+ return;
+ sprintf(tmpBuf, "%s ", s);
+ strcat(tmpBuf, format);
+ LogVWrite(verb, tmpBuf, args);
+ free(tmpBuf);
+ } else
+ LogVWrite(verb, format, args);
+ }
+}
+
+/* Log message with verbosity level specified. */
+void
+LogMessageVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Log a message with the standard verbosity level of 1. */
+void
+LogMessage(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ LogVMessageVerb(type, 1, format, ap);
+ va_end(ap);
+}
+
+#ifdef __GNUC__
+void AbortServer(void) __attribute__((noreturn));
+#endif
+
+void
+AbortServer(void)
+{
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
+ fprintf(stderr, "AbortServer: Going to abort the current server.\n");
+#endif
+ OsCleanup(TRUE);
+ AbortDDX();
+ fflush(stderr);
+ if (CoreDump)
+ abort();
+#ifdef NX_TRANS_EXIT
+#ifdef NX_TRANS_TEST
+ fprintf(stderr, "AbortServer: Going to clean up NX resources and exit.\n");
+#endif
+ NXTransExit(1);
+#else /* #ifdef NX_TRANS_EXIT */
+ exit (1);
+#endif
+}
+
+#ifndef AUDIT_PREFIX
+#define AUDIT_PREFIX "AUDIT: %s: %ld %s: "
+#endif
+#ifndef AUDIT_TIMEOUT
+#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */
+#endif
+
+static int nrepeat = 0;
+static int oldlen = -1;
+static OsTimerPtr auditTimer = NULL;
+
+void
+FreeAuditTimer(void)
+{
+ if (auditTimer != NULL) {
+ /* Force output of pending messages */
+ TimerForce(auditTimer);
+ TimerFree(auditTimer);
+ auditTimer = NULL;
+ }
+}
+
+static char *
+AuditPrefix(void)
+{
+ time_t tm;
+ char *autime, *s;
+ char *tmpBuf;
+ int len;
+
+ time(&tm);
+ autime = ctime(&tm);
+ if ((s = strchr(autime, '\n')))
+ *s = '\0';
+ if ((s = strrchr(argvGlobal[0], '/')))
+ s++;
+ else
+ s = argvGlobal[0];
+ len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + strlen(s) + 1;
+ tmpBuf = malloc(len);
+ if (!tmpBuf)
+ return NULL;
+ snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid(), s);
+ return tmpBuf;
+}
+
+void
+AuditF(const char * f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+
+ VAuditF(f, args);
+ va_end(args);
+}
+
+static CARD32
+AuditFlush(OsTimerPtr timer, CARD32 now, void * arg)
+{
+ char *prefix;
+
+ if (nrepeat > 0) {
+ prefix = AuditPrefix();
+ ErrorF("%slast message repeated %d times\n",
+ prefix != NULL ? prefix : "", nrepeat);
+ nrepeat = 0;
+ if (prefix != NULL)
+ free(prefix);
+ return AUDIT_TIMEOUT;
+ } else {
+ /* if the timer expires without anything to print, flush the message */
+ oldlen = -1;
+ return 0;
+ }
+}
+
+void
+VAuditF(const char *f, va_list args)
+{
+ char *prefix;
+ char buf[1024];
+ int len;
+ static char oldbuf[1024];
+
+ prefix = AuditPrefix();
+ len = vsnprintf(buf, sizeof(buf), f, args);
+
+ if (len == oldlen && strcmp(buf, oldbuf) == 0) {
+ /* Message already seen */
+ nrepeat++;
+ } else {
+ /* new message */
+ if (auditTimer != NULL)
+ TimerForce(auditTimer);
+ ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
+ strlcpy(oldbuf, buf, sizeof(oldbuf));
+ oldlen = len;
+ nrepeat = 0;
+ auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
+ }
+ if (prefix != NULL)
+ free(prefix);
+}
+
+void
+FatalError(const char *f, ...)
+{
+ va_list args;
+ static Bool beenhere = FALSE;
+
+#ifdef NX_TRANS_EXIT
+ if (beenhere) {
+ fprintf(stderr, "Error: Aborting session with fatal error function reentered.\n");
+ }
+ else {
+ /*
+ * Tell to the log function that this
+ * is a fatal error.
+ */
+
+ OsVendorVErrorFFatal = 1;
+
+ fprintf(stderr, "Error: Aborting session with '");
+
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+
+ fprintf(stderr, "'.\n");
+ }
+#else /* #ifdef NX_TRANS_EXIT */
+ if (beenhere)
+ ErrorF("\nFatalError re-entered, aborting\n");
+ else
+ ErrorF("\nFatal server error:\n");
+
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+ ErrorF("\n");
+#endif /* #ifdef NX_TRANS_EXIT */
+#ifdef DDXOSFATALERROR
+ if (!beenhere)
+ OsVendorFatalError();
+#endif
+#ifdef ABORTONFATALERROR
+ abort();
+#endif
+ if (!beenhere) {
+ beenhere = TRUE;
+ AbortServer();
+ } else
+ abort();
+ /*NOTREACHED*/
+}
+
+void
+VErrorF(const char *f, va_list args)
+{
+#ifdef DDXOSVERRORF
+ if (OsVendorVErrorFProc)
+ OsVendorVErrorFProc(f, args);
+ else
+ LogVWrite(-1, f, args);
+#else
+ LogVWrite(-1, f, args);
+#endif
+}
+
+void
+ErrorF(const char * f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+}
+
+/* A perror() workalike. */
+
+#ifndef NEED_STRERROR
+#ifdef SYSV
+#if !defined(ISC) || defined(ISC202) || defined(ISC22)
+#define NEED_STRERROR
+#endif
+#endif
+#endif
+
+#if defined(NEED_STRERROR) && !defined(strerror)
+extern char *sys_errlist[];
+extern int sys_nerr;
+#define strerror(n) \
+ ((n) >= 0 && (n) < sys_nerr) ? sys_errlist[(n)] : "unknown error"
+#endif
+
+void
+Error(char *str)
+{
+ char *err = NULL;
+ int saveErrno = errno;
+
+ if (str) {
+ err = malloc(strlen(strerror(saveErrno)) + strlen(str) + 2 + 1);
+ if (!err)
+ return;
+ sprintf(err, "%s: ", str);
+ strcat(err, strerror(saveErrno));
+ LogWrite(-1, "%s", err);
+ } else
+ LogWrite(-1, "%s", strerror(saveErrno));
+}
+
+void
+LogPrintMarkers()
+{
+ /* Show what the message marker symbols mean. */
+ ErrorF("Markers: ");
+ LogMessageVerb(X_PROBED, -1, "probed, ");
+ LogMessageVerb(X_CONFIG, -1, "from config file, ");
+ LogMessageVerb(X_DEFAULT, -1, "default setting,\n\t");
+ LogMessageVerb(X_CMDLINE, -1, "from command line, ");
+ LogMessageVerb(X_NOTICE, -1, "notice, ");
+ LogMessageVerb(X_INFO, -1, "informational,\n\t");
+ LogMessageVerb(X_WARNING, -1, "warning, ");
+ LogMessageVerb(X_ERROR, -1, "error, ");
+ LogMessageVerb(X_NOT_IMPLEMENTED, -1, "not implemented, ");
+ LogMessageVerb(X_UNKNOWN, -1, "unknown.\n");
+}
+
diff --git a/nx-X11/programs/Xserver/os/mitauth.c b/nx-X11/programs/Xserver/os/mitauth.c
new file mode 100644
index 000000000..578f8ba42
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/mitauth.c
@@ -0,0 +1,197 @@
+/*
+
+Copyright 1988, 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.
+
+*/
+
+/*
+ * MIT-MAGIC-COOKIE-1 authorization scheme
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+static struct auth {
+ struct auth *next;
+ unsigned short len;
+ char *data;
+ XID id;
+} *mit_auth;
+
+int
+MitAddCookie (
+ unsigned short data_length,
+ char *data,
+ XID id)
+{
+ struct auth *new;
+
+ new = (struct auth *) malloc (sizeof (struct auth));
+ if (!new)
+ return 0;
+ new->data = (char *) malloc ((unsigned) data_length);
+ if (!new->data) {
+ free(new);
+ return 0;
+ }
+ new->next = mit_auth;
+ mit_auth = new;
+ memmove(new->data, data, (int) data_length);
+ new->len = data_length;
+ new->id = id;
+ return 1;
+}
+
+XID
+MitCheckCookie (
+ unsigned short data_length,
+ char *data,
+ ClientPtr client,
+ char **reason)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (data_length == auth->len &&
+ timingsafe_memcmp (data, auth->data, (int) data_length) == 0)
+ return auth->id;
+ }
+ *reason = "Invalid MIT-MAGIC-COOKIE-1 key";
+ return (XID) -1;
+}
+
+int
+MitResetCookie (void)
+{
+ struct auth *auth, *next;
+
+ for (auth = mit_auth; auth; auth=next) {
+ next = auth->next;
+ free (auth->data);
+ free (auth);
+ }
+ mit_auth = 0;
+ return 0;
+}
+
+XID
+MitToID (
+ unsigned short data_length,
+ char *data)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (data_length == auth->len &&
+ memcmp (data, auth->data, data_length) == 0)
+ return auth->id;
+ }
+ return (XID) -1;
+}
+
+int
+MitFromID (
+ XID id,
+ unsigned short *data_lenp,
+ char **datap)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (id == auth->id) {
+ *data_lenp = auth->len;
+ *datap = auth->data;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+MitRemoveCookie (
+ unsigned short data_length,
+ char *data)
+{
+ struct auth *auth, *prev;
+
+ prev = 0;
+ for (auth = mit_auth; auth; prev = auth, auth=auth->next) {
+ if (data_length == auth->len &&
+ memcmp (data, auth->data, data_length) == 0)
+ {
+ if (prev)
+ prev->next = auth->next;
+ else
+ mit_auth = auth->next;
+ free (auth->data);
+ free (auth);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifdef XCSECURITY
+
+static char cookie[16]; /* 128 bits */
+
+XID
+MitGenerateCookie (
+ unsigned data_length,
+ char *data,
+ XID id,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ int i = 0;
+ int status;
+
+ while (data_length--)
+ {
+ cookie[i++] += *data++;
+ if (i >= sizeof (cookie)) i = 0;
+ }
+ GenerateRandomData(sizeof (cookie), cookie);
+ status = MitAddCookie(sizeof (cookie), cookie, id);
+ if (!status)
+ {
+ id = -1;
+ }
+ else
+ {
+ *data_return = cookie;
+ *data_length_return = sizeof (cookie);
+ }
+ return id;
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/os/oscolor.c b/nx-X11/programs/Xserver/os/oscolor.c
new file mode 100644
index 000000000..70940653f
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/oscolor.c
@@ -0,0 +1,1661 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "os.h"
+
+typedef struct _builtinColor {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned short name;
+} BuiltinColor;
+
+static const char BuiltinColorNames[] = {
+ "alice blue\0"
+ "AliceBlue\0"
+ "antique white\0"
+ "AntiqueWhite\0"
+ "AntiqueWhite1\0"
+ "AntiqueWhite2\0"
+ "AntiqueWhite3\0"
+ "AntiqueWhite4\0"
+ "aqua\0"
+ "aquamarine\0"
+ "aquamarine1\0"
+ "aquamarine2\0"
+ "aquamarine3\0"
+ "aquamarine4\0"
+ "azure\0"
+ "azure1\0"
+ "azure2\0"
+ "azure3\0"
+ "azure4\0"
+ "beige\0"
+ "bisque\0"
+ "bisque1\0"
+ "bisque2\0"
+ "bisque3\0"
+ "bisque4\0"
+ "black\0"
+ "blanched almond\0"
+ "BlanchedAlmond\0"
+ "blue\0"
+ "blue violet\0"
+ "blue1\0"
+ "blue2\0"
+ "blue3\0"
+ "blue4\0"
+ "BlueViolet\0"
+ "brown\0"
+ "brown1\0"
+ "brown2\0"
+ "brown3\0"
+ "brown4\0"
+ "burlywood\0"
+ "burlywood1\0"
+ "burlywood2\0"
+ "burlywood3\0"
+ "burlywood4\0"
+ "cadet blue\0"
+ "CadetBlue\0"
+ "CadetBlue1\0"
+ "CadetBlue2\0"
+ "CadetBlue3\0"
+ "CadetBlue4\0"
+ "chartreuse\0"
+ "chartreuse1\0"
+ "chartreuse2\0"
+ "chartreuse3\0"
+ "chartreuse4\0"
+ "chocolate\0"
+ "chocolate1\0"
+ "chocolate2\0"
+ "chocolate3\0"
+ "chocolate4\0"
+ "coral\0"
+ "coral1\0"
+ "coral2\0"
+ "coral3\0"
+ "coral4\0"
+ "cornflower blue\0"
+ "CornflowerBlue\0"
+ "cornsilk\0"
+ "cornsilk1\0"
+ "cornsilk2\0"
+ "cornsilk3\0"
+ "cornsilk4\0"
+ "crimson\0"
+ "cyan\0"
+ "cyan1\0"
+ "cyan2\0"
+ "cyan3\0"
+ "cyan4\0"
+ "dark blue\0"
+ "dark cyan\0"
+ "dark goldenrod\0"
+ "dark gray\0"
+ "dark green\0"
+ "dark grey\0"
+ "dark khaki\0"
+ "dark magenta\0"
+ "dark olive green\0"
+ "dark orange\0"
+ "dark orchid\0"
+ "dark red\0"
+ "dark salmon\0"
+ "dark sea green\0"
+ "dark slate blue\0"
+ "dark slate gray\0"
+ "dark slate grey\0"
+ "dark turquoise\0"
+ "dark violet\0"
+ "DarkBlue\0"
+ "DarkCyan\0"
+ "DarkGoldenrod\0"
+ "DarkGoldenrod1\0"
+ "DarkGoldenrod2\0"
+ "DarkGoldenrod3\0"
+ "DarkGoldenrod4\0"
+ "DarkGray\0"
+ "DarkGreen\0"
+ "DarkGrey\0"
+ "DarkKhaki\0"
+ "DarkMagenta\0"
+ "DarkOliveGreen\0"
+ "DarkOliveGreen1\0"
+ "DarkOliveGreen2\0"
+ "DarkOliveGreen3\0"
+ "DarkOliveGreen4\0"
+ "DarkOrange\0"
+ "DarkOrange1\0"
+ "DarkOrange2\0"
+ "DarkOrange3\0"
+ "DarkOrange4\0"
+ "DarkOrchid\0"
+ "DarkOrchid1\0"
+ "DarkOrchid2\0"
+ "DarkOrchid3\0"
+ "DarkOrchid4\0"
+ "DarkRed\0"
+ "DarkSalmon\0"
+ "DarkSeaGreen\0"
+ "DarkSeaGreen1\0"
+ "DarkSeaGreen2\0"
+ "DarkSeaGreen3\0"
+ "DarkSeaGreen4\0"
+ "DarkSlateBlue\0"
+ "DarkSlateGray\0"
+ "DarkSlateGray1\0"
+ "DarkSlateGray2\0"
+ "DarkSlateGray3\0"
+ "DarkSlateGray4\0"
+ "DarkSlateGrey\0"
+ "DarkTurquoise\0"
+ "DarkViolet\0"
+ "deep pink\0"
+ "deep sky blue\0"
+ "DeepPink\0"
+ "DeepPink1\0"
+ "DeepPink2\0"
+ "DeepPink3\0"
+ "DeepPink4\0"
+ "DeepSkyBlue\0"
+ "DeepSkyBlue1\0"
+ "DeepSkyBlue2\0"
+ "DeepSkyBlue3\0"
+ "DeepSkyBlue4\0"
+ "dim gray\0"
+ "dim grey\0"
+ "DimGray\0"
+ "DimGrey\0"
+ "dodger blue\0"
+ "DodgerBlue\0"
+ "DodgerBlue1\0"
+ "DodgerBlue2\0"
+ "DodgerBlue3\0"
+ "DodgerBlue4\0"
+ "firebrick\0"
+ "firebrick1\0"
+ "firebrick2\0"
+ "firebrick3\0"
+ "firebrick4\0"
+ "floral white\0"
+ "FloralWhite\0"
+ "forest green\0"
+ "ForestGreen\0"
+ "fuchsia\0"
+ "gainsboro\0"
+ "ghost white\0"
+ "GhostWhite\0"
+ "gold\0"
+ "gold1\0"
+ "gold2\0"
+ "gold3\0"
+ "gold4\0"
+ "goldenrod\0"
+ "goldenrod1\0"
+ "goldenrod2\0"
+ "goldenrod3\0"
+ "goldenrod4\0"
+ "gray\0"
+ "gray0\0"
+ "gray1\0"
+ "gray10\0"
+ "gray100\0"
+ "gray11\0"
+ "gray12\0"
+ "gray13\0"
+ "gray14\0"
+ "gray15\0"
+ "gray16\0"
+ "gray17\0"
+ "gray18\0"
+ "gray19\0"
+ "gray2\0"
+ "gray20\0"
+ "gray21\0"
+ "gray22\0"
+ "gray23\0"
+ "gray24\0"
+ "gray25\0"
+ "gray26\0"
+ "gray27\0"
+ "gray28\0"
+ "gray29\0"
+ "gray3\0"
+ "gray30\0"
+ "gray31\0"
+ "gray32\0"
+ "gray33\0"
+ "gray34\0"
+ "gray35\0"
+ "gray36\0"
+ "gray37\0"
+ "gray38\0"
+ "gray39\0"
+ "gray4\0"
+ "gray40\0"
+ "gray41\0"
+ "gray42\0"
+ "gray43\0"
+ "gray44\0"
+ "gray45\0"
+ "gray46\0"
+ "gray47\0"
+ "gray48\0"
+ "gray49\0"
+ "gray5\0"
+ "gray50\0"
+ "gray51\0"
+ "gray52\0"
+ "gray53\0"
+ "gray54\0"
+ "gray55\0"
+ "gray56\0"
+ "gray57\0"
+ "gray58\0"
+ "gray59\0"
+ "gray6\0"
+ "gray60\0"
+ "gray61\0"
+ "gray62\0"
+ "gray63\0"
+ "gray64\0"
+ "gray65\0"
+ "gray66\0"
+ "gray67\0"
+ "gray68\0"
+ "gray69\0"
+ "gray7\0"
+ "gray70\0"
+ "gray71\0"
+ "gray72\0"
+ "gray73\0"
+ "gray74\0"
+ "gray75\0"
+ "gray76\0"
+ "gray77\0"
+ "gray78\0"
+ "gray79\0"
+ "gray8\0"
+ "gray80\0"
+ "gray81\0"
+ "gray82\0"
+ "gray83\0"
+ "gray84\0"
+ "gray85\0"
+ "gray86\0"
+ "gray87\0"
+ "gray88\0"
+ "gray89\0"
+ "gray9\0"
+ "gray90\0"
+ "gray91\0"
+ "gray92\0"
+ "gray93\0"
+ "gray94\0"
+ "gray95\0"
+ "gray96\0"
+ "gray97\0"
+ "gray98\0"
+ "gray99\0"
+ "green\0"
+ "green yellow\0"
+ "green1\0"
+ "green2\0"
+ "green3\0"
+ "green4\0"
+ "GreenYellow\0"
+ "grey\0"
+ "grey0\0"
+ "grey1\0"
+ "grey10\0"
+ "grey100\0"
+ "grey11\0"
+ "grey12\0"
+ "grey13\0"
+ "grey14\0"
+ "grey15\0"
+ "grey16\0"
+ "grey17\0"
+ "grey18\0"
+ "grey19\0"
+ "grey2\0"
+ "grey20\0"
+ "grey21\0"
+ "grey22\0"
+ "grey23\0"
+ "grey24\0"
+ "grey25\0"
+ "grey26\0"
+ "grey27\0"
+ "grey28\0"
+ "grey29\0"
+ "grey3\0"
+ "grey30\0"
+ "grey31\0"
+ "grey32\0"
+ "grey33\0"
+ "grey34\0"
+ "grey35\0"
+ "grey36\0"
+ "grey37\0"
+ "grey38\0"
+ "grey39\0"
+ "grey4\0"
+ "grey40\0"
+ "grey41\0"
+ "grey42\0"
+ "grey43\0"
+ "grey44\0"
+ "grey45\0"
+ "grey46\0"
+ "grey47\0"
+ "grey48\0"
+ "grey49\0"
+ "grey5\0"
+ "grey50\0"
+ "grey51\0"
+ "grey52\0"
+ "grey53\0"
+ "grey54\0"
+ "grey55\0"
+ "grey56\0"
+ "grey57\0"
+ "grey58\0"
+ "grey59\0"
+ "grey6\0"
+ "grey60\0"
+ "grey61\0"
+ "grey62\0"
+ "grey63\0"
+ "grey64\0"
+ "grey65\0"
+ "grey66\0"
+ "grey67\0"
+ "grey68\0"
+ "grey69\0"
+ "grey7\0"
+ "grey70\0"
+ "grey71\0"
+ "grey72\0"
+ "grey73\0"
+ "grey74\0"
+ "grey75\0"
+ "grey76\0"
+ "grey77\0"
+ "grey78\0"
+ "grey79\0"
+ "grey8\0"
+ "grey80\0"
+ "grey81\0"
+ "grey82\0"
+ "grey83\0"
+ "grey84\0"
+ "grey85\0"
+ "grey86\0"
+ "grey87\0"
+ "grey88\0"
+ "grey89\0"
+ "grey9\0"
+ "grey90\0"
+ "grey91\0"
+ "grey92\0"
+ "grey93\0"
+ "grey94\0"
+ "grey95\0"
+ "grey96\0"
+ "grey97\0"
+ "grey98\0"
+ "grey99\0"
+ "honeydew\0"
+ "honeydew1\0"
+ "honeydew2\0"
+ "honeydew3\0"
+ "honeydew4\0"
+ "hot pink\0"
+ "HotPink\0"
+ "HotPink1\0"
+ "HotPink2\0"
+ "HotPink3\0"
+ "HotPink4\0"
+ "indian red\0"
+ "IndianRed\0"
+ "IndianRed1\0"
+ "IndianRed2\0"
+ "IndianRed3\0"
+ "IndianRed4\0"
+ "indigo\0"
+ "ivory\0"
+ "ivory1\0"
+ "ivory2\0"
+ "ivory3\0"
+ "ivory4\0"
+ "khaki\0"
+ "khaki1\0"
+ "khaki2\0"
+ "khaki3\0"
+ "khaki4\0"
+ "lavender\0"
+ "lavender blush\0"
+ "LavenderBlush\0"
+ "LavenderBlush1\0"
+ "LavenderBlush2\0"
+ "LavenderBlush3\0"
+ "LavenderBlush4\0"
+ "lawn green\0"
+ "LawnGreen\0"
+ "lemon chiffon\0"
+ "LemonChiffon\0"
+ "LemonChiffon1\0"
+ "LemonChiffon2\0"
+ "LemonChiffon3\0"
+ "LemonChiffon4\0"
+ "light blue\0"
+ "light coral\0"
+ "light cyan\0"
+ "light goldenrod\0"
+ "light goldenrod yellow\0"
+ "light gray\0"
+ "light green\0"
+ "light grey\0"
+ "light pink\0"
+ "light salmon\0"
+ "light sea green\0"
+ "light sky blue\0"
+ "light slate blue\0"
+ "light slate gray\0"
+ "light slate grey\0"
+ "light steel blue\0"
+ "light yellow\0"
+ "LightBlue\0"
+ "LightBlue1\0"
+ "LightBlue2\0"
+ "LightBlue3\0"
+ "LightBlue4\0"
+ "LightCoral\0"
+ "LightCyan\0"
+ "LightCyan1\0"
+ "LightCyan2\0"
+ "LightCyan3\0"
+ "LightCyan4\0"
+ "LightGoldenrod\0"
+ "LightGoldenrod1\0"
+ "LightGoldenrod2\0"
+ "LightGoldenrod3\0"
+ "LightGoldenrod4\0"
+ "LightGoldenrodYellow\0"
+ "LightGray\0"
+ "LightGreen\0"
+ "LightGrey\0"
+ "LightPink\0"
+ "LightPink1\0"
+ "LightPink2\0"
+ "LightPink3\0"
+ "LightPink4\0"
+ "LightSalmon\0"
+ "LightSalmon1\0"
+ "LightSalmon2\0"
+ "LightSalmon3\0"
+ "LightSalmon4\0"
+ "LightSeaGreen\0"
+ "LightSkyBlue\0"
+ "LightSkyBlue1\0"
+ "LightSkyBlue2\0"
+ "LightSkyBlue3\0"
+ "LightSkyBlue4\0"
+ "LightSlateBlue\0"
+ "LightSlateGray\0"
+ "LightSlateGrey\0"
+ "LightSteelBlue\0"
+ "LightSteelBlue1\0"
+ "LightSteelBlue2\0"
+ "LightSteelBlue3\0"
+ "LightSteelBlue4\0"
+ "LightYellow\0"
+ "LightYellow1\0"
+ "LightYellow2\0"
+ "LightYellow3\0"
+ "LightYellow4\0"
+ "lime\0"
+ "lime green\0"
+ "LimeGreen\0"
+ "linen\0"
+ "magenta\0"
+ "magenta1\0"
+ "magenta2\0"
+ "magenta3\0"
+ "magenta4\0"
+ "maroon\0"
+ "maroon1\0"
+ "maroon2\0"
+ "maroon3\0"
+ "maroon4\0"
+ "medium aquamarine\0"
+ "medium blue\0"
+ "medium orchid\0"
+ "medium purple\0"
+ "medium sea green\0"
+ "medium slate blue\0"
+ "medium spring green\0"
+ "medium turquoise\0"
+ "medium violet red\0"
+ "MediumAquamarine\0"
+ "MediumBlue\0"
+ "MediumOrchid\0"
+ "MediumOrchid1\0"
+ "MediumOrchid2\0"
+ "MediumOrchid3\0"
+ "MediumOrchid4\0"
+ "MediumPurple\0"
+ "MediumPurple1\0"
+ "MediumPurple2\0"
+ "MediumPurple3\0"
+ "MediumPurple4\0"
+ "MediumSeaGreen\0"
+ "MediumSlateBlue\0"
+ "MediumSpringGreen\0"
+ "MediumTurquoise\0"
+ "MediumVioletRed\0"
+ "midnight blue\0"
+ "MidnightBlue\0"
+ "mint cream\0"
+ "MintCream\0"
+ "misty rose\0"
+ "MistyRose\0"
+ "MistyRose1\0"
+ "MistyRose2\0"
+ "MistyRose3\0"
+ "MistyRose4\0"
+ "moccasin\0"
+ "navajo white\0"
+ "NavajoWhite\0"
+ "NavajoWhite1\0"
+ "NavajoWhite2\0"
+ "NavajoWhite3\0"
+ "NavajoWhite4\0"
+ "navy\0"
+ "navy blue\0"
+ "NavyBlue\0"
+ "old lace\0"
+ "OldLace\0"
+ "olive\0"
+ "olive drab\0"
+ "OliveDrab\0"
+ "OliveDrab1\0"
+ "OliveDrab2\0"
+ "OliveDrab3\0"
+ "OliveDrab4\0"
+ "orange\0"
+ "orange red\0"
+ "orange1\0"
+ "orange2\0"
+ "orange3\0"
+ "orange4\0"
+ "OrangeRed\0"
+ "OrangeRed1\0"
+ "OrangeRed2\0"
+ "OrangeRed3\0"
+ "OrangeRed4\0"
+ "orchid\0"
+ "orchid1\0"
+ "orchid2\0"
+ "orchid3\0"
+ "orchid4\0"
+ "pale goldenrod\0"
+ "pale green\0"
+ "pale turquoise\0"
+ "pale violet red\0"
+ "PaleGoldenrod\0"
+ "PaleGreen\0"
+ "PaleGreen1\0"
+ "PaleGreen2\0"
+ "PaleGreen3\0"
+ "PaleGreen4\0"
+ "PaleTurquoise\0"
+ "PaleTurquoise1\0"
+ "PaleTurquoise2\0"
+ "PaleTurquoise3\0"
+ "PaleTurquoise4\0"
+ "PaleVioletRed\0"
+ "PaleVioletRed1\0"
+ "PaleVioletRed2\0"
+ "PaleVioletRed3\0"
+ "PaleVioletRed4\0"
+ "papaya whip\0"
+ "PapayaWhip\0"
+ "peach puff\0"
+ "PeachPuff\0"
+ "PeachPuff1\0"
+ "PeachPuff2\0"
+ "PeachPuff3\0"
+ "PeachPuff4\0"
+ "peru\0"
+ "pink\0"
+ "pink1\0"
+ "pink2\0"
+ "pink3\0"
+ "pink4\0"
+ "plum\0"
+ "plum1\0"
+ "plum2\0"
+ "plum3\0"
+ "plum4\0"
+ "powder blue\0"
+ "PowderBlue\0"
+ "purple\0"
+ "purple1\0"
+ "purple2\0"
+ "purple3\0"
+ "purple4\0"
+ "rebecca purple\0"
+ "RebeccaPurple\0"
+ "red\0"
+ "red1\0"
+ "red2\0"
+ "red3\0"
+ "red4\0"
+ "rosy brown\0"
+ "RosyBrown\0"
+ "RosyBrown1\0"
+ "RosyBrown2\0"
+ "RosyBrown3\0"
+ "RosyBrown4\0"
+ "royal blue\0"
+ "RoyalBlue\0"
+ "RoyalBlue1\0"
+ "RoyalBlue2\0"
+ "RoyalBlue3\0"
+ "RoyalBlue4\0"
+ "saddle brown\0"
+ "SaddleBrown\0"
+ "salmon\0"
+ "salmon1\0"
+ "salmon2\0"
+ "salmon3\0"
+ "salmon4\0"
+ "sandy brown\0"
+ "SandyBrown\0"
+ "sea green\0"
+ "SeaGreen\0"
+ "SeaGreen1\0"
+ "SeaGreen2\0"
+ "SeaGreen3\0"
+ "SeaGreen4\0"
+ "seashell\0"
+ "seashell1\0"
+ "seashell2\0"
+ "seashell3\0"
+ "seashell4\0"
+ "sienna\0"
+ "sienna1\0"
+ "sienna2\0"
+ "sienna3\0"
+ "sienna4\0"
+ "silver\0"
+ "sky blue\0"
+ "SkyBlue\0"
+ "SkyBlue1\0"
+ "SkyBlue2\0"
+ "SkyBlue3\0"
+ "SkyBlue4\0"
+ "slate blue\0"
+ "slate gray\0"
+ "slate grey\0"
+ "SlateBlue\0"
+ "SlateBlue1\0"
+ "SlateBlue2\0"
+ "SlateBlue3\0"
+ "SlateBlue4\0"
+ "SlateGray\0"
+ "SlateGray1\0"
+ "SlateGray2\0"
+ "SlateGray3\0"
+ "SlateGray4\0"
+ "SlateGrey\0"
+ "snow\0"
+ "snow1\0"
+ "snow2\0"
+ "snow3\0"
+ "snow4\0"
+ "spring green\0"
+ "SpringGreen\0"
+ "SpringGreen1\0"
+ "SpringGreen2\0"
+ "SpringGreen3\0"
+ "SpringGreen4\0"
+ "steel blue\0"
+ "SteelBlue\0"
+ "SteelBlue1\0"
+ "SteelBlue2\0"
+ "SteelBlue3\0"
+ "SteelBlue4\0"
+ "tan\0"
+ "tan1\0"
+ "tan2\0"
+ "tan3\0"
+ "tan4\0"
+ "teal\0"
+ "thistle\0"
+ "thistle1\0"
+ "thistle2\0"
+ "thistle3\0"
+ "thistle4\0"
+ "tomato\0"
+ "tomato1\0"
+ "tomato2\0"
+ "tomato3\0"
+ "tomato4\0"
+ "turquoise\0"
+ "turquoise1\0"
+ "turquoise2\0"
+ "turquoise3\0"
+ "turquoise4\0"
+ "violet\0"
+ "violet red\0"
+ "VioletRed\0"
+ "VioletRed1\0"
+ "VioletRed2\0"
+ "VioletRed3\0"
+ "VioletRed4\0"
+ "web gray\0"
+ "web green\0"
+ "web grey\0"
+ "web maroon\0"
+ "web purple\0"
+ "WebGray\0"
+ "WebGreen\0"
+ "WebGrey\0"
+ "WebMaroon\0"
+ "WebPurple\0"
+ "wheat\0"
+ "wheat1\0"
+ "wheat2\0"
+ "wheat3\0"
+ "wheat4\0"
+ "white\0"
+ "white smoke\0"
+ "WhiteSmoke\0"
+ "x11 gray\0"
+ "x11 green\0"
+ "x11 grey\0"
+ "x11 maroon\0"
+ "x11 purple\0"
+ "X11Gray\0"
+ "X11Green\0"
+ "X11Grey\0"
+ "X11Maroon\0"
+ "X11Purple\0"
+ "yellow\0"
+ "yellow green\0"
+ "yellow1\0"
+ "yellow2\0"
+ "yellow3\0"
+ "yellow4\0"
+ "YellowGreen\0"
+};
+
+static const BuiltinColor BuiltinColors[] = {
+ {240, 248, 255, 0}, /* alice blue */
+ {240, 248, 255, 11}, /* AliceBlue */
+ {250, 235, 215, 21}, /* antique white */
+ {250, 235, 215, 35}, /* AntiqueWhite */
+ {255, 239, 219, 48}, /* AntiqueWhite1 */
+ {238, 223, 204, 62}, /* AntiqueWhite2 */
+ {205, 192, 176, 76}, /* AntiqueWhite3 */
+ {139, 131, 120, 90}, /* AntiqueWhite4 */
+ {0, 255, 255, 104}, /* aqua */
+ {127, 255, 212, 109}, /* aquamarine */
+ {127, 255, 212, 120}, /* aquamarine1 */
+ {118, 238, 198, 132}, /* aquamarine2 */
+ {102, 205, 170, 144}, /* aquamarine3 */
+ {69, 139, 116, 156}, /* aquamarine4 */
+ {240, 255, 255, 168}, /* azure */
+ {240, 255, 255, 174}, /* azure1 */
+ {224, 238, 238, 181}, /* azure2 */
+ {193, 205, 205, 188}, /* azure3 */
+ {131, 139, 139, 195}, /* azure4 */
+ {245, 245, 220, 202}, /* beige */
+ {255, 228, 196, 208}, /* bisque */
+ {255, 228, 196, 215}, /* bisque1 */
+ {238, 213, 183, 223}, /* bisque2 */
+ {205, 183, 158, 231}, /* bisque3 */
+ {139, 125, 107, 239}, /* bisque4 */
+ {0, 0, 0, 247}, /* black */
+ {255, 235, 205, 253}, /* blanched almond */
+ {255, 235, 205, 269}, /* BlanchedAlmond */
+ {0, 0, 255, 284}, /* blue */
+ {138, 43, 226, 289}, /* blue violet */
+ {0, 0, 255, 301}, /* blue1 */
+ {0, 0, 238, 307}, /* blue2 */
+ {0, 0, 205, 313}, /* blue3 */
+ {0, 0, 139, 319}, /* blue4 */
+ {138, 43, 226, 325}, /* BlueViolet */
+ {165, 42, 42, 336}, /* brown */
+ {255, 64, 64, 342}, /* brown1 */
+ {238, 59, 59, 349}, /* brown2 */
+ {205, 51, 51, 356}, /* brown3 */
+ {139, 35, 35, 363}, /* brown4 */
+ {222, 184, 135, 370}, /* burlywood */
+ {255, 211, 155, 380}, /* burlywood1 */
+ {238, 197, 145, 391}, /* burlywood2 */
+ {205, 170, 125, 402}, /* burlywood3 */
+ {139, 115, 85, 413}, /* burlywood4 */
+ {95, 158, 160, 424}, /* cadet blue */
+ {95, 158, 160, 435}, /* CadetBlue */
+ {152, 245, 255, 445}, /* CadetBlue1 */
+ {142, 229, 238, 456}, /* CadetBlue2 */
+ {122, 197, 205, 467}, /* CadetBlue3 */
+ {83, 134, 139, 478}, /* CadetBlue4 */
+ {127, 255, 0, 489}, /* chartreuse */
+ {127, 255, 0, 500}, /* chartreuse1 */
+ {118, 238, 0, 512}, /* chartreuse2 */
+ {102, 205, 0, 524}, /* chartreuse3 */
+ {69, 139, 0, 536}, /* chartreuse4 */
+ {210, 105, 30, 548}, /* chocolate */
+ {255, 127, 36, 558}, /* chocolate1 */
+ {238, 118, 33, 569}, /* chocolate2 */
+ {205, 102, 29, 580}, /* chocolate3 */
+ {139, 69, 19, 591}, /* chocolate4 */
+ {255, 127, 80, 602}, /* coral */
+ {255, 114, 86, 608}, /* coral1 */
+ {238, 106, 80, 615}, /* coral2 */
+ {205, 91, 69, 622}, /* coral3 */
+ {139, 62, 47, 629}, /* coral4 */
+ {100, 149, 237, 636}, /* cornflower blue */
+ {100, 149, 237, 652}, /* CornflowerBlue */
+ {255, 248, 220, 667}, /* cornsilk */
+ {255, 248, 220, 676}, /* cornsilk1 */
+ {238, 232, 205, 686}, /* cornsilk2 */
+ {205, 200, 177, 696}, /* cornsilk3 */
+ {139, 136, 120, 706}, /* cornsilk4 */
+ {220, 20, 60, 716}, /* crimson */
+ {0, 255, 255, 724}, /* cyan */
+ {0, 255, 255, 729}, /* cyan1 */
+ {0, 238, 238, 735}, /* cyan2 */
+ {0, 205, 205, 741}, /* cyan3 */
+ {0, 139, 139, 747}, /* cyan4 */
+ {0, 0, 139, 753}, /* dark blue */
+ {0, 139, 139, 763}, /* dark cyan */
+ {184, 134, 11, 773}, /* dark goldenrod */
+ {169, 169, 169, 788}, /* dark gray */
+ {0, 100, 0, 798}, /* dark green */
+ {169, 169, 169, 809}, /* dark grey */
+ {189, 183, 107, 819}, /* dark khaki */
+ {139, 0, 139, 830}, /* dark magenta */
+ {85, 107, 47, 843}, /* dark olive green */
+ {255, 140, 0, 860}, /* dark orange */
+ {153, 50, 204, 872}, /* dark orchid */
+ {139, 0, 0, 884}, /* dark red */
+ {233, 150, 122, 893}, /* dark salmon */
+ {143, 188, 143, 905}, /* dark sea green */
+ {72, 61, 139, 920}, /* dark slate blue */
+ {47, 79, 79, 936}, /* dark slate gray */
+ {47, 79, 79, 952}, /* dark slate grey */
+ {0, 206, 209, 968}, /* dark turquoise */
+ {148, 0, 211, 983}, /* dark violet */
+ {0, 0, 139, 995}, /* DarkBlue */
+ {0, 139, 139, 1004}, /* DarkCyan */
+ {184, 134, 11, 1013}, /* DarkGoldenrod */
+ {255, 185, 15, 1027}, /* DarkGoldenrod1 */
+ {238, 173, 14, 1042}, /* DarkGoldenrod2 */
+ {205, 149, 12, 1057}, /* DarkGoldenrod3 */
+ {139, 101, 8, 1072}, /* DarkGoldenrod4 */
+ {169, 169, 169, 1087}, /* DarkGray */
+ {0, 100, 0, 1096}, /* DarkGreen */
+ {169, 169, 169, 1106}, /* DarkGrey */
+ {189, 183, 107, 1115}, /* DarkKhaki */
+ {139, 0, 139, 1125}, /* DarkMagenta */
+ {85, 107, 47, 1137}, /* DarkOliveGreen */
+ {202, 255, 112, 1152}, /* DarkOliveGreen1 */
+ {188, 238, 104, 1168}, /* DarkOliveGreen2 */
+ {162, 205, 90, 1184}, /* DarkOliveGreen3 */
+ {110, 139, 61, 1200}, /* DarkOliveGreen4 */
+ {255, 140, 0, 1216}, /* DarkOrange */
+ {255, 127, 0, 1227}, /* DarkOrange1 */
+ {238, 118, 0, 1239}, /* DarkOrange2 */
+ {205, 102, 0, 1251}, /* DarkOrange3 */
+ {139, 69, 0, 1263}, /* DarkOrange4 */
+ {153, 50, 204, 1275}, /* DarkOrchid */
+ {191, 62, 255, 1286}, /* DarkOrchid1 */
+ {178, 58, 238, 1298}, /* DarkOrchid2 */
+ {154, 50, 205, 1310}, /* DarkOrchid3 */
+ {104, 34, 139, 1322}, /* DarkOrchid4 */
+ {139, 0, 0, 1334}, /* DarkRed */
+ {233, 150, 122, 1342}, /* DarkSalmon */
+ {143, 188, 143, 1353}, /* DarkSeaGreen */
+ {193, 255, 193, 1366}, /* DarkSeaGreen1 */
+ {180, 238, 180, 1380}, /* DarkSeaGreen2 */
+ {155, 205, 155, 1394}, /* DarkSeaGreen3 */
+ {105, 139, 105, 1408}, /* DarkSeaGreen4 */
+ {72, 61, 139, 1422}, /* DarkSlateBlue */
+ {47, 79, 79, 1436}, /* DarkSlateGray */
+ {151, 255, 255, 1450}, /* DarkSlateGray1 */
+ {141, 238, 238, 1465}, /* DarkSlateGray2 */
+ {121, 205, 205, 1480}, /* DarkSlateGray3 */
+ {82, 139, 139, 1495}, /* DarkSlateGray4 */
+ {47, 79, 79, 1510}, /* DarkSlateGrey */
+ {0, 206, 209, 1524}, /* DarkTurquoise */
+ {148, 0, 211, 1538}, /* DarkViolet */
+ {255, 20, 147, 1549}, /* deep pink */
+ {0, 191, 255, 1559}, /* deep sky blue */
+ {255, 20, 147, 1573}, /* DeepPink */
+ {255, 20, 147, 1582}, /* DeepPink1 */
+ {238, 18, 137, 1592}, /* DeepPink2 */
+ {205, 16, 118, 1602}, /* DeepPink3 */
+ {139, 10, 80, 1612}, /* DeepPink4 */
+ {0, 191, 255, 1622}, /* DeepSkyBlue */
+ {0, 191, 255, 1634}, /* DeepSkyBlue1 */
+ {0, 178, 238, 1647}, /* DeepSkyBlue2 */
+ {0, 154, 205, 1660}, /* DeepSkyBlue3 */
+ {0, 104, 139, 1673}, /* DeepSkyBlue4 */
+ {105, 105, 105, 1686}, /* dim gray */
+ {105, 105, 105, 1695}, /* dim grey */
+ {105, 105, 105, 1704}, /* DimGray */
+ {105, 105, 105, 1712}, /* DimGrey */
+ {30, 144, 255, 1720}, /* dodger blue */
+ {30, 144, 255, 1732}, /* DodgerBlue */
+ {30, 144, 255, 1743}, /* DodgerBlue1 */
+ {28, 134, 238, 1755}, /* DodgerBlue2 */
+ {24, 116, 205, 1767}, /* DodgerBlue3 */
+ {16, 78, 139, 1779}, /* DodgerBlue4 */
+ {178, 34, 34, 1791}, /* firebrick */
+ {255, 48, 48, 1801}, /* firebrick1 */
+ {238, 44, 44, 1812}, /* firebrick2 */
+ {205, 38, 38, 1823}, /* firebrick3 */
+ {139, 26, 26, 1834}, /* firebrick4 */
+ {255, 250, 240, 1845}, /* floral white */
+ {255, 250, 240, 1858}, /* FloralWhite */
+ {34, 139, 34, 1870}, /* forest green */
+ {34, 139, 34, 1883}, /* ForestGreen */
+ {255, 0, 255, 1895}, /* fuchsia */
+ {220, 220, 220, 1903}, /* gainsboro */
+ {248, 248, 255, 1913}, /* ghost white */
+ {248, 248, 255, 1925}, /* GhostWhite */
+ {255, 215, 0, 1936}, /* gold */
+ {255, 215, 0, 1941}, /* gold1 */
+ {238, 201, 0, 1947}, /* gold2 */
+ {205, 173, 0, 1953}, /* gold3 */
+ {139, 117, 0, 1959}, /* gold4 */
+ {218, 165, 32, 1965}, /* goldenrod */
+ {255, 193, 37, 1975}, /* goldenrod1 */
+ {238, 180, 34, 1986}, /* goldenrod2 */
+ {205, 155, 29, 1997}, /* goldenrod3 */
+ {139, 105, 20, 2008}, /* goldenrod4 */
+ {190, 190, 190, 2019}, /* gray */
+ {0, 0, 0, 2024}, /* gray0 */
+ {3, 3, 3, 2030}, /* gray1 */
+ {26, 26, 26, 2036}, /* gray10 */
+ {255, 255, 255, 2043}, /* gray100 */
+ {28, 28, 28, 2051}, /* gray11 */
+ {31, 31, 31, 2058}, /* gray12 */
+ {33, 33, 33, 2065}, /* gray13 */
+ {36, 36, 36, 2072}, /* gray14 */
+ {38, 38, 38, 2079}, /* gray15 */
+ {41, 41, 41, 2086}, /* gray16 */
+ {43, 43, 43, 2093}, /* gray17 */
+ {46, 46, 46, 2100}, /* gray18 */
+ {48, 48, 48, 2107}, /* gray19 */
+ {5, 5, 5, 2114}, /* gray2 */
+ {51, 51, 51, 2120}, /* gray20 */
+ {54, 54, 54, 2127}, /* gray21 */
+ {56, 56, 56, 2134}, /* gray22 */
+ {59, 59, 59, 2141}, /* gray23 */
+ {61, 61, 61, 2148}, /* gray24 */
+ {64, 64, 64, 2155}, /* gray25 */
+ {66, 66, 66, 2162}, /* gray26 */
+ {69, 69, 69, 2169}, /* gray27 */
+ {71, 71, 71, 2176}, /* gray28 */
+ {74, 74, 74, 2183}, /* gray29 */
+ {8, 8, 8, 2190}, /* gray3 */
+ {77, 77, 77, 2196}, /* gray30 */
+ {79, 79, 79, 2203}, /* gray31 */
+ {82, 82, 82, 2210}, /* gray32 */
+ {84, 84, 84, 2217}, /* gray33 */
+ {87, 87, 87, 2224}, /* gray34 */
+ {89, 89, 89, 2231}, /* gray35 */
+ {92, 92, 92, 2238}, /* gray36 */
+ {94, 94, 94, 2245}, /* gray37 */
+ {97, 97, 97, 2252}, /* gray38 */
+ {99, 99, 99, 2259}, /* gray39 */
+ {10, 10, 10, 2266}, /* gray4 */
+ {102, 102, 102, 2272}, /* gray40 */
+ {105, 105, 105, 2279}, /* gray41 */
+ {107, 107, 107, 2286}, /* gray42 */
+ {110, 110, 110, 2293}, /* gray43 */
+ {112, 112, 112, 2300}, /* gray44 */
+ {115, 115, 115, 2307}, /* gray45 */
+ {117, 117, 117, 2314}, /* gray46 */
+ {120, 120, 120, 2321}, /* gray47 */
+ {122, 122, 122, 2328}, /* gray48 */
+ {125, 125, 125, 2335}, /* gray49 */
+ {13, 13, 13, 2342}, /* gray5 */
+ {127, 127, 127, 2348}, /* gray50 */
+ {130, 130, 130, 2355}, /* gray51 */
+ {133, 133, 133, 2362}, /* gray52 */
+ {135, 135, 135, 2369}, /* gray53 */
+ {138, 138, 138, 2376}, /* gray54 */
+ {140, 140, 140, 2383}, /* gray55 */
+ {143, 143, 143, 2390}, /* gray56 */
+ {145, 145, 145, 2397}, /* gray57 */
+ {148, 148, 148, 2404}, /* gray58 */
+ {150, 150, 150, 2411}, /* gray59 */
+ {15, 15, 15, 2418}, /* gray6 */
+ {153, 153, 153, 2424}, /* gray60 */
+ {156, 156, 156, 2431}, /* gray61 */
+ {158, 158, 158, 2438}, /* gray62 */
+ {161, 161, 161, 2445}, /* gray63 */
+ {163, 163, 163, 2452}, /* gray64 */
+ {166, 166, 166, 2459}, /* gray65 */
+ {168, 168, 168, 2466}, /* gray66 */
+ {171, 171, 171, 2473}, /* gray67 */
+ {173, 173, 173, 2480}, /* gray68 */
+ {176, 176, 176, 2487}, /* gray69 */
+ {18, 18, 18, 2494}, /* gray7 */
+ {179, 179, 179, 2500}, /* gray70 */
+ {181, 181, 181, 2507}, /* gray71 */
+ {184, 184, 184, 2514}, /* gray72 */
+ {186, 186, 186, 2521}, /* gray73 */
+ {189, 189, 189, 2528}, /* gray74 */
+ {191, 191, 191, 2535}, /* gray75 */
+ {194, 194, 194, 2542}, /* gray76 */
+ {196, 196, 196, 2549}, /* gray77 */
+ {199, 199, 199, 2556}, /* gray78 */
+ {201, 201, 201, 2563}, /* gray79 */
+ {20, 20, 20, 2570}, /* gray8 */
+ {204, 204, 204, 2576}, /* gray80 */
+ {207, 207, 207, 2583}, /* gray81 */
+ {209, 209, 209, 2590}, /* gray82 */
+ {212, 212, 212, 2597}, /* gray83 */
+ {214, 214, 214, 2604}, /* gray84 */
+ {217, 217, 217, 2611}, /* gray85 */
+ {219, 219, 219, 2618}, /* gray86 */
+ {222, 222, 222, 2625}, /* gray87 */
+ {224, 224, 224, 2632}, /* gray88 */
+ {227, 227, 227, 2639}, /* gray89 */
+ {23, 23, 23, 2646}, /* gray9 */
+ {229, 229, 229, 2652}, /* gray90 */
+ {232, 232, 232, 2659}, /* gray91 */
+ {235, 235, 235, 2666}, /* gray92 */
+ {237, 237, 237, 2673}, /* gray93 */
+ {240, 240, 240, 2680}, /* gray94 */
+ {242, 242, 242, 2687}, /* gray95 */
+ {245, 245, 245, 2694}, /* gray96 */
+ {247, 247, 247, 2701}, /* gray97 */
+ {250, 250, 250, 2708}, /* gray98 */
+ {252, 252, 252, 2715}, /* gray99 */
+ {0, 255, 0, 2722}, /* green */
+ {173, 255, 47, 2728}, /* green yellow */
+ {0, 255, 0, 2741}, /* green1 */
+ {0, 238, 0, 2748}, /* green2 */
+ {0, 205, 0, 2755}, /* green3 */
+ {0, 139, 0, 2762}, /* green4 */
+ {173, 255, 47, 2769}, /* GreenYellow */
+ {190, 190, 190, 2781}, /* grey */
+ {0, 0, 0, 2786}, /* grey0 */
+ {3, 3, 3, 2792}, /* grey1 */
+ {26, 26, 26, 2798}, /* grey10 */
+ {255, 255, 255, 2805}, /* grey100 */
+ {28, 28, 28, 2813}, /* grey11 */
+ {31, 31, 31, 2820}, /* grey12 */
+ {33, 33, 33, 2827}, /* grey13 */
+ {36, 36, 36, 2834}, /* grey14 */
+ {38, 38, 38, 2841}, /* grey15 */
+ {41, 41, 41, 2848}, /* grey16 */
+ {43, 43, 43, 2855}, /* grey17 */
+ {46, 46, 46, 2862}, /* grey18 */
+ {48, 48, 48, 2869}, /* grey19 */
+ {5, 5, 5, 2876}, /* grey2 */
+ {51, 51, 51, 2882}, /* grey20 */
+ {54, 54, 54, 2889}, /* grey21 */
+ {56, 56, 56, 2896}, /* grey22 */
+ {59, 59, 59, 2903}, /* grey23 */
+ {61, 61, 61, 2910}, /* grey24 */
+ {64, 64, 64, 2917}, /* grey25 */
+ {66, 66, 66, 2924}, /* grey26 */
+ {69, 69, 69, 2931}, /* grey27 */
+ {71, 71, 71, 2938}, /* grey28 */
+ {74, 74, 74, 2945}, /* grey29 */
+ {8, 8, 8, 2952}, /* grey3 */
+ {77, 77, 77, 2958}, /* grey30 */
+ {79, 79, 79, 2965}, /* grey31 */
+ {82, 82, 82, 2972}, /* grey32 */
+ {84, 84, 84, 2979}, /* grey33 */
+ {87, 87, 87, 2986}, /* grey34 */
+ {89, 89, 89, 2993}, /* grey35 */
+ {92, 92, 92, 3000}, /* grey36 */
+ {94, 94, 94, 3007}, /* grey37 */
+ {97, 97, 97, 3014}, /* grey38 */
+ {99, 99, 99, 3021}, /* grey39 */
+ {10, 10, 10, 3028}, /* grey4 */
+ {102, 102, 102, 3034}, /* grey40 */
+ {105, 105, 105, 3041}, /* grey41 */
+ {107, 107, 107, 3048}, /* grey42 */
+ {110, 110, 110, 3055}, /* grey43 */
+ {112, 112, 112, 3062}, /* grey44 */
+ {115, 115, 115, 3069}, /* grey45 */
+ {117, 117, 117, 3076}, /* grey46 */
+ {120, 120, 120, 3083}, /* grey47 */
+ {122, 122, 122, 3090}, /* grey48 */
+ {125, 125, 125, 3097}, /* grey49 */
+ {13, 13, 13, 3104}, /* grey5 */
+ {127, 127, 127, 3110}, /* grey50 */
+ {130, 130, 130, 3117}, /* grey51 */
+ {133, 133, 133, 3124}, /* grey52 */
+ {135, 135, 135, 3131}, /* grey53 */
+ {138, 138, 138, 3138}, /* grey54 */
+ {140, 140, 140, 3145}, /* grey55 */
+ {143, 143, 143, 3152}, /* grey56 */
+ {145, 145, 145, 3159}, /* grey57 */
+ {148, 148, 148, 3166}, /* grey58 */
+ {150, 150, 150, 3173}, /* grey59 */
+ {15, 15, 15, 3180}, /* grey6 */
+ {153, 153, 153, 3186}, /* grey60 */
+ {156, 156, 156, 3193}, /* grey61 */
+ {158, 158, 158, 3200}, /* grey62 */
+ {161, 161, 161, 3207}, /* grey63 */
+ {163, 163, 163, 3214}, /* grey64 */
+ {166, 166, 166, 3221}, /* grey65 */
+ {168, 168, 168, 3228}, /* grey66 */
+ {171, 171, 171, 3235}, /* grey67 */
+ {173, 173, 173, 3242}, /* grey68 */
+ {176, 176, 176, 3249}, /* grey69 */
+ {18, 18, 18, 3256}, /* grey7 */
+ {179, 179, 179, 3262}, /* grey70 */
+ {181, 181, 181, 3269}, /* grey71 */
+ {184, 184, 184, 3276}, /* grey72 */
+ {186, 186, 186, 3283}, /* grey73 */
+ {189, 189, 189, 3290}, /* grey74 */
+ {191, 191, 191, 3297}, /* grey75 */
+ {194, 194, 194, 3304}, /* grey76 */
+ {196, 196, 196, 3311}, /* grey77 */
+ {199, 199, 199, 3318}, /* grey78 */
+ {201, 201, 201, 3325}, /* grey79 */
+ {20, 20, 20, 3332}, /* grey8 */
+ {204, 204, 204, 3338}, /* grey80 */
+ {207, 207, 207, 3345}, /* grey81 */
+ {209, 209, 209, 3352}, /* grey82 */
+ {212, 212, 212, 3359}, /* grey83 */
+ {214, 214, 214, 3366}, /* grey84 */
+ {217, 217, 217, 3373}, /* grey85 */
+ {219, 219, 219, 3380}, /* grey86 */
+ {222, 222, 222, 3387}, /* grey87 */
+ {224, 224, 224, 3394}, /* grey88 */
+ {227, 227, 227, 3401}, /* grey89 */
+ {23, 23, 23, 3408}, /* grey9 */
+ {229, 229, 229, 3414}, /* grey90 */
+ {232, 232, 232, 3421}, /* grey91 */
+ {235, 235, 235, 3428}, /* grey92 */
+ {237, 237, 237, 3435}, /* grey93 */
+ {240, 240, 240, 3442}, /* grey94 */
+ {242, 242, 242, 3449}, /* grey95 */
+ {245, 245, 245, 3456}, /* grey96 */
+ {247, 247, 247, 3463}, /* grey97 */
+ {250, 250, 250, 3470}, /* grey98 */
+ {252, 252, 252, 3477}, /* grey99 */
+ {240, 255, 240, 3484}, /* honeydew */
+ {240, 255, 240, 3493}, /* honeydew1 */
+ {224, 238, 224, 3503}, /* honeydew2 */
+ {193, 205, 193, 3513}, /* honeydew3 */
+ {131, 139, 131, 3523}, /* honeydew4 */
+ {255, 105, 180, 3533}, /* hot pink */
+ {255, 105, 180, 3542}, /* HotPink */
+ {255, 110, 180, 3550}, /* HotPink1 */
+ {238, 106, 167, 3559}, /* HotPink2 */
+ {205, 96, 144, 3568}, /* HotPink3 */
+ {139, 58, 98, 3577}, /* HotPink4 */
+ {205, 92, 92, 3586}, /* indian red */
+ {205, 92, 92, 3597}, /* IndianRed */
+ {255, 106, 106, 3607}, /* IndianRed1 */
+ {238, 99, 99, 3618}, /* IndianRed2 */
+ {205, 85, 85, 3629}, /* IndianRed3 */
+ {139, 58, 58, 3640}, /* IndianRed4 */
+ {75, 0, 130, 3651}, /* indigo */
+ {255, 255, 240, 3658}, /* ivory */
+ {255, 255, 240, 3664}, /* ivory1 */
+ {238, 238, 224, 3671}, /* ivory2 */
+ {205, 205, 193, 3678}, /* ivory3 */
+ {139, 139, 131, 3685}, /* ivory4 */
+ {240, 230, 140, 3692}, /* khaki */
+ {255, 246, 143, 3698}, /* khaki1 */
+ {238, 230, 133, 3705}, /* khaki2 */
+ {205, 198, 115, 3712}, /* khaki3 */
+ {139, 134, 78, 3719}, /* khaki4 */
+ {230, 230, 250, 3726}, /* lavender */
+ {255, 240, 245, 3735}, /* lavender blush */
+ {255, 240, 245, 3750}, /* LavenderBlush */
+ {255, 240, 245, 3764}, /* LavenderBlush1 */
+ {238, 224, 229, 3779}, /* LavenderBlush2 */
+ {205, 193, 197, 3794}, /* LavenderBlush3 */
+ {139, 131, 134, 3809}, /* LavenderBlush4 */
+ {124, 252, 0, 3824}, /* lawn green */
+ {124, 252, 0, 3835}, /* LawnGreen */
+ {255, 250, 205, 3845}, /* lemon chiffon */
+ {255, 250, 205, 3859}, /* LemonChiffon */
+ {255, 250, 205, 3872}, /* LemonChiffon1 */
+ {238, 233, 191, 3886}, /* LemonChiffon2 */
+ {205, 201, 165, 3900}, /* LemonChiffon3 */
+ {139, 137, 112, 3914}, /* LemonChiffon4 */
+ {173, 216, 230, 3928}, /* light blue */
+ {240, 128, 128, 3939}, /* light coral */
+ {224, 255, 255, 3951}, /* light cyan */
+ {238, 221, 130, 3962}, /* light goldenrod */
+ {250, 250, 210, 3978}, /* light goldenrod yellow */
+ {211, 211, 211, 4001}, /* light gray */
+ {144, 238, 144, 4012}, /* light green */
+ {211, 211, 211, 4024}, /* light grey */
+ {255, 182, 193, 4035}, /* light pink */
+ {255, 160, 122, 4046}, /* light salmon */
+ {32, 178, 170, 4059}, /* light sea green */
+ {135, 206, 250, 4075}, /* light sky blue */
+ {132, 112, 255, 4090}, /* light slate blue */
+ {119, 136, 153, 4107}, /* light slate gray */
+ {119, 136, 153, 4124}, /* light slate grey */
+ {176, 196, 222, 4141}, /* light steel blue */
+ {255, 255, 224, 4158}, /* light yellow */
+ {173, 216, 230, 4171}, /* LightBlue */
+ {191, 239, 255, 4181}, /* LightBlue1 */
+ {178, 223, 238, 4192}, /* LightBlue2 */
+ {154, 192, 205, 4203}, /* LightBlue3 */
+ {104, 131, 139, 4214}, /* LightBlue4 */
+ {240, 128, 128, 4225}, /* LightCoral */
+ {224, 255, 255, 4236}, /* LightCyan */
+ {224, 255, 255, 4246}, /* LightCyan1 */
+ {209, 238, 238, 4257}, /* LightCyan2 */
+ {180, 205, 205, 4268}, /* LightCyan3 */
+ {122, 139, 139, 4279}, /* LightCyan4 */
+ {238, 221, 130, 4290}, /* LightGoldenrod */
+ {255, 236, 139, 4305}, /* LightGoldenrod1 */
+ {238, 220, 130, 4321}, /* LightGoldenrod2 */
+ {205, 190, 112, 4337}, /* LightGoldenrod3 */
+ {139, 129, 76, 4353}, /* LightGoldenrod4 */
+ {250, 250, 210, 4369}, /* LightGoldenrodYellow */
+ {211, 211, 211, 4390}, /* LightGray */
+ {144, 238, 144, 4400}, /* LightGreen */
+ {211, 211, 211, 4411}, /* LightGrey */
+ {255, 182, 193, 4421}, /* LightPink */
+ {255, 174, 185, 4431}, /* LightPink1 */
+ {238, 162, 173, 4442}, /* LightPink2 */
+ {205, 140, 149, 4453}, /* LightPink3 */
+ {139, 95, 101, 4464}, /* LightPink4 */
+ {255, 160, 122, 4475}, /* LightSalmon */
+ {255, 160, 122, 4487}, /* LightSalmon1 */
+ {238, 149, 114, 4500}, /* LightSalmon2 */
+ {205, 129, 98, 4513}, /* LightSalmon3 */
+ {139, 87, 66, 4526}, /* LightSalmon4 */
+ {32, 178, 170, 4539}, /* LightSeaGreen */
+ {135, 206, 250, 4553}, /* LightSkyBlue */
+ {176, 226, 255, 4566}, /* LightSkyBlue1 */
+ {164, 211, 238, 4580}, /* LightSkyBlue2 */
+ {141, 182, 205, 4594}, /* LightSkyBlue3 */
+ {96, 123, 139, 4608}, /* LightSkyBlue4 */
+ {132, 112, 255, 4622}, /* LightSlateBlue */
+ {119, 136, 153, 4637}, /* LightSlateGray */
+ {119, 136, 153, 4652}, /* LightSlateGrey */
+ {176, 196, 222, 4667}, /* LightSteelBlue */
+ {202, 225, 255, 4682}, /* LightSteelBlue1 */
+ {188, 210, 238, 4698}, /* LightSteelBlue2 */
+ {162, 181, 205, 4714}, /* LightSteelBlue3 */
+ {110, 123, 139, 4730}, /* LightSteelBlue4 */
+ {255, 255, 224, 4746}, /* LightYellow */
+ {255, 255, 224, 4758}, /* LightYellow1 */
+ {238, 238, 209, 4771}, /* LightYellow2 */
+ {205, 205, 180, 4784}, /* LightYellow3 */
+ {139, 139, 122, 4797}, /* LightYellow4 */
+ {0, 255, 0, 4810}, /* lime */
+ {50, 205, 50, 4815}, /* lime green */
+ {50, 205, 50, 4826}, /* LimeGreen */
+ {250, 240, 230, 4836}, /* linen */
+ {255, 0, 255, 4842}, /* magenta */
+ {255, 0, 255, 4850}, /* magenta1 */
+ {238, 0, 238, 4859}, /* magenta2 */
+ {205, 0, 205, 4868}, /* magenta3 */
+ {139, 0, 139, 4877}, /* magenta4 */
+ {176, 48, 96, 4886}, /* maroon */
+ {255, 52, 179, 4893}, /* maroon1 */
+ {238, 48, 167, 4901}, /* maroon2 */
+ {205, 41, 144, 4909}, /* maroon3 */
+ {139, 28, 98, 4917}, /* maroon4 */
+ {102, 205, 170, 4925}, /* medium aquamarine */
+ {0, 0, 205, 4943}, /* medium blue */
+ {186, 85, 211, 4955}, /* medium orchid */
+ {147, 112, 219, 4969}, /* medium purple */
+ {60, 179, 113, 4983}, /* medium sea green */
+ {123, 104, 238, 5000}, /* medium slate blue */
+ {0, 250, 154, 5018}, /* medium spring green */
+ {72, 209, 204, 5038}, /* medium turquoise */
+ {199, 21, 133, 5055}, /* medium violet red */
+ {102, 205, 170, 5073}, /* MediumAquamarine */
+ {0, 0, 205, 5090}, /* MediumBlue */
+ {186, 85, 211, 5101}, /* MediumOrchid */
+ {224, 102, 255, 5114}, /* MediumOrchid1 */
+ {209, 95, 238, 5128}, /* MediumOrchid2 */
+ {180, 82, 205, 5142}, /* MediumOrchid3 */
+ {122, 55, 139, 5156}, /* MediumOrchid4 */
+ {147, 112, 219, 5170}, /* MediumPurple */
+ {171, 130, 255, 5183}, /* MediumPurple1 */
+ {159, 121, 238, 5197}, /* MediumPurple2 */
+ {137, 104, 205, 5211}, /* MediumPurple3 */
+ {93, 71, 139, 5225}, /* MediumPurple4 */
+ {60, 179, 113, 5239}, /* MediumSeaGreen */
+ {123, 104, 238, 5254}, /* MediumSlateBlue */
+ {0, 250, 154, 5270}, /* MediumSpringGreen */
+ {72, 209, 204, 5288}, /* MediumTurquoise */
+ {199, 21, 133, 5304}, /* MediumVioletRed */
+ {25, 25, 112, 5320}, /* midnight blue */
+ {25, 25, 112, 5334}, /* MidnightBlue */
+ {245, 255, 250, 5347}, /* mint cream */
+ {245, 255, 250, 5358}, /* MintCream */
+ {255, 228, 225, 5368}, /* misty rose */
+ {255, 228, 225, 5379}, /* MistyRose */
+ {255, 228, 225, 5389}, /* MistyRose1 */
+ {238, 213, 210, 5400}, /* MistyRose2 */
+ {205, 183, 181, 5411}, /* MistyRose3 */
+ {139, 125, 123, 5422}, /* MistyRose4 */
+ {255, 228, 181, 5433}, /* moccasin */
+ {255, 222, 173, 5442}, /* navajo white */
+ {255, 222, 173, 5455}, /* NavajoWhite */
+ {255, 222, 173, 5467}, /* NavajoWhite1 */
+ {238, 207, 161, 5480}, /* NavajoWhite2 */
+ {205, 179, 139, 5493}, /* NavajoWhite3 */
+ {139, 121, 94, 5506}, /* NavajoWhite4 */
+ {0, 0, 128, 5519}, /* navy */
+ {0, 0, 128, 5524}, /* navy blue */
+ {0, 0, 128, 5534}, /* NavyBlue */
+ {253, 245, 230, 5543}, /* old lace */
+ {253, 245, 230, 5552}, /* OldLace */
+ {128, 128, 0, 5560}, /* olive */
+ {107, 142, 35, 5566}, /* olive drab */
+ {107, 142, 35, 5577}, /* OliveDrab */
+ {192, 255, 62, 5587}, /* OliveDrab1 */
+ {179, 238, 58, 5598}, /* OliveDrab2 */
+ {154, 205, 50, 5609}, /* OliveDrab3 */
+ {105, 139, 34, 5620}, /* OliveDrab4 */
+ {255, 165, 0, 5631}, /* orange */
+ {255, 69, 0, 5638}, /* orange red */
+ {255, 165, 0, 5649}, /* orange1 */
+ {238, 154, 0, 5657}, /* orange2 */
+ {205, 133, 0, 5665}, /* orange3 */
+ {139, 90, 0, 5673}, /* orange4 */
+ {255, 69, 0, 5681}, /* OrangeRed */
+ {255, 69, 0, 5691}, /* OrangeRed1 */
+ {238, 64, 0, 5702}, /* OrangeRed2 */
+ {205, 55, 0, 5713}, /* OrangeRed3 */
+ {139, 37, 0, 5724}, /* OrangeRed4 */
+ {218, 112, 214, 5735}, /* orchid */
+ {255, 131, 250, 5742}, /* orchid1 */
+ {238, 122, 233, 5750}, /* orchid2 */
+ {205, 105, 201, 5758}, /* orchid3 */
+ {139, 71, 137, 5766}, /* orchid4 */
+ {238, 232, 170, 5774}, /* pale goldenrod */
+ {152, 251, 152, 5789}, /* pale green */
+ {175, 238, 238, 5800}, /* pale turquoise */
+ {219, 112, 147, 5815}, /* pale violet red */
+ {238, 232, 170, 5831}, /* PaleGoldenrod */
+ {152, 251, 152, 5845}, /* PaleGreen */
+ {154, 255, 154, 5855}, /* PaleGreen1 */
+ {144, 238, 144, 5866}, /* PaleGreen2 */
+ {124, 205, 124, 5877}, /* PaleGreen3 */
+ {84, 139, 84, 5888}, /* PaleGreen4 */
+ {175, 238, 238, 5899}, /* PaleTurquoise */
+ {187, 255, 255, 5913}, /* PaleTurquoise1 */
+ {174, 238, 238, 5928}, /* PaleTurquoise2 */
+ {150, 205, 205, 5943}, /* PaleTurquoise3 */
+ {102, 139, 139, 5958}, /* PaleTurquoise4 */
+ {219, 112, 147, 5973}, /* PaleVioletRed */
+ {255, 130, 171, 5987}, /* PaleVioletRed1 */
+ {238, 121, 159, 6002}, /* PaleVioletRed2 */
+ {205, 104, 137, 6017}, /* PaleVioletRed3 */
+ {139, 71, 93, 6032}, /* PaleVioletRed4 */
+ {255, 239, 213, 6047}, /* papaya whip */
+ {255, 239, 213, 6059}, /* PapayaWhip */
+ {255, 218, 185, 6070}, /* peach puff */
+ {255, 218, 185, 6081}, /* PeachPuff */
+ {255, 218, 185, 6091}, /* PeachPuff1 */
+ {238, 203, 173, 6102}, /* PeachPuff2 */
+ {205, 175, 149, 6113}, /* PeachPuff3 */
+ {139, 119, 101, 6124}, /* PeachPuff4 */
+ {205, 133, 63, 6135}, /* peru */
+ {255, 192, 203, 6140}, /* pink */
+ {255, 181, 197, 6145}, /* pink1 */
+ {238, 169, 184, 6151}, /* pink2 */
+ {205, 145, 158, 6157}, /* pink3 */
+ {139, 99, 108, 6163}, /* pink4 */
+ {221, 160, 221, 6169}, /* plum */
+ {255, 187, 255, 6174}, /* plum1 */
+ {238, 174, 238, 6180}, /* plum2 */
+ {205, 150, 205, 6186}, /* plum3 */
+ {139, 102, 139, 6192}, /* plum4 */
+ {176, 224, 230, 6198}, /* powder blue */
+ {176, 224, 230, 6210}, /* PowderBlue */
+ {160, 32, 240, 6221}, /* purple */
+ {155, 48, 255, 6228}, /* purple1 */
+ {145, 44, 238, 6236}, /* purple2 */
+ {125, 38, 205, 6244}, /* purple3 */
+ {85, 26, 139, 6252}, /* purple4 */
+ {102, 51, 153, 6260}, /* rebecca purple */
+ {102, 51, 153, 6275}, /* RebeccaPurple */
+ {255, 0, 0, 6289}, /* red */
+ {255, 0, 0, 6293}, /* red1 */
+ {238, 0, 0, 6298}, /* red2 */
+ {205, 0, 0, 6303}, /* red3 */
+ {139, 0, 0, 6308}, /* red4 */
+ {188, 143, 143, 6313}, /* rosy brown */
+ {188, 143, 143, 6324}, /* RosyBrown */
+ {255, 193, 193, 6334}, /* RosyBrown1 */
+ {238, 180, 180, 6345}, /* RosyBrown2 */
+ {205, 155, 155, 6356}, /* RosyBrown3 */
+ {139, 105, 105, 6367}, /* RosyBrown4 */
+ {65, 105, 225, 6378}, /* royal blue */
+ {65, 105, 225, 6389}, /* RoyalBlue */
+ {72, 118, 255, 6399}, /* RoyalBlue1 */
+ {67, 110, 238, 6410}, /* RoyalBlue2 */
+ {58, 95, 205, 6421}, /* RoyalBlue3 */
+ {39, 64, 139, 6432}, /* RoyalBlue4 */
+ {139, 69, 19, 6443}, /* saddle brown */
+ {139, 69, 19, 6456}, /* SaddleBrown */
+ {250, 128, 114, 6468}, /* salmon */
+ {255, 140, 105, 6475}, /* salmon1 */
+ {238, 130, 98, 6483}, /* salmon2 */
+ {205, 112, 84, 6491}, /* salmon3 */
+ {139, 76, 57, 6499}, /* salmon4 */
+ {244, 164, 96, 6507}, /* sandy brown */
+ {244, 164, 96, 6519}, /* SandyBrown */
+ {46, 139, 87, 6530}, /* sea green */
+ {46, 139, 87, 6540}, /* SeaGreen */
+ {84, 255, 159, 6549}, /* SeaGreen1 */
+ {78, 238, 148, 6559}, /* SeaGreen2 */
+ {67, 205, 128, 6569}, /* SeaGreen3 */
+ {46, 139, 87, 6579}, /* SeaGreen4 */
+ {255, 245, 238, 6589}, /* seashell */
+ {255, 245, 238, 6598}, /* seashell1 */
+ {238, 229, 222, 6608}, /* seashell2 */
+ {205, 197, 191, 6618}, /* seashell3 */
+ {139, 134, 130, 6628}, /* seashell4 */
+ {160, 82, 45, 6638}, /* sienna */
+ {255, 130, 71, 6645}, /* sienna1 */
+ {238, 121, 66, 6653}, /* sienna2 */
+ {205, 104, 57, 6661}, /* sienna3 */
+ {139, 71, 38, 6669}, /* sienna4 */
+ {192, 192, 192, 6677}, /* silver */
+ {135, 206, 235, 6684}, /* sky blue */
+ {135, 206, 235, 6693}, /* SkyBlue */
+ {135, 206, 255, 6701}, /* SkyBlue1 */
+ {126, 192, 238, 6710}, /* SkyBlue2 */
+ {108, 166, 205, 6719}, /* SkyBlue3 */
+ {74, 112, 139, 6728}, /* SkyBlue4 */
+ {106, 90, 205, 6737}, /* slate blue */
+ {112, 128, 144, 6748}, /* slate gray */
+ {112, 128, 144, 6759}, /* slate grey */
+ {106, 90, 205, 6770}, /* SlateBlue */
+ {131, 111, 255, 6780}, /* SlateBlue1 */
+ {122, 103, 238, 6791}, /* SlateBlue2 */
+ {105, 89, 205, 6802}, /* SlateBlue3 */
+ {71, 60, 139, 6813}, /* SlateBlue4 */
+ {112, 128, 144, 6824}, /* SlateGray */
+ {198, 226, 255, 6834}, /* SlateGray1 */
+ {185, 211, 238, 6845}, /* SlateGray2 */
+ {159, 182, 205, 6856}, /* SlateGray3 */
+ {108, 123, 139, 6867}, /* SlateGray4 */
+ {112, 128, 144, 6878}, /* SlateGrey */
+ {255, 250, 250, 6888}, /* snow */
+ {255, 250, 250, 6893}, /* snow1 */
+ {238, 233, 233, 6899}, /* snow2 */
+ {205, 201, 201, 6905}, /* snow3 */
+ {139, 137, 137, 6911}, /* snow4 */
+ {0, 255, 127, 6917}, /* spring green */
+ {0, 255, 127, 6930}, /* SpringGreen */
+ {0, 255, 127, 6942}, /* SpringGreen1 */
+ {0, 238, 118, 6955}, /* SpringGreen2 */
+ {0, 205, 102, 6968}, /* SpringGreen3 */
+ {0, 139, 69, 6981}, /* SpringGreen4 */
+ {70, 130, 180, 6994}, /* steel blue */
+ {70, 130, 180, 7005}, /* SteelBlue */
+ {99, 184, 255, 7015}, /* SteelBlue1 */
+ {92, 172, 238, 7026}, /* SteelBlue2 */
+ {79, 148, 205, 7037}, /* SteelBlue3 */
+ {54, 100, 139, 7048}, /* SteelBlue4 */
+ {210, 180, 140, 7059}, /* tan */
+ {255, 165, 79, 7063}, /* tan1 */
+ {238, 154, 73, 7068}, /* tan2 */
+ {205, 133, 63, 7073}, /* tan3 */
+ {139, 90, 43, 7078}, /* tan4 */
+ {0, 128, 128, 7083}, /* teal */
+ {216, 191, 216, 7088}, /* thistle */
+ {255, 225, 255, 7096}, /* thistle1 */
+ {238, 210, 238, 7105}, /* thistle2 */
+ {205, 181, 205, 7114}, /* thistle3 */
+ {139, 123, 139, 7123}, /* thistle4 */
+ {255, 99, 71, 7132}, /* tomato */
+ {255, 99, 71, 7139}, /* tomato1 */
+ {238, 92, 66, 7147}, /* tomato2 */
+ {205, 79, 57, 7155}, /* tomato3 */
+ {139, 54, 38, 7163}, /* tomato4 */
+ {64, 224, 208, 7171}, /* turquoise */
+ {0, 245, 255, 7181}, /* turquoise1 */
+ {0, 229, 238, 7192}, /* turquoise2 */
+ {0, 197, 205, 7203}, /* turquoise3 */
+ {0, 134, 139, 7214}, /* turquoise4 */
+ {238, 130, 238, 7225}, /* violet */
+ {208, 32, 144, 7232}, /* violet red */
+ {208, 32, 144, 7243}, /* VioletRed */
+ {255, 62, 150, 7253}, /* VioletRed1 */
+ {238, 58, 140, 7264}, /* VioletRed2 */
+ {205, 50, 120, 7275}, /* VioletRed3 */
+ {139, 34, 82, 7286}, /* VioletRed4 */
+ {128, 128, 128, 7297}, /* web gray */
+ {0, 128, 0, 7306}, /* web green */
+ {128, 128, 128, 7316}, /* web grey */
+ {128, 0, 0, 7325}, /* web maroon */
+ {128, 0, 128, 7336}, /* web purple */
+ {128, 128, 128, 7347}, /* WebGray */
+ {0, 128, 0, 7355}, /* WebGreen */
+ {128, 128, 128, 7364}, /* WebGrey */
+ {128, 0, 0, 7372}, /* WebMaroon */
+ {128, 0, 128, 7382}, /* WebPurple */
+ {245, 222, 179, 7392}, /* wheat */
+ {255, 231, 186, 7398}, /* wheat1 */
+ {238, 216, 174, 7405}, /* wheat2 */
+ {205, 186, 150, 7412}, /* wheat3 */
+ {139, 126, 102, 7419}, /* wheat4 */
+ {255, 255, 255, 7426}, /* white */
+ {245, 245, 245, 7432}, /* white smoke */
+ {245, 245, 245, 7444}, /* WhiteSmoke */
+ {190, 190, 190, 7455}, /* x11 gray */
+ {0, 255, 0, 7464}, /* x11 green */
+ {190, 190, 190, 7474}, /* x11 grey */
+ {176, 48, 96, 7483}, /* x11 maroon */
+ {160, 32, 240, 7494}, /* x11 purple */
+ {190, 190, 190, 7505}, /* X11Gray */
+ {0, 255, 0, 7513}, /* X11Green */
+ {190, 190, 190, 7522}, /* X11Grey */
+ {176, 48, 96, 7530}, /* X11Maroon */
+ {160, 32, 240, 7540}, /* X11Purple */
+ {255, 255, 0, 7550}, /* yellow */
+ {154, 205, 50, 7557}, /* yellow green */
+ {255, 255, 0, 7570}, /* yellow1 */
+ {238, 238, 0, 7578}, /* yellow2 */
+ {205, 205, 0, 7586}, /* yellow3 */
+ {139, 139, 0, 7594}, /* yellow4 */
+ {154, 205, 50, 7602}, /* YellowGreen */
+};
+
+#define NUM_BUILTIN_COLORS (sizeof (BuiltinColors) / sizeof (BuiltinColors[0]))
+
+Bool
+OsLookupColor(int screen,
+ char *name,
+ unsigned int len,
+ unsigned short *pred,
+ unsigned short *pgreen, unsigned short *pblue)
+{
+ const BuiltinColor *c;
+ int low, mid, high;
+ int r;
+
+ low = 0;
+ high = NUM_BUILTIN_COLORS - 1;
+ while (high >= low) {
+ mid = (low + high) / 2;
+ c = &BuiltinColors[mid];
+ r = strncasecmp(&BuiltinColorNames[c->name], name, len);
+ if (r == 0 && len == strlen(&BuiltinColorNames[c->name])) {
+ *pred = c->red * 0x101;
+ *pgreen = c->green * 0x101;
+ *pblue = c->blue * 0x101;
+ return TRUE;
+ }
+ if (r < 0)
+ low = mid + 1;
+ else
+ high = mid - 1;
+ }
+ return FALSE;
+}
diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h
new file mode 100644
index 000000000..d3e9d0b33
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/osdep.h
@@ -0,0 +1,313 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _OSDEP_H_
+#define _OSDEP_H_ 1
+
+#define BUFSIZE 4096
+#define BUFWATERMARK 8192
+#ifndef MAXBUFSIZE
+#define MAXBUFSIZE (1 << 22)
+#endif
+
+#include <X11/Xdmcp.h>
+
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#else /* X_NOT_POSIX */
+#ifdef WIN32
+#define _POSIX_
+#include <limits.h>
+#undef _POSIX_
+#endif
+#endif /* X_NOT_POSIX */
+
+#ifndef OPEN_MAX
+#ifdef SVR4
+#define OPEN_MAX 256
+#else
+#include <sys/param.h>
+#ifndef OPEN_MAX
+#if defined(NOFILE) && !defined(NOFILES_MAX)
+#define OPEN_MAX NOFILE
+#else
+#if !defined(WIN32)
+#define OPEN_MAX NOFILES_MAX
+#else
+#define OPEN_MAX 256
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#include <nx-X11/Xpoll.h>
+
+/*
+ * MAXSOCKS is used only for initialising MaxClients when no other method
+ * like sysconf(_SC_OPEN_MAX) is not supported.
+ */
+
+#if OPEN_MAX <= 256
+#define MAXSOCKS (OPEN_MAX - 1)
+#else
+#define MAXSOCKS 256
+#endif
+
+/* MAXSELECT is the number of fds that select() can handle */
+#define MAXSELECT (sizeof(fd_set) * NBBY)
+
+#if !defined(SVR4) && !defined(SYSV)
+#define HAS_GETDTABLESIZE
+#endif
+
+#include <stddef.h>
+
+typedef Bool (*ValidatorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
+typedef Bool (*GeneratorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
+typedef Bool (*AddAuthorFunc)(unsigned name_length, char *name, unsigned data_length, char *data);
+
+typedef struct _connectionInput {
+ struct _connectionInput *next;
+ char *buffer; /* contains current client input */
+ char *bufptr; /* pointer to current start of data */
+ int bufcnt; /* count of bytes in buffer */
+ int lenLastReq;
+ int size;
+ unsigned int ignoreBytes; /* bytes to ignore before the next request */
+} ConnectionInput, *ConnectionInputPtr;
+
+typedef struct _connectionOutput {
+ struct _connectionOutput *next;
+ int size;
+ unsigned char *buf;
+ int count;
+} ConnectionOutput, *ConnectionOutputPtr;
+
+struct _osComm;
+
+#define AuthInitArgs void
+typedef void (*AuthInitFunc) (AuthInitArgs);
+
+#define AuthAddCArgs unsigned short data_length, char *data, XID id
+typedef int (*AuthAddCFunc) (AuthAddCArgs);
+
+#define AuthCheckArgs unsigned short data_length, char *data, ClientPtr client, char **reason
+typedef XID (*AuthCheckFunc) (AuthCheckArgs);
+
+#define AuthFromIDArgs XID id, unsigned short *data_lenp, char **datap
+typedef int (*AuthFromIDFunc) (AuthFromIDArgs);
+
+#define AuthGenCArgs unsigned data_length, char *data, XID id, unsigned *data_length_return, char **data_return
+typedef XID (*AuthGenCFunc) (AuthGenCArgs);
+
+#define AuthRemCArgs unsigned short data_length, char *data
+typedef int (*AuthRemCFunc) (AuthRemCArgs);
+
+#define AuthRstCArgs void
+typedef int (*AuthRstCFunc) (AuthRstCArgs);
+
+#define AuthToIDArgs unsigned short data_length, char *data
+typedef XID (*AuthToIDFunc) (AuthToIDArgs);
+
+typedef void (*OsCloseFunc)(ClientPtr);
+
+typedef int (*OsFlushFunc)(ClientPtr who, struct _osComm * oc, char* extraBuf, int extraCount);
+
+typedef struct _osComm {
+ int fd;
+ ConnectionInputPtr input;
+ ConnectionOutputPtr output;
+ XID auth_id; /* authorization id */
+ CARD32 conn_time; /* timestamp if not established, else 0 */
+ struct _XtransConnInfo *trans_conn; /* transport connection object */
+} OsCommRec, *OsCommPtr;
+
+extern int FlushClient(
+ ClientPtr /*who*/,
+ OsCommPtr /*oc*/,
+ const void * /*__extraBuf*/,
+ int /*extraCount*/
+);
+
+extern void FreeOsBuffers(
+ OsCommPtr /*oc*/
+);
+
+extern void InitNotifyFds(void);
+
+extern void HandleNotifyFds(void);
+
+#include "dix.h"
+
+extern ConnectionInputPtr AllocateInputBuffer(void);
+
+extern ConnectionOutputPtr AllocateOutputBuffer(void);
+
+extern fd_set AllSockets;
+extern fd_set AllClients;
+extern fd_set LastSelectMask;
+extern fd_set LastSelectWriteMask;
+extern fd_set WellKnownConnections;
+extern fd_set EnabledDevices;
+extern fd_set NotifyReadFds;
+extern fd_set NotifyWriteFds;
+extern fd_set ClientsWithInput;
+extern fd_set ClientsWriteBlocked;
+extern fd_set OutputPending;
+extern fd_set IgnoredClientsWithInput;
+
+#ifndef WIN32
+extern int *ConnectionTranslation;
+#else
+extern int GetConnectionTranslation(int conn);
+extern void SetConnectionTranslation(int conn, int client);
+extern void ClearConnectionTranslation();
+#endif
+
+extern Bool NewOutputPending;
+extern Bool AnyWritesPending;
+extern Bool NumNotifyWriteFd;
+extern Bool CriticalOutputPending;
+
+extern int timesThisConnection;
+extern ConnectionInputPtr FreeInputs;
+extern ConnectionOutputPtr FreeOutputs;
+extern OsCommPtr AvailableInput;
+
+extern WorkQueuePtr workQueue;
+
+/* added by raphael */
+#ifdef WIN32
+typedef long int fd_mask;
+#endif
+#define ffs mffs
+extern int mffs(fd_mask);
+
+/* in access.c */
+extern Bool ComputeLocalClient(ClientPtr client);
+
+/* in auth.c */
+extern void GenerateRandomData (int len, char *buf);
+
+/* in mitauth.c */
+extern XID MitCheckCookie (AuthCheckArgs);
+extern XID MitGenerateCookie (AuthGenCArgs);
+extern XID MitToID (AuthToIDArgs);
+extern int MitAddCookie (AuthAddCArgs);
+extern int MitFromID (AuthFromIDArgs);
+extern int MitRemoveCookie (AuthRemCArgs);
+extern int MitResetCookie (AuthRstCArgs);
+
+/* in xdmauth.c */
+#ifdef HASXDMAUTH
+extern XID XdmCheckCookie (AuthCheckArgs);
+extern XID XdmToID (AuthToIDArgs);
+extern int XdmAddCookie (AuthAddCArgs);
+extern int XdmFromID (AuthFromIDArgs);
+extern int XdmRemoveCookie (AuthRemCArgs);
+extern int XdmResetCookie (AuthRstCArgs);
+#endif
+
+/* in rpcauth.c */
+#ifdef SECURE_RPC
+extern void SecureRPCInit (AuthInitArgs);
+extern XID SecureRPCCheck (AuthCheckArgs);
+extern XID SecureRPCToID (AuthToIDArgs);
+extern int SecureRPCAdd (AuthAddCArgs);
+extern int SecureRPCFromID (AuthFromIDArgs);
+extern int SecureRPCRemove (AuthRemCArgs);
+extern int SecureRPCReset (AuthRstCArgs);
+#endif
+
+/* in secauth.c */
+extern XID AuthSecurityCheck (AuthCheckArgs);
+
+/* in xdmcp.c */
+extern void XdmcpUseMsg (void);
+extern int XdmcpOptions(int argc, char **argv, int i);
+extern void XdmcpSetAuthentication (ARRAY8Ptr name);
+extern void XdmcpRegisterConnection (
+ int type,
+ char *address,
+ int addrlen);
+extern void XdmcpRegisterAuthorizations (void);
+extern void XdmcpRegisterAuthorization (char *name, int namelen);
+extern void XdmcpRegisterDisplayClass (char *name, int length);
+extern void XdmcpInit (void);
+extern void XdmcpReset (void);
+extern void XdmcpOpenDisplay(int sock);
+extern void XdmcpCloseDisplay(int sock);
+extern void XdmcpRegisterAuthentication (
+ char *name,
+ int namelen,
+ char *data,
+ int datalen,
+ ValidatorFunc Validator,
+ GeneratorFunc Generator,
+ AddAuthorFunc AddAuth);
+extern int XdmcpCheckAuthentication (ARRAY8Ptr Name, ARRAY8Ptr Data, int packet_type);
+extern int XdmcpAddAuthorization (ARRAY8Ptr name, ARRAY8Ptr data);
+
+struct sockaddr_in;
+extern void XdmcpRegisterBroadcastAddress (struct sockaddr_in *addr);
+
+#ifdef HASXDMAUTH
+extern void XdmAuthenticationInit (char *cookie, int cookie_length);
+#endif
+
+#endif /* _OSDEP_H_ */
diff --git a/nx-X11/programs/Xserver/os/osinit.c b/nx-X11/programs/Xserver/os/osinit.c
new file mode 100644
index 000000000..a660337ca
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/osinit.c
@@ -0,0 +1,234 @@
+/***********************************************************
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include "os.h"
+#include "osdep.h"
+#include <nx-X11/Xos.h>
+
+#include "dixstruct.h"
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+#if defined(__SCO__)
+#include <sys/wait.h>
+#endif
+
+#if !defined(SYSV) && !defined(WIN32)
+#include <sys/resource.h>
+#endif
+
+#ifndef ADMPATH
+#define ADMPATH "/usr/adm/X%smsgs"
+#endif
+
+extern char *display;
+#ifdef RLIMIT_DATA
+int limitDataSpace = -1;
+#endif
+#ifdef RLIMIT_STACK
+int limitStackSpace = -1;
+#endif
+#ifdef RLIMIT_NOFILE
+int limitNoFile = -1;
+#endif
+
+void
+OsInit(void)
+{
+ static Bool been_here = FALSE;
+ static char* admpath = ADMPATH;
+ static char* devnull = "/dev/null";
+ char fname[PATH_MAX];
+
+#ifdef macII
+ set42sig();
+#endif
+
+ if (!been_here) {
+
+ InitNotifyFds();
+
+#if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__)
+ fclose(stdin);
+ fclose(stdout);
+#endif
+
+
+ /*
+ * If a write of zero bytes to stderr returns non-zero, i.e. -1,
+ * then writing to stderr failed, and we'll write somewhere else
+ * instead. (Apparently this never happens in the Real World.)
+ */
+ if (write (2, fname, 0) == -1)
+ {
+ FILE *err;
+
+ if (strlen (display) + strlen (admpath) + 1 < sizeof fname)
+ sprintf (fname, admpath, display);
+ else
+ strcpy (fname, devnull);
+ /*
+ * uses stdio to avoid os dependencies here,
+ * a real os would use
+ * open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
+ */
+ if (!(err = fopen (fname, "a+")))
+ err = fopen (devnull, "w");
+ if (err && (fileno(err) != 2)) {
+ dup2 (fileno (err), 2);
+ fclose (err);
+ }
+#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__)
+ {
+ static char buf[BUFSIZ];
+ setvbuf (stderr, buf, _IOLBF, BUFSIZ);
+ }
+#else
+ setlinebuf(stderr);
+#endif
+ }
+
+#ifndef X_NOT_POSIX
+ if (getpgrp () == 0)
+ setpgid (0, 0);
+#else
+#if !defined(SYSV) && !defined(WIN32)
+ if (getpgrp (0) == 0)
+ setpgrp (0, getpid ());
+#endif
+#endif
+
+#ifdef RLIMIT_DATA
+ if (limitDataSpace >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_DATA, &rlim))
+ {
+ if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
+ rlim.rlim_cur = limitDataSpace;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_DATA, &rlim);
+ }
+ }
+#endif
+#ifdef RLIMIT_STACK
+ if (limitStackSpace >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_STACK, &rlim))
+ {
+ if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
+ rlim.rlim_cur = limitStackSpace;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_STACK, &rlim);
+ }
+ }
+#endif
+#ifdef RLIMIT_NOFILE
+ if (limitNoFile >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_NOFILE, &rlim))
+ {
+ if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
+ rlim.rlim_cur = limitNoFile;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+#if 0
+ if (rlim.rlim_cur > MAXSOCKS)
+ rlim.rlim_cur = MAXSOCKS;
+#endif
+ (void)setrlimit(RLIMIT_NOFILE, &rlim);
+ }
+ }
+#endif
+#ifdef SERVER_LOCK
+ LockServer();
+#endif
+ been_here = TRUE;
+ }
+ TimerInit();
+#ifdef DDXOSINIT
+ OsVendorInit();
+#endif
+ /*
+ * No log file by default. OsVendorInit() should call LogInit() with the
+ * log file name if logging to a file is desired.
+ */
+ LogInit(NULL, NULL);
+ SmartScheduleInit();
+
+ OsInitAllocator();
+}
+
+void
+OsCleanup(Bool terminating)
+{
+#ifdef SERVER_LOCK
+ if (terminating)
+ {
+ UnlockServer();
+ }
+#endif
+}
diff --git a/nx-X11/programs/Xserver/os/reallocarray.c b/nx-X11/programs/Xserver/os/reallocarray.c
new file mode 100644
index 000000000..c415e09af
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/reallocarray.c
@@ -0,0 +1,43 @@
+/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "os.h"
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+ if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(optr, size * nmemb);
+}
diff --git a/nx-X11/programs/Xserver/os/rpcauth.c b/nx-X11/programs/Xserver/os/rpcauth.c
new file mode 100644
index 000000000..678bedf6c
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/rpcauth.c
@@ -0,0 +1,201 @@
+/*
+
+Copyright 1991, 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.
+
+*/
+
+/*
+ * SUN-DES-1 authentication mechanism
+ * Author: Mayank Choudhary, Sun Microsystems
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef SECURE_RPC
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xauth.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+
+#include <rpc/rpc.h>
+
+#ifdef sun
+/* <rpc/auth.h> only includes this if _KERNEL is #defined... */
+extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *);
+#endif
+
+#ifdef ultrix
+#include <time.h>
+#include <rpc/auth_des.h>
+#endif
+
+static enum auth_stat why;
+
+static char *
+authdes_ezdecode(char *inmsg, int len)
+{
+ struct rpc_msg msg;
+ char cred_area[MAX_AUTH_BYTES];
+ char verf_area[MAX_AUTH_BYTES];
+ char *temp_inmsg;
+ struct svc_req r;
+ bool_t res0, res1;
+ XDR xdr;
+ SVCXPRT xprt;
+
+ temp_inmsg = (char *) malloc(len);
+ if (temp_inmsg == NULL) {
+ why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */
+ return NULL;
+ }
+ memmove(temp_inmsg, inmsg, len);
+
+ memset((char *)&msg, 0, sizeof(msg));
+ memset((char *)&r, 0, sizeof(r));
+ memset(cred_area, 0, sizeof(cred_area));
+ memset(verf_area, 0, sizeof(verf_area));
+
+ msg.rm_call.cb_cred.oa_base = cred_area;
+ msg.rm_call.cb_verf.oa_base = verf_area;
+ why = AUTH_FAILED;
+ xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
+
+ if ((r.rq_clntcred = (caddr_t) malloc(MAX_AUTH_BYTES)) == NULL)
+ goto bad1;
+ r.rq_xprt = &xprt;
+
+ /* decode into msg */
+ res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
+ res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
+ if ( ! (res0 && res1) )
+ goto bad2;
+
+ /* do the authentication */
+
+ r.rq_cred = msg.rm_call.cb_cred; /* read by opaque stuff */
+ if (r.rq_cred.oa_flavor != AUTH_DES) {
+ why = AUTH_TOOWEAK;
+ goto bad2;
+ }
+#ifdef SVR4
+ if ((why = __authenticate(&r, &msg)) != AUTH_OK) {
+#else
+ if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
+#endif
+ goto bad2;
+ }
+ return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
+
+bad2:
+ free(r.rq_clntcred);
+bad1:
+ return ((char *)0); /* ((struct authdes_cred *) NULL); */
+}
+
+static XID rpc_id = (XID) ~0L;
+
+static Bool
+CheckNetName (
+ unsigned char *addr,
+ short len,
+ void * closure
+)
+{
+ return (len == strlen ((char *) closure) &&
+ strncmp ((char *) addr, (char *) closure, len) == 0);
+}
+
+static char rpc_error[MAXNETNAMELEN+50];
+
+XID
+SecureRPCCheck (unsigned short data_length, char *data,
+ ClientPtr client, char **reason)
+{
+ char *fullname;
+
+ if (rpc_id == (XID) ~0L) {
+ *reason = "Secure RPC authorization not initialized";
+ } else {
+ fullname = authdes_ezdecode(data, data_length);
+ if (fullname == (char *)0) {
+ sprintf(rpc_error, "Unable to authenticate secure RPC client (why=%d)", why);
+ *reason = rpc_error;
+ } else {
+ if (ForEachHostInFamily (FamilyNetname, CheckNetName, fullname))
+ return rpc_id;
+ sprintf(rpc_error, "Principal \"%s\" is not authorized to connect",
+ fullname);
+ *reason = rpc_error;
+ }
+ }
+ return (XID) ~0L;
+}
+
+void
+SecureRPCInit (void)
+{
+ if (rpc_id == ~0L)
+ AddAuthorization (9, "SUN-DES-1", 0, (char *) 0);
+}
+
+int
+SecureRPCAdd (unsigned short data_length, char *data, XID id)
+{
+ if (data_length)
+ AddHost ((void *) 0, FamilyNetname, data_length, data);
+ rpc_id = id;
+ return 1;
+}
+
+int
+SecureRPCReset (void)
+{
+ rpc_id = (XID) ~0L;
+ return 1;
+}
+
+XID
+SecureRPCToID (unsigned short data_length, char *data)
+{
+ return rpc_id;
+}
+
+int
+SecureRPCFromID (XID id, unsigned short *data_lenp, char **datap)
+{
+ return 0;
+}
+
+int
+SecureRPCRemove (unsigned short data_length, char *data)
+{
+ return 0;
+}
+#endif /* SECURE_RPC */
diff --git a/nx-X11/programs/Xserver/os/secauth.c b/nx-X11/programs/Xserver/os/secauth.c
new file mode 100644
index 000000000..5219b488a
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/secauth.c
@@ -0,0 +1,203 @@
+/*
+Copyright 1996, 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.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+#include "swaprep.h"
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+static char InvalidPolicyReason[] = "invalid policy specification";
+static char PolicyViolationReason[] = "policy violation";
+
+static Bool
+AuthCheckSitePolicy(
+ unsigned short *data_lengthP,
+ char **dataP,
+ ClientPtr client,
+ char **reason)
+{
+ CARD8 *policy = *(CARD8 **)dataP;
+ int length;
+ Bool permit;
+ int nPolicies;
+ char **sitePolicies;
+ int nSitePolicies;
+ Bool found = FALSE;
+
+ if ((length = *data_lengthP) < 2) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ permit = (*policy++ == 0);
+ nPolicies = (CARD8) *policy++;
+
+ length -= 2;
+
+ sitePolicies = SecurityGetSitePolicyStrings(&nSitePolicies);
+
+ while (nPolicies) {
+ int strLen, sitePolicy;
+
+ if (length == 0) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ strLen = (CARD8) *policy++;
+ if (--length < strLen) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ if (!found)
+ {
+ for (sitePolicy = 0; sitePolicy < nSitePolicies; sitePolicy++)
+ {
+ char *testPolicy = sitePolicies[sitePolicy];
+ if ((strLen == strlen(testPolicy)) &&
+ (strncmp((char *)policy, testPolicy, strLen) == 0))
+ {
+ found = TRUE; /* need to continue parsing the policy... */
+ break;
+ }
+ }
+ }
+
+ policy += strLen;
+ length -= strLen;
+ nPolicies--;
+ }
+
+ if (found != permit)
+ {
+ *reason = PolicyViolationReason;
+ return FALSE;
+ }
+
+ *data_lengthP = length;
+ *dataP = (char *)policy;
+ return TRUE;
+}
+
+XID
+AuthSecurityCheck (
+ unsigned short data_length,
+ char *data,
+ ClientPtr client,
+ char **reason)
+{
+#ifdef XCSECURITY
+ xConnSetupPrefix csp;
+ xReq freq;
+
+ if (client->clientState == ClientStateCheckedSecurity)
+ {
+ *reason = "repeated security check not permitted";
+ return (XID) -1;
+ }
+ else if (data_length > 0)
+ {
+ char policy_mask = *data++;
+
+ if (--data_length == 1) {
+ *reason = InvalidPolicyReason;
+ return (XID) -1;
+ }
+
+ if (policy_mask & 0x01) /* Extensions policy */
+ {
+ /* AuthCheckExtensionPolicy(&data_length, &data, client, reason) */
+ *reason = "security policy not implemented";
+ return (XID) -1;
+ }
+
+ if (policy_mask & 0x02) /* Site policy */
+ {
+ if (!AuthCheckSitePolicy(&data_length, &data, client, reason))
+ return (XID) -1;
+ }
+
+ if (data_length > 0) { /* did we consume the whole policy? */
+ *reason = InvalidPolicyReason;
+ return (XID) -1;
+ }
+
+ }
+ else if (!GetAccessControl())
+ {
+ /*
+ * The client - possibly the X FireWall Proxy - gave
+ * no auth data and host-based authorization is turned
+ * off. In this case, the client should be denied
+ * access to the X server.
+ */
+ *reason = "server host access control is disabled";
+ return (XID) -1;
+ }
+
+ client->clientState = ClientStateCheckingSecurity;
+
+ csp.success = 2 /* Authenticate */;
+ csp.lengthReason = 0;
+ csp.length = 0;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ WriteToClient(client, sz_xConnSetupPrefix, &csp);
+
+ /*
+ * Next time the client sends the real auth data, we want
+ * ProcEstablishConnection to be called.
+ */
+
+ freq.reqType = 1;
+ freq.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ client->swapped = FALSE;
+ if (!InsertFakeRequest(client, (char *)&freq, sz_xReq))
+ {
+ *reason = "internal error";
+ return (XID) -1;
+ }
+
+ return (XID) 0;
+#else
+ *reason = "method not supported";
+ return (XID) -1;
+#endif
+}
diff --git a/nx-X11/programs/Xserver/os/strlcat.c b/nx-X11/programs/Xserver/os/strlcat.c
new file mode 100644
index 000000000..fc137cabb
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/strlcat.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
diff --git a/nx-X11/programs/Xserver/os/strlcpy.c b/nx-X11/programs/Xserver/os/strlcpy.c
new file mode 100644
index 000000000..989d0385e
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/strlcpy.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
diff --git a/nx-X11/programs/Xserver/os/timingsafe_memcmp.c b/nx-X11/programs/Xserver/os/timingsafe_memcmp.c
new file mode 100644
index 000000000..fe87de7bc
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/timingsafe_memcmp.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Google Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+
+#include <limits.h>
+#include <string.h>
+#include <nx-X11/Xfuncproto.h>
+#include "os.h"
+
+int
+timingsafe_memcmp(const void *b1, const void *b2, size_t len)
+{
+ const unsigned char *p1 = b1, *p2 = b2;
+ size_t i;
+ int res = 0, done = 0;
+
+ for (i = 0; i < len; i++) {
+ /* lt is -1 if p1[i] < p2[i]; else 0. */
+ int lt = (p1[i] - p2[i]) >> CHAR_BIT;
+
+ /* gt is -1 if p1[i] > p2[i]; else 0. */
+ int gt = (p2[i] - p1[i]) >> CHAR_BIT;
+
+ /* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
+ int cmp = lt - gt;
+
+ /* set res = cmp if !done. */
+ res |= cmp & ~done;
+
+ /* set done if p1[i] != p2[i]. */
+ done |= lt | gt;
+ }
+
+ return (res);
+}
diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c
new file mode 100644
index 000000000..dd637ca4b
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/utils.c
@@ -0,0 +1,2260 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+
+Copyright 1987, 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.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 Quarterdeck Office Systems.
+
+ 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 and
+Quarterdeck not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+DIGITAL AND QUARTERDECK DISCLAIM 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef __CYGWIN__
+#include <stdlib.h>
+#include <signal.h>
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include <nx-X11/Xwinsock.h>
+#endif
+#include <nx-X11/Xos.h>
+#include <stdio.h>
+#include "misc.h"
+#include <nx-X11/X.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#include "input.h"
+#include "dixfont.h"
+#ifdef HAS_XFONT2
+# include <X11/fonts/libxfont2.h>
+#else
+# include <X11/fonts/fontutil.h>
+#endif /* HAS_XFONT2 */
+#include "osdep.h"
+#ifdef X_POSIX_C_SOURCE
+#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
+#include <signal.h>
+#undef _POSIX_C_SOURCE
+#else
+#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
+#include <signal.h>
+#else
+#define _POSIX_SOURCE
+#include <signal.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#ifndef WIN32
+#include <sys/wait.h>
+#endif
+#if !defined(SYSV) && !defined(WIN32)
+#include <sys/resource.h>
+#endif
+#include <time.h>
+#include <sys/stat.h>
+#include <ctype.h> /* for isspace */
+#include <stdarg.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+
+#include <stdlib.h> /* for malloc() */
+
+#if defined(TCPCONN)
+# ifndef WIN32
+# include <netdb.h>
+# endif
+#endif
+
+#include "opaque.h"
+
+#include "dixstruct.h"
+
+#ifdef XKB
+#include "xkbsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <nx-X11/extensions/security.h>
+#endif
+
+#ifdef RENDER
+#include "picture.h"
+#endif
+
+Bool noTestExtensions;
+#ifdef BIGREQS
+Bool noBigReqExtension = FALSE;
+#endif
+#ifdef COMPOSITE
+/* COMPOSITE is disabled by default for now until the
+ * interface is stable */
+Bool noCompositeExtension = TRUE;
+#endif
+#ifdef DAMAGE
+Bool noDamageExtension = FALSE;
+#endif
+#ifdef DBE
+Bool noDbeExtension = FALSE;
+#endif
+#ifdef DPSEXT
+Bool noDPSExtension = FALSE;
+#endif
+#ifdef DPMSExtension
+Bool noDPMSExtension = FALSE;
+#endif
+#ifdef GLXEXT
+Bool noGlxExtension = FALSE;
+#endif
+#ifdef SCREENSAVER
+Bool noScreenSaverExtension = FALSE;
+#endif
+#ifdef MITSHM
+Bool noMITShmExtension = FALSE;
+#endif
+#ifdef RANDR
+Bool noRRExtension = FALSE;
+Bool noRRXineramaExtension = FALSE;
+#endif
+#ifdef RENDER
+Bool noRenderExtension = FALSE;
+#endif
+#ifdef SHAPE
+Bool noShapeExtension = FALSE;
+#endif
+#ifdef XCSECURITY
+Bool noSecurityExtension = FALSE;
+#endif
+#ifdef XSYNC
+Bool noSyncExtension = FALSE;
+#endif
+#ifdef RES
+Bool noResExtension = FALSE;
+#endif
+#ifdef XCMISC
+Bool noXCMiscExtension = FALSE;
+#endif
+#ifdef XF86BIGFONT
+Bool noXFree86BigfontExtension = FALSE;
+#endif
+#ifdef XF86DRI
+Bool noXFree86DRIExtension = FALSE;
+#endif
+#ifdef XFIXES
+Bool noXFixesExtension = FALSE;
+#endif
+/* |noXkbExtension| is defined in xc/programs/Xserver/xkb/xkbInit.c */
+#ifdef PANORAMIX
+/* Xinerama is disabled by default unless enabled via +xinerama */
+Bool noPanoramiXExtension = TRUE;
+#endif
+#ifdef XINPUT
+Bool noXInputExtension = FALSE;
+#endif
+#ifdef XIDLE
+Bool noXIdleExtension = FALSE;
+#endif
+#ifdef XV
+Bool noXvExtension = FALSE;
+#endif
+
+#define X_INCLUDE_NETDB_H
+#include <nx-X11/Xos_r.h>
+
+#include <errno.h>
+
+#ifdef NX_TRANS_SOCKET
+
+#include <nx/NX.h>
+#include <nx/NXvars.h>
+
+#endif
+
+#ifdef NX_TRANS_EXIT
+
+void (*OsVendorStartRedirectErrorFProc)() = NULL;
+void (*OsVendorEndRedirectErrorFProc)() = NULL;
+
+#endif
+
+Bool CoreDump;
+
+#ifdef PANORAMIX
+Bool PanoramiXVisibilityNotifySent = FALSE;
+Bool PanoramiXMapped = FALSE;
+Bool PanoramiXWindowExposureSent = FALSE;
+Bool PanoramiXOneExposeRequest = FALSE;
+Bool PanoramiXExtensionDisabledHack = FALSE;
+#endif
+
+int auditTrailLevel = 1;
+
+Bool Must_have_memory = FALSE;
+
+#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
+#define HAS_SAVED_IDS_AND_SETEUID
+#endif
+
+#ifdef MEMBUG
+#define MEM_FAIL_SCALE 100000
+long Memory_fail = 0;
+#include <stdlib.h> /* for random() */
+#endif
+
+char *dev_tty_from_init = NULL; /* since we need to parse it anyway */
+
+extern char dispatchExceptionAtReset;
+
+/* Extension enable/disable in miinitext.c */
+extern Bool EnableDisableExtension(char *name, Bool enable);
+extern void EnableDisableExtensionError(char *name, Bool enable);
+
+OsSigHandlerPtr
+OsSignal(sig, handler)
+ int sig;
+ OsSigHandlerPtr handler;
+{
+#ifdef X_NOT_POSIX
+ return signal(sig, handler);
+#else
+ struct sigaction act, oact;
+
+ sigemptyset(&act.sa_mask);
+ if (handler != SIG_IGN)
+ sigaddset(&act.sa_mask, sig);
+ act.sa_flags = 0;
+ act.sa_handler = handler;
+ if (sigaction(sig, &act, &oact))
+ perror("sigaction");
+ return oact.sa_handler;
+#endif
+}
+
+#ifdef SERVER_LOCK
+/*
+ * Explicit support for a server lock file like the ones used for UUCP.
+ * For architectures with virtual terminals that can run more than one
+ * server at a time. This keeps the servers from stomping on each other
+ * if the user forgets to give them different display numbers.
+ */
+#define LOCK_DIR "/tmp"
+#define LOCK_TMP_PREFIX "/.tX"
+#define LOCK_PREFIX "/.X"
+#define LOCK_SUFFIX "-lock"
+
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+static Bool StillLocking = FALSE;
+static char LockFile[PATH_MAX];
+static Bool nolock = FALSE;
+
+/*
+ * LockServer --
+ * Check if the server lock file exists. If so, check if the PID
+ * contained inside is valid. If so, then die. Otherwise, create
+ * the lock file containing the PID.
+ */
+void
+LockServer(void)
+{
+ char tmp[PATH_MAX], pid_str[12];
+ int lfd, i, haslock, l_pid, t;
+ char *tmppath = NULL;
+ int len;
+ char port[20];
+
+ if (nolock || NoListenAll) return;
+ /*
+ * Path names
+ */
+ tmppath = LOCK_DIR;
+
+ sprintf(port, "%d", atoi(display));
+ len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
+ strlen(LOCK_TMP_PREFIX);
+ len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
+ if (len > sizeof(LockFile))
+ FatalError("Display name `%s' is too long\n", port);
+ (void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
+ (void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
+
+ /*
+ * Create a temporary file containing our PID. Attempt three times
+ * to create the file.
+ */
+ StillLocking = TRUE;
+ i = 0;
+ do {
+ i++;
+ lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (lfd < 0)
+ sleep(2);
+ else
+ break;
+ } while (i < 3);
+ if (lfd < 0) {
+ unlink(tmp);
+ i = 0;
+ do {
+ i++;
+ lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (lfd < 0)
+ sleep(2);
+ else
+ break;
+ } while (i < 3);
+ }
+ if (lfd < 0)
+ FatalError("Could not create lock file in %s\n", tmp);
+ (void) sprintf(pid_str, "%10ld\n", (long)getpid());
+ if (write(lfd, pid_str, 11) != 11)
+ FatalError("Could not write pid to lock file in %s\n", tmp);
+
+#ifndef USE_CHMOD
+ (void) fchmod(lfd, 0444);
+#else
+ (void) chmod(tmp, 0444);
+#endif
+ (void) close(lfd);
+
+ /*
+ * OK. Now the tmp file exists. Try three times to move it in place
+ * for the lock.
+ */
+ i = 0;
+ haslock = 0;
+ while ((!haslock) && (i++ < 3)) {
+ haslock = (link(tmp,LockFile) == 0);
+ if (haslock) {
+ /*
+ * We're done.
+ */
+ break;
+ }
+ else {
+ /*
+ * Read the pid from the existing file
+ */
+ lfd = open(LockFile, O_RDONLY|O_NOFOLLOW);
+ if (lfd < 0) {
+ unlink(tmp);
+ FatalError("Can't read lock file %s\n", LockFile);
+ }
+ pid_str[0] = '\0';
+ if (read(lfd, pid_str, 11) != 11) {
+ /*
+ * Bogus lock file.
+ */
+ unlink(LockFile);
+ close(lfd);
+ continue;
+ }
+ pid_str[11] = '\0';
+ sscanf(pid_str, "%d", &l_pid);
+ close(lfd);
+
+ /*
+ * Now try to kill the PID to see if it exists.
+ */
+ errno = 0;
+ t = kill(l_pid, 0);
+ if ((t< 0) && (errno == ESRCH)) {
+ /*
+ * Stale lock file.
+ */
+ unlink(LockFile);
+ continue;
+ }
+ else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
+ /*
+ * Process is still active.
+ */
+ unlink(tmp);
+ FatalError("Server is already active for display %s\n%s %s\n%s\n",
+ port, "\tIf this server is no longer running, remove",
+ LockFile, "\tand start again.");
+ }
+ }
+ }
+ unlink(tmp);
+ if (!haslock)
+ FatalError("Could not create server lock file: %s\n", LockFile);
+ StillLocking = FALSE;
+}
+
+/*
+ * UnlockServer --
+ * Remove the server lock file.
+ */
+void
+UnlockServer(void)
+{
+ if (nolock || NoListenAll) return;
+
+ if (!StillLocking){
+
+ (void) unlink(LockFile);
+ }
+}
+#endif /* SERVER_LOCK */
+
+/* Force connections to close on SIGHUP from init */
+
+/*ARGSUSED*/
+SIGVAL
+AutoResetServer (int sig)
+{
+ int olderrno = errno;
+
+ dispatchException |= DE_RESET;
+ isItTimeToYield = TRUE;
+#ifdef GPROF
+ chdir ("/tmp");
+ exit (0);
+#endif
+#if defined(SYSV) && defined(X_NOT_POSIX)
+ OsSignal (SIGHUP, AutoResetServer);
+#endif
+ errno = olderrno;
+}
+
+/* Force connections to close and then exit on SIGTERM, SIGINT */
+
+/*ARGSUSED*/
+SIGVAL
+GiveUp(int sig)
+{
+ int olderrno = errno;
+
+#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
+ fprintf(stderr, "GiveUp: Called with signal [%d].\n", sig);
+#endif
+
+ dispatchException |= DE_TERMINATE;
+ isItTimeToYield = TRUE;
+#if defined(SYSV) && defined(X_NOT_POSIX)
+ if (sig)
+ OsSignal(sig, SIG_IGN);
+#endif
+ errno = olderrno;
+}
+
+#ifndef DDXTIME
+CARD32
+GetTimeInMillis(void)
+{
+ struct timeval tp;
+
+ X_GETTIMEOFDAY(&tp);
+ return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+#endif
+
+void
+AdjustWaitForDelay (void * waitTime, unsigned long newdelay)
+{
+ static struct timeval delay_val;
+ struct timeval **wt = (struct timeval **) waitTime;
+ unsigned long olddelay;
+
+ if (*wt == NULL)
+ {
+ delay_val.tv_sec = newdelay / 1000;
+ delay_val.tv_usec = 1000 * (newdelay % 1000);
+ *wt = &delay_val;
+ }
+ else
+ {
+ olddelay = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000;
+ if (newdelay < olddelay)
+ {
+ (*wt)->tv_sec = newdelay / 1000;
+ (*wt)->tv_usec = 1000 * (newdelay % 1000);
+ }
+ }
+}
+
+void UseMsg(void)
+{
+ ErrorF("use: X [:<display>] [option]\n");
+ ErrorF("-a # mouse acceleration (pixels)\n");
+ ErrorF("-ac disable access control restrictions\n");
+#ifdef MEMBUG
+ ErrorF("-alloc int chance alloc should fail\n");
+#endif
+ ErrorF("-audit int set audit trail level\n");
+ ErrorF("-auth file select authorization file\n");
+ ErrorF("bc enable bug compatibility\n");
+ ErrorF("-br create root window with black background\n");
+ ErrorF("+bs enable any backing store support\n");
+ ErrorF("-bs disable any backing store support\n");
+ ErrorF("-c turns off key-click\n");
+ ErrorF("c # key-click volume (0-100)\n");
+ ErrorF("-cc int default color visual class\n");
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+ ErrorF("-config file read options from file\n");
+#endif
+ ErrorF("-core generate core dump on fatal error\n");
+ ErrorF("-dpi int screen resolution in dots per inch\n");
+#ifdef DPMSExtension
+ ErrorF("dpms enables VESA DPMS monitor control\n");
+ ErrorF("-dpms disables VESA DPMS monitor control\n");
+#endif
+ ErrorF("-deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs\n");
+ ErrorF("-f # bell base (0-100)\n");
+ ErrorF("-fc string cursor font\n");
+ ErrorF("-fn string default font name\n");
+ ErrorF("-fp string default font path\n");
+ ErrorF("-help prints message with these options\n");
+ ErrorF("-I ignore all remaining arguments\n");
+#ifdef RLIMIT_DATA
+ ErrorF("-ld int limit data space to N Kb\n");
+#endif
+#ifdef RLIMIT_NOFILE
+ ErrorF("-lf int limit number of open files to N\n");
+#endif
+#ifdef RLIMIT_STACK
+ ErrorF("-ls int limit stack space to N Kb\n");
+#endif
+#ifdef SERVER_LOCK
+ ErrorF("-nolock disable the locking mechanism\n");
+#endif
+#ifndef NOLOGOHACK
+ ErrorF("-logo enable logo in screen saver\n");
+ ErrorF("nologo disable logo in screen saver\n");
+#endif
+ ErrorF("-nolisten string don't listen on protocol\n");
+ ErrorF("-noreset don't reset after last client exists\n");
+ ErrorF("-reset reset after last client exists\n");
+ ErrorF("-p # screen-saver pattern duration (minutes)\n");
+ ErrorF("-pn accept failure to listen on all ports\n");
+ ErrorF("-nopn reject failure to listen on all ports\n");
+ ErrorF("-r turns off auto-repeat\n");
+ ErrorF("r turns on auto-repeat \n");
+#ifdef RENDER
+ ErrorF("-render [default|mono|gray|color] set render color alloc policy\n");
+#endif
+ ErrorF("-s # screen-saver timeout (minutes)\n");
+#ifdef XCSECURITY
+ ErrorF("-sp file security policy file\n");
+#endif
+ ErrorF("-su disable any save under support\n");
+ ErrorF("-t # mouse threshold (pixels)\n");
+ ErrorF("-terminate terminate at server reset\n");
+ ErrorF("-to # connection time out\n");
+ ErrorF("-tst disable testing extensions\n");
+ ErrorF("ttyxx server started from init on /dev/ttyxx\n");
+ ErrorF("v video blanking for screen-saver\n");
+ ErrorF("-v screen-saver without video blanking\n");
+ ErrorF("-wm WhenMapped default backing-store\n");
+ ErrorF("-maxbigreqsize set maximal bigrequest size \n");
+#ifdef PANORAMIX
+ ErrorF("+xinerama Enable XINERAMA (PanoramiX) extension\n");
+ ErrorF("-xinerama Disable XINERAMA (PanoramiX) extension (default)\n");
+ ErrorF("-disablexineramaextension Disable XINERAMA extension\n");
+#endif
+#ifdef RANDR
+ ErrorF("+rrxinerama Enable XINERAMA (via RandR) extension (default)\n");
+ ErrorF("-rrxinerama Disable XINERAMA (via RandR) extension\n");
+#endif
+ ErrorF("-dumbSched Disable smart scheduling, enable old behavior\n");
+ ErrorF("-schedInterval int Set scheduler interval in msec\n");
+ ErrorF("+extension name Enable extension\n");
+ ErrorF("-extension name Disable extension\n");
+#ifdef XDMCP
+ XdmcpUseMsg();
+#endif
+#ifdef XKB
+ XkbUseMsg();
+#endif
+ ddxUseMsg();
+}
+
+/* This function performs a rudimentary sanity check
+ * on the display name passed in on the command-line,
+ * since this string is used to generate filenames.
+ * It is especially important that the display name
+ * not contain a "/" and not start with a "-".
+ * --kvajk
+ */
+static int
+VerifyDisplayName(const char *d)
+{
+ if ( d == (char *)0 ) return( 0 ); /* null */
+ if ( *d == '\0' ) return( 0 ); /* empty */
+ if ( *d == '-' ) return( 0 ); /* could be confused for an option */
+ if ( *d == '.' ) return( 0 ); /* must not equal "." or ".." */
+ if ( strchr(d, '/') != (char *)0 ) return( 0 ); /* very important!!! */
+ return( 1 );
+}
+
+/*
+ * This function is responsible for doing initalisation of any global
+ * variables at an very early point of server startup (even before
+ * |ProcessCommandLine()|.
+ */
+void InitGlobals(void)
+{
+ ddxInitGlobals();
+}
+
+
+/*
+ * This function parses the command line. Handles device-independent fields
+ * and allows ddx to handle additional fields. It is not allowed to modify
+ * argc or any of the strings pointed to by argv.
+ */
+void
+ProcessCommandLine(int argc, char *argv[])
+{
+ int i, skip;
+
+ defaultKeyboardControl.autoRepeat = TRUE;
+
+#ifdef NO_PART_NET
+ PartialNetwork = FALSE;
+#else
+ PartialNetwork = TRUE;
+#endif
+
+ for ( i = 1; i < argc; i++ )
+ {
+ /* call ddx first, so it can peek/override if it wants */
+ if((skip = ddxProcessArgument(argc, argv, i)))
+ {
+ i += (skip - 1);
+ }
+ else if(argv[i][0] == ':')
+ {
+ /* initialize display */
+ display = argv[i];
+ explicit_display = TRUE;
+ display++;
+ if( ! VerifyDisplayName( display ) ) {
+ ErrorF("Bad display name: %s\n", display);
+ UseMsg();
+ FatalError("Bad display name, exiting: %s\n", display);
+ }
+ }
+ else if ( strcmp( argv[i], "-a") == 0)
+ {
+ if(++i < argc)
+ defaultPointerControl.num = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-ac") == 0)
+ {
+ defeatAccessControl = TRUE;
+ }
+#ifdef MEMBUG
+ else if ( strcmp( argv[i], "-alloc") == 0)
+ {
+ if(++i < argc)
+ Memory_fail = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+#endif
+ else if ( strcmp( argv[i], "-audit") == 0)
+ {
+ if(++i < argc)
+ auditTrailLevel = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-auth") == 0)
+ {
+ if(++i < argc)
+ InitAuthorization (argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "bc") == 0)
+ permitOldBugs = TRUE;
+ else if ( strcmp( argv[i], "-br") == 0)
+ blackRoot = TRUE;
+ else if ( strcmp( argv[i], "+bs") == 0)
+ enableBackingStore = TRUE;
+ else if ( strcmp( argv[i], "-bs") == 0)
+ disableBackingStore = TRUE;
+ else if ( strcmp( argv[i], "c") == 0)
+ {
+ if(++i < argc)
+ defaultKeyboardControl.click = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-c") == 0)
+ {
+ defaultKeyboardControl.click = 0;
+ }
+ else if ( strcmp( argv[i], "-cc") == 0)
+ {
+ if(++i < argc)
+ defaultColorVisualClass = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-core") == 0)
+ CoreDump = TRUE;
+ else if ( strcmp( argv[i], "-dpi") == 0)
+ {
+ if(++i < argc)
+ monitorResolution = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if (strcmp(argv[i], "-displayfd") == 0) {
+ if (++i < argc) {
+ displayfd = atoi(argv[i]);
+ nolock = TRUE;
+ }
+ else
+ UseMsg();
+ }
+
+#ifdef DPMSExtension
+ else if ( strcmp( argv[i], "dpms") == 0)
+ DPMSEnabledSwitch = TRUE;
+ else if ( strcmp( argv[i], "-dpms") == 0)
+ DPMSDisabledSwitch = TRUE;
+#endif
+ else if ( strcmp( argv[i], "-deferglyphs") == 0)
+ {
+#ifdef HAS_XFONT2
+ if(++i >= argc || !!xfont2_parse_glyph_caching_mode(argv[i]))
+#else
+ if(++i >= argc || !ParseGlyphCachingMode(argv[i]))
+#endif /* HAS_XFONT2 */
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-f") == 0)
+ {
+ if(++i < argc)
+ defaultKeyboardControl.bell = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fc") == 0)
+ {
+ if(++i < argc)
+ defaultCursorFont = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fn") == 0)
+ {
+ if(++i < argc)
+ defaultTextFont = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fp") == 0)
+ {
+ if(++i < argc)
+ {
+ defaultFontPath = argv[i];
+ }
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-help") == 0)
+ {
+ UseMsg();
+ exit(0);
+ }
+#ifdef XKB
+ else if ( (skip=XkbProcessArguments(argc,argv,i))!=0 ) {
+ if (skip>0)
+ i+= skip-1;
+ else UseMsg();
+ }
+#endif
+#ifdef RLIMIT_DATA
+ else if ( strcmp( argv[i], "-ld") == 0)
+ {
+ if(++i < argc)
+ {
+ limitDataSpace = atoi(argv[i]);
+ if (limitDataSpace > 0)
+ limitDataSpace *= 1024;
+ }
+ else
+ UseMsg();
+ }
+#endif
+#ifdef RLIMIT_NOFILE
+ else if ( strcmp( argv[i], "-lf") == 0)
+ {
+ if(++i < argc)
+ limitNoFile = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+#endif
+#ifdef RLIMIT_STACK
+ else if ( strcmp( argv[i], "-ls") == 0)
+ {
+ if(++i < argc)
+ {
+ limitStackSpace = atoi(argv[i]);
+ if (limitStackSpace > 0)
+ limitStackSpace *= 1024;
+ }
+ else
+ UseMsg();
+ }
+#endif
+#ifdef SERVER_LOCK
+ else if ( strcmp ( argv[i], "-nolock") == 0)
+ {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != 0)
+ ErrorF("Warning: the -nolock option can only be used by root\n");
+ else
+#endif
+ nolock = TRUE;
+ }
+#endif
+#ifndef NOLOGOHACK
+ else if ( strcmp( argv[i], "-logo") == 0)
+ {
+ logoScreenSaver = 1;
+ }
+ else if ( strcmp( argv[i], "nologo") == 0)
+ {
+ logoScreenSaver = 0;
+ }
+#endif
+ else if ( strcmp( argv[i], "-nolisten") == 0)
+ {
+ if(++i < argc) {
+#ifdef NXAGENT_SERVER
+ if (strcmp( argv[i], "ANY" ) == 0)
+ NoListenAll = TRUE;
+ else
+#endif /* NXAGENT_SERVER */
+ if (_XSERVTransNoListen(argv[i]))
+ FatalError ("Failed to disable listen for %s transport",
+ argv[i]);
+ } else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-noreset") == 0)
+ {
+ dispatchExceptionAtReset = 0;
+ }
+ else if ( strcmp( argv[i], "-reset") == 0)
+ {
+ dispatchExceptionAtReset = DE_RESET;
+ }
+ else if ( strcmp( argv[i], "-p") == 0)
+ {
+ if(++i < argc)
+ defaultScreenSaverInterval = ((CARD32)atoi(argv[i])) *
+ MILLI_PER_MIN;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-pn") == 0)
+ PartialNetwork = TRUE;
+ else if ( strcmp( argv[i], "-nopn") == 0)
+ PartialNetwork = FALSE;
+ else if ( strcmp( argv[i], "r") == 0)
+ defaultKeyboardControl.autoRepeat = TRUE;
+ else if ( strcmp( argv[i], "-r") == 0)
+ defaultKeyboardControl.autoRepeat = FALSE;
+ else if ( strcmp( argv[i], "-s") == 0)
+ {
+ if(++i < argc)
+ defaultScreenSaverTime = ((CARD32)atoi(argv[i])) *
+ MILLI_PER_MIN;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-su") == 0)
+ disableSaveUnders = TRUE;
+ else if ( strcmp( argv[i], "-t") == 0)
+ {
+ if(++i < argc)
+ defaultPointerControl.threshold = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-terminate") == 0)
+ {
+ dispatchExceptionAtReset = DE_TERMINATE;
+ }
+ else if ( strcmp( argv[i], "-to") == 0)
+ {
+ if(++i < argc)
+ TimeOutValue = ((CARD32)atoi(argv[i])) * MILLI_PER_SECOND;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-tst") == 0)
+ {
+ noTestExtensions = TRUE;
+ }
+ else if ( strcmp( argv[i], "v") == 0)
+ defaultScreenSaverBlanking = PreferBlanking;
+ else if ( strcmp( argv[i], "-v") == 0)
+ defaultScreenSaverBlanking = DontPreferBlanking;
+ else if ( strcmp( argv[i], "-wm") == 0)
+ defaultBackingStore = WhenMapped;
+ else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
+ if(++i < argc) {
+ long reqSizeArg = atol(argv[i]);
+
+ /* Request size > 128MB does not make much sense... */
+ if( reqSizeArg > 0L && reqSizeArg < 128L ) {
+ maxBigRequestSize = (reqSizeArg * 1048576L) - 1L;
+ }
+ else
+ {
+ UseMsg();
+ }
+ }
+ else
+ {
+ UseMsg();
+ }
+ }
+#ifdef PANORAMIX
+ else if ( strcmp( argv[i], "+xinerama") == 0){
+ noPanoramiXExtension = FALSE;
+ }
+ else if ( strcmp( argv[i], "-xinerama") == 0){
+ noPanoramiXExtension = TRUE;
+ }
+ else if ( strcmp( argv[i], "-disablexineramaextension") == 0){
+ PanoramiXExtensionDisabledHack = TRUE;
+ }
+#endif
+#ifdef RANDR
+ else if ( strcmp( argv[i], "+rrxinerama") == 0){
+ noRRXineramaExtension = FALSE;
+ }
+ else if ( strcmp( argv[i], "-rrxinerama") == 0){
+ noRRXineramaExtension = TRUE;
+ }
+#endif
+ else if ( strcmp( argv[i], "-I") == 0)
+ {
+ /* ignore all remaining arguments */
+ break;
+ }
+ else if (strncmp (argv[i], "tty", 3) == 0)
+ {
+ /* just in case any body is interested */
+ dev_tty_from_init = argv[i];
+ }
+#ifdef XDMCP
+ else if ((skip = XdmcpOptions(argc, argv, i)) != i)
+ {
+ i = skip - 1;
+ }
+#endif
+#ifdef XCSECURITY
+ else if ((skip = XSecurityOptions(argc, argv, i)) != i)
+ {
+ i = skip - 1;
+ }
+#endif
+#if HAVE_SETITIMER
+ else if ( strcmp( argv[i], "-dumbSched") == 0)
+ {
+ SmartScheduleSignalEnable = FALSE;
+ }
+#endif
+ else if ( strcmp( argv[i], "-schedInterval") == 0)
+ {
+ if (++i < argc)
+ {
+ SmartScheduleInterval = atoi(argv[i]);
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-schedMax") == 0)
+ {
+ if (++i < argc)
+ {
+ SmartScheduleMaxSlice = atoi(argv[i]);
+ }
+ else
+ UseMsg();
+ }
+#ifdef RENDER
+ else if ( strcmp( argv[i], "-render" ) == 0)
+ {
+ if (++i < argc)
+ {
+ int policy = PictureParseCmapPolicy (argv[i]);
+
+ if (policy != PictureCmapPolicyInvalid)
+ PictureCmapPolicy = policy;
+ else
+ UseMsg ();
+ }
+ else
+ UseMsg ();
+ }
+#endif
+ else if ( strcmp( argv[i], "+extension") == 0)
+ {
+ if (++i < argc)
+ {
+ if (!EnableDisableExtension(argv[i], TRUE))
+ EnableDisableExtensionError(argv[i], TRUE);
+ }
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-extension") == 0)
+ {
+ if (++i < argc)
+ {
+ if (!EnableDisableExtension(argv[i], FALSE))
+ EnableDisableExtensionError(argv[i], FALSE);
+ }
+ else
+ UseMsg();
+ }
+ else
+ {
+ ErrorF("Unrecognized option: %s\n", argv[i]);
+ UseMsg();
+ FatalError("Unrecognized option: %s\n", argv[i]);
+ }
+ }
+}
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+static void
+InsertFileIntoCommandLine(
+ int *resargc, char ***resargv,
+ int prefix_argc, char **prefix_argv,
+ char *filename,
+ int suffix_argc, char **suffix_argv)
+{
+ struct stat st;
+ FILE *f;
+ char *p;
+ char *q;
+ int insert_argc;
+ char *buf;
+ int len;
+ int i;
+
+ f = fopen(filename, "r");
+ if (!f)
+ FatalError("Can't open option file %s\n", filename);
+
+ fstat(fileno(f), &st);
+
+ buf = (char *) malloc((unsigned) st.st_size + 1);
+ if (!buf)
+ FatalError("Out of Memory\n");
+
+ len = fread(buf, 1, (unsigned) st.st_size, f);
+
+ fclose(f);
+
+ if (len < 0)
+ FatalError("Error reading option file %s\n", filename);
+
+ buf[len] = '\0';
+
+ p = buf;
+ q = buf;
+ insert_argc = 0;
+
+ while (*p)
+ {
+ while (isspace(*p))
+ p++;
+ if (!*p)
+ break;
+ if (*p == '#')
+ {
+ while (*p && *p != '\n')
+ p++;
+ } else
+ {
+ while (*p && !isspace(*p))
+ *q++ = *p++;
+ /* Since p and q might still be pointing at the same place, we */
+ /* need to step p over the whitespace now before we add the null. */
+ if (*p)
+ p++;
+ *q++ = '\0';
+ insert_argc++;
+ }
+ }
+
+ buf = (char *) realloc(buf, q - buf);
+ if (!buf)
+ FatalError("Out of memory reallocing option buf\n");
+
+ *resargc = prefix_argc + insert_argc + suffix_argc;
+ *resargv = (char **) malloc((*resargc + 1) * sizeof(char *));
+ if (!*resargv)
+ FatalError("Out of Memory\n");
+
+ memcpy(*resargv, prefix_argv, prefix_argc * sizeof(char *));
+
+ p = buf;
+ for (i = 0; i < insert_argc; i++)
+ {
+ (*resargv)[prefix_argc + i] = p;
+ p += strlen(p) + 1;
+ }
+
+ memcpy(*resargv + prefix_argc + insert_argc,
+ suffix_argv, suffix_argc * sizeof(char *));
+
+ (*resargv)[*resargc] = NULL;
+} /* end InsertFileIntoCommandLine */
+
+
+void
+ExpandCommandLine(int *pargc, char ***pargv)
+{
+ int i;
+
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid())
+ return;
+#endif
+
+ for (i = 1; i < *pargc; i++)
+ {
+ if ( (0 == strcmp((*pargv)[i], "-config")) && (i < (*pargc - 1)) )
+ {
+ InsertFileIntoCommandLine(pargc, pargv,
+ i, *pargv,
+ (*pargv)[i+1], /* filename */
+ *pargc - i - 2, *pargv + i + 2);
+ i--;
+ }
+ }
+} /* end ExpandCommandLine */
+#endif
+
+/* Implement a simple-minded font authorization scheme. The authorization
+ name is "hp-hostname-1", the contents are simply the host name. */
+int
+set_font_authorizations(char **authorizations, int *authlen, void * client)
+{
+#define AUTHORIZATION_NAME "hp-hostname-1"
+#if defined(TCPCONN)
+ static char *result = NULL;
+ static char *p = NULL;
+
+ if (p == NULL)
+ {
+ char hname[1024], *hnameptr;
+ unsigned int len;
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo hints, *ai = NULL;
+#else
+ struct hostent *host;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+ _Xgethostbynameparams hparams;
+#endif
+#endif
+
+ gethostname(hname, 1024);
+#if defined(IPv6) && defined(AF_INET6)
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_CANONNAME;
+ if (getaddrinfo(hname, NULL, &hints, &ai) == 0) {
+ hnameptr = ai->ai_canonname;
+ } else {
+ hnameptr = hname;
+ }
+#else
+ host = _XGethostbyname(hname, hparams);
+ if (host == NULL)
+ hnameptr = hname;
+ else
+ hnameptr = host->h_name;
+#endif
+
+ len = strlen(hnameptr) + 1;
+ result = malloc(len + sizeof(AUTHORIZATION_NAME) + 4);
+
+ p = result;
+ *p++ = sizeof(AUTHORIZATION_NAME) >> 8;
+ *p++ = sizeof(AUTHORIZATION_NAME) & 0xff;
+ *p++ = (len) >> 8;
+ *p++ = (len & 0xff);
+
+ memmove(p, AUTHORIZATION_NAME, sizeof(AUTHORIZATION_NAME));
+ p += sizeof(AUTHORIZATION_NAME);
+ memmove(p, hnameptr, len);
+ p += len;
+#if defined(IPv6) && defined(AF_INET6)
+ if (ai) {
+ freeaddrinfo(ai);
+ }
+#endif
+ }
+ *authlen = p - result;
+ *authorizations = result;
+ return 1;
+#else /* TCPCONN */
+ return 0;
+#endif /* TCPCONN */
+}
+
+/*****************
+ * XNFalloc
+ * "no failure" alloc
+ *****************/
+
+void *
+XNFalloc(unsigned long amount)
+{
+ void *ptr = malloc(amount);
+ if (!ptr)
+ {
+ FatalError("Out of memory");
+ }
+ return ptr;
+}
+
+/*****************
+ * XNFcalloc
+ *****************/
+
+void *
+XNFcalloc(unsigned long amount)
+{
+ void *ret = calloc(1, amount);
+ if (!ret)
+ FatalError("XNFcalloc: Out of memory");
+ return ret;
+}
+
+/*****************
+ * XNFrealloc
+ * "no failure" realloc
+ *****************/
+
+void *
+XNFrealloc(void * ptr, unsigned long amount)
+{
+ void *ret = realloc(ptr, amount);
+ if (!ret)
+ FatalError("XNFrealloc: Out of memory");
+ return ret;
+}
+
+void
+OsInitAllocator (void)
+{
+#ifdef MEMBUG
+ static int been_here;
+
+ /* Check the memory system after each generation */
+ if (been_here)
+ CheckMemory ();
+ else
+ been_here = 1;
+#endif
+}
+
+char *
+Xstrdup(const char *s)
+{
+ if (s == NULL)
+ return NULL;
+ return strdup(s);
+}
+
+
+char *
+XNFstrdup(const char *s)
+{
+ char *ret;
+
+ if (s == NULL)
+ return NULL;
+
+ ret = strdup(s);
+ if (!ret)
+ FatalError("XNFstrdup: Out of memory");
+ return ret;
+}
+
+void
+SmartScheduleStopTimer (void)
+{
+#if HAVE_SETITIMER
+ struct itimerval timer;
+
+ if (!SmartScheduleSignalEnable)
+ return;
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n");
+ #endif
+
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 0;
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = 0;
+ (void) setitimer (ITIMER_REAL, &timer, 0);
+#endif
+}
+
+void
+SmartScheduleStartTimer (void)
+{
+#if HAVE_SETITIMER
+ struct itimerval timer;
+
+ if (!SmartScheduleSignalEnable)
+ return;
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n",
+ SmartScheduleInterval);
+ #endif
+
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = SmartScheduleInterval * 1000;
+ setitimer (ITIMER_REAL, &timer, 0);
+#endif
+}
+
+#if HAVE_SETITIMER
+static void
+SmartScheduleTimer (int sig)
+{
+ SmartScheduleTime += SmartScheduleInterval;
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n",
+ SmartScheduleTime);
+ #endif
+}
+
+int
+SmartScheduleEnable (void)
+{
+ int ret = 0;
+ struct sigaction act;
+
+ if (!SmartScheduleSignalEnable)
+ return 0;
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartScheduleEnable: Enabling the smart scheduler.\n");
+ #endif
+
+ memset((char *) &act, 0, sizeof(struct sigaction));
+
+ /* Set up the timer signal function */
+ act.sa_flags = SA_RESTART;
+ act.sa_handler = SmartScheduleTimer;
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGALRM);
+ ret = sigaction(SIGALRM, &act, 0);
+ return ret;
+}
+
+static int
+SmartSchedulePause(void)
+{
+ int ret = 0;
+ struct sigaction act;
+
+ if (!SmartScheduleSignalEnable)
+ return 0;
+
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartSchedulePause: Pausing the smart scheduler.\n");
+ #endif
+
+ memset((char *) &act, 0, sizeof(struct sigaction));
+
+ act.sa_handler = SIG_IGN;
+ sigemptyset(&act.sa_mask);
+ ret = sigaction(SIGALRM, &act, 0);
+ return ret;
+}
+#endif
+
+void
+SmartScheduleInit(void)
+{
+#if HAVE_SETITIMER
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n");
+ #endif
+
+ if (SmartScheduleEnable() < 0) {
+ perror("sigaction for smart scheduler");
+ SmartScheduleSignalEnable = FALSE;
+ }
+#endif
+}
+
+#ifdef SIG_BLOCK
+static sigset_t PreviousSignalMask;
+static int BlockedSignalCount;
+#endif
+
+void
+OsBlockSignals (void)
+{
+#ifdef SIG_BLOCK
+ if (BlockedSignalCount++ == 0)
+ {
+ sigset_t set;
+
+ sigemptyset (&set);
+#ifdef SIGALRM
+ sigaddset (&set, SIGALRM);
+#endif
+#ifdef SIGVTALRM
+ sigaddset (&set, SIGVTALRM);
+#endif
+#ifdef SIGWINCH
+ sigaddset (&set, SIGWINCH);
+#endif
+#ifdef SIGIO
+ sigaddset (&set, SIGIO);
+#endif
+#ifdef SIGTSTP
+ sigaddset (&set, SIGTSTP);
+#endif
+#ifdef SIGTTIN
+ sigaddset (&set, SIGTTIN);
+#endif
+#ifdef SIGTTOU
+ sigaddset (&set, SIGTTOU);
+#endif
+#ifdef SIGCHLD
+ sigaddset (&set, SIGCHLD);
+#endif
+ sigprocmask (SIG_BLOCK, &set, &PreviousSignalMask);
+ }
+#endif
+}
+
+void
+OsReleaseSignals (void)
+{
+#ifdef SIG_BLOCK
+ if (--BlockedSignalCount == 0)
+ {
+ sigprocmask (SIG_SETMASK, &PreviousSignalMask, 0);
+ }
+#endif
+}
+
+#if !defined(WIN32)
+/*
+ * "safer" versions of system(3), popen(3) and pclose(3) which give up
+ * all privs before running a command.
+ *
+ * This is based on the code in FreeBSD 2.2 libc.
+ *
+ * XXX It'd be good to redirect stderr so that it ends up in the log file
+ * as well. As it is now, xkbcomp messages don't end up in the log file.
+ */
+
+int
+System(char *command)
+{
+ int pid, p;
+#ifdef SIGCHLD
+ void (*csig)(int);
+#endif
+ int status;
+ struct passwd *pwent;
+
+ if (!command)
+ return(1);
+
+#ifdef SIGCHLD
+ csig = OsSignal(SIGCHLD, SIG_DFL);
+ if (csig == SIG_ERR) {
+ perror("signal");
+ return -1;
+ }
+#endif
+
+#ifdef DEBUG
+ ErrorF("System: `%s'\n", command);
+#endif
+
+#ifdef NX_TRANS_EXIT
+ if (OsVendorStartRedirectErrorFProc != NULL) {
+ OsVendorStartRedirectErrorFProc();
+ }
+#endif
+ switch (pid = fork()) {
+ case -1: /* error */
+ p = -1;
+ case 0: /* child */
+ pwent = getpwuid(getuid());
+ if (initgroups(pwent->pw_name,getgid()) == -1)
+ _exit(127);
+ if (setgid(getgid()) == -1)
+ _exit(127);
+ if (setuid(getuid()) == -1)
+ _exit(127);
+ execl("/bin/sh", "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ default: /* parent */
+ do {
+ p = waitpid(pid, &status, 0);
+ } while (p == -1 && errno == EINTR);
+
+ }
+#ifdef NX_TRANS_EXIT
+ if (OsVendorEndRedirectErrorFProc != NULL) {
+ OsVendorEndRedirectErrorFProc();
+ }
+#endif
+
+#ifdef SIGCHLD
+ if (OsSignal(SIGCHLD, csig) == SIG_ERR) {
+ perror("signal");
+ return -1;
+ }
+#endif
+
+ return p == -1 ? -1 : status;
+}
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ int pid;
+} *pidlist;
+
+void *
+Popen(char *command, char *type)
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid;
+
+ if (command == NULL || type == NULL)
+ return NULL;
+
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return NULL;
+
+ if ((cur = (struct pid *)malloc(sizeof(struct pid))) == NULL)
+ return NULL;
+
+ if (pipe(pdes) < 0) {
+ free(cur);
+ return NULL;
+ }
+
+ /* Ignore the smart scheduler while this is going on */
+#if HAVE_SETITIMER
+ if (SmartSchedulePause() < 0) {
+ close(pdes[0]);
+ close(pdes[1]);
+ free(cur);
+ perror("signal");
+ return NULL;
+ }
+#endif
+
+#ifdef NX_TRANS_EXIT
+ if (OsVendorStartRedirectErrorFProc != NULL) {
+ OsVendorStartRedirectErrorFProc();
+ }
+ OsBlockSignals ();
+#endif
+ switch (pid = fork()) {
+ case -1: /* error */
+ close(pdes[0]);
+ close(pdes[1]);
+ free(cur);
+#if HAVE_SETITIMER
+ if (SmartScheduleEnable() < 0)
+ perror("signal");
+#endif
+#ifdef NX_TRANS_EXIT
+ if (OsVendorEndRedirectErrorFProc != NULL) {
+ OsVendorEndRedirectErrorFProc();
+ }
+ OsReleaseSignals ();
+#endif
+ return NULL;
+ case 0: /* child */
+ if (setgid(getgid()) == -1)
+ _exit(127);
+ if (setuid(getuid()) == -1)
+ _exit(127);
+ if (*type == 'r') {
+ if (pdes[1] != 1) {
+ /* stdout */
+ dup2(pdes[1], 1);
+ close(pdes[1]);
+ }
+ close(pdes[0]);
+ } else {
+ if (pdes[0] != 0) {
+ /* stdin */
+ dup2(pdes[0], 0);
+ close(pdes[0]);
+ }
+ close(pdes[1]);
+ }
+
+ #ifdef NX_TRANS_SOCKET
+
+ /*
+ * Check if the child process should not
+ * use the parent's libraries.
+ */
+
+ if (_NXUnsetLibraryPath)
+ {
+ #ifndef __sun
+
+ unsetenv ("LD_LIBRARY_PATH");
+
+ #else
+
+ extern char **environ;
+
+ char **ep = environ;
+
+ ep = environ;
+
+ while (*ep)
+ {
+ if (!strncmp("LD_LIBRARY_PATH=", *ep, strlen("LD_LIBRARY_PATH=")))
+ {
+ break;
+ }
+
+ *ep++;
+ }
+
+ while (*ep)
+ {
+ *ep = *(ep + 1);
+ ep++;
+ }
+
+ #endif
+ }
+
+ #endif
+
+ #ifdef NX_TRANS_EXIT
+ OsReleaseSignals ();
+ #endif
+
+#if HAVE_SETITIMER
+ if (SmartScheduleEnable() < 0) {
+ perror("signal");
+ return NULL;
+ }
+#endif
+
+ execl("/bin/sh", "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ }
+
+#ifndef NX_TRANS_EXIT
+ /* Avoid EINTR during stdio calls */
+ OsBlockSignals ();
+#endif
+
+ /* parent */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ close(pdes[0]);
+ }
+
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+#ifdef DEBUG
+ ErrorF("Popen: `%s', fp = %p\n", command, iop);
+#endif
+
+ return iop;
+}
+
+/* fopen that drops privileges */
+void *
+Fopen(char *file, char *type)
+{
+ FILE *iop;
+#ifndef HAS_SAVED_IDS_AND_SETEUID
+ struct pid *cur;
+ int pdes[2], pid;
+
+ if (file == NULL || type == NULL)
+ return NULL;
+
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return NULL;
+
+ if ((cur = (struct pid *)malloc(sizeof(struct pid))) == NULL)
+ return NULL;
+
+ if (pipe(pdes) < 0) {
+ free(cur);
+ return NULL;
+ }
+
+ switch (pid = fork()) {
+ case -1: /* error */
+ close(pdes[0]);
+ close(pdes[1]);
+ free(cur);
+ return NULL;
+ case 0: /* child */
+ if (setgid(getgid()) == -1)
+ _exit(127);
+ if (setuid(getuid()) == -1)
+ _exit(127);
+ if (*type == 'r') {
+ if (pdes[1] != 1) {
+ /* stdout */
+ dup2(pdes[1], 1);
+ close(pdes[1]);
+ }
+ close(pdes[0]);
+ } else {
+ if (pdes[0] != 0) {
+ /* stdin */
+ dup2(pdes[0], 0);
+ close(pdes[0]);
+ }
+ close(pdes[1]);
+ }
+ execl("/bin/cat", "cat", file, (char *)NULL);
+ _exit(127);
+ }
+
+ /* Avoid EINTR during stdio calls */
+ OsBlockSignals ();
+
+ /* parent */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ close(pdes[0]);
+ }
+
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+#ifdef DEBUG
+ ErrorF("Popen: `%s', fp = %p\n", command, iop);
+#endif
+
+ return iop;
+#else
+ int ruid, euid;
+
+ ruid = getuid();
+ euid = geteuid();
+
+ if (seteuid(ruid) == -1) {
+ return NULL;
+ }
+ iop = fopen(file, type);
+
+ if (seteuid(euid) == -1) {
+ fclose(iop);
+ return NULL;
+ }
+ return iop;
+#endif /* HAS_SAVED_IDS_AND_SETEUID */
+}
+
+int
+Pclose(void * iop)
+{
+ struct pid *cur, *last;
+ int pstat;
+ int pid;
+
+#ifdef DEBUG
+ ErrorF("Pclose: fp = %p\n", iop);
+#endif
+
+ fclose(iop);
+
+ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
+ if (cur->fp == iop)
+ break;
+ if (cur == NULL)
+ return -1;
+
+ do {
+ pid = waitpid(cur->pid, &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+
+ if (last == NULL)
+ pidlist = cur->next;
+ else
+ last->next = cur->next;
+ free(cur);
+
+ /* allow EINTR again */
+ OsReleaseSignals ();
+
+#ifdef NX_TRANS_EXIT
+ if (OsVendorEndRedirectErrorFProc != NULL) {
+ OsVendorEndRedirectErrorFProc();
+ }
+#endif
+ return pid == -1 ? -1 : pstat;
+}
+
+int
+Fclose(void * iop)
+{
+#ifdef HAS_SAVED_IDS_AND_SETEUID
+ return fclose(iop);
+#else
+ return Pclose(iop);
+#endif
+}
+
+#endif /* !WIN32 */
+
+
+/*
+ * CheckUserParameters: check for long command line arguments and long
+ * environment variables. By default, these checks are only done when
+ * the server's euid != ruid. In 3.3.x, these checks were done in an
+ * external wrapper utility.
+ */
+
+/* Consider LD* variables insecure? */
+#ifndef REMOVE_ENV_LD
+#define REMOVE_ENV_LD 1
+#endif
+
+/* Remove long environment variables? */
+#ifndef REMOVE_LONG_ENV
+#define REMOVE_LONG_ENV 1
+#endif
+
+/*
+ * Disallow stdout or stderr as pipes? It's possible to block the X server
+ * when piping stdout+stderr to a pipe.
+ *
+ * Don't enable this because it looks like it's going to cause problems.
+ */
+#ifndef NO_OUTPUT_PIPES
+#define NO_OUTPUT_PIPES 0
+#endif
+
+
+/* Check args and env only if running setuid (euid == 0 && euid != uid) ? */
+#ifndef CHECK_EUID
+#ifndef WIN32
+#define CHECK_EUID 1
+#else
+#define CHECK_EUID 0
+#endif
+#endif
+
+/*
+ * Maybe the locale can be faked to make isprint(3) report that everything
+ * is printable? Avoid it by default.
+ */
+#ifndef USE_ISPRINT
+#define USE_ISPRINT 0
+#endif
+
+#define MAX_ARG_LENGTH 128
+#define MAX_ENV_LENGTH 256
+#define MAX_ENV_PATH_LENGTH 2048 /* Limit for *PATH and TERMCAP */
+
+#if USE_ISPRINT
+#include <ctype.h>
+#define checkPrintable(c) isprint(c)
+#else
+#define checkPrintable(c) (((c) & 0x7f) >= 0x20 && ((c) & 0x7f) != 0x7f)
+#endif
+
+enum BadCode {
+ NotBad = 0,
+ UnsafeArg,
+ ArgTooLong,
+ UnprintableArg,
+ EnvTooLong,
+ OutputIsPipe,
+ InternalError
+};
+
+#if defined(VENDORSUPPORT)
+#define BUGADDRESS VENDORSUPPORT
+#elif defined(BUILDERADDR)
+#define BUGADDRESS BUILDERADDR
+#else
+#define BUGADDRESS "xorg@freedesktop.org"
+#endif
+
+#define ARGMSG \
+ "\nIf the arguments used are valid, and have been rejected incorrectly\n" \
+ "please send details of the arguments and why they are valid to\n" \
+ "%s. In the meantime, you can start the Xserver as\n" \
+ "the \"super user\" (root).\n"
+
+#define ENVMSG \
+ "\nIf the environment is valid, and have been rejected incorrectly\n" \
+ "please send details of the environment and why it is valid to\n" \
+ "%s. In the meantime, you can start the Xserver as\n" \
+ "the \"super user\" (root).\n"
+
+void
+CheckUserParameters(int argc, char **argv, char **envp)
+{
+ enum BadCode bad = NotBad;
+ int i = 0, j;
+ char *a, *e = NULL;
+
+#if CHECK_EUID
+ if (geteuid() == 0 && getuid() != geteuid())
+#endif
+ {
+ /* Check each argv[] */
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-fp") == 0)
+ {
+ i++; /* continue with next argument. skip the length check */
+ if (i >= argc)
+ break;
+ } else
+ {
+ if (strlen(argv[i]) > MAX_ARG_LENGTH) {
+ bad = ArgTooLong;
+ break;
+ }
+ }
+ a = argv[i];
+ while (*a) {
+ if (checkPrintable(*a) == 0) {
+ bad = UnprintableArg;
+ break;
+ }
+ a++;
+ }
+ if (bad)
+ break;
+ }
+ if (!bad) {
+ /* Check each envp[] */
+ for (i = 0; envp[i]; i++) {
+
+ /* Check for bad environment variables and values */
+#if REMOVE_ENV_LD
+ while (envp[i] && (strncmp(envp[i], "LD", 2) == 0)) {
+#ifdef ENVDEBUG
+ ErrorF("CheckUserParameters: removing %s from the "
+ "environment\n", strtok(envp[i], "="));
+#endif
+ for (j = i; envp[j]; j++) {
+ envp[j] = envp[j+1];
+ }
+ }
+#endif
+ if (envp[i] && (strlen(envp[i]) > MAX_ENV_LENGTH)) {
+#if REMOVE_LONG_ENV
+#ifdef ENVDEBUG
+ ErrorF("CheckUserParameters: removing %s from the "
+ "environment\n", strtok(envp[i], "="));
+#endif
+ for (j = i; envp[j]; j++) {
+ envp[j] = envp[j+1];
+ }
+ i--;
+#else
+ char *eq;
+ int len;
+
+ eq = strchr(envp[i], '=');
+ if (!eq)
+ continue;
+ len = eq - envp[i];
+ e = malloc(len + 1);
+ if (!e) {
+ bad = InternalError;
+ break;
+ }
+ strncpy(e, envp[i], len);
+ e[len] = 0;
+ if (len >= 4 &&
+ (strcmp(e + len - 4, "PATH") == 0 ||
+ strcmp(e, "TERMCAP") == 0)) {
+ if (strlen(envp[i]) > MAX_ENV_PATH_LENGTH) {
+ bad = EnvTooLong;
+ break;
+ } else {
+ free(e);
+ }
+ } else {
+ bad = EnvTooLong;
+ break;
+ }
+#endif
+ }
+ }
+ }
+#if NO_OUTPUT_PIPES
+ if (!bad) {
+ struct stat buf;
+
+ if (fstat(fileno(stdout), &buf) == 0 && S_ISFIFO(buf.st_mode))
+ bad = OutputIsPipe;
+ if (fstat(fileno(stderr), &buf) == 0 && S_ISFIFO(buf.st_mode))
+ bad = OutputIsPipe;
+ }
+#endif
+ }
+ switch (bad) {
+ case NotBad:
+ return;
+ case UnsafeArg:
+ ErrorF("Command line argument number %d is unsafe\n", i);
+ ErrorF(ARGMSG, BUGADDRESS);
+ break;
+ case ArgTooLong:
+ ErrorF("Command line argument number %d is too long\n", i);
+ ErrorF(ARGMSG, BUGADDRESS);
+ break;
+ case UnprintableArg:
+ ErrorF("Command line argument number %d contains unprintable"
+ " characters\n", i);
+ ErrorF(ARGMSG, BUGADDRESS);
+ break;
+ case EnvTooLong:
+ ErrorF("Environment variable `%s' is too long\n", e);
+ ErrorF(ENVMSG, BUGADDRESS);
+ break;
+ case OutputIsPipe:
+ ErrorF("Stdout and/or stderr is a pipe\n");
+ break;
+ case InternalError:
+ ErrorF("Internal Error\n");
+ break;
+ default:
+ ErrorF("Unknown error\n");
+ ErrorF(ARGMSG, BUGADDRESS);
+ ErrorF(ENVMSG, BUGADDRESS);
+ break;
+ }
+ FatalError("X server aborted because of unsafe environment\n");
+}
+
+/*
+ * CheckUserAuthorization: check if the user is allowed to start the
+ * X server. This usually means some sort of PAM checking, and it is
+ * usually only done for setuid servers (uid != euid).
+ */
+
+#ifdef USE_PAM
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#include <pwd.h>
+#endif /* USE_PAM */
+
+void
+CheckUserAuthorization(void)
+{
+#ifdef USE_PAM
+ static struct pam_conv conv = {
+ misc_conv,
+ NULL
+ };
+
+ pam_handle_t *pamh = NULL;
+ struct passwd *pw;
+ int retval;
+
+ if (getuid() != geteuid()) {
+ pw = getpwuid(getuid());
+ if (pw == NULL)
+ FatalError("getpwuid() failed for uid %d\n", getuid());
+
+ retval = pam_start("xserver", pw->pw_name, &conv, &pamh);
+ if (retval != PAM_SUCCESS)
+ FatalError("pam_start() failed.\n"
+ "\tMissing or mangled PAM config file or module?\n");
+
+ retval = pam_authenticate(pamh, 0);
+ if (retval != PAM_SUCCESS) {
+ pam_end(pamh, retval);
+ FatalError("PAM authentication failed, cannot start X server.\n"
+ "\tPerhaps you do not have console ownership?\n");
+ }
+
+ retval = pam_acct_mgmt(pamh, 0);
+ if (retval != PAM_SUCCESS) {
+ pam_end(pamh, retval);
+ FatalError("PAM authentication failed, cannot start X server.\n"
+ "\tPerhaps you do not have console ownership?\n");
+ }
+
+ /* this is not a session, so do not do session management */
+ pam_end(pamh, PAM_SUCCESS);
+ }
+#endif
+}
+
+#ifdef __SCO__
+#include <fcntl.h>
+
+static void
+lockit (int fd, short what)
+{
+ struct flock lck;
+
+ lck.l_whence = 0;
+ lck.l_start = 0;
+ lck.l_len = 1;
+ lck.l_type = what;
+
+ (void)fcntl (fd, F_SETLKW, &lck);
+}
+
+/* SCO OpenServer 5 lacks pread/pwrite. Emulate them. */
+ssize_t
+pread (int fd, void *buf, size_t nbytes, off_t offset)
+{
+ off_t saved;
+ ssize_t ret;
+
+ lockit (fd, F_RDLCK);
+ saved = lseek (fd, 0, SEEK_CUR);
+ lseek (fd, offset, SEEK_SET);
+ ret = read (fd, buf, nbytes);
+ lseek (fd, saved, SEEK_SET);
+ lockit (fd, F_UNLCK);
+
+ return ret;
+}
+
+ssize_t
+pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
+{
+ off_t saved;
+ ssize_t ret;
+
+ lockit (fd, F_WRLCK);
+ saved = lseek (fd, 0, SEEK_CUR);
+ lseek (fd, offset, SEEK_SET);
+ ret = write (fd, buf, nbytes);
+ lseek (fd, saved, SEEK_SET);
+ lockit (fd, F_UNLCK);
+
+ return ret;
+}
+#endif /* __SCO__ */
diff --git a/nx-X11/programs/Xserver/os/xdmauth.c b/nx-X11/programs/Xserver/os/xdmauth.c
new file mode 100644
index 000000000..4a59b48f2
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/xdmauth.c
@@ -0,0 +1,501 @@
+/*
+
+Copyright 1988, 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.
+
+*/
+
+/*
+ * XDM-AUTHENTICATION-1 (XDMCP authentication) and
+ * XDM-AUTHORIZATION-1 (client authorization) protocols
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+#ifdef HASXDMAUTH
+
+static Bool authFromXDMCP;
+
+#ifdef XDMCP
+#include <nx-X11/Xmd.h>
+#undef REQUEST
+#include <X11/Xdmcp.h>
+
+/* XDM-AUTHENTICATION-1 */
+
+static XdmAuthKeyRec privateKey;
+static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
+#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
+static XdmAuthKeyRec rho;
+
+static Bool
+XdmAuthenticationValidator (ARRAY8Ptr privateData, ARRAY8Ptr incomingData,
+ xdmOpCode packet_type)
+{
+ XdmAuthKeyPtr incoming;
+
+ XdmcpUnwrap (incomingData->data, (unsigned char *)&privateKey,
+ incomingData->data,incomingData->length);
+ if (packet_type == ACCEPT) {
+ if (incomingData->length != 8)
+ return FALSE;
+ incoming = (XdmAuthKeyPtr) incomingData->data;
+ XdmcpDecrementKey (incoming);
+ return XdmcpCompareKeys (incoming, &rho);
+ }
+ return FALSE;
+}
+
+static Bool
+XdmAuthenticationGenerator (ARRAY8Ptr privateData, ARRAY8Ptr outgoingData,
+ xdmOpCode packet_type)
+{
+ outgoingData->length = 0;
+ outgoingData->data = 0;
+ if (packet_type == REQUEST) {
+ if (XdmcpAllocARRAY8 (outgoingData, 8))
+ XdmcpWrap ((unsigned char *)&rho, (unsigned char *)&privateKey,
+ outgoingData->data, 8);
+ }
+ return TRUE;
+}
+
+static Bool
+XdmAuthenticationAddAuth (int name_len, char *name,
+ int data_len, char *data)
+{
+ Bool ret;
+ XdmcpUnwrap ((unsigned char *)data, (unsigned char *)&privateKey,
+ (unsigned char *)data, data_len);
+ authFromXDMCP = TRUE;
+ ret = AddAuthorization (name_len, name, data_len, data);
+ authFromXDMCP = FALSE;
+ return ret;
+}
+
+
+#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
+ 'a' <= c && c <= 'f' ? c - 'a' + 10 : \
+ 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
+
+static int
+HexToBinary (char *in, char *out, int len)
+{
+ int top, bottom;
+
+ while (len > 0)
+ {
+ top = atox(in[0]);
+ if (top == -1)
+ return 0;
+ bottom = atox(in[1]);
+ if (bottom == -1)
+ return 0;
+ *out++ = (top << 4) | bottom;
+ in += 2;
+ len -= 2;
+ }
+ if (len)
+ return 0;
+ *out++ = '\0';
+ return 1;
+}
+
+void
+XdmAuthenticationInit (char *cookie, int cookie_len)
+{
+ bzero (privateKey.data, 8);
+ if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
+ {
+ if (cookie_len > 2 + 2 * 8)
+ cookie_len = 2 + 2 * 8;
+ HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
+ }
+ else
+ {
+ if (cookie_len > 7)
+ cookie_len = 7;
+ memmove (privateKey.data + 1, cookie, cookie_len);
+ }
+ XdmcpGenerateKey (&rho);
+ XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
+ (char *)&rho,
+ sizeof (rho),
+ (ValidatorFunc)XdmAuthenticationValidator,
+ (GeneratorFunc)XdmAuthenticationGenerator,
+ (AddAuthorFunc)XdmAuthenticationAddAuth);
+}
+
+#endif /* XDMCP */
+
+/* XDM-AUTHORIZATION-1 */
+typedef struct _XdmAuthorization {
+ struct _XdmAuthorization *next;
+ XdmAuthKeyRec rho;
+ XdmAuthKeyRec key;
+ XID id;
+} XdmAuthorizationRec, *XdmAuthorizationPtr;
+
+static XdmAuthorizationPtr xdmAuth;
+
+typedef struct _XdmClientAuth {
+ struct _XdmClientAuth *next;
+ XdmAuthKeyRec rho;
+ char client[6];
+ long time;
+} XdmClientAuthRec, *XdmClientAuthPtr;
+
+static XdmClientAuthPtr xdmClients;
+static long clockOffset;
+static Bool gotClock;
+
+#define TwentyMinutes (20 * 60)
+#define TwentyFiveMinutes (25 * 60)
+
+static Bool
+XdmClientAuthCompare (XdmClientAuthPtr a, XdmClientAuthPtr b)
+{
+ int i;
+
+ if (!XdmcpCompareKeys (&a->rho, &b->rho))
+ return FALSE;
+ for (i = 0; i < 6; i++)
+ if (a->client[i] != b->client[i])
+ return FALSE;
+ return a->time == b->time;
+}
+
+static void
+XdmClientAuthDecode (unsigned char *plain, XdmClientAuthPtr auth)
+{
+ int i, j;
+
+ j = 0;
+ for (i = 0; i < 8; i++)
+ {
+ auth->rho.data[i] = plain[j];
+ ++j;
+ }
+ for (i = 0; i < 6; i++)
+ {
+ auth->client[i] = plain[j];
+ ++j;
+ }
+ auth->time = 0;
+ for (i = 0; i < 4; i++)
+ {
+ auth->time |= plain[j] << ((3 - i) << 3);
+ j++;
+ }
+}
+
+static void
+XdmClientAuthTimeout (long now)
+{
+ XdmClientAuthPtr client, next, prev;
+
+ prev = 0;
+ for (client = xdmClients; client; client=next)
+ {
+ next = client->next;
+ if (abs (now - client->time) > TwentyFiveMinutes)
+ {
+ if (prev)
+ prev->next = next;
+ else
+ xdmClients = next;
+ free (client);
+ }
+ else
+ prev = client;
+ }
+}
+
+static XdmClientAuthPtr
+XdmAuthorizationValidate (unsigned char *plain, int length,
+ XdmAuthKeyPtr rho, ClientPtr xclient, char **reason)
+{
+ XdmClientAuthPtr client, existing;
+ long now;
+ int i;
+
+ if (length != (192 / 8)) {
+ if (reason)
+ *reason = "Bad XDM authorization key length";
+ return NULL;
+ }
+ client = (XdmClientAuthPtr) malloc (sizeof (XdmClientAuthRec));
+ if (!client)
+ return NULL;
+ XdmClientAuthDecode (plain, client);
+ if (!XdmcpCompareKeys (&client->rho, rho))
+ {
+ free (client);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)";
+ return NULL;
+ }
+ for (i = 18; i < 24; i++)
+ if (plain[i] != 0) {
+ free (client);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)";
+ return NULL;
+ }
+ if (xclient) {
+ int family, addr_len;
+ Xtransaddr *addr;
+
+ if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
+ &family, &addr_len, &addr) == 0
+ && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
+#if defined(TCPCONN)
+ if (family == FamilyInternet &&
+ memcmp((char *)addr, client->client, 4) != 0) {
+ free (client);
+ free (addr);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)";
+ return NULL;
+
+ }
+#endif
+ free (addr);
+ }
+ }
+ now = time(0);
+ if (!gotClock)
+ {
+ clockOffset = client->time - now;
+ gotClock = TRUE;
+ }
+ now += clockOffset;
+ XdmClientAuthTimeout (now);
+ if (abs (client->time - now) > TwentyMinutes)
+ {
+ free (client);
+ if (reason)
+ *reason = "Excessive XDM-AUTHORIZATION-1 time offset";
+ return NULL;
+ }
+ for (existing = xdmClients; existing; existing=existing->next)
+ {
+ if (XdmClientAuthCompare (existing, client))
+ {
+ free (client);
+ if (reason)
+ *reason = "XDM authorization key matches an existing client!";
+ return NULL;
+ }
+ }
+ return client;
+}
+
+int
+XdmAddCookie (unsigned short data_length, char *data, XID id)
+{
+ XdmAuthorizationPtr new;
+ unsigned char *rho_bits, *key_bits;
+
+ switch (data_length)
+ {
+ case 16: /* auth from files is 16 bytes long */
+#ifdef XDMCP
+ if (authFromXDMCP)
+ {
+ /* R5 xdm sent bogus authorization data in the accept packet,
+ * but we can recover */
+ rho_bits = rho.data;
+ key_bits = (unsigned char *) data;
+ key_bits[0] = '\0';
+ }
+ else
+#endif
+ {
+ rho_bits = (unsigned char *) data;
+ key_bits = (unsigned char *) (data + 8);
+ }
+ break;
+#ifdef XDMCP
+ case 8: /* auth from XDMCP is 8 bytes long */
+ rho_bits = rho.data;
+ key_bits = (unsigned char *) data;
+ break;
+#endif
+ default:
+ return 0;
+ }
+ /* the first octet of the key must be zero */
+ if (key_bits[0] != '\0')
+ return 0;
+ new = (XdmAuthorizationPtr) malloc (sizeof (XdmAuthorizationRec));
+ if (!new)
+ return 0;
+ new->next = xdmAuth;
+ xdmAuth = new;
+ memmove (new->key.data, key_bits, (int) 8);
+ memmove (new->rho.data, rho_bits, (int) 8);
+ new->id = id;
+ return 1;
+}
+
+XID
+XdmCheckCookie (unsigned short cookie_length, char *cookie,
+ ClientPtr xclient, char **reason)
+{
+ XdmAuthorizationPtr auth;
+ XdmClientAuthPtr client;
+ unsigned char *plain;
+
+ /* Auth packets must be a multiple of 8 bytes long */
+ if (cookie_length & 7)
+ return (XID) -1;
+ plain = (unsigned char *) malloc (cookie_length);
+ if (!plain)
+ return (XID) -1;
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ XdmcpUnwrap ((unsigned char *)cookie, (unsigned char *)&auth->key, plain, cookie_length);
+ if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason)) != NULL)
+ {
+ client->next = xdmClients;
+ xdmClients = client;
+ free (plain);
+ return auth->id;
+ }
+ }
+ free (plain);
+ return (XID) -1;
+}
+
+int
+XdmResetCookie (void)
+{
+ XdmAuthorizationPtr auth, next_auth;
+ XdmClientAuthPtr client, next_client;
+
+ for (auth = xdmAuth; auth; auth=next_auth)
+ {
+ next_auth = auth->next;
+ free (auth);
+ }
+ xdmAuth = 0;
+ for (client = xdmClients; client; client=next_client)
+ {
+ next_client = client->next;
+ free (client);
+ }
+ xdmClients = (XdmClientAuthPtr) 0;
+ return 1;
+}
+
+XID
+XdmToID (unsigned short cookie_length, char *cookie)
+{
+ XdmAuthorizationPtr auth;
+ XdmClientAuthPtr client;
+ unsigned char *plain;
+
+ plain = (unsigned char *) malloc (cookie_length);
+ if (!plain)
+ return (XID) -1;
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ XdmcpUnwrap ((unsigned char *)cookie, (unsigned char *)&auth->key, plain, cookie_length);
+ if ((client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL)) != NULL)
+ {
+ free (client);
+ free (cookie);
+ return auth->id;
+ }
+ }
+ free (cookie);
+ return (XID) -1;
+}
+
+int
+XdmFromID (XID id, unsigned short *data_lenp, char **datap)
+{
+ XdmAuthorizationPtr auth;
+
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ if (id == auth->id) {
+ *data_lenp = 16;
+ *datap = (char *) &auth->rho;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+XdmRemoveCookie (unsigned short data_length, char *data)
+{
+ XdmAuthorizationPtr auth, prev;
+ XdmAuthKeyPtr key_bits, rho_bits;
+
+ prev = 0;
+ switch (data_length)
+ {
+ case 16:
+ rho_bits = (XdmAuthKeyPtr) data;
+ key_bits = (XdmAuthKeyPtr) (data + 8);
+ break;
+#ifdef XDMCP
+ case 8:
+ rho_bits = &rho;
+ key_bits = (XdmAuthKeyPtr) data;
+ break;
+#endif
+ default:
+ return 0;
+ }
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
+ XdmcpCompareKeys (key_bits, &auth->key))
+ {
+ if (prev)
+ prev->next = auth->next;
+ else
+ xdmAuth = auth->next;
+ free (auth);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/os/xdmcp.c b/nx-X11/programs/Xserver/os/xdmcp.c
new file mode 100644
index 000000000..c1aa57e95
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/xdmcp.c
@@ -0,0 +1,1629 @@
+/*
+ * Copyright 1989 Network Computing Devices, Inc., Mountain View, California.
+ *
+ * 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 name of N.C.D. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. N.C.D. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef WIN32
+#include <nx-X11/Xwinsock.h>
+#define XSERV_t
+#define TRANS_SERVER
+#define TRANS_REOPEN
+#include <nx-X11/Xtrans/Xtrans.h>
+#endif
+
+#include <nx-X11/Xos.h>
+
+#if !defined(WIN32)
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "misc.h"
+#include <nx-X11/Xpoll.h>
+#include "osdep.h"
+#include "input.h"
+#include "dixstruct.h"
+#include "opaque.h"
+
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+#define NX_TRANS_TEST
+
+#endif
+
+#ifdef XDMCP
+#undef REQUEST
+
+#ifdef XDMCP_NO_IPV6
+#undef IPv6
+#endif
+
+#include <X11/Xdmcp.h>
+
+#define X_INCLUDE_NETDB_H
+#include <nx-X11/Xos_r.h>
+
+#ifdef NX_TRANS_SOCKET
+
+xdmcp_states XdmcpState;
+
+int XdmcpStartTime;
+int XdmcpTimeOutRtx;
+
+#endif
+
+extern char *defaultDisplayClass;
+
+static int xdmcpSocket, sessionSocket;
+static xdmcp_states state;
+#if defined(IPv6) && defined(AF_INET6)
+static int xdmcpSocket6;
+static struct sockaddr_storage req_sockaddr;
+#else
+static struct sockaddr_in req_sockaddr;
+#endif
+static int req_socklen;
+static CARD32 SessionID;
+static CARD32 timeOutTime;
+static int timeOutRtx;
+static CARD16 DisplayNumber;
+static xdmcp_states XDM_INIT_STATE = XDM_OFF;
+#ifdef HASXDMAUTH
+static char *xdmAuthCookie;
+#endif
+
+static XdmcpBuffer buffer;
+
+#if defined(IPv6) && defined(AF_INET6)
+
+static struct addrinfo *mgrAddr;
+static struct addrinfo *mgrAddrFirst;
+
+#define SOCKADDR_TYPE struct sockaddr_storage
+#define SOCKADDR_FAMILY(s) ((struct sockaddr *)&(s))->sa_family
+
+#ifdef BSD44SOCKETS
+#define SOCKLEN_FIELD(s) ((struct sockaddr *)&(s))->sa_len
+#define SOCKLEN_TYPE unsigned char
+#else
+#define SOCKLEN_TYPE unsigned int
+#endif
+
+#else
+
+#define SOCKADDR_TYPE struct sockaddr_in
+#define SOCKADDR_FAMILY(s) (s).sin_family
+
+#ifdef BSD44SOCKETS
+#define SOCKLEN_FIELD(s) (s).sin_len
+#define SOCKLEN_TYPE unsigned char
+#else
+#define SOCKLEN_TYPE size_t
+#endif
+
+#endif
+
+static SOCKADDR_TYPE ManagerAddress;
+static SOCKADDR_TYPE FromAddress;
+
+#ifdef SOCKLEN_FIELD
+#define ManagerAddressLen SOCKLEN_FIELD(ManagerAddress)
+#define FromAddressLen SOCKLEN_FIELD(FromAddress)
+#else
+static SOCKLEN_TYPE ManagerAddressLen, FromAddressLen;
+#endif
+
+#if defined(IPv6) && defined(AF_INET6)
+static struct multicastinfo {
+ struct multicastinfo *next;
+ struct addrinfo *ai;
+ int hops;
+} *mcastlist;
+#endif
+
+static void XdmcpAddHost(
+ struct sockaddr *from,
+ int fromlen,
+ ARRAY8Ptr AuthenticationName,
+ ARRAY8Ptr hostname,
+ ARRAY8Ptr status);
+
+static void XdmcpSelectHost(
+ struct sockaddr *host_sockaddr,
+ int host_len,
+ ARRAY8Ptr AuthenticationName);
+
+static void get_xdmcp_sock(void);
+
+static void send_query_msg(void);
+
+static void recv_willing_msg(
+ struct sockaddr * /*from*/,
+ int /*fromlen*/,
+ unsigned /*length*/);
+
+static void send_request_msg(void);
+
+static void recv_accept_msg(unsigned /*length*/);
+
+static void recv_decline_msg(unsigned /*length*/);
+
+static void send_manage_msg(void);
+
+static void recv_refuse_msg(unsigned /*length*/);
+
+static void recv_failed_msg(unsigned /*length*/);
+
+static void send_keepalive_msg(void);
+
+static void recv_alive_msg(unsigned /*length*/);
+
+static void XdmcpFatal(
+ char * /*type*/,
+ ARRAY8Ptr /*status*/);
+
+static void XdmcpWarning(char * /*str*/);
+
+static void get_manager_by_name(
+ int /*argc*/,
+ char ** /*argv*/,
+ int /*i*/);
+
+static void get_fromaddr_by_name(int /*argc*/, char ** /*argv*/, int /*i*/);
+
+#if defined(IPv6) && defined(AF_INET6)
+static int get_mcast_options(int /*argc*/, char ** /*argv*/, int /*i*/);
+#endif
+
+static void receive_packet(int /*socketfd*/);
+
+static void send_packet(void);
+
+extern void XdmcpDeadSession(char * /*reason*/);
+
+static void timeout(void);
+
+static void XdmcpBlockHandler(
+ void * /*data*/,
+ struct timeval ** /*wt*/,
+ void * /*LastSelectMask*/);
+
+static void XdmcpWakeupHandler(
+ void * /*data*/,
+ int /*i*/,
+ void * /*LastSelectMask*/);
+
+void XdmcpRegisterManufacturerDisplayID(
+ char * /*name*/,
+ int /*length*/);
+
+
+static unsigned short xdm_udp_port = XDM_UDP_PORT;
+static Bool OneSession = FALSE;
+static const char *xdm_from = NULL;
+
+void
+XdmcpUseMsg (void)
+{
+ ErrorF("-query host-name contact named host for XDMCP\n");
+ ErrorF("-broadcast broadcast for XDMCP\n");
+#if defined(IPv6) && defined(AF_INET6)
+ ErrorF("-multicast [addr [hops]] IPv6 multicast for XDMCP\n");
+#endif
+ ErrorF("-indirect host-name contact named host for indirect XDMCP\n");
+ ErrorF("-port port-num UDP port number to send messages to\n");
+ ErrorF("-from local-address specify the local address to connect from\n");
+ ErrorF("-once Terminate server after one session\n");
+ ErrorF("-class display-class specify display class to send in manage\n");
+#ifdef HASXDMAUTH
+ ErrorF("-cookie xdm-auth-bits specify the magic cookie for XDMCP\n");
+#endif
+ ErrorF("-displayID display-id manufacturer display ID for request\n");
+}
+
+int
+XdmcpOptions(int argc, char **argv, int i)
+{
+ if (strcmp(argv[i], "-query") == 0) {
+ get_manager_by_name(argc, argv, i++);
+ XDM_INIT_STATE = XDM_QUERY;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-broadcast") == 0) {
+ XDM_INIT_STATE = XDM_BROADCAST;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ if (strcmp(argv[i], "-multicast") == 0) {
+ i = get_mcast_options(argc, argv, ++i);
+ XDM_INIT_STATE = XDM_MULTICAST;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+#endif
+ if (strcmp(argv[i], "-indirect") == 0) {
+ get_manager_by_name(argc, argv, i++);
+ XDM_INIT_STATE = XDM_INDIRECT;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-port") == 0) {
+ if (++i == argc) {
+ FatalError("Xserver: missing port number in command line\n");
+ }
+ xdm_udp_port = (unsigned short) atoi(argv[i]);
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-from") == 0) {
+ get_fromaddr_by_name(argc, argv, ++i);
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-once") == 0) {
+ OneSession = TRUE;
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-class") == 0) {
+ if (++i == argc) {
+ FatalError("Xserver: missing class name in command line\n");
+ }
+ defaultDisplayClass = argv[i];
+ return (i + 1);
+ }
+#ifdef HASXDMAUTH
+ if (strcmp(argv[i], "-cookie") == 0) {
+ if (++i == argc) {
+ FatalError("Xserver: missing cookie data in command line\n");
+ }
+ xdmAuthCookie = argv[i];
+ return (i + 1);
+ }
+#endif
+ if (strcmp(argv[i], "-displayID") == 0) {
+ if (++i == argc) {
+ FatalError("Xserver: missing displayID in command line\n");
+ }
+ XdmcpRegisterManufacturerDisplayID (argv[i], strlen (argv[i]));
+ return (i + 1);
+ }
+ return (i);
+}
+
+/*
+ * This section is a collection of routines for
+ * registering server-specific data with the XDMCP
+ * state machine.
+ */
+
+
+/*
+ * Save all broadcast addresses away so BroadcastQuery
+ * packets get sent everywhere
+ */
+
+#define MAX_BROADCAST 10
+
+/* This stays sockaddr_in since IPv6 doesn't support broadcast */
+static struct sockaddr_in BroadcastAddresses[MAX_BROADCAST];
+static int NumBroadcastAddresses;
+
+void
+XdmcpRegisterBroadcastAddress (struct sockaddr_in *addr)
+{
+ struct sockaddr_in *bcast;
+ if (NumBroadcastAddresses >= MAX_BROADCAST)
+ return;
+ bcast = &BroadcastAddresses[NumBroadcastAddresses++];
+ bzero (bcast, sizeof (struct sockaddr_in));
+#ifdef BSD44SOCKETS
+ bcast->sin_len = addr->sin_len;
+#endif
+ bcast->sin_family = addr->sin_family;
+ bcast->sin_port = htons (xdm_udp_port);
+ bcast->sin_addr = addr->sin_addr;
+}
+
+/*
+ * Each authentication type is registered here; Validator
+ * will be called to check all access attempts using
+ * the specified authentication type
+ */
+
+static ARRAYofARRAY8 AuthenticationNames, AuthenticationDatas;
+typedef struct _AuthenticationFuncs {
+ ValidatorFunc Validator;
+ GeneratorFunc Generator;
+ AddAuthorFunc AddAuth;
+} AuthenticationFuncsRec, *AuthenticationFuncsPtr;
+
+static AuthenticationFuncsPtr AuthenticationFuncsList;
+
+void
+XdmcpRegisterAuthentication (
+ char *name,
+ int namelen,
+ char *data,
+ int datalen,
+ ValidatorFunc Validator,
+ GeneratorFunc Generator,
+ AddAuthorFunc AddAuth)
+{
+ int i;
+ ARRAY8 AuthenticationName, AuthenticationData;
+ static AuthenticationFuncsPtr newFuncs;
+
+ if (!XdmcpAllocARRAY8 (&AuthenticationName, namelen))
+ return;
+ if (!XdmcpAllocARRAY8 (&AuthenticationData, datalen))
+ {
+ XdmcpDisposeARRAY8 (&AuthenticationName);
+ return;
+ }
+ for (i = 0; i < namelen; i++)
+ AuthenticationName.data[i] = name[i];
+ for (i = 0; i < datalen; i++)
+ AuthenticationData.data[i] = data[i];
+ if (!(XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
+ AuthenticationNames.length + 1) &&
+ XdmcpReallocARRAYofARRAY8 (&AuthenticationDatas,
+ AuthenticationDatas.length + 1) &&
+ (newFuncs = (AuthenticationFuncsPtr) malloc (
+ (AuthenticationNames.length + 1) * sizeof (AuthenticationFuncsRec)))))
+ {
+ XdmcpDisposeARRAY8 (&AuthenticationName);
+ XdmcpDisposeARRAY8 (&AuthenticationData);
+ return;
+ }
+ for (i = 0; i < AuthenticationNames.length - 1; i++)
+ newFuncs[i] = AuthenticationFuncsList[i];
+ newFuncs[AuthenticationNames.length-1].Validator = Validator;
+ newFuncs[AuthenticationNames.length-1].Generator = Generator;
+ newFuncs[AuthenticationNames.length-1].AddAuth = AddAuth;
+ free (AuthenticationFuncsList);
+ AuthenticationFuncsList = newFuncs;
+ AuthenticationNames.data[AuthenticationNames.length-1] = AuthenticationName;
+ AuthenticationDatas.data[AuthenticationDatas.length-1] = AuthenticationData;
+}
+
+/*
+ * Select the authentication type to be used; this is
+ * set by the manager of the host to be connected to.
+ */
+
+ARRAY8 noAuthenticationName = {(CARD16) 0, (CARD8Ptr) 0};
+ARRAY8 noAuthenticationData = {(CARD16) 0, (CARD8Ptr) 0};
+ARRAY8Ptr AuthenticationName = &noAuthenticationName;
+ARRAY8Ptr AuthenticationData = &noAuthenticationData;
+AuthenticationFuncsPtr AuthenticationFuncs;
+
+void
+XdmcpSetAuthentication (ARRAY8Ptr name)
+{
+ int i;
+
+ for (i = 0; i < AuthenticationNames.length; i++)
+ if (XdmcpARRAY8Equal (&AuthenticationNames.data[i], name))
+ {
+ AuthenticationName = &AuthenticationNames.data[i];
+ AuthenticationData = &AuthenticationDatas.data[i];
+ AuthenticationFuncs = &AuthenticationFuncsList[i];
+ break;
+ }
+}
+
+/*
+ * Register the host address for the display
+ */
+
+static ARRAY16 ConnectionTypes;
+static ARRAYofARRAY8 ConnectionAddresses;
+static long xdmcpGeneration;
+
+void
+XdmcpRegisterConnection (
+ int type,
+ char *address,
+ int addrlen)
+{
+ int i;
+ CARD8 *newAddress;
+
+ if (xdmcpGeneration != serverGeneration)
+ {
+ XdmcpDisposeARRAY16 (&ConnectionTypes);
+ XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses);
+ xdmcpGeneration = serverGeneration;
+ }
+ if (xdm_from != NULL) { /* Only register the requested address */
+ const void *regAddr = address;
+ const void *fromAddr = NULL;
+ int regAddrlen = addrlen;
+
+ if (addrlen == sizeof(struct in_addr)) {
+ if (SOCKADDR_FAMILY(FromAddress) == AF_INET) {
+ fromAddr = &((struct sockaddr_in *)&FromAddress)->sin_addr;
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if ((SOCKADDR_FAMILY(FromAddress) == AF_INET6) &&
+ IN6_IS_ADDR_V4MAPPED(
+ &((struct sockaddr_in6 *)&FromAddress)->sin6_addr)) {
+ fromAddr = &((struct sockaddr_in6 *)&FromAddress)->sin6_addr.s6_addr[12];
+ }
+#endif
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if (addrlen == sizeof(struct in6_addr)) {
+ if (SOCKADDR_FAMILY(FromAddress) == AF_INET6) {
+ fromAddr = &((struct sockaddr_in6 *)&FromAddress)->sin6_addr;
+ } else if ((SOCKADDR_FAMILY(FromAddress) == AF_INET) &&
+ IN6_IS_ADDR_V4MAPPED((struct in6_addr *) address)) {
+ fromAddr = &((struct sockaddr_in *)&FromAddress)->sin_addr;
+ regAddr = &((struct sockaddr_in6 *)&address)->sin6_addr.s6_addr[12];
+ regAddrlen = sizeof(struct in_addr);
+ }
+ }
+#endif
+ if (fromAddr && memcmp(regAddr, fromAddr, regAddrlen) != 0) {
+ return;
+ }
+ }
+ newAddress = (CARD8 *) malloc (addrlen * sizeof (CARD8));
+ if (!newAddress)
+ return;
+ if (!XdmcpReallocARRAY16 (&ConnectionTypes, ConnectionTypes.length + 1))
+ {
+ free (newAddress);
+ return;
+ }
+ if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses,
+ ConnectionAddresses.length + 1))
+ {
+ free (newAddress);
+ return;
+ }
+ ConnectionTypes.data[ConnectionTypes.length - 1] = (CARD16) type;
+ for (i = 0; i < addrlen; i++)
+ newAddress[i] = address[i];
+ ConnectionAddresses.data[ConnectionAddresses.length-1].data = newAddress;
+ ConnectionAddresses.data[ConnectionAddresses.length-1].length = addrlen;
+}
+
+/*
+ * Register an Authorization Name. XDMCP advertises this list
+ * to the manager.
+ */
+
+static ARRAYofARRAY8 AuthorizationNames;
+
+void
+XdmcpRegisterAuthorizations (void)
+{
+ XdmcpDisposeARRAYofARRAY8 (&AuthorizationNames);
+ RegisterAuthorizations ();
+}
+
+void
+XdmcpRegisterAuthorization (char *name, int namelen)
+{
+ ARRAY8 authName;
+ int i;
+
+ authName.data = (CARD8 *) malloc (namelen * sizeof (CARD8));
+ if (!authName.data)
+ return;
+ if (!XdmcpReallocARRAYofARRAY8 (&AuthorizationNames, AuthorizationNames.length +1))
+ {
+ free (authName.data);
+ return;
+ }
+ for (i = 0; i < namelen; i++)
+ authName.data[i] = (CARD8) name[i];
+ authName.length = namelen;
+ AuthorizationNames.data[AuthorizationNames.length-1] = authName;
+}
+
+/*
+ * Register the DisplayClass string
+ */
+
+ARRAY8 DisplayClass;
+
+void
+XdmcpRegisterDisplayClass (char *name, int length)
+{
+ int i;
+
+ XdmcpDisposeARRAY8 (&DisplayClass);
+ if (!XdmcpAllocARRAY8 (&DisplayClass, length))
+ return;
+ for (i = 0; i < length; i++)
+ DisplayClass.data[i] = (CARD8) name[i];
+}
+
+/*
+ * Register the Manufacturer display ID
+ */
+
+ARRAY8 ManufacturerDisplayID;
+
+void
+XdmcpRegisterManufacturerDisplayID (char *name, int length)
+{
+ int i;
+
+ XdmcpDisposeARRAY8 (&ManufacturerDisplayID);
+ if (!XdmcpAllocARRAY8 (&ManufacturerDisplayID, length))
+ return;
+ for (i = 0; i < length; i++)
+ ManufacturerDisplayID.data[i] = (CARD8) name[i];
+}
+
+/*
+ * initialize XDMCP; create the socket, compute the display
+ * number, set up the state machine
+ */
+
+void
+XdmcpInit(void)
+{
+#ifdef NX_TRANS_SOCKET
+
+ XdmcpStartTime = GetTimeInMillis();
+
+#endif
+
+ state = XDM_INIT_STATE;
+#ifdef HASXDMAUTH
+ if (xdmAuthCookie)
+ XdmAuthenticationInit (xdmAuthCookie, strlen (xdmAuthCookie));
+#endif
+ if (state != XDM_OFF)
+ {
+ XdmcpRegisterAuthorizations();
+ XdmcpRegisterDisplayClass (defaultDisplayClass, strlen (defaultDisplayClass));
+ AccessUsingXdmcp();
+ RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler,
+ (void *) 0);
+ timeOutRtx = 0;
+ DisplayNumber = (CARD16) atoi(display);
+ get_xdmcp_sock();
+ send_packet();
+ }
+}
+
+void
+XdmcpReset (void)
+{
+ state = XDM_INIT_STATE;
+ if (state != XDM_OFF)
+ {
+ RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler,
+ (void *) 0);
+ timeOutRtx = 0;
+ send_packet();
+ }
+}
+
+/*
+ * Called whenever a new connection is created; notices the
+ * first connection and saves it to terminate the session
+ * when it is closed
+ */
+
+void
+XdmcpOpenDisplay(int sock)
+{
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ state = XDM_RUN_SESSION;
+ timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+ sessionSocket = sock;
+}
+
+void
+XdmcpCloseDisplay(int sock)
+{
+ if ((state != XDM_RUN_SESSION && state != XDM_AWAIT_ALIVE_RESPONSE)
+ || sessionSocket != sock)
+ return;
+ state = XDM_INIT_STATE;
+ if (OneSession)
+ dispatchException |= DE_TERMINATE;
+ else
+ dispatchException |= DE_RESET;
+ isItTimeToYield = TRUE;
+}
+
+/*
+ * called before going to sleep, this routine
+ * may modify the timeout value about to be sent
+ * to select; in this way XDMCP can do appropriate things
+ * dynamically while starting up
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpBlockHandler(
+ void * data, /* unused */
+ struct timeval **wt,
+ void * pReadmask)
+{
+ fd_set *LastSelectMask = (fd_set*)pReadmask;
+ CARD32 millisToGo;
+
+ if (state == XDM_OFF)
+ return;
+ FD_SET(xdmcpSocket, LastSelectMask);
+#if defined(IPv6) && defined(AF_INET6)
+ if (xdmcpSocket6 >= 0)
+ FD_SET(xdmcpSocket6, LastSelectMask);
+#endif
+ if (timeOutTime == 0)
+ return;
+ millisToGo = timeOutTime - GetTimeInMillis();
+ if ((int) millisToGo < 0)
+ millisToGo = 0;
+ AdjustWaitForDelay (wt, millisToGo);
+}
+
+/*
+ * called after select returns; this routine will
+ * recognise when XDMCP packets await and
+ * process them appropriately
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpWakeupHandler(
+ void * data, /* unused */
+ int i,
+ void * pReadmask)
+{
+ fd_set* LastSelectMask = (fd_set*)pReadmask;
+
+#ifdef NX_TRANS_SOCKET
+
+ XdmcpState = state;
+ XdmcpTimeOutRtx = timeOutRtx;
+
+#endif
+
+ if (state == XDM_OFF)
+ return;
+ if (i > 0)
+ {
+ if (FD_ISSET(xdmcpSocket, LastSelectMask))
+ {
+ receive_packet(xdmcpSocket);
+ FD_CLR(xdmcpSocket, LastSelectMask);
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ if (xdmcpSocket6 >= 0 && FD_ISSET(xdmcpSocket6, LastSelectMask))
+ {
+ receive_packet(xdmcpSocket6);
+ FD_CLR(xdmcpSocket6, LastSelectMask);
+ }
+#endif
+ }
+ else if (timeOutTime && (int) (GetTimeInMillis() - timeOutTime) >= 0)
+ {
+ if (state == XDM_RUN_SESSION)
+ {
+ state = XDM_KEEPALIVE;
+ send_packet();
+ }
+ else
+ timeout();
+ }
+}
+
+/*
+ * This routine should be called from the routine that drives the
+ * user's host menu when the user selects a host
+ */
+
+static void
+XdmcpSelectHost(
+ struct sockaddr *host_sockaddr,
+ int host_len,
+ ARRAY8Ptr AuthenticationName)
+{
+ state = XDM_START_CONNECTION;
+ memmove(&req_sockaddr, host_sockaddr, host_len);
+ req_socklen = host_len;
+ XdmcpSetAuthentication (AuthenticationName);
+ send_packet();
+}
+
+/*
+ * !!! this routine should be replaced by a routine that adds
+ * the host to the user's host menu. the current version just
+ * selects the first host to respond with willing message.
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpAddHost(
+ struct sockaddr *from,
+ int fromlen,
+ ARRAY8Ptr AuthenticationName,
+ ARRAY8Ptr hostname,
+ ARRAY8Ptr status)
+{
+ XdmcpSelectHost(from, fromlen, AuthenticationName);
+}
+
+/*
+ * A message is queued on the socket; read it and
+ * do the appropriate thing
+ */
+
+ARRAY8 UnwillingMessage = { (CARD8) 14, (CARD8 *) "Host unwilling" };
+
+static void
+receive_packet(int socketfd)
+{
+#if defined(IPv6) && defined(AF_INET6)
+ struct sockaddr_storage from;
+#else
+ struct sockaddr_in from;
+#endif
+ int fromlen = sizeof(from);
+ XdmcpHeader header;
+
+ /* read message off socket */
+ if (!XdmcpFill (socketfd, &buffer, (XdmcpNetaddr) &from, &fromlen))
+ return;
+
+ /* reset retransmission backoff */
+ timeOutRtx = 0;
+
+ if (!XdmcpReadHeader (&buffer, &header))
+ return;
+
+ if (header.version != XDM_PROTOCOL_VERSION)
+ return;
+
+ switch (header.opcode) {
+ case WILLING:
+ recv_willing_msg((struct sockaddr *) &from, fromlen, header.length);
+ break;
+ case UNWILLING:
+ XdmcpFatal("Manager unwilling", &UnwillingMessage);
+ break;
+ case ACCEPT:
+ recv_accept_msg(header.length);
+ break;
+ case DECLINE:
+ recv_decline_msg(header.length);
+ break;
+ case REFUSE:
+ recv_refuse_msg(header.length);
+ break;
+ case FAILED:
+ recv_failed_msg(header.length);
+ break;
+ case ALIVE:
+ recv_alive_msg(header.length);
+ break;
+ }
+}
+
+/*
+ * send the appropriate message given the current state
+ */
+
+static void
+send_packet(void)
+{
+ int rtx;
+ switch (state) {
+ case XDM_QUERY:
+ case XDM_BROADCAST:
+ case XDM_INDIRECT:
+#if defined(IPv6) && defined(AF_INET6)
+ case XDM_MULTICAST:
+#endif
+ send_query_msg();
+ break;
+ case XDM_START_CONNECTION:
+ send_request_msg();
+ break;
+ case XDM_MANAGE:
+ send_manage_msg();
+ break;
+ case XDM_KEEPALIVE:
+ send_keepalive_msg();
+ break;
+ default:
+ break;
+ }
+ rtx = (XDM_MIN_RTX << timeOutRtx);
+ if (rtx > XDM_MAX_RTX)
+ rtx = XDM_MAX_RTX;
+ timeOutTime = GetTimeInMillis() + rtx * 1000;
+}
+
+/*
+ * The session is declared dead for some reason; too many
+ * timeouts, or Keepalive failure.
+ */
+
+void
+XdmcpDeadSession (char *reason)
+{
+ ErrorF ("XDM: %s, declaring session dead\n", reason);
+ state = XDM_INIT_STATE;
+ isItTimeToYield = TRUE;
+ dispatchException |= DE_RESET;
+ timeOutTime = 0;
+ timeOutRtx = 0;
+ send_packet();
+}
+
+/*
+ * Timeout waiting for an XDMCP response.
+ */
+
+static void
+timeout(void)
+{
+ timeOutRtx++;
+ if (state == XDM_AWAIT_ALIVE_RESPONSE && timeOutRtx >= XDM_KA_RTX_LIMIT )
+ {
+ XdmcpDeadSession ("too many keepalive retransmissions");
+ return;
+ }
+ else if (timeOutRtx >= XDM_RTX_LIMIT)
+ {
+ /* Quit if "-once" specified, otherwise reset and try again. */
+ if (OneSession) {
+ dispatchException |= DE_TERMINATE;
+ ErrorF("XDM: too many retransmissions\n");
+ } else {
+ XdmcpDeadSession("too many retransmissions");
+ }
+ return;
+ }
+
+#if defined(IPv6) && defined(AF_INET6)
+ if (state == XDM_COLLECT_QUERY || state == XDM_COLLECT_INDIRECT_QUERY) {
+ /* Try next address */
+ for (mgrAddr = mgrAddr->ai_next; ; mgrAddr = mgrAddr->ai_next) {
+ if (mgrAddr == NULL) {
+ mgrAddr = mgrAddrFirst;
+ }
+ if (mgrAddr->ai_family == AF_INET
+ || mgrAddr->ai_family == AF_INET6)
+ break;
+ }
+#ifndef SIN6_LEN
+ ManagerAddressLen = mgrAddr->ai_addrlen;
+#endif
+ memcpy(&ManagerAddress, mgrAddr->ai_addr, mgrAddr->ai_addrlen);
+ }
+#endif
+
+ switch (state) {
+ case XDM_COLLECT_QUERY:
+ state = XDM_QUERY;
+ break;
+ case XDM_COLLECT_BROADCAST_QUERY:
+ state = XDM_BROADCAST;
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case XDM_COLLECT_MULTICAST_QUERY:
+ state = XDM_MULTICAST;
+ break;
+#endif
+ case XDM_COLLECT_INDIRECT_QUERY:
+ state = XDM_INDIRECT;
+ break;
+ case XDM_AWAIT_REQUEST_RESPONSE:
+ state = XDM_START_CONNECTION;
+ break;
+ case XDM_AWAIT_MANAGE_RESPONSE:
+ state = XDM_MANAGE;
+ break;
+ case XDM_AWAIT_ALIVE_RESPONSE:
+ state = XDM_KEEPALIVE;
+ break;
+ default:
+ break;
+ }
+ send_packet();
+}
+
+int
+XdmcpCheckAuthentication (
+ ARRAY8Ptr Name,
+ ARRAY8Ptr Data,
+ int packet_type)
+{
+ return (XdmcpARRAY8Equal (Name, AuthenticationName) &&
+ (AuthenticationName->length == 0 ||
+ (*AuthenticationFuncs->Validator) (AuthenticationData, Data, packet_type)));
+}
+
+int
+XdmcpAddAuthorization (
+ ARRAY8Ptr name,
+ ARRAY8Ptr data)
+{
+ AddAuthorFunc AddAuth;
+
+ if (AuthenticationFuncs && AuthenticationFuncs->AddAuth)
+ AddAuth = AuthenticationFuncs->AddAuth;
+ else
+ AddAuth = AddAuthorization;
+ return (*AddAuth) ((unsigned short)name->length,
+ (char *)name->data,
+ (unsigned short)data->length,
+ (char *)data->data);
+}
+
+/*
+ * from here to the end of this file are routines private
+ * to the state machine.
+ */
+
+static void
+get_xdmcp_sock(void)
+{
+ int soopts = 1;
+
+#if defined(IPv6) && defined(AF_INET6)
+ if ((xdmcpSocket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ XdmcpWarning("INET6 UDP socket creation failed");
+#endif
+ if ((xdmcpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ XdmcpWarning("UDP socket creation failed");
+#ifdef SO_BROADCAST
+ else if (setsockopt(xdmcpSocket, SOL_SOCKET, SO_BROADCAST, (char *)&soopts,
+ sizeof(soopts)) < 0)
+ XdmcpWarning("UDP set broadcast socket-option failed");
+#endif /* SO_BROADCAST */
+ if (xdmcpSocket >= 0 && xdm_from != NULL) {
+ if (bind(xdmcpSocket, (struct sockaddr *)&FromAddress,
+ FromAddressLen) < 0) {
+ FatalError("Xserver: failed to bind to -from address: %s\n", xdm_from);
+ }
+ }
+}
+
+static void
+send_query_msg(void)
+{
+ XdmcpHeader header;
+ Bool broadcast = FALSE;
+#if defined(IPv6) && defined(AF_INET6)
+ Bool multicast = FALSE;
+#endif
+ int i;
+ int socketfd = xdmcpSocket;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ switch(state){
+ case XDM_QUERY:
+ header.opcode = (CARD16) QUERY;
+ state = XDM_COLLECT_QUERY;
+ break;
+ case XDM_BROADCAST:
+ header.opcode = (CARD16) BROADCAST_QUERY;
+ state = XDM_COLLECT_BROADCAST_QUERY;
+ broadcast = TRUE;
+ break;
+#if defined(IPv6) && defined(AF_INET6)
+ case XDM_MULTICAST:
+ header.opcode = (CARD16) BROADCAST_QUERY;
+ state = XDM_COLLECT_MULTICAST_QUERY;
+ multicast = TRUE;
+ break;
+#endif
+ case XDM_INDIRECT:
+ header.opcode = (CARD16) INDIRECT_QUERY;
+ state = XDM_COLLECT_INDIRECT_QUERY;
+ break;
+ default:
+ break;
+ }
+ header.length = 1;
+ for (i = 0; i < AuthenticationNames.length; i++)
+ header.length += 2 + AuthenticationNames.data[i].length;
+
+ XdmcpWriteHeader (&buffer, &header);
+ XdmcpWriteARRAYofARRAY8 (&buffer, &AuthenticationNames);
+ if (broadcast)
+ {
+ int i;
+
+ for (i = 0; i < NumBroadcastAddresses; i++)
+ XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &BroadcastAddresses[i],
+ sizeof (struct sockaddr_in));
+ }
+#if defined(IPv6) && defined(AF_INET6)
+ else if (multicast)
+ {
+ struct multicastinfo *mcl;
+ struct addrinfo *ai;
+
+ for (mcl = mcastlist; mcl != NULL; mcl = mcl->next) {
+ for (ai = mcl->ai ; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family == AF_INET) {
+ unsigned char hopflag = (unsigned char) mcl->hops;
+ socketfd = xdmcpSocket;
+ setsockopt(socketfd, IPPROTO_IP, IP_MULTICAST_TTL,
+ &hopflag, sizeof(hopflag));
+ } else if (ai->ai_family == AF_INET6) {
+ int hopflag6 = mcl->hops;
+ socketfd = xdmcpSocket6;
+ setsockopt(socketfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ &hopflag6, sizeof(hopflag6));
+ } else {
+ continue;
+ }
+ XdmcpFlush (socketfd, &buffer,
+ (XdmcpNetaddr) ai->ai_addr, ai->ai_addrlen);
+ break;
+ }
+ }
+ }
+#endif
+ else
+ {
+#if defined(IPv6) && defined(AF_INET6)
+ if (SOCKADDR_FAMILY(ManagerAddress) == AF_INET6)
+ socketfd = xdmcpSocket6;
+#endif
+ XdmcpFlush (socketfd, &buffer, (XdmcpNetaddr) &ManagerAddress,
+ ManagerAddressLen);
+ }
+}
+
+static void
+recv_willing_msg(
+ struct sockaddr *from,
+ int fromlen,
+ unsigned length)
+{
+ ARRAY8 authenticationName;
+ ARRAY8 hostname;
+ ARRAY8 status;
+
+ authenticationName.data = 0;
+ hostname.data = 0;
+ status.data = 0;
+ if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &hostname) &&
+ XdmcpReadARRAY8 (&buffer, &status))
+ {
+ if (length == 6 + authenticationName.length +
+ hostname.length + status.length)
+ {
+ switch (state)
+ {
+ case XDM_COLLECT_QUERY:
+ XdmcpSelectHost(from, fromlen, &authenticationName);
+ break;
+ case XDM_COLLECT_BROADCAST_QUERY:
+#if defined(IPv6) && defined(AF_INET6)
+ case XDM_COLLECT_MULTICAST_QUERY:
+#endif
+ case XDM_COLLECT_INDIRECT_QUERY:
+ XdmcpAddHost(from, fromlen, &authenticationName, &hostname, &status);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ XdmcpDisposeARRAY8 (&authenticationName);
+ XdmcpDisposeARRAY8 (&hostname);
+ XdmcpDisposeARRAY8 (&status);
+}
+
+static void
+send_request_msg(void)
+{
+ XdmcpHeader header;
+ int length;
+ int i;
+ CARD16 XdmcpConnectionType;
+ ARRAY8 authenticationData;
+ int socketfd = xdmcpSocket;
+
+ switch (SOCKADDR_FAMILY(ManagerAddress))
+ {
+ case AF_INET: XdmcpConnectionType=FamilyInternet; break;
+#if defined(IPv6) && defined(AF_INET6)
+ case AF_INET6: XdmcpConnectionType=FamilyInternet6; break;
+#endif
+ default: XdmcpConnectionType=0xffff; break;
+ }
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) REQUEST;
+
+ length = 2; /* display number */
+ length += 1 + 2 * ConnectionTypes.length; /* connection types */
+ length += 1; /* connection addresses */
+ for (i = 0; i < ConnectionAddresses.length; i++)
+ length += 2 + ConnectionAddresses.data[i].length;
+ authenticationData.length = 0;
+ authenticationData.data = 0;
+ if (AuthenticationFuncs)
+ {
+ (*AuthenticationFuncs->Generator) (AuthenticationData,
+ &authenticationData,
+ REQUEST);
+ }
+ length += 2 + AuthenticationName->length; /* authentication name */
+ length += 2 + authenticationData.length; /* authentication data */
+ length += 1; /* authorization names */
+ for (i = 0; i < AuthorizationNames.length; i++)
+ length += 2 + AuthorizationNames.data[i].length;
+ length += 2 + ManufacturerDisplayID.length; /* display ID */
+ header.length = length;
+
+ if (!XdmcpWriteHeader (&buffer, &header))
+ {
+ XdmcpDisposeARRAY8 (&authenticationData);
+ return;
+ }
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteCARD8 (&buffer, ConnectionTypes.length);
+
+ /* The connection array is send reordered, so that connections of */
+ /* the same address type as the XDMCP manager connection are send */
+ /* first. This works around a bug in xdm. mario@klebsch.de */
+ for (i = 0; i < (int)ConnectionTypes.length; i++)
+ if (ConnectionTypes.data[i]==XdmcpConnectionType)
+ XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]);
+ for (i = 0; i < (int)ConnectionTypes.length; i++)
+ if (ConnectionTypes.data[i]!=XdmcpConnectionType)
+ XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]);
+
+ XdmcpWriteCARD8 (&buffer, ConnectionAddresses.length);
+ for (i = 0; i < (int)ConnectionAddresses.length; i++)
+ if ( (i<ConnectionTypes.length) &&
+ (ConnectionTypes.data[i]==XdmcpConnectionType) )
+ XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses.data[i]);
+ for (i = 0; i < (int)ConnectionAddresses.length; i++)
+ if ( (i>=ConnectionTypes.length) ||
+ (ConnectionTypes.data[i]!=XdmcpConnectionType) )
+ XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses.data[i]);
+
+ XdmcpWriteARRAY8 (&buffer, AuthenticationName);
+ XdmcpWriteARRAY8 (&buffer, &authenticationData);
+ XdmcpDisposeARRAY8 (&authenticationData);
+ XdmcpWriteARRAYofARRAY8 (&buffer, &AuthorizationNames);
+ XdmcpWriteARRAY8 (&buffer, &ManufacturerDisplayID);
+#if defined(IPv6) && defined(AF_INET6)
+ if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
+ socketfd = xdmcpSocket6;
+#endif
+ if (XdmcpFlush (socketfd, &buffer,
+ (XdmcpNetaddr) &req_sockaddr, req_socklen))
+ state = XDM_AWAIT_REQUEST_RESPONSE;
+}
+
+static void
+recv_accept_msg(unsigned length)
+{
+ CARD32 AcceptSessionID;
+ ARRAY8 AcceptAuthenticationName, AcceptAuthenticationData;
+ ARRAY8 AcceptAuthorizationName, AcceptAuthorizationData;
+
+ if (state != XDM_AWAIT_REQUEST_RESPONSE)
+ return;
+ AcceptAuthenticationName.data = 0;
+ AcceptAuthenticationData.data = 0;
+ AcceptAuthorizationName.data = 0;
+ AcceptAuthorizationData.data = 0;
+ if (XdmcpReadCARD32 (&buffer, &AcceptSessionID) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationData) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationName) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationData))
+ {
+ if (length == 12 + AcceptAuthenticationName.length +
+ AcceptAuthenticationData.length +
+ AcceptAuthorizationName.length +
+ AcceptAuthorizationData.length)
+ {
+ if (!XdmcpCheckAuthentication (&AcceptAuthenticationName,
+ &AcceptAuthenticationData, ACCEPT))
+ {
+ XdmcpFatal ("Authentication Failure", &AcceptAuthenticationName);
+ }
+ /* permit access control manipulations from this host */
+ AugmentSelf (&req_sockaddr, req_socklen);
+ /* if the authorization specified in the packet fails
+ * to be acceptable, enable the local addresses
+ */
+ if (!XdmcpAddAuthorization (&AcceptAuthorizationName,
+ &AcceptAuthorizationData))
+ {
+ AddLocalHosts ();
+ }
+ SessionID = AcceptSessionID;
+ state = XDM_MANAGE;
+ send_packet();
+ }
+ }
+ XdmcpDisposeARRAY8 (&AcceptAuthenticationName);
+ XdmcpDisposeARRAY8 (&AcceptAuthenticationData);
+ XdmcpDisposeARRAY8 (&AcceptAuthorizationName);
+ XdmcpDisposeARRAY8 (&AcceptAuthorizationData);
+}
+
+static void
+recv_decline_msg(unsigned length)
+{
+ ARRAY8 status, DeclineAuthenticationName, DeclineAuthenticationData;
+
+ status.data = 0;
+ DeclineAuthenticationName.data = 0;
+ DeclineAuthenticationData.data = 0;
+ if (XdmcpReadARRAY8 (&buffer, &status) &&
+ XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationData))
+ {
+ if (length == 6 + status.length +
+ DeclineAuthenticationName.length +
+ DeclineAuthenticationData.length &&
+ XdmcpCheckAuthentication (&DeclineAuthenticationName,
+ &DeclineAuthenticationData, DECLINE))
+ {
+ XdmcpFatal ("Session declined", &status);
+ }
+ }
+ XdmcpDisposeARRAY8 (&status);
+ XdmcpDisposeARRAY8 (&DeclineAuthenticationName);
+ XdmcpDisposeARRAY8 (&DeclineAuthenticationData);
+}
+
+static void
+send_manage_msg(void)
+{
+ XdmcpHeader header;
+ int socketfd = xdmcpSocket;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) MANAGE;
+ header.length = 8 + DisplayClass.length;
+
+ if (!XdmcpWriteHeader (&buffer, &header))
+ return;
+ XdmcpWriteCARD32 (&buffer, SessionID);
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteARRAY8 (&buffer, &DisplayClass);
+ state = XDM_AWAIT_MANAGE_RESPONSE;
+#if defined(IPv6) && defined(AF_INET6)
+ if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
+ socketfd = xdmcpSocket6;
+#endif
+ XdmcpFlush (socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
+}
+
+static void
+recv_refuse_msg(unsigned length)
+{
+ CARD32 RefusedSessionID;
+
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ if (length != 4)
+ return;
+ if (XdmcpReadCARD32 (&buffer, &RefusedSessionID))
+ {
+ if (RefusedSessionID == SessionID)
+ {
+ state = XDM_START_CONNECTION;
+ send_packet();
+ }
+ }
+}
+
+static void
+recv_failed_msg(unsigned length)
+{
+ CARD32 FailedSessionID;
+ ARRAY8 status;
+
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ status.data = 0;
+ if (XdmcpReadCARD32 (&buffer, &FailedSessionID) &&
+ XdmcpReadARRAY8 (&buffer, &status))
+ {
+ if (length == 6 + status.length &&
+ SessionID == FailedSessionID)
+ {
+ XdmcpFatal ("Session failed", &status);
+ }
+ }
+ XdmcpDisposeARRAY8 (&status);
+}
+
+static void
+send_keepalive_msg(void)
+{
+ XdmcpHeader header;
+ int socketfd = xdmcpSocket;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) KEEPALIVE;
+ header.length = 6;
+
+ XdmcpWriteHeader (&buffer, &header);
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteCARD32 (&buffer, SessionID);
+
+ state = XDM_AWAIT_ALIVE_RESPONSE;
+#if defined(IPv6) && defined(AF_INET6)
+ if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
+ socketfd = xdmcpSocket6;
+#endif
+ XdmcpFlush (socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
+}
+
+static void
+recv_alive_msg (unsigned length)
+{
+ CARD8 SessionRunning;
+ CARD32 AliveSessionID;
+
+ if (state != XDM_AWAIT_ALIVE_RESPONSE)
+ return;
+ if (length != 5)
+ return;
+ if (XdmcpReadCARD8 (&buffer, &SessionRunning) &&
+ XdmcpReadCARD32 (&buffer, &AliveSessionID))
+ {
+ if (SessionRunning && AliveSessionID == SessionID)
+ {
+ state = XDM_RUN_SESSION;
+ timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+ }
+ else
+ {
+ XdmcpDeadSession ("Alive response indicates session dead");
+ }
+ }
+}
+
+static void
+XdmcpFatal (
+ char *type,
+ ARRAY8Ptr status)
+{
+ FatalError ("XDMCP fatal error: %s %*.*s\n", type,
+ status->length, status->length, status->data);
+}
+
+static void
+XdmcpWarning(char *str)
+{
+ ErrorF("XDMCP warning: %s\n", str);
+}
+
+static void
+get_addr_by_name(
+ char * argtype,
+ char * namestr,
+ int port,
+ int socktype,
+ SOCKADDR_TYPE *addr,
+ SOCKLEN_TYPE *addrlen
+#if defined(IPv6) && defined(AF_INET6)
+ ,
+ struct addrinfo **aip,
+ struct addrinfo **aifirstp
+#endif
+ )
+{
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai;
+ struct addrinfo hints;
+ char portstr[6];
+ char *pport = portstr;
+ int gaierr;
+
+ bzero(&hints, sizeof(hints));
+ hints.ai_socktype = socktype;
+
+ if (port == 0) {
+ pport = NULL;
+ } else if (port > 0 && port < 65535) {
+ sprintf(portstr, "%d", port);
+ } else {
+ FatalError("Xserver: port out of range: %d\n", port);
+ }
+
+ if (*aifirstp != NULL) {
+ freeaddrinfo(*aifirstp);
+ *aifirstp = NULL;
+ }
+
+ if ((gaierr = getaddrinfo(namestr, pport, &hints, aifirstp)) == 0) {
+ for (ai = *aifirstp; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family == AF_INET || ai->ai_family == AF_INET6)
+ break;
+ }
+ if ((ai == NULL) || (ai->ai_addrlen > sizeof(SOCKADDR_TYPE))) {
+ FatalError ("Xserver: %s host %s not on supported network type\n",
+ argtype, namestr);
+ } else {
+ *aip = ai;
+ *addrlen = ai->ai_addrlen;
+ memcpy(addr, ai->ai_addr, ai->ai_addrlen);
+ }
+ } else {
+ FatalError("Xserver: %s: %s %s\n", gai_strerror(gaierr), argtype, namestr);
+ }
+#else
+ struct hostent *hep;
+#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
+ _Xgethostbynameparams hparams;
+#endif
+#if defined(WIN32) && defined(TCPCONN)
+ _XSERVTransWSAStartup();
+#endif
+ if (!(hep = _XGethostbyname(namestr, hparams)))
+ {
+ FatalError("Xserver: %s unknown host: %s\n", argtype, namestr);
+ }
+ if (hep->h_length == sizeof (struct in_addr))
+ {
+ memmove(&addr->sin_addr, hep->h_addr, hep->h_length);
+ *addrlen = sizeof(struct sockaddr_in);
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons (port);
+ }
+ else
+ {
+ FatalError("Xserver: %s host on strange network %s\n", argtype, namestr);
+ }
+#endif
+}
+
+static void
+get_manager_by_name(
+ int argc,
+ char **argv,
+ int i)
+{
+
+ if ((i + 1) == argc)
+ {
+ FatalError("Xserver: missing %s host name in command line\n", argv[i]);
+ }
+
+ get_addr_by_name(argv[i], argv[i+1], xdm_udp_port, SOCK_DGRAM,
+ &ManagerAddress, &ManagerAddressLen
+#if defined(IPv6) && defined(AF_INET6)
+ , &mgrAddr, &mgrAddrFirst
+#endif
+ );
+}
+
+
+static void
+get_fromaddr_by_name(
+ int argc,
+ char **argv,
+ int i)
+{
+#if defined(IPv6) && defined(AF_INET6)
+ struct addrinfo *ai = NULL;
+ struct addrinfo *aifirst = NULL;
+#endif
+ if (i == argc)
+ {
+ FatalError("Xserver: missing -from host name in command line\n");
+ }
+ get_addr_by_name("-from", argv[i], 0, 0, &FromAddress, &FromAddressLen
+#if defined(IPv6) && defined(AF_INET6)
+ , &ai, &aifirst
+#endif
+ );
+ xdm_from = argv[i];
+}
+
+
+#if defined(IPv6) && defined(AF_INET6)
+static int
+get_mcast_options(argc, argv, i)
+ int argc, i;
+ char **argv;
+{
+ char *address = XDM_DEFAULT_MCAST_ADDR6;
+ int hopcount = 1;
+ struct addrinfo hints;
+ char portstr[6];
+ int gaierr;
+ struct addrinfo *ai, *firstai;
+
+ if ((i < argc) && (argv[i][0] != '-') && (argv[i][0] != '+')) {
+ address = argv[i++];
+ if ((i < argc) && (argv[i][0] != '-') && (argv[i][0] != '+')) {
+ hopcount = strtol(argv[i++], NULL, 10);
+ if ((hopcount < 1) || (hopcount > 255)) {
+ FatalError("Xserver: multicast hop count out of range: %d\n",
+ hopcount);
+ }
+ }
+ }
+
+ if (xdm_udp_port > 0 && xdm_udp_port < 65535) {
+ sprintf(portstr, "%d", xdm_udp_port);
+ } else {
+ FatalError("Xserver: port out of range: %d\n", xdm_udp_port);
+ }
+ bzero(&hints, sizeof(hints));
+ hints.ai_socktype = SOCK_DGRAM;
+
+ if ((gaierr = getaddrinfo(address, portstr, &hints, &firstai)) == 0) {
+ for (ai = firstai; ai != NULL; ai = ai->ai_next) {
+ if (((ai->ai_family == AF_INET) &&
+ IN_MULTICAST(((struct sockaddr_in *) ai->ai_addr)
+ ->sin_addr.s_addr))
+ || ((ai->ai_family == AF_INET6) &&
+ IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *) ai->ai_addr)
+ ->sin6_addr)))
+ break;
+ }
+ if (ai == NULL) {
+ FatalError ("Xserver: address not supported multicast type %s\n",
+ address);
+ } else {
+ struct multicastinfo *mcastinfo, *mcl;
+
+ mcastinfo = malloc(sizeof(struct multicastinfo));
+ mcastinfo->next = NULL;
+ mcastinfo->ai = firstai;
+ mcastinfo->hops = hopcount;
+
+ if (mcastlist == NULL) {
+ mcastlist = mcastinfo;
+ } else {
+ for (mcl = mcastlist; mcl->next != NULL; mcl = mcl->next) {
+ /* Do nothing - just find end of list */
+ }
+ mcl->next = mcastinfo;
+ }
+ }
+ } else {
+ FatalError("Xserver: %s: %s\n", gai_strerror(gaierr), address);
+ }
+ return i;
+}
+#endif
+
+#else
+static int xdmcp_non_empty; /* avoid complaint by ranlib */
+#endif /* XDMCP */
diff --git a/nx-X11/programs/Xserver/os/xprintf.c b/nx-X11/programs/Xserver/os/xprintf.c
new file mode 100644
index 000000000..1bcb36d3c
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/xprintf.c
@@ -0,0 +1,163 @@
+/*
+ * printf routines which malloc their buffer
+ */
+/*
+ * Copyright (c) 2004 Alexander Gottwald
+ *
+ * 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
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/Xos.h>
+#include "os.h"
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifndef va_copy
+# ifdef __va_copy
+# define va_copy __va_copy
+# else
+# error "no working va_copy was found"
+# endif
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+#define START_SIZE 256
+#define END_SIZE 2048
+
+char *
+Xvprintf(const char *format, va_list va)
+{
+ char *ret;
+ char *newret;
+ int size;
+ int r;
+
+ size = 0;
+
+ for (;;)
+ {
+ if (size == 0)
+ {
+ ret = (char *)malloc(START_SIZE);
+ if (ret == NULL)
+ return NULL;
+ size = START_SIZE;
+ }
+ else if (size < END_SIZE &&
+ (newret = (char *) realloc(ret, 2 * size)) != NULL)
+ {
+ ret = newret;
+ size = 2 * size;
+ }
+ else
+ {
+ free(ret);
+ return NULL;
+ }
+
+ r = vsnprintf(ret, size, format, va);
+
+ if (r == -1 || r == size || r > size || r == size - 1)
+ {
+ continue;
+ }
+ else
+ {
+ ret[r] = 0;
+ return ret;
+ }
+ }
+}
+
+#else
+
+char *
+Xvprintf(const char *format, va_list va)
+{
+ char *ret;
+ int size;
+ va_list va2;
+
+ va_copy(va2, va);
+ size = vsnprintf(NULL, 0, format, va2);
+ va_end(va2);
+
+ ret = (char *)malloc(size + 1);
+ if (ret == NULL)
+ return NULL;
+
+ vsnprintf(ret, size + 1, format, va);
+ ret[size] = 0;
+ return ret;
+}
+
+#endif
+
+char *Xprintf(const char *format, ...)
+{
+ char *ret;
+ va_list va;
+ va_start(va, format);
+ ret = Xvprintf(format, va);
+ va_end(va);
+ return ret;
+}
+
+char *
+XNFvprintf(const char *format, va_list va)
+{
+ char *ret;
+ int size;
+ va_list va2;
+
+ va_copy(va2, va);
+ size = vsnprintf(NULL, 0, format, va2);
+ va_end(va2);
+
+ ret = (char *)XNFalloc(size + 1);
+ if (ret == NULL)
+ return NULL;
+
+ vsnprintf(ret, size + 1, format, va);
+ ret[size] = 0;
+ return ret;
+}
+
+char *XNFprintf(const char *format, ...)
+{
+ char *ret;
+ va_list va;
+ va_start(va, format);
+ ret = XNFvprintf(format, va);
+ va_end(va);
+ return ret;
+}
diff --git a/nx-X11/programs/Xserver/os/xstrans.c b/nx-X11/programs/Xserver/os/xstrans.c
new file mode 100644
index 000000000..cdb664430
--- /dev/null
+++ b/nx-X11/programs/Xserver/os/xstrans.c
@@ -0,0 +1,17 @@
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/Xfuncproto.h>
+
+/* ErrorF is used by xtrans */
+#ifndef HAVE_DIX_CONFIG_H
+extern _X_EXPORT void
+ErrorF(const char *f, ...)
+_X_ATTRIBUTE_PRINTF(1, 2);
+#endif
+
+#define TRANS_REOPEN
+#define TRANS_SERVER
+#define XSERV_t
+#include <nx-X11/Xtrans/transport.c>
diff --git a/nx-X11/programs/Xserver/randr/Imakefile b/nx-X11/programs/Xserver/randr/Imakefile
new file mode 100644
index 000000000..6c5c89450
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/Imakefile
@@ -0,0 +1,89 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#include <Server.tmpl>
+
+ NULL =
+
+ SRCS = randr.c \
+ rrcrtc.c \
+ rrdispatch.c \
+ rrinfo.c \
+ rrmode.c \
+ rrmonitor.c \
+ rroutput.c \
+ rrpointer.c \
+ rrproperty.c \
+ rrprovider.c \
+ rrproviderproperty.c \
+ rrscreen.c \
+ rrsdispatch.c \
+ rrtransform.c \
+ rrxinerama.c \
+ $(NULL)
+
+ OBJS = randr.o \
+ rrcrtc.o \
+ rrdispatch.o \
+ rrinfo.o \
+ rrmode.o \
+ rrmonitor.o \
+ rroutput.o \
+ rrpointer.o \
+ rrproperty.o \
+ rrprovider.o \
+ rrproviderproperty.o \
+ rrscreen.o \
+ rrsdispatch.o \
+ rrtransform.o \
+ rrxinerama.o \
+ $(NULL)
+
+ INCLUDES = -I../include -I../mi \
+ -I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ -I../render \
+ `pkg-config --cflags-only-I pixman-1`
+
+#if defined(BuildXinerama)
+ PNRX_DEFINES = -DXINERAMA -DPANORAMIX
+#endif
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+ DEFINES = \
+ $(PNRX_DEFINES) \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryTarget(randr,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(randr,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/randr/panoramiXproto.h b/nx-X11/programs/Xserver/randr/panoramiXproto.h
new file mode 100644
index 000000000..de3fa7194
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/panoramiXproto.h
@@ -0,0 +1,198 @@
+/*****************************************************************
+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.
+******************************************************************/
+
+/* 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/nx-X11/programs/Xserver/randr/randr.c b/nx-X11/programs/Xserver/randr/randr.c
new file mode 100644
index 000000000..c742cf6e0
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/randr.c
@@ -0,0 +1,793 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett-Packard Company
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ *
+ * Author: Jim Gettys, Hewlett-Packard Company, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "randrstr.h"
+
+#ifndef NXAGENT_SERVER
+#include "extinit.h"
+#endif
+
+/* From render.h */
+#ifndef SubPixelUnknown
+#define SubPixelUnknown 0
+#endif
+
+#define RR_VALIDATE
+static int RRNScreens;
+
+#define wrap(priv,real,mem,func) {\
+ ((ScreenPtr)priv)->mem = ((ScreenPtr)real)->mem; \
+ ((ScreenPtr)real)->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+ ((ScreenPtr)real)->mem = ((ScreenPtr)priv)->mem; \
+}
+
+static int ProcRRDispatch(ClientPtr pClient);
+static int SProcRRDispatch(ClientPtr pClient);
+
+int RREventBase;
+int RRErrorBase;
+RESTYPE RRClientType, RREventType; /* resource types for event masks */
+
+#ifndef NXAGENT_SERVER
+DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey;
+DevPrivateKey rrPrivKey = &rrPrivKey;
+#else
+int RRClientPrivateIndex;
+int rrPrivIndex = -1;
+#endif
+
+static void
+RRClientCallback(CallbackListPtr *list, void *closure, void *data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+
+ rrClientPriv(pClient);
+ RRTimesPtr pTimes = (RRTimesPtr) (pRRClient + 1);
+ int i;
+
+ pRRClient->major_version = 0;
+ pRRClient->minor_version = 0;
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+
+ rrScrPriv(pScreen);
+
+ if (pScrPriv) {
+ pTimes[i].setTime = pScrPriv->lastSetTime;
+ pTimes[i].configTime = pScrPriv->lastConfigTime;
+ }
+ }
+}
+
+static Bool
+RRCloseScreen(
+ ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ int j;
+
+ unwrap(pScrPriv, pScreen, CloseScreen);
+ for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
+ RRCrtcDestroy(pScrPriv->crtcs[j]);
+ for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
+ RROutputDestroy(pScrPriv->outputs[j]);
+
+ if (pScrPriv->provider)
+ RRProviderDestroy(pScrPriv->provider);
+
+ RRMonitorClose(pScreen);
+
+ free(pScrPriv->crtcs);
+ free(pScrPriv->outputs);
+ free(pScrPriv);
+ RRNScreens -= 1; /* ok, one fewer screen with RandR running */
+ return (*pScreen->CloseScreen) (pScreen);
+}
+
+static void
+SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent * from,
+ xRRScreenChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->rotation = from->rotation;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->root, to->root);
+ cpswapl(from->window, to->window);
+ cpswaps(from->sizeID, to->sizeID);
+ cpswaps(from->subpixelOrder, to->subpixelOrder);
+ cpswaps(from->widthInPixels, to->widthInPixels);
+ cpswaps(from->heightInPixels, to->heightInPixels);
+ cpswaps(from->widthInMillimeters, to->widthInMillimeters);
+ cpswaps(from->heightInMillimeters, to->heightInMillimeters);
+}
+
+static void
+SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent * from,
+ xRRCrtcChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->window, to->window);
+ cpswapl(from->crtc, to->crtc);
+ cpswapl(from->mode, to->mode);
+ cpswaps(from->rotation, to->rotation);
+ /* pad1 */
+ cpswaps(from->x, to->x);
+ cpswaps(from->y, to->y);
+ cpswaps(from->width, to->width);
+ cpswaps(from->height, to->height);
+}
+
+static void
+SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent * from,
+ xRROutputChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->configTimestamp, to->configTimestamp);
+ cpswapl(from->window, to->window);
+ cpswapl(from->output, to->output);
+ cpswapl(from->crtc, to->crtc);
+ cpswapl(from->mode, to->mode);
+ cpswaps(from->rotation, to->rotation);
+ to->connection = from->connection;
+ to->subpixelOrder = from->subpixelOrder;
+}
+
+static void
+SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent * from,
+ xRROutputPropertyNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->window, to->window);
+ cpswapl(from->output, to->output);
+ cpswapl(from->atom, to->atom);
+ cpswapl(from->timestamp, to->timestamp);
+ to->state = from->state;
+ /* pad1 */
+ /* pad2 */
+ /* pad3 */
+ /* pad4 */
+}
+
+static void
+SRRProviderChangeNotifyEvent(xRRProviderChangeNotifyEvent * from,
+ xRRProviderChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->window, to->window);
+ cpswapl(from->provider, to->provider);
+}
+
+static void
+SRRProviderPropertyNotifyEvent(xRRProviderPropertyNotifyEvent * from,
+ xRRProviderPropertyNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->window, to->window);
+ cpswapl(from->provider, to->provider);
+ cpswapl(from->atom, to->atom);
+ cpswapl(from->timestamp, to->timestamp);
+ to->state = from->state;
+ /* pad1 */
+ /* pad2 */
+ /* pad3 */
+ /* pad4 */
+}
+
+static void
+SRRResourceChangeNotifyEvent(xRRResourceChangeNotifyEvent * from,
+ xRRResourceChangeNotifyEvent * to)
+{
+ to->type = from->type;
+ to->subCode = from->subCode;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->timestamp, to->timestamp);
+ cpswapl(from->window, to->window);
+}
+
+static void
+SRRNotifyEvent(xEvent *from, xEvent *to)
+{
+ switch (from->u.u.detail) {
+ case RRNotify_CrtcChange:
+ SRRCrtcChangeNotifyEvent((xRRCrtcChangeNotifyEvent *) from,
+ (xRRCrtcChangeNotifyEvent *) to);
+ break;
+ case RRNotify_OutputChange:
+ SRROutputChangeNotifyEvent((xRROutputChangeNotifyEvent *) from,
+ (xRROutputChangeNotifyEvent *) to);
+ break;
+ case RRNotify_OutputProperty:
+ SRROutputPropertyNotifyEvent((xRROutputPropertyNotifyEvent *) from,
+ (xRROutputPropertyNotifyEvent *) to);
+ break;
+ case RRNotify_ProviderChange:
+ SRRProviderChangeNotifyEvent((xRRProviderChangeNotifyEvent *) from,
+ (xRRProviderChangeNotifyEvent *) to);
+ break;
+ case RRNotify_ProviderProperty:
+ SRRProviderPropertyNotifyEvent((xRRProviderPropertyNotifyEvent *) from,
+ (xRRProviderPropertyNotifyEvent *) to);
+ break;
+ case RRNotify_ResourceChange:
+ SRRResourceChangeNotifyEvent((xRRResourceChangeNotifyEvent *) from,
+ (xRRResourceChangeNotifyEvent *) to);
+ default:
+ break;
+ }
+}
+
+static int RRGeneration;
+
+Bool
+RRInit(void)
+{
+ if (RRGeneration != serverGeneration) {
+#ifdef NXAGENT_SERVER
+ if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+#endif
+ if (!RRModeInit())
+ return FALSE;
+ if (!RRCrtcInit())
+ return FALSE;
+ if (!RROutputInit())
+ return FALSE;
+ if (!RRProviderInit())
+ return FALSE;
+ RRGeneration = serverGeneration;
+ }
+#ifndef NXAGENT_SERVER
+ if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ return TRUE;
+}
+
+Bool
+RRScreenInit(ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRInit())
+ return FALSE;
+
+ pScrPriv = (rrScrPrivPtr) calloc(1, sizeof(rrScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ SetRRScreen(pScreen, pScrPriv);
+
+ /*
+ * Calling function best set these function vectors
+ */
+ pScrPriv->rrGetInfo = 0;
+ pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
+ pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
+
+ pScrPriv->width = pScreen->width;
+ pScrPriv->height = pScreen->height;
+ pScrPriv->mmWidth = pScreen->mmWidth;
+ pScrPriv->mmHeight = pScreen->mmHeight;
+#if RANDR_12_INTERFACE
+ pScrPriv->rrScreenSetSize = NULL;
+ pScrPriv->rrCrtcSet = NULL;
+ pScrPriv->rrCrtcSetGamma = NULL;
+#endif
+#if RANDR_10_INTERFACE
+ pScrPriv->rrSetConfig = 0;
+ pScrPriv->rotations = RR_Rotate_0;
+ pScrPriv->reqWidth = pScreen->width;
+ pScrPriv->reqHeight = pScreen->height;
+ pScrPriv->nSizes = 0;
+ pScrPriv->pSizes = NULL;
+ pScrPriv->rotation = RR_Rotate_0;
+ pScrPriv->rate = 0;
+ pScrPriv->size = 0;
+#endif
+
+ /*
+ * This value doesn't really matter -- any client must call
+ * GetScreenInfo before reading it which will automatically update
+ * the time
+ */
+ pScrPriv->lastSetTime = currentTime;
+ pScrPriv->lastConfigTime = currentTime;
+
+ wrap(pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+
+ pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
+ pScreen->ReplaceScanoutPixmap = RRReplaceScanoutPixmap;
+ pScrPriv->numOutputs = 0;
+ pScrPriv->outputs = NULL;
+ pScrPriv->numCrtcs = 0;
+ pScrPriv->crtcs = NULL;
+
+ RRMonitorInit(pScreen);
+
+ RRNScreens += 1; /* keep count of screens that implement randr */
+ return TRUE;
+}
+
+ /*ARGSUSED*/ static int
+RRFreeClient(void *data, XID id)
+{
+ RREventPtr pRREvent;
+ WindowPtr pWin;
+ RREventPtr *pHead, pCur, pPrev;
+
+ pRREvent = (RREventPtr) data;
+ pWin = pRREvent->window;
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixDestroyAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pRREvent; pCur = pCur->next)
+ pPrev = pCur;
+ if (pCur) {
+ if (pPrev)
+ pPrev->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ }
+ }
+ free((void *) pRREvent);
+ return 1;
+}
+
+ /*ARGSUSED*/ static int
+RRFreeEvents(void *data, XID id)
+{
+ RREventPtr *pHead, pCur, pNext;
+
+ pHead = (RREventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource(pCur->clientResource, RRClientType);
+ free((void *) pCur);
+ }
+ free((void *) pHead);
+ return 1;
+}
+
+void
+RRExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ if (RRNScreens == 0)
+ return;
+
+#ifndef NXAGENT_SERVER
+ if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT,
+ sizeof(RRClientRec) +
+ screenInfo.numScreens * sizeof(RRTimesRec)))
+ return;
+#else /* !defined(NXAGENT_SERVER) */
+ RRClientPrivateIndex = AllocateClientPrivateIndex();
+ if (!AllocateClientPrivate(RRClientPrivateIndex,
+ sizeof(RRClientRec) +
+ screenInfo.numScreens * sizeof(RRTimesRec)))
+ return;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (!AddCallback(&ClientStateCallback, RRClientCallback, 0))
+ return;
+
+ RRClientType = CreateNewResourceType(RRFreeClient
+#ifndef NXAGENT_SERVER
+ , "RandRClient"
+#endif
+ );
+ if (!RRClientType)
+ return;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RRClientType, "RandRClient");
+#endif
+
+ RREventType = CreateNewResourceType(RRFreeEvents
+#ifndef NXAGENT_SERVER
+ , "RandREvent"
+#endif
+ );
+ if (!RREventType)
+ return;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RREventType, "RandREvent");
+#endif
+
+ extEntry = AddExtension(RANDR_NAME, RRNumberEvents, RRNumberErrors,
+ ProcRRDispatch, SProcRRDispatch,
+ NULL, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+ RRErrorBase = extEntry->errorBase;
+ RREventBase = extEntry->eventBase;
+ EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr)
+ SRRScreenChangeNotifyEvent;
+ EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
+ SRRNotifyEvent;
+
+ RRModeInitErrorValue();
+ RRCrtcInitErrorValue();
+ RROutputInitErrorValue();
+ RRProviderInitErrorValue();
+#ifdef PANORAMIX
+ RRXineramaExtensionInit();
+#endif
+}
+
+void
+RRResourcesChanged(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ pScrPriv->resourcesChanged = TRUE;
+
+ RRSetChanged(pScreen);
+}
+
+static void
+RRDeliverResourceEvent(ClientPtr client, WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRResourceChangeNotifyEvent re = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ResourceChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &re);
+}
+
+static int
+TellChanged(WindowPtr pWin, void *value)
+{
+ RREventPtr *pHead, pRREvent;
+ ClientPtr client;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
+#endif
+
+ rrScrPriv(pScreen);
+ int i;
+
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ client = pRREvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+
+ if (pRREvent->mask & RRScreenChangeNotifyMask)
+ RRDeliverScreenEvent(client, pWin, pScreen);
+
+ if (pRREvent->mask & RRCrtcChangeNotifyMask) {
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ if (crtc->changed)
+ RRDeliverCrtcEvent(client, pWin, crtc);
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i];
+
+ if (crtc->changed)
+ RRDeliverCrtcEvent(client, pWin, crtc);
+ }
+ }
+#endif
+ }
+
+ if (pRREvent->mask & RROutputChangeNotifyMask) {
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ RROutputPtr output = pScrPriv->outputs[i];
+
+ if (output->changed)
+ RRDeliverOutputEvent(client, pWin, output);
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++) {
+ RROutputPtr output = pSlaveScrPriv->outputs[i];
+
+ if (output->changed)
+ RRDeliverOutputEvent(client, pWin, output);
+ }
+ }
+#endif
+ }
+
+#ifndef NXAGENT_SERVER
+ if (pRREvent->mask & RRProviderChangeNotifyMask) {
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ }
+#endif
+
+ if (pRREvent->mask & RRResourceChangeNotifyMask) {
+ if (pScrPriv->resourcesChanged) {
+ RRDeliverResourceEvent(client, pWin);
+ }
+ }
+ }
+ return WT_WALKCHILDREN;
+}
+
+void
+RRSetChanged(ScreenPtr pScreen)
+{
+#ifndef NXAGENT_SERVER
+ /* set changed bits on the master screen only */
+ ScreenPtr master;
+
+ rrScrPriv(pScreen);
+ rrScrPrivPtr mastersp;
+
+ if (pScreen->isGPU) {
+ master = pScreen->current_master;
+ if (!master)
+ return;
+ mastersp = rrGetScrPriv(master);
+ }
+ else
+ {
+ master = pScreen;
+ mastersp = pScrPriv;
+ }
+
+ mastersp->changed = TRUE;
+#else /* !defined(NXAGENT_SERVER) */
+ rrScrPriv(pScreen);
+ pScrPriv->changed = TRUE;
+#endif
+}
+
+/*
+ * Something changed; send events and adjust pointer position
+ */
+void
+RRTellChanged(ScreenPtr pScreen)
+{
+ ScreenPtr master;
+ rrScrPriv(pScreen);
+ rrScrPrivPtr mastersp;
+ int i;
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
+#endif
+
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ master = pScreen->current_master;
+ mastersp = rrGetScrPriv(master);
+ }
+ else
+#endif
+ {
+ master = pScreen;
+ mastersp = pScrPriv;
+ }
+
+ if (mastersp->changed) {
+ UpdateCurrentTimeIf();
+ if (mastersp->configChanged) {
+ mastersp->lastConfigTime = currentTime;
+ mastersp->configChanged = FALSE;
+ }
+ pScrPriv->changed = FALSE;
+ mastersp->changed = FALSE;
+
+ WalkTree(master, TellChanged, (void *) master);
+
+ mastersp->resourcesChanged = FALSE;
+
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ pScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pScrPriv->numCrtcs; i++)
+ pScrPriv->crtcs[i]->changed = FALSE;
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
+ pSlaveScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
+ pSlaveScrPriv->crtcs[i]->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (mastersp->layoutChanged) {
+ pScrPriv->layoutChanged = FALSE;
+ RRPointerScreenConfigured(master);
+ RRSendConfigNotify(master);
+ }
+ }
+}
+
+/*
+ * Return the first output which is connected to an active CRTC
+ * Used in emulating 1.0 behaviour
+ */
+RROutputPtr
+RRFirstOutput(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ RROutputPtr output;
+ int i, j;
+
+ if (!pScrPriv)
+ return NULL;
+
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
+ return pScrPriv->primaryOutput;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ for (j = 0; j < pScrPriv->numOutputs; j++) {
+ output = pScrPriv->outputs[j];
+ if (output->crtc == crtc)
+ return output;
+ }
+ }
+ return NULL;
+}
+
+CARD16
+RRVerticalRefresh(xRRModeInfo * mode)
+{
+ CARD32 refresh;
+ CARD32 dots = mode->hTotal * mode->vTotal;
+
+ if (!dots)
+ return 0;
+ refresh = (mode->dotClock + dots / 2) / dots;
+ if (refresh > 0xffff)
+ refresh = 0xffff;
+ return (CARD16) refresh;
+}
+
+static int
+ProcRRDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+ return BadRequest;
+ UpdateCurrentTimeIf();
+ return (*ProcRandrVector[stuff->data]) (client);
+}
+
+static int
+SProcRRDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ if (stuff->data >= RRNumberRequests || !SProcRandrVector[stuff->data])
+ return BadRequest;
+ UpdateCurrentTimeIf();
+ return (*SProcRandrVector[stuff->data]) (client);
+}
diff --git a/nx-X11/programs/Xserver/randr/randrstr.h b/nx-X11/programs/Xserver/randr/randrstr.h
new file mode 100644
index 000000000..4b497f82d
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/randrstr.h
@@ -0,0 +1,1212 @@
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett-Packard Company
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ *
+ * Author: Jim Gettys, Hewlett-Packard Company, Inc.
+ * Keith Packard, Intel Corporation
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _RANDRSTR_H_
+#define _RANDRSTR_H_
+
+#ifndef NXAGENT_SERVER
+#include "list.h"
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "rrtransform.h"
+#include <nx-X11/extensions/randr.h>
+#include <nx-X11/extensions/randrproto.h>
+#include <nx-X11/extensions/render.h> /* we share subpixel order information */
+#include "picturestr.h"
+#include <nx-X11/Xfuncproto.h>
+
+/* required for ABI compatibility for now */
+#define RANDR_10_INTERFACE 1
+#define RANDR_12_INTERFACE 1
+#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_15_INTERFACE 1
+#define RANDR_GET_CRTC_INTERFACE 1
+
+#define RANDR_INTERFACE_VERSION 0x0104
+
+typedef XID RRMode;
+typedef XID RROutput;
+typedef XID RRCrtc;
+typedef XID RRProvider;
+
+extern int RREventBase, RRErrorBase;
+
+extern int (*ProcRandrVector[RRNumberRequests]) (ClientPtr);
+extern int (*SProcRandrVector[RRNumberRequests]) (ClientPtr);
+
+/*
+ * Modeline for a monitor. Name follows directly after this struct
+ */
+
+#define RRModeName(pMode) ((char *) (pMode + 1))
+typedef struct _rrMode RRModeRec, *RRModePtr;
+typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
+typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
+typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
+typedef struct _rrOutput RROutputRec, *RROutputPtr;
+typedef struct _rrProvider RRProviderRec, *RRProviderPtr;
+typedef struct _rrMonitor RRMonitorRec, *RRMonitorPtr;
+
+struct _rrMode {
+ int refcnt;
+ xRRModeInfo mode;
+ char *name;
+ ScreenPtr userScreen;
+};
+
+struct _rrPropertyValue {
+ Atom type; /* ignored by server */
+ short format; /* format of data for swapping - 8,16,32 */
+ long size; /* size of data in (format/8) bytes */
+ void *data; /* private to client */
+};
+
+struct _rrProperty {
+ RRPropertyPtr next;
+ ATOM propertyName;
+ Bool is_pending;
+ Bool range;
+ Bool immutable;
+ int num_valid;
+ INT32 *valid_values;
+ RRPropertyValueRec current, pending;
+};
+
+struct _rrCrtc {
+ RRCrtc id;
+ ScreenPtr pScreen;
+ RRModePtr mode;
+ int x, y;
+ Rotation rotation;
+ Rotation rotations;
+ Bool changed;
+ int numOutputs;
+ RROutputPtr *outputs;
+ int gammaSize;
+ CARD16 *gammaRed;
+ CARD16 *gammaBlue;
+ CARD16 *gammaGreen;
+ void *devPrivate;
+ Bool transforms;
+ RRTransformRec client_pending_transform;
+ RRTransformRec client_current_transform;
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+
+ PixmapPtr scanout_pixmap;
+};
+
+struct _rrOutput {
+ RROutput id;
+ ScreenPtr pScreen;
+ char *name;
+ int nameLength;
+ CARD8 connection;
+ CARD8 subpixelOrder;
+ int mmWidth;
+ int mmHeight;
+ RRCrtcPtr crtc;
+ int numCrtcs;
+ RRCrtcPtr *crtcs;
+ int numClones;
+ RROutputPtr *clones;
+ int numModes;
+ int numPreferred;
+ RRModePtr *modes;
+ int numUserModes;
+ RRModePtr *userModes;
+ Bool changed;
+ RRPropertyPtr properties;
+ Bool pendingProperties;
+ void *devPrivate;
+};
+
+struct _rrProvider {
+ RRProvider id;
+ ScreenPtr pScreen;
+ uint32_t capabilities;
+ char *name;
+ int nameLength;
+ RRPropertyPtr properties;
+ Bool pendingProperties;
+ Bool changed;
+ struct _rrProvider *offload_sink;
+ struct _rrProvider *output_source;
+};
+
+typedef struct _rrMonitorGeometry {
+ BoxRec box;
+ CARD32 mmWidth;
+ CARD32 mmHeight;
+} RRMonitorGeometryRec, *RRMonitorGeometryPtr;
+
+struct _rrMonitor {
+ Atom name;
+ ScreenPtr pScreen;
+ int numOutputs;
+ RROutput *outputs;
+ Bool primary;
+ Bool automatic;
+ RRMonitorGeometryRec geometry;
+};
+
+#if RANDR_12_INTERFACE
+typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
+ CARD16 width,
+ CARD16 height,
+ CARD32 mmWidth, CARD32 mmHeight);
+
+typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
+ RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int numOutputs, RROutputPtr * outputs);
+
+typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
+
+typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr pScreen, RRCrtcPtr crtc);
+
+typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property,
+ RRPropertyValuePtr value);
+
+typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output,
+ RRModePtr mode);
+
+typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, RRModePtr mode);
+
+#endif
+
+#if RANDR_13_INTERFACE
+typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen,
+ RROutputPtr output, Atom property);
+typedef Bool (*RRGetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea, INT16 *border);
+typedef Bool (*RRSetPanningProcPtr) (ScreenPtr pScrn,
+ RRCrtcPtr crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea, INT16 *border);
+
+#endif /* RANDR_13_INTERFACE */
+
+typedef Bool (*RRProviderGetPropertyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ Atom property);
+typedef Bool (*RRProviderSetPropertyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ Atom property,
+ RRPropertyValuePtr value);
+
+typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation * rotations);
+typedef Bool (*RRCloseScreenProcPtr) (ScreenPtr pscreen);
+
+typedef Bool (*RRProviderSetOutputSourceProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ RRProviderPtr output_source);
+
+typedef Bool (*RRProviderSetOffloadSinkProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider,
+ RRProviderPtr offload_sink);
+
+typedef void (*RRProviderDestroyProcPtr) (ScreenPtr pScreen,
+ RRProviderPtr provider);
+
+/* These are for 1.0 compatibility */
+
+typedef struct _rrRefresh {
+ CARD16 rate;
+ RRModePtr mode;
+} RRScreenRate, *RRScreenRatePtr;
+
+typedef struct _rrScreenSize {
+ int id;
+ short width, height;
+ short mmWidth, mmHeight;
+ int nRates;
+ RRScreenRatePtr pRates;
+} RRScreenSize, *RRScreenSizePtr;
+
+#ifdef RANDR_10_INTERFACE
+
+typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate, RRScreenSizePtr pSize);
+
+#endif
+
+typedef Bool (*RRCrtcSetScanoutPixmapProcPtr) (RRCrtcPtr crtc, PixmapPtr pixmap);
+
+typedef struct _rrScrPriv {
+ /*
+ * 'public' part of the structure; DDXen fill this in
+ * as they initialize
+ */
+#if RANDR_10_INTERFACE
+ RRSetConfigProcPtr rrSetConfig;
+#endif
+ RRGetInfoProcPtr rrGetInfo;
+#if RANDR_12_INTERFACE
+ RRScreenSetSizeProcPtr rrScreenSetSize;
+ RRCrtcSetProcPtr rrCrtcSet;
+ RRCrtcSetGammaProcPtr rrCrtcSetGamma;
+ RRCrtcGetGammaProcPtr rrCrtcGetGamma;
+ RROutputSetPropertyProcPtr rrOutputSetProperty;
+ RROutputValidateModeProcPtr rrOutputValidateMode;
+ RRModeDestroyProcPtr rrModeDestroy;
+#endif
+#if RANDR_13_INTERFACE
+ RROutputGetPropertyProcPtr rrOutputGetProperty;
+ RRGetPanningProcPtr rrGetPanning;
+ RRSetPanningProcPtr rrSetPanning;
+#endif
+ /* TODO #if RANDR_15_INTERFACE */
+ RRCrtcSetScanoutPixmapProcPtr rrCrtcSetScanoutPixmap;
+
+ RRProviderSetOutputSourceProcPtr rrProviderSetOutputSource;
+ RRProviderSetOffloadSinkProcPtr rrProviderSetOffloadSink;
+ RRProviderGetPropertyProcPtr rrProviderGetProperty;
+ RRProviderSetPropertyProcPtr rrProviderSetProperty;
+
+ /*
+ * Private part of the structure; not considered part of the ABI
+ */
+ TimeStamp lastSetTime; /* last changed by client */
+ TimeStamp lastConfigTime; /* possible configs changed */
+ RRCloseScreenProcPtr CloseScreen;
+
+ Bool changed; /* some config changed */
+ Bool configChanged; /* configuration changed */
+ Bool layoutChanged; /* screen layout changed */
+ Bool resourcesChanged; /* screen resources change */
+
+ CARD16 minWidth, minHeight;
+ CARD16 maxWidth, maxHeight;
+ CARD16 width, height; /* last known screen size */
+ CARD16 mmWidth, mmHeight; /* last known screen size */
+
+ int numOutputs;
+ RROutputPtr *outputs;
+ RROutputPtr primaryOutput;
+
+ int numCrtcs;
+ RRCrtcPtr *crtcs;
+
+ /* Last known pointer position */
+ RRCrtcPtr pointerCrtc;
+
+#ifdef RANDR_10_INTERFACE
+ /*
+ * Configuration information
+ */
+ Rotation rotations;
+ CARD16 reqWidth, reqHeight;
+
+ int nSizes;
+ RRScreenSizePtr pSizes;
+
+ Rotation rotation;
+ int rate;
+ int size;
+#endif
+ Bool discontiguous;
+
+ RRProviderPtr provider;
+
+ RRProviderDestroyProcPtr rrProviderDestroy;
+
+ int numMonitors;
+ RRMonitorPtr *monitors;
+
+} rrScrPrivRec, *rrScrPrivPtr;
+
+#ifndef NXAGENT_SERVER
+extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
+
+#define rrPrivKey (&rrPrivKeyRec)
+extern DevPrivateKey rrPrivKey;
+#else
+extern int rrPrivIndex;
+#endif
+
+#ifndef NXAGENT_SERVER
+
+#define rrGetScrPriv(pScr) ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
+#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
+#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p)
+
+#else /* !defined(NXAGENT_SERVER) */
+
+#define rrGetScrPriv(pScr) ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr)
+#define rrScrPriv(pScr) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScr)
+#define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (void *) (p))
+
+#endif /* !defined(NXAGENT_SERVER) */
+
+/*
+ * each window has a list of clients requesting
+ * RRNotify events. Each client has a resource
+ * for each window it selects RRNotify input for,
+ * this resource is used to delete the RRNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _RREvent *RREventPtr;
+
+typedef struct _RREvent {
+ RREventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+ int mask;
+} RREventRec;
+
+typedef struct _RRTimes {
+ TimeStamp setTime;
+ TimeStamp configTime;
+} RRTimesRec, *RRTimesPtr;
+
+typedef struct _RRClient {
+ int major_version;
+ int minor_version;
+/* RRTimesRec times[0]; */
+} RRClientRec, *RRClientPtr;
+
+extern RESTYPE RRClientType, RREventType; /* resource types for event masks */
+
+#ifndef NXAGENT_SERVER
+extern DevPrivateKey RRClientPrivateKey;
+#else
+extern int RRClientPrivateIndex;
+#endif
+
+extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType, RRProviderType;
+
+#ifdef NXAGENT_SERVER
+
+#define LookupOutput(client,id,a) ((RROutputPtr) \
+ (SecurityLookupIDByType (client, id, \
+ RROutputType, a)))
+#define LookupCrtc(client,id,a) ((RRCrtcPtr) \
+ (SecurityLookupIDByType (client, id, \
+ RRCrtcType, a)))
+#define LookupMode(client,id,a) ((RRModePtr) \
+ (SecurityLookupIDByType (client, id, \
+ RRModeType, a)))
+#define LookupProvider(client,id,a) ((RRProviderPtr) \
+ (SecurityLookupIDByType (client, id, \
+ RRProviderType, a)))
+
+#define DixSetAttrAccess DixWriteAccess
+#define DixUseAccess DixWriteAccess
+
+#endif
+
+#ifndef NXAGENT_SERVER
+
+#define RRClientPrivateKey (&RRClientPrivateKeyRec)
+#define GetRRClient(pClient) ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
+
+#else /* !defined/NXAGENT_SERVER) */
+
+#define GetRRClient(pClient) ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+
+#endif /* !defined(NXAGENT_SERVER) */
+#define rrClientPriv(pClient) RRClientPtr pRRClient = GetRRClient(pClient)
+
+/* Initialize the extension */
+void
+ RRExtensionInit(void);
+
+#ifndef NXAGENT_SERVER
+#define VERIFY_RR_OUTPUT(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RROutputType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_CRTC(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRCrtcType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_MODE(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRModeType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+
+#define VERIFY_RR_PROVIDER(id, ptr, a)\
+ {\
+ int rc = dixLookupResourceByType((void **)&(ptr), id,\
+ RRProviderType, client, a);\
+ if (rc != Success) {\
+ client->errorValue = id;\
+ return rc;\
+ }\
+ }
+#else /* !defined(NXAGENT_SERVER) */
+#define VERIFY_RR_OUTPUT(id, ptr, a)\
+ {\
+ ptr = LookupOutput(client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRROutput;\
+ }\
+ }
+
+#define VERIFY_RR_CRTC(id, ptr, a)\
+ {\
+ ptr = LookupCrtc (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRCrtc;\
+ }\
+ }
+
+#define VERIFY_RR_MODE(id, ptr, a)\
+ {\
+ ptr = LookupMode (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRMode;\
+ }\
+ }
+
+#define VERIFY_RR_PROVIDER(id, ptr, a)\
+ {\
+ ptr = LookupProvider (client, id, a);\
+ if (!ptr) {\
+ client->errorValue = id;\
+ return RRErrorBase + BadRRProvider;\
+ }\
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+#ifdef RANDR_12_INTERFACE
+/*
+ * Set the range of sizes for the screen
+ */
+extern _X_EXPORT void
+
+RRScreenSetSizeRange(ScreenPtr pScreen,
+ CARD16 minWidth,
+ CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight);
+#endif
+
+/* rrscreen.c */
+/*
+ * Notify the extension that the screen size has been changed.
+ * The driver is responsible for calling this whenever it has changed
+ * the size of the screen
+ */
+extern _X_EXPORT void
+ RRScreenSizeNotify(ScreenPtr pScreen);
+
+/*
+ * Request that the screen be resized
+ */
+extern _X_EXPORT Bool
+
+RRScreenSizeSet(ScreenPtr pScreen,
+ CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight);
+
+/*
+ * Send ConfigureNotify event to root window when 'something' happens
+ */
+extern _X_EXPORT void
+ RRSendConfigNotify(ScreenPtr pScreen);
+
+/*
+ * screen dispatch
+ */
+extern _X_EXPORT int
+ ProcRRGetScreenSizeRange(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetScreenSize(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetScreenResources(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetScreenResourcesCurrent(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetScreenConfig(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetScreenInfo(ClientPtr client);
+
+/*
+ * Deliver a ScreenNotify event
+ */
+extern _X_EXPORT void
+ RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
+
+extern _X_EXPORT void
+ RRResourcesChanged(ScreenPtr pScreen);
+
+/* randr.c */
+/* set a screen change on the primary screen */
+extern _X_EXPORT void
+ RRSetChanged(ScreenPtr pScreen);
+
+/*
+ * Send all pending events
+ */
+extern _X_EXPORT void
+ RRTellChanged(ScreenPtr pScreen);
+
+/*
+ * Poll the driver for changed information
+ */
+extern _X_EXPORT Bool
+ RRGetInfo(ScreenPtr pScreen, Bool force_query);
+
+extern _X_EXPORT Bool RRInit(void);
+
+extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
+
+extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen);
+
+extern _X_EXPORT CARD16
+ RRVerticalRefresh(xRRModeInfo * mode);
+
+#ifdef RANDR_10_INTERFACE
+/*
+ * This is the old interface, deprecated but left
+ * around for compatibility
+ */
+
+/*
+ * Then, register the specific size with the screen
+ */
+
+extern _X_EXPORT RRScreenSizePtr
+RRRegisterSize(ScreenPtr pScreen,
+ short width, short height, short mmWidth, short mmHeight);
+
+extern _X_EXPORT Bool
+ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate);
+
+/*
+ * Finally, set the current configuration of the screen
+ */
+
+extern _X_EXPORT void
+
+
+RRSetCurrentConfig(ScreenPtr pScreen,
+ Rotation rotation, int rate, RRScreenSizePtr pSize);
+
+extern _X_EXPORT Rotation RRGetRotation(ScreenPtr pScreen);
+
+#endif
+
+/* rrcrtc.c */
+
+/*
+ * Notify the CRTC of some change; layoutChanged indicates that
+ * some position or size element changed
+ */
+extern _X_EXPORT void
+ RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged);
+
+/*
+ * Create a CRTC
+ */
+extern _X_EXPORT RRCrtcPtr RRCrtcCreate(ScreenPtr pScreen, void *devPrivate);
+
+/*
+ * Set the allowed rotations on a CRTC
+ */
+extern _X_EXPORT void
+ RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations);
+
+/*
+ * Set whether transforms are allowed on a CRTC
+ */
+extern _X_EXPORT void
+ RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms);
+
+/*
+ * Notify the extension that the Crtc has been reconfigured,
+ * the driver calls this whenever it has updated the mode
+ */
+extern _X_EXPORT Bool
+
+RRCrtcNotify(RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ RRTransformPtr transform, int numOutputs, RROutputPtr * outputs);
+
+extern _X_EXPORT void
+ RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
+
+/*
+ * Request that the Crtc be reconfigured
+ */
+extern _X_EXPORT Bool
+
+RRCrtcSet(RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y, Rotation rotation, int numOutput, RROutputPtr * outputs);
+
+/*
+ * Request that the Crtc gamma be changed
+ */
+
+extern _X_EXPORT Bool
+ RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue);
+
+/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+
+extern _X_EXPORT Bool
+ RRCrtcGammaGet(RRCrtcPtr crtc);
+
+/*
+ * Notify the extension that the Crtc gamma has been changed
+ * The driver calls this whenever it has changed the gamma values
+ * in the RRCrtcRec
+ */
+
+extern _X_EXPORT Bool
+ RRCrtcGammaNotify(RRCrtcPtr crtc);
+
+/*
+ * Set the size of the gamma table at server startup time
+ */
+
+extern _X_EXPORT Bool
+ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size);
+
+/*
+ * Return the area of the frame buffer scanned out by the crtc,
+ * taking into account the current mode and rotation
+ */
+
+extern _X_EXPORT void
+ RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
+
+/*
+ * Return crtc transform
+ */
+extern _X_EXPORT RRTransformPtr RRCrtcGetTransform(RRCrtcPtr crtc);
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+extern _X_EXPORT Bool
+ RRCrtcPendingTransform(RRCrtcPtr crtc);
+
+/*
+ * Destroy a Crtc at shutdown
+ */
+extern _X_EXPORT void
+ RRCrtcDestroy(RRCrtcPtr crtc);
+
+/*
+ * Set the pending CRTC transformation
+ */
+
+extern _X_EXPORT int
+
+RRCrtcTransformSet(RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse,
+ char *filter, int filter_len, xFixed * params, int nparams);
+
+/*
+ * Initialize crtc type
+ */
+extern _X_EXPORT Bool
+ RRCrtcInit(void);
+
+/*
+ * Initialize crtc type error value
+ */
+extern _X_EXPORT void
+ RRCrtcInitErrorValue(void);
+
+/*
+ * Detach and free a scanout pixmap
+ */
+extern _X_EXPORT void
+ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc);
+
+extern _X_EXPORT Bool
+ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable);
+
+/*
+ * Crtc dispatch
+ */
+
+extern _X_EXPORT int
+ ProcRRGetCrtcInfo(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetCrtcConfig(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetCrtcGammaSize(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetCrtcGamma(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetCrtcGamma(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetCrtcTransform(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetCrtcTransform(ClientPtr client);
+
+int
+ ProcRRGetPanning(ClientPtr client);
+
+int
+ ProcRRSetPanning(ClientPtr client);
+
+void
+ RRConstrainCursorHarder(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr, int, int *, int *);
+
+/* rrdispatch.c */
+extern _X_EXPORT Bool
+ RRClientKnowsRates(ClientPtr pClient);
+
+/* rrmode.c */
+/*
+ * Find, and if necessary, create a mode
+ */
+
+extern _X_EXPORT RRModePtr RRModeGet(xRRModeInfo * modeInfo, const char *name);
+
+/*
+ * Destroy a mode.
+ */
+
+extern _X_EXPORT void
+ RRModeDestroy(RRModePtr mode);
+
+/*
+ * Return a list of modes that are valid for some output in pScreen
+ */
+extern _X_EXPORT RRModePtr *RRModesForScreen(ScreenPtr pScreen, int *num_ret);
+
+/*
+ * Initialize mode type
+ */
+extern _X_EXPORT Bool
+ RRModeInit(void);
+
+/*
+ * Initialize mode type error value
+ */
+extern _X_EXPORT void
+ RRModeInitErrorValue(void);
+
+extern _X_EXPORT int
+ ProcRRCreateMode(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRDestroyMode(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRAddOutputMode(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRDeleteOutputMode(ClientPtr client);
+
+/* rroutput.c */
+
+/*
+ * Notify the output of some change. configChanged indicates whether
+ * any external configuration (mode list, clones, connected status)
+ * has changed, or whether the change was strictly internal
+ * (which crtc is in use)
+ */
+extern _X_EXPORT void
+ RROutputChanged(RROutputPtr output, Bool configChanged);
+
+/*
+ * Create an output
+ */
+
+extern _X_EXPORT RROutputPtr
+RROutputCreate(ScreenPtr pScreen,
+ const char *name, int nameLength, void *devPrivate);
+
+/*
+ * Notify extension that output parameters have been changed
+ */
+extern _X_EXPORT Bool
+ RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones);
+
+extern _X_EXPORT Bool
+
+RROutputSetModes(RROutputPtr output,
+ RRModePtr * modes, int numModes, int numPreferred);
+
+extern _X_EXPORT int
+ RROutputAddUserMode(RROutputPtr output, RRModePtr mode);
+
+extern _X_EXPORT int
+ RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode);
+
+extern _X_EXPORT Bool
+ RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs);
+
+extern _X_EXPORT Bool
+ RROutputSetConnection(RROutputPtr output, CARD8 connection);
+
+extern _X_EXPORT Bool
+ RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder);
+
+extern _X_EXPORT Bool
+ RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight);
+
+extern _X_EXPORT void
+ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
+
+extern _X_EXPORT void
+ RROutputDestroy(RROutputPtr output);
+
+extern _X_EXPORT int
+ ProcRRGetOutputInfo(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetOutputPrimary(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetOutputPrimary(ClientPtr client);
+
+/*
+ * Initialize output type
+ */
+extern _X_EXPORT Bool
+ RROutputInit(void);
+
+/*
+ * Initialize output type error value
+ */
+extern _X_EXPORT void
+ RROutputInitErrorValue(void);
+
+/* rrpointer.c */
+extern _X_EXPORT void
+ RRPointerMoved(ScreenPtr pScreen, int x, int y);
+
+extern _X_EXPORT void
+ RRPointerScreenConfigured(ScreenPtr pScreen);
+
+/* rrproperty.c */
+
+extern _X_EXPORT void
+ RRDeleteAllOutputProperties(RROutputPtr output);
+
+extern _X_EXPORT RRPropertyValuePtr
+RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending);
+
+extern _X_EXPORT RRPropertyPtr
+RRQueryOutputProperty(RROutputPtr output, Atom property);
+
+extern _X_EXPORT void
+ RRDeleteOutputProperty(RROutputPtr output, Atom property);
+
+extern _X_EXPORT Bool
+ RRPostPendingProperties(RROutputPtr output);
+
+extern _X_EXPORT int
+
+RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending);
+
+extern _X_EXPORT int
+
+RRConfigureOutputProperty(RROutputPtr output, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values);
+extern _X_EXPORT int
+ ProcRRChangeOutputProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetOutputProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRListOutputProperties(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRQueryOutputProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRConfigureOutputProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRDeleteOutputProperty(ClientPtr client);
+
+/* rrprovider.c */
+extern _X_EXPORT void
+ RRProviderInitErrorValue(void);
+
+extern _X_EXPORT int
+ ProcRRGetProviders(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRGetProviderInfo(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetProviderOutputSource(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRSetProviderOffloadSink(ClientPtr client);
+
+extern _X_EXPORT Bool
+ RRProviderInit(void);
+
+extern _X_EXPORT RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, const char *name, int nameLength);
+
+extern _X_EXPORT void
+ RRProviderDestroy(RRProviderPtr provider);
+
+extern _X_EXPORT void
+ RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities);
+
+extern _X_EXPORT Bool
+ RRProviderLookup(XID id, RRProviderPtr * provider_p);
+
+extern _X_EXPORT void
+
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider);
+
+/* rrproviderproperty.c */
+
+extern _X_EXPORT void
+ RRDeleteAllProviderProperties(RRProviderPtr provider);
+
+extern _X_EXPORT RRPropertyValuePtr
+RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending);
+
+extern _X_EXPORT RRPropertyPtr
+RRQueryProviderProperty(RRProviderPtr provider, Atom property);
+
+extern _X_EXPORT void
+ RRDeleteProviderProperty(RRProviderPtr provider, Atom property);
+
+extern _X_EXPORT int
+RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending);
+
+extern _X_EXPORT int
+RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values);
+
+extern _X_EXPORT Bool
+ RRPostProviderPendingProperties(RRProviderPtr provider);
+
+extern _X_EXPORT int
+ ProcRRGetProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRListProviderProperties(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRQueryProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRConfigureProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRChangeProviderProperty(ClientPtr client);
+
+extern _X_EXPORT int
+ ProcRRDeleteProviderProperty(ClientPtr client);
+
+/* rrxinerama.c */
+#ifdef XINERAMA
+extern _X_EXPORT void
+ RRXineramaExtensionInit(void);
+#endif
+
+void
+ RRMonitorInit(ScreenPtr screen);
+
+Bool
+
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret);
+
+int
+ RRMonitorCountList(ScreenPtr screen);
+
+void
+ RRMonitorFreeList(RRMonitorPtr monitors, int nmon);
+
+void
+ RRMonitorClose(ScreenPtr screen);
+
+RRMonitorPtr
+RRMonitorAlloc(int noutput);
+
+int
+ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor);
+
+void
+ RRMonitorFree(RRMonitorPtr monitor);
+
+int
+ ProcRRGetMonitors(ClientPtr client);
+
+int
+ ProcRRSetMonitor(ClientPtr client);
+
+int
+ ProcRRDeleteMonitor(ClientPtr client);
+
+#endif /* _RANDRSTR_H_ */
+
+/*
+
+randr extension implementation structure
+
+Query state:
+ ProcRRGetScreenInfo/ProcRRGetScreenResources
+ RRGetInfo
+
+ • Request configuration from driver, either 1.0 or 1.2 style
+ • These functions only record state changes, all
+ other actions are pended until RRTellChanged is called
+
+ ->rrGetInfo
+ 1.0:
+ RRRegisterSize
+ RRRegisterRate
+ RRSetCurrentConfig
+ 1.2:
+ RRScreenSetSizeRange
+ RROutputSetCrtcs
+ RRModeGet
+ RROutputSetModes
+ RROutputSetConnection
+ RROutputSetSubpixelOrder
+ RROutputSetClones
+ RRCrtcNotify
+
+ • Must delay scanning configuration until after ->rrGetInfo returns
+ because some drivers will call SetCurrentConfig in the middle
+ of the ->rrGetInfo operation.
+
+ 1.0:
+
+ • Scan old configuration, mirror to new structures
+
+ RRScanOldConfig
+ RRCrtcCreate
+ RROutputCreate
+ RROutputSetCrtcs
+ RROutputSetConnection
+ RROutputSetSubpixelOrder
+ RROldModeAdd • This adds modes one-at-a-time
+ RRModeGet
+ RRCrtcNotify
+
+ • send events, reset pointer if necessary
+
+ RRTellChanged
+ WalkTree (sending events)
+
+ • when layout has changed:
+ RRPointerScreenConfigured
+ RRSendConfigNotify
+
+Asynchronous state setting (1.2 only)
+ When setting state asynchronously, the driver invokes the
+ ->rrGetInfo function and then calls RRTellChanged to flush
+ the changes to the clients and reset pointer if necessary
+
+Set state
+
+ ProcRRSetScreenConfig
+ RRCrtcSet
+ 1.2:
+ ->rrCrtcSet
+ RRCrtcNotify
+ 1.0:
+ ->rrSetConfig
+ RRCrtcNotify
+ RRTellChanged
+ */
diff --git a/nx-X11/programs/Xserver/randr/rrcrtc.c b/nx-X11/programs/Xserver/randr/rrcrtc.c
new file mode 100644
index 000000000..7775747f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrcrtc.c
@@ -0,0 +1,1883 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright 2010 Red Hat, Inc
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+#include "mipointer.h"
+
+RESTYPE RRCrtcType;
+
+/*
+ * Notify the CRTC of some change
+ */
+void
+RRCrtcChanged(RRCrtcPtr crtc, Bool layoutChanged)
+{
+ ScreenPtr pScreen = crtc->pScreen;
+
+ crtc->changed = TRUE;
+ if (pScreen) {
+ rrScrPriv(pScreen);
+
+ RRSetChanged(pScreen);
+ /*
+ * Send ConfigureNotify on any layout change
+ */
+ if (layoutChanged)
+ pScrPriv->layoutChanged = TRUE;
+ }
+}
+
+/*
+ * Create a CRTC
+ */
+RRCrtcPtr
+RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
+{
+ RRCrtcPtr crtc;
+ RRCrtcPtr *crtcs;
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRInit())
+ return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ /* make space for the crtc pointer */
+ if (pScrPriv->numCrtcs)
+ crtcs = reallocarray(pScrPriv->crtcs,
+ pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr));
+ else
+ crtcs = malloc(sizeof(RRCrtcPtr));
+ if (!crtcs)
+ return FALSE;
+ pScrPriv->crtcs = crtcs;
+
+ crtc = calloc(1, sizeof(RRCrtcRec));
+ if (!crtc)
+ return NULL;
+ crtc->id = FakeClientID(0);
+ crtc->pScreen = pScreen;
+ crtc->mode = NULL;
+ crtc->x = 0;
+ crtc->y = 0;
+ crtc->rotation = RR_Rotate_0;
+ crtc->rotations = RR_Rotate_0;
+ crtc->outputs = NULL;
+ crtc->numOutputs = 0;
+ crtc->gammaSize = 0;
+ crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
+ crtc->changed = FALSE;
+ crtc->devPrivate = devPrivate;
+ RRTransformInit(&crtc->client_pending_transform);
+ RRTransformInit(&crtc->client_current_transform);
+ pixman_transform_init_identity(&crtc->transform);
+ pixman_f_transform_init_identity(&crtc->f_transform);
+ pixman_f_transform_init_identity(&crtc->f_inverse);
+
+ if (!AddResource(crtc->id, RRCrtcType, (void *) crtc))
+ return NULL;
+
+ /* attach the screen and crtc together */
+ crtc->pScreen = pScreen;
+ pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+
+ RRResourcesChanged(pScreen);
+
+ return crtc;
+}
+
+/*
+ * Set the allowed rotations on a CRTC
+ */
+void
+RRCrtcSetRotations(RRCrtcPtr crtc, Rotation rotations)
+{
+ crtc->rotations = rotations;
+}
+
+/*
+ * Set whether transforms are allowed on a CRTC
+ */
+void
+RRCrtcSetTransformSupport(RRCrtcPtr crtc, Bool transforms)
+{
+ crtc->transforms = transforms;
+}
+
+/*
+ * Notify the extension that the Crtc has been reconfigured,
+ * the driver calls this whenever it has updated the mode
+ */
+Bool
+RRCrtcNotify(RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ RRTransformPtr transform, int numOutputs, RROutputPtr * outputs)
+{
+ int i, j;
+
+ /*
+ * Check to see if any of the new outputs were
+ * not in the old list and mark them as changed
+ */
+ for (i = 0; i < numOutputs; i++) {
+ for (j = 0; j < crtc->numOutputs; j++)
+ if (outputs[i] == crtc->outputs[j])
+ break;
+ if (j == crtc->numOutputs) {
+ outputs[i]->crtc = crtc;
+ RROutputChanged(outputs[i], FALSE);
+ RRCrtcChanged(crtc, FALSE);
+ }
+ }
+ /*
+ * Check to see if any of the old outputs are
+ * not in the new list and mark them as changed
+ */
+ for (j = 0; j < crtc->numOutputs; j++) {
+ for (i = 0; i < numOutputs; i++)
+ if (outputs[i] == crtc->outputs[j])
+ break;
+ if (i == numOutputs) {
+ if (crtc->outputs[j]->crtc == crtc)
+ crtc->outputs[j]->crtc = NULL;
+ RROutputChanged(crtc->outputs[j], FALSE);
+ RRCrtcChanged(crtc, FALSE);
+ }
+ }
+ /*
+ * Reallocate the crtc output array if necessary
+ */
+ if (numOutputs != crtc->numOutputs) {
+ RROutputPtr *newoutputs;
+
+ if (numOutputs) {
+ if (crtc->numOutputs)
+ newoutputs = reallocarray(crtc->outputs,
+ numOutputs, sizeof(RROutputPtr));
+ else
+ newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr));
+ if (!newoutputs)
+ return FALSE;
+ }
+ else {
+ free(crtc->outputs);
+ newoutputs = NULL;
+ }
+ crtc->outputs = newoutputs;
+ crtc->numOutputs = numOutputs;
+ }
+ /*
+ * Copy the new list of outputs into the crtc
+ */
+ memcpy(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr));
+ /*
+ * Update remaining crtc fields
+ */
+ if (mode != crtc->mode) {
+ if (crtc->mode)
+ RRModeDestroy(crtc->mode);
+ crtc->mode = mode;
+ if (mode != NULL)
+ mode->refcnt++;
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (x != crtc->x) {
+ crtc->x = x;
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (y != crtc->y) {
+ crtc->y = y;
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (rotation != crtc->rotation) {
+ crtc->rotation = rotation;
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (!RRTransformEqual(transform, &crtc->client_current_transform)) {
+ RRTransformCopy(&crtc->client_current_transform, transform);
+ RRCrtcChanged(crtc, TRUE);
+ }
+ if (crtc->changed && mode) {
+ RRTransformCompute(x, y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_current_transform,
+ &crtc->transform, &crtc->f_transform,
+ &crtc->f_inverse);
+ }
+ return TRUE;
+}
+
+void
+RRDeliverCrtcEvent(ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+ RRModePtr mode = crtc->mode;
+
+ xRRCrtcChangeNotifyEvent ce = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_CrtcChange,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id,
+ .crtc = crtc->id,
+ .mode = mode ? mode->mode.id : None,
+ .rotation = crtc->rotation,
+ .x = mode ? crtc->x : 0,
+ .y = mode ? crtc->y : 0,
+ .width = mode ? mode->mode.width : 0,
+ .height = mode ? mode->mode.height : 0
+ };
+ WriteEventsToClient(client, 1, (xEvent *) &ce);
+}
+
+static Bool
+RRCrtcPendingProperties(RRCrtcPtr crtc)
+{
+ ScreenPtr pScreen = crtc->pScreen;
+
+ rrScrPriv(pScreen);
+ int o;
+
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+
+ if (output->crtc == crtc && output->pendingProperties)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
+{
+ *left = crtc->x;
+ *top = crtc->y;
+
+ switch (crtc->rotation) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ default:
+ *right = crtc->x + crtc->mode->mode.width;
+ *bottom = crtc->y + crtc->mode->mode.height;
+ return;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ *right = crtc->x + crtc->mode->mode.height;
+ *bottom = crtc->y + crtc->mode->mode.width;
+ return;
+ }
+}
+
+/* overlapping counts as adjacent */
+static Bool
+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
+{
+ /* left, right, top, bottom... */
+ int al, ar, at, ab;
+ int bl, br, bt, bb;
+ int cl, cr, ct, cb; /* the overlap, if any */
+
+ crtc_bounds(a, &al, &ar, &at, &ab);
+ crtc_bounds(b, &bl, &br, &bt, &bb);
+
+ cl = max(al, bl);
+ cr = min(ar, br);
+ ct = max(at, bt);
+ cb = min(ab, bb);
+
+ return (cl <= cr) && (ct <= cb);
+}
+
+/* Depth-first search and mark all CRTCs reachable from cur */
+static void
+mark_crtcs(rrScrPrivPtr pScrPriv, int *reachable, int cur)
+{
+ int i;
+
+ reachable[cur] = TRUE;
+ for (i = 0; i < pScrPriv->numCrtcs; ++i) {
+ if (reachable[i] || !pScrPriv->crtcs[i]->mode)
+ continue;
+ if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
+ mark_crtcs(pScrPriv, reachable, i);
+ }
+}
+
+static void
+RRComputeContiguity(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ Bool discontiguous = TRUE;
+ int i, n = pScrPriv->numCrtcs;
+
+ int *reachable = calloc(n, sizeof(int));
+
+ if (!reachable)
+ goto out;
+
+ /* Find first enabled CRTC and start search for reachable CRTCs from it */
+ for (i = 0; i < n; ++i) {
+ if (pScrPriv->crtcs[i]->mode) {
+ mark_crtcs(pScrPriv, reachable, i);
+ break;
+ }
+ }
+
+ /* Check that all enabled CRTCs were marked as reachable */
+ for (i = 0; i < n; ++i)
+ if (pScrPriv->crtcs[i]->mode && !reachable[i])
+ goto out;
+
+ discontiguous = FALSE;
+
+ out:
+ free(reachable);
+ pScrPriv->discontiguous = discontiguous;
+}
+
+static void
+rrDestroySharedPixmap(RRCrtcPtr crtc, PixmapPtr pPixmap) {
+#ifndef NXAGENT_SERVER
+ ScreenPtr master = crtc->pScreen->current_master;
+
+ if (master && pPixmap->master_pixmap) {
+ PixmapPtr mscreenpix = master->GetScreenPixmap(master);
+
+ master->StopPixmapTracking(mscreenpix, pPixmap);
+ /*
+ * Unref the pixmap twice: once for the original reference, and once
+ * for the reference implicitly added by PixmapShareToSlave.
+ */
+ master->DestroyPixmap(pPixmap->master_pixmap);
+ master->DestroyPixmap(pPixmap->master_pixmap);
+ }
+#endif
+
+ crtc->pScreen->DestroyPixmap(pPixmap);
+}
+
+void
+RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
+{
+ rrScrPriv(crtc->pScreen);
+
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
+ if (crtc->scanout_pixmap) {
+ rrDestroySharedPixmap(crtc, crtc->scanout_pixmap);
+ }
+ crtc->scanout_pixmap = NULL;
+ RRCrtcChanged(crtc, TRUE);
+}
+
+#ifndef NXAGENT_SERVER
+static PixmapPtr
+rrCreateSharedPixmap(RRCrtcPtr crtc, ScreenPtr master,
+ int width, int height, int depth,
+ int x, int y, Rotation rotation)
+{
+ Bool ret;
+ PixmapPtr mpix, spix;
+ rrScrPriv(crtc->pScreen);
+
+ mpix = master->CreatePixmap(master, width, height, depth,
+ CREATE_PIXMAP_USAGE_SHARED);
+ if (!mpix)
+ return NULL;
+
+ spix = PixmapShareToSlave(mpix, crtc->pScreen);
+ if (spix == NULL) {
+ master->DestroyPixmap(mpix);
+ return NULL;
+ }
+
+ ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix);
+ if (ret == FALSE) {
+ rrDestroySharedPixmap(crtc, spix);
+ ErrorF("randr: failed to set shadow slave pixmap\n");
+ return NULL;
+ }
+
+ return spix;
+}
+
+static Bool
+rrSetupPixmapSharing(RRCrtcPtr crtc, int width, int height,
+ int x, int y, Rotation rotation)
+{
+ ScreenPtr master = crtc->pScreen->current_master;
+ int depth;
+ PixmapPtr mscreenpix;
+ PixmapPtr spix;
+
+ /* create a pixmap on the master screen,
+ then get a shared handle for it
+ create a shared pixmap on the slave screen using the handle
+ set the master screen to do dirty updates to the shared pixmap
+ from the screen pixmap.
+ set slave screen to scanout shared linear pixmap
+ */
+
+ mscreenpix = master->GetScreenPixmap(master);
+ depth = mscreenpix->drawable.depth;
+
+ if (crtc->scanout_pixmap)
+ RRCrtcDetachScanoutPixmap(crtc);
+
+ if (width == 0 && height == 0) {
+ return TRUE;
+ }
+
+ spix = rrCreateSharedPixmap(crtc, master,
+ width, height, depth,
+ x, y, rotation);
+ if (spix == NULL) {
+ return FALSE;
+ }
+
+ crtc->scanout_pixmap = spix;
+
+ master->StartPixmapTracking(mscreenpix, spix, x, y, 0, 0, rotation);
+ return TRUE;
+}
+
+static void crtc_to_box(BoxPtr box, RRCrtcPtr crtc)
+{
+ box->x1 = crtc->x;
+ box->y1 = crtc->y;
+ switch (crtc->rotation) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ default:
+ box->x2 = crtc->x + crtc->mode->mode.width;
+ box->y2 = crtc->y + crtc->mode->mode.height;
+ break;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ box->x2 = crtc->x + crtc->mode->mode.height;
+ box->y2 = crtc->y + crtc->mode->mode.width;
+ break;
+ }
+}
+
+static Bool
+rrCheckPixmapBounding(ScreenPtr pScreen,
+ RRCrtcPtr rr_crtc, Rotation rotation,
+ int x, int y, int w, int h)
+{
+ RegionRec root_pixmap_region, total_region, new_crtc_region;
+ int c;
+ BoxRec newbox;
+ BoxPtr newsize;
+ ScreenPtr slave;
+ int new_width, new_height;
+ PixmapPtr screen_pixmap = pScreen->GetScreenPixmap(pScreen);
+ rrScrPriv(pScreen);
+
+ PixmapRegionInit(&root_pixmap_region, screen_pixmap);
+ RegionInit(&total_region, NULL, 0);
+
+ /* have to iterate all the crtcs of the attached gpu masters
+ and all their output slaves */
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+
+ if (crtc == rr_crtc) {
+ newbox.x1 = x;
+ newbox.y1 = y;
+ if (rotation == RR_Rotate_90 ||
+ rotation == RR_Rotate_270) {
+ newbox.x2 = x + h;
+ newbox.y2 = y + w;
+ } else {
+ newbox.x2 = x + w;
+ newbox.y2 = y + h;
+ }
+ } else {
+ if (!crtc->mode)
+ continue;
+ crtc_to_box(&newbox, crtc);
+ }
+ RegionInit(&new_crtc_region, &newbox, 1);
+ RegionUnion(&total_region, &total_region, &new_crtc_region);
+ }
+
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ rrScrPrivPtr slave_priv = rrGetScrPriv(slave);
+ for (c = 0; c < slave_priv->numCrtcs; c++) {
+ RRCrtcPtr slave_crtc = slave_priv->crtcs[c];
+
+ if (slave_crtc == rr_crtc) {
+ newbox.x1 = x;
+ newbox.y1 = y;
+ if (rotation == RR_Rotate_90 ||
+ rotation == RR_Rotate_270) {
+ newbox.x2 = x + h;
+ newbox.y2 = y + w;
+ } else {
+ newbox.x2 = x + w;
+ newbox.y2 = y + h;
+ }
+ }
+ else {
+ if (!slave_crtc->mode)
+ continue;
+ crtc_to_box(&newbox, slave_crtc);
+ }
+ RegionInit(&new_crtc_region, &newbox, 1);
+ RegionUnion(&total_region, &total_region, &new_crtc_region);
+ }
+ }
+
+ newsize = RegionExtents(&total_region);
+ new_width = newsize->x2 - newsize->x1;
+ new_height = newsize->y2 - newsize->y1;
+
+ if (new_width == screen_pixmap->drawable.width &&
+ new_height == screen_pixmap->drawable.height) {
+ } else {
+ pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
+ }
+
+ /* set shatters TODO */
+ return TRUE;
+}
+#endif /* !defined(NXAGENT_SERVER) */
+
+/*
+ * Request that the Crtc be reconfigured
+ */
+Bool
+RRCrtcSet(RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y, Rotation rotation, int numOutputs, RROutputPtr * outputs)
+{
+ ScreenPtr pScreen = crtc->pScreen;
+ Bool ret = FALSE;
+ Bool recompute = TRUE;
+ Bool crtcChanged;
+ int o;
+
+ rrScrPriv(pScreen);
+
+ crtcChanged = FALSE;
+ for (o = 0; o < numOutputs; o++) {
+ if (outputs[o] && outputs[o]->crtc != crtc) {
+ crtcChanged = TRUE;
+ break;
+ }
+ }
+
+ /* See if nothing changed */
+ if (crtc->mode == mode &&
+ crtc->x == x &&
+ crtc->y == y &&
+ crtc->rotation == rotation &&
+ crtc->numOutputs == numOutputs &&
+ !memcmp(crtc->outputs, outputs, numOutputs * sizeof(RROutputPtr)) &&
+ !RRCrtcPendingProperties(crtc) && !RRCrtcPendingTransform(crtc) &&
+ !crtcChanged) {
+ recompute = FALSE;
+ ret = TRUE;
+ }
+ else {
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ ScreenPtr master = pScreen->current_master;
+ int width = 0, height = 0;
+
+ if (mode) {
+ width = mode->mode.width;
+ height = mode->mode.height;
+ }
+ ret = rrCheckPixmapBounding(master, crtc,
+ rotation, x, y, width, height);
+ if (!ret)
+ return FALSE;
+
+ if (pScreen->current_master) {
+ ret = rrSetupPixmapSharing(crtc, width, height, x, y, rotation);
+ }
+ }
+#endif
+#if RANDR_12_INTERFACE
+ if (pScrPriv->rrCrtcSet) {
+ ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+ rotation, numOutputs, outputs);
+ }
+ else
+#endif
+ {
+#if RANDR_10_INTERFACE
+ if (pScrPriv->rrSetConfig) {
+ RRScreenSize size;
+ RRScreenRate rate;
+
+ if (!mode) {
+ RRCrtcNotify(crtc, NULL, x, y, rotation, NULL, 0, NULL);
+ ret = TRUE;
+ }
+ else {
+ size.width = mode->mode.width;
+ size.height = mode->mode.height;
+ if (outputs[0]->mmWidth && outputs[0]->mmHeight) {
+ size.mmWidth = outputs[0]->mmWidth;
+ size.mmHeight = outputs[0]->mmHeight;
+ }
+ else {
+ size.mmWidth = pScreen->mmWidth;
+ size.mmHeight = pScreen->mmHeight;
+ }
+ size.nRates = 1;
+ rate.rate = RRVerticalRefresh(&mode->mode);
+ size.pRates = &rate;
+ ret =
+ (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate,
+ &size);
+ /*
+ * Old 1.0 interface tied screen size to mode size
+ */
+ if (ret) {
+ RRCrtcNotify(crtc, mode, x, y, rotation, NULL, 1,
+ outputs);
+ RRScreenSizeNotify(pScreen);
+ }
+ }
+ }
+#endif
+ }
+ if (ret) {
+
+ RRTellChanged(pScreen);
+
+ for (o = 0; o < numOutputs; o++)
+ RRPostPendingProperties(outputs[o]);
+ }
+ }
+
+ if (recompute)
+ RRComputeContiguity(pScreen);
+
+ return ret;
+}
+
+/*
+ * Return crtc transform
+ */
+RRTransformPtr
+RRCrtcGetTransform(RRCrtcPtr crtc)
+{
+ RRTransformPtr transform = &crtc->client_pending_transform;
+
+ if (pixman_transform_is_identity(&transform->transform))
+ return NULL;
+ return transform;
+}
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+Bool
+RRCrtcPendingTransform(RRCrtcPtr crtc)
+{
+ return memcmp(&crtc->client_current_transform.transform,
+ &crtc->client_pending_transform.transform,
+ sizeof(PictTransform)) != 0;
+}
+
+/*
+ * Destroy a Crtc at shutdown
+ */
+void
+RRCrtcDestroy(RRCrtcPtr crtc)
+{
+ FreeResource(crtc->id, 0);
+}
+
+static int
+RRCrtcDestroyResource(void *value, XID pid)
+{
+ RRCrtcPtr crtc = (RRCrtcPtr) value;
+ ScreenPtr pScreen = crtc->pScreen;
+
+ if (pScreen) {
+ rrScrPriv(pScreen);
+ int i;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ if (pScrPriv->crtcs[i] == crtc) {
+ memmove(pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
+ (pScrPriv->numCrtcs - (i + 1)) * sizeof(RRCrtcPtr));
+ --pScrPriv->numCrtcs;
+ break;
+ }
+ }
+
+ RRResourcesChanged(pScreen);
+ }
+
+ if (crtc->scanout_pixmap)
+ RRCrtcDetachScanoutPixmap(crtc);
+ free(crtc->gammaRed);
+ if (crtc->mode)
+ RRModeDestroy(crtc->mode);
+ free(crtc);
+ return 1;
+}
+
+/*
+ * Request that the Crtc gamma be changed
+ */
+
+Bool
+RRCrtcGammaSet(RRCrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue)
+{
+ Bool ret = TRUE;
+
+#if RANDR_12_INTERFACE
+ ScreenPtr pScreen = crtc->pScreen;
+#endif
+
+ memcpy(crtc->gammaRed, red, crtc->gammaSize * sizeof(CARD16));
+ memcpy(crtc->gammaGreen, green, crtc->gammaSize * sizeof(CARD16));
+ memcpy(crtc->gammaBlue, blue, crtc->gammaSize * sizeof(CARD16));
+#if RANDR_12_INTERFACE
+ if (pScreen) {
+ rrScrPriv(pScreen);
+ if (pScrPriv->rrCrtcSetGamma)
+ ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
+ }
+#endif
+ return ret;
+}
+
+/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+Bool
+RRCrtcGammaGet(RRCrtcPtr crtc)
+{
+ Bool ret = TRUE;
+
+#if RANDR_12_INTERFACE
+ ScreenPtr pScreen = crtc->pScreen;
+#endif
+
+#if RANDR_12_INTERFACE
+ if (pScreen) {
+ rrScrPriv(pScreen);
+ if (pScrPriv->rrCrtcGetGamma)
+ ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
+ }
+#endif
+ return ret;
+}
+
+/*
+ * Notify the extension that the Crtc gamma has been changed
+ * The driver calls this whenever it has changed the gamma values
+ * in the RRCrtcRec
+ */
+
+Bool
+RRCrtcGammaNotify(RRCrtcPtr crtc)
+{
+ return TRUE; /* not much going on here */
+}
+
+static void
+RRModeGetScanoutSize(RRModePtr mode, PictTransformPtr transform,
+ int *width, int *height)
+{
+ BoxRec box;
+
+ if (mode == NULL) {
+ *width = 0;
+ *height = 0;
+ return;
+ }
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = mode->mode.width;
+ box.y2 = mode->mode.height;
+
+ pixman_transform_bounds(transform, &box);
+ *width = box.x2 - box.x1;
+ *height = box.y2 - box.y1;
+}
+
+/**
+ * Returns the width/height that the crtc scans out from the framebuffer
+ */
+void
+RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+{
+ RRModeGetScanoutSize(crtc->mode, &crtc->transform, width, height);
+}
+
+/*
+ * Set the size of the gamma table at server startup time
+ */
+
+Bool
+RRCrtcGammaSetSize(RRCrtcPtr crtc, int size)
+{
+ CARD16 *gamma;
+
+ if (size == crtc->gammaSize)
+ return TRUE;
+ if (size) {
+ gamma = xallocarray(size, 3 * sizeof(CARD16));
+ if (!gamma)
+ return FALSE;
+ }
+ else
+ gamma = NULL;
+ free(crtc->gammaRed);
+ crtc->gammaRed = gamma;
+ crtc->gammaGreen = gamma + size;
+ crtc->gammaBlue = gamma + size * 2;
+ crtc->gammaSize = size;
+ return TRUE;
+}
+
+/*
+ * Set the pending CRTC transformation
+ */
+
+int
+RRCrtcTransformSet(RRCrtcPtr crtc,
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse,
+ char *filter_name,
+ int filter_len, xFixed * params, int nparams)
+{
+ PictFilterPtr filter = NULL;
+ int width = 0, height = 0;
+
+ if (!crtc->transforms)
+ return BadValue;
+
+ if (filter_len) {
+ filter = PictureFindFilter(crtc->pScreen, filter_name, filter_len);
+ if (!filter)
+ return BadName;
+ if (filter->ValidateParams) {
+ if (!filter->ValidateParams(crtc->pScreen, filter->id,
+ params, nparams, &width, &height))
+ return BadMatch;
+ }
+ else {
+ width = filter->width;
+ height = filter->height;
+ }
+ }
+ else {
+ if (nparams)
+ return BadMatch;
+ }
+ if (!RRTransformSetFilter(&crtc->client_pending_transform,
+ filter, params, nparams, width, height))
+ return BadAlloc;
+
+ crtc->client_pending_transform.transform = *transform;
+ crtc->client_pending_transform.f_transform = *f_transform;
+ crtc->client_pending_transform.f_inverse = *f_inverse;
+ return Success;
+}
+
+/*
+ * Initialize crtc type
+ */
+Bool
+RRCrtcInit(void)
+{
+ RRCrtcType = CreateNewResourceType(RRCrtcDestroyResource
+#ifndef NXAGENT_SERVER
+ , "CRTC"
+#endif
+ );
+ if (!RRCrtcType)
+ return FALSE;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RRCrtcType, "CRTC");
+#endif
+
+ return TRUE;
+}
+
+/*
+ * Initialize crtc type error value
+ */
+void
+RRCrtcInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc);
+#endif
+}
+
+int
+ProcRRGetCrtcInfo(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcInfoReq);
+ xRRGetCrtcInfoReply rep;
+ RRCrtcPtr crtc;
+ CARD8 *extra;
+ unsigned long extraLen;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ RRModePtr mode;
+ RROutput *outputs;
+ RROutput *possible;
+ int i, j, k;
+ int width, height;
+ BoxRec panned_area;
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ mode = crtc->mode;
+
+ memset(&rep, 0, sizeof(xRRGetCrtcInfoReply));
+ rep = (xRRGetCrtcInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1)) {
+ rep.x = panned_area.x1;
+ rep.y = panned_area.y1;
+ rep.width = panned_area.x2 - panned_area.x1;
+ rep.height = panned_area.y2 - panned_area.y1;
+ }
+ else {
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ rep.x = crtc->x;
+ rep.y = crtc->y;
+ rep.width = width;
+ rep.height = height;
+ }
+ rep.mode = mode ? mode->mode.id : 0;
+ rep.rotation = crtc->rotation;
+ rep.rotations = crtc->rotations;
+ rep.nOutput = crtc->numOutputs;
+ k = 0;
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+ if (pScrPriv->outputs[i]->crtcs[j] == crtc)
+ k++;
+ rep.nPossibleOutput = k;
+
+ rep.length = rep.nOutput + rep.nPossibleOutput;
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = calloc(1, extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ outputs = (RROutput *) extra;
+ possible = (RROutput *) (outputs + rep.nOutput);
+
+ for (i = 0; i < crtc->numOutputs; i++) {
+ outputs[i] = crtc->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i]);
+ }
+ k = 0;
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+ if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
+ possible[k] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&possible[k]);
+ k++;
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swaps(&rep.x);
+ swaps(&rep.y);
+ swaps(&rep.width);
+ swaps(&rep.height);
+ swapl(&rep.mode);
+ swaps(&rep.rotation);
+ swaps(&rep.rotations);
+ swaps(&rep.nOutput);
+ swaps(&rep.nPossibleOutput);
+ }
+ WriteToClient(client, sizeof(xRRGetCrtcInfoReply), &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+
+ return Success;
+}
+
+int
+ProcRRSetCrtcConfig(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcConfigReq);
+ xRRSetCrtcConfigReply rep;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ RRCrtcPtr crtc;
+ RRModePtr mode;
+ int numOutputs;
+ RROutputPtr *outputs = NULL;
+ RROutput *outputIds;
+ TimeStamp time;
+ Rotation rotation;
+ int
+#ifndef NXAGENT_SERVER
+ ret,
+#endif
+ i, j;
+ CARD8 status;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
+ numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq)));
+
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
+
+ if (stuff->mode == None) {
+ mode = NULL;
+ if (numOutputs > 0)
+ return BadMatch;
+ }
+ else {
+ VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
+ if (numOutputs == 0)
+ return BadMatch;
+ }
+ if (numOutputs) {
+ outputs = xallocarray(numOutputs, sizeof(RROutputPtr));
+ if (!outputs)
+ return BadAlloc;
+ }
+ else
+ outputs = NULL;
+
+ outputIds = (RROutput *) (stuff + 1);
+ for (i = 0; i < numOutputs; i++) {
+#ifndef NXAGENT_SERVER
+ ret = dixLookupResourceByType((void **) (outputs + i), outputIds[i],
+ RROutputType, client, DixSetAttrAccess);
+
+ if (ret != Success) {
+ free(outputs);
+ return ret;
+ }
+#else /* !defined(NXAGENT_SERVER) */
+ outputs[i] = (RROutputPtr) LookupIDByType(outputIds[i], RROutputType);
+ if (!outputs[i]) {
+ client->errorValue = outputIds[i];
+ if (outputs)
+ free(outputs);
+ return RRErrorBase + BadRROutput;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+ /* validate crtc for this output */
+ for (j = 0; j < outputs[i]->numCrtcs; j++)
+ if (outputs[i]->crtcs[j] == crtc)
+ break;
+ if (j == outputs[i]->numCrtcs) {
+ free(outputs);
+ return BadMatch;
+ }
+ /* validate mode for this output */
+ for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) {
+ RRModePtr m = (j < outputs[i]->numModes ?
+ outputs[i]->modes[j] :
+ outputs[i]->userModes[j - outputs[i]->numModes]);
+ if (m == mode)
+ break;
+ }
+ if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
+ free(outputs);
+ return BadMatch;
+ }
+ }
+ /* validate clones */
+ for (i = 0; i < numOutputs; i++) {
+ for (j = 0; j < numOutputs; j++) {
+ int k;
+
+ if (i == j)
+ continue;
+ for (k = 0; k < outputs[i]->numClones; k++) {
+ if (outputs[i]->clones[k] == outputs[j])
+ break;
+ }
+ if (k == outputs[i]->numClones) {
+ free(outputs);
+ return BadMatch;
+ }
+ }
+ }
+
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = stuff->rotation;
+ free(outputs);
+ return BadValue;
+ }
+
+ if (mode) {
+ if ((~crtc->rotations) & rotation) {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = stuff->rotation;
+ free(outputs);
+ return BadMatch;
+ }
+
+#ifdef RANDR_12_INTERFACE
+ /*
+ * Check screen size bounds if the DDX provides a 1.2 interface
+ * for setting screen size. Else, assume the CrtcSet sets
+ * the size along with the mode. If the driver supports transforms,
+ * then it must allow crtcs to display a subset of the screen, so
+ * only do this check for drivers without transform support.
+ */
+ if (pScrPriv->rrScreenSetSize && !crtc->transforms) {
+ int source_width;
+ int source_height;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
+ int width, height;
+
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ width = pScreen->current_master->width;
+ height = pScreen->current_master->height;
+ }
+ else
+#else /* !defined(NXAGENT_SERVER) */
+ {
+ width = pScreen->width;
+ height = pScreen->height;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ RRTransformCompute(stuff->x, stuff->y,
+ mode->mode.width, mode->mode.height,
+ rotation,
+ &crtc->client_pending_transform,
+ &transform, &f_transform, &f_inverse);
+
+ RRModeGetScanoutSize(mode, &transform, &source_width,
+ &source_height);
+ if (stuff->x + source_width > width) {
+ client->errorValue = stuff->x;
+ free(outputs);
+ return BadValue;
+ }
+
+ if (stuff->y + source_height > height) {
+ client->errorValue = stuff->y;
+ free(outputs);
+ return BadValue;
+ }
+ }
+#endif
+ }
+
+ if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
+ rotation, numOutputs, outputs)) {
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ status = RRSetConfigSuccess;
+ pScrPriv->lastSetTime = time;
+
+ sendReply:
+ free(outputs);
+
+ memset(&rep, 0, sizeof(xRRSetCrtcConfigReply));
+ rep = (xRRSetCrtcConfigReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.newTimestamp);
+ }
+ WriteToClient(client, sizeof(xRRSetCrtcConfigReply), &rep);
+
+ return Success;
+}
+
+int
+ProcRRGetPanning(ClientPtr client)
+{
+ REQUEST(xRRGetPanningReq);
+ xRRGetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv)
+ return RRErrorBase + BadRRCrtc;
+
+ memset(&rep, 0, sizeof(xRRGetPanningReply));
+ rep = (xRRGetPanningReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 1,
+ .timestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) {
+ rep.left = total.x1;
+ rep.top = total.y1;
+ rep.width = total.x2 - total.x1;
+ rep.height = total.y2 - total.y1;
+ rep.track_left = tracking.x1;
+ rep.track_top = tracking.y1;
+ rep.track_width = tracking.x2 - tracking.x1;
+ rep.track_height = tracking.y2 - tracking.y1;
+ rep.border_left = border[0];
+ rep.border_top = border[1];
+ rep.border_right = border[2];
+ rep.border_bottom = border[3];
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swaps(&rep.left);
+ swaps(&rep.top);
+ swaps(&rep.width);
+ swaps(&rep.height);
+ swaps(&rep.track_left);
+ swaps(&rep.track_top);
+ swaps(&rep.track_width);
+ swaps(&rep.track_height);
+ swaps(&rep.border_left);
+ swaps(&rep.border_top);
+ swaps(&rep.border_right);
+ swaps(&rep.border_bottom);
+ }
+ WriteToClient(client, sizeof(xRRGetPanningReply), &rep);
+ return Success;
+}
+
+int
+ProcRRSetPanning(ClientPtr client)
+{
+ REQUEST(xRRSetPanningReq);
+ xRRSetPanningReply rep;
+ RRCrtcPtr crtc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp time;
+ BoxRec total;
+ BoxRec tracking;
+ INT16 border[4];
+ CARD8 status;
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* All crtcs must be associated with screens before client
+ * requests are processed
+ */
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+
+ if (!pScrPriv->rrGetPanning)
+ return RRErrorBase + BadRRCrtc;
+
+ total.x1 = stuff->left;
+ total.y1 = stuff->top;
+ total.x2 = total.x1 + stuff->width;
+ total.y2 = total.y1 + stuff->height;
+ tracking.x1 = stuff->track_left;
+ tracking.y1 = stuff->track_top;
+ tracking.x2 = tracking.x1 + stuff->track_width;
+ tracking.y2 = tracking.y1 + stuff->track_height;
+ border[0] = stuff->border_left;
+ border[1] = stuff->border_top;
+ border[2] = stuff->border_right;
+ border[3] = stuff->border_bottom;
+
+ if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border))
+ return BadMatch;
+
+ pScrPriv->lastSetTime = time;
+
+ status = RRSetConfigSuccess;
+
+ sendReply:
+ memset(&rep, 0, sizeof(xRRSetPanningReply));
+ rep = (xRRSetPanningReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.newTimestamp);
+ }
+ WriteToClient(client, sizeof(xRRSetPanningReply), &rep);
+ return Success;
+}
+
+int
+ProcRRGetCrtcGammaSize(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcGammaSizeReq);
+ xRRGetCrtcGammaSizeReply reply;
+ RRCrtcPtr crtc;
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* Gamma retrieval failed, any better error? */
+ if (!RRCrtcGammaGet(crtc))
+ return RRErrorBase + BadRRCrtc;
+
+ reply = (xRRGetCrtcGammaSizeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .size = crtc->gammaSize
+ };
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swaps(&reply.size);
+ }
+ WriteToClient(client, sizeof(xRRGetCrtcGammaSizeReply), &reply);
+ return Success;
+}
+
+int
+ProcRRGetCrtcGamma(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcGammaReq);
+ xRRGetCrtcGammaReply reply;
+ RRCrtcPtr crtc;
+ unsigned long len;
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ /* Gamma retrieval failed, any better error? */
+ if (!RRCrtcGammaGet(crtc))
+ return RRErrorBase + BadRRCrtc;
+
+ len = crtc->gammaSize * 3 * 2;
+
+ if (crtc->gammaSize) {
+ extra = calloc(1, len);
+ if (!extra)
+ return BadAlloc;
+ }
+
+ reply = (xRRGetCrtcGammaReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(len),
+ .size = crtc->gammaSize
+ };
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swaps(&reply.size);
+ }
+ WriteToClient(client, sizeof(xRRGetCrtcGammaReply), &reply);
+ if (crtc->gammaSize) {
+ memcpy(extra, crtc->gammaRed, len);
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
+ WriteSwappedDataToClient(client, len, extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRSetCrtcGamma(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcGammaReq);
+ RRCrtcPtr crtc;
+ unsigned long len;
+ CARD16 *red, *green, *blue;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcGammaReq));
+ if (len < (stuff->size * 3 + 1) >> 1)
+ return BadLength;
+
+ if (stuff->size != crtc->gammaSize)
+ return BadMatch;
+
+ red = (CARD16 *) (stuff + 1);
+ green = red + crtc->gammaSize;
+ blue = green + crtc->gammaSize;
+
+ RRCrtcGammaSet(crtc, red, green, blue);
+
+ return Success;
+}
+
+/* Version 1.3 additions */
+
+int
+ProcRRSetCrtcTransform(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcTransformReq);
+ RRCrtcPtr crtc;
+ PictTransform transform;
+ struct pixman_f_transform f_transform, f_inverse;
+ char *filter;
+ int nbytes;
+ xFixed *params;
+ int nparams;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ PictTransform_from_xRenderTransform(&transform, &stuff->transform);
+ pixman_f_transform_from_pixman_transform(&f_transform, &transform);
+ if (!pixman_f_transform_invert(&f_inverse, &f_transform))
+ return BadMatch;
+
+ filter = (char *) (stuff + 1);
+ nbytes = stuff->nbytesFilter;
+ params = (xFixed *) (filter + pad_to_int32(nbytes));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ return RRCrtcTransformSet(crtc, &transform, &f_transform, &f_inverse,
+ filter, nbytes, params, nparams);
+}
+
+#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
+
+static int
+transform_filter_length(RRTransformPtr transform)
+{
+ int nbytes, nparams;
+
+ if (transform->filter == NULL)
+ return 0;
+ nbytes = strlen(transform->filter->name);
+ nparams = transform->nparams;
+ return pad_to_int32(nbytes) + (nparams * sizeof(xFixed));
+}
+
+static int
+transform_filter_encode(ClientPtr client, char *output,
+ CARD16 *nbytesFilter,
+ CARD16 *nparamsFilter, RRTransformPtr transform)
+{
+ int nbytes, nparams;
+
+ if (transform->filter == NULL) {
+ *nbytesFilter = 0;
+ *nparamsFilter = 0;
+ return 0;
+ }
+ nbytes = strlen(transform->filter->name);
+ nparams = transform->nparams;
+ *nbytesFilter = nbytes;
+ *nparamsFilter = nparams;
+ memcpy(output, transform->filter->name, nbytes);
+ while ((nbytes & 3) != 0)
+ output[nbytes++] = 0;
+ memcpy(output + nbytes, transform->params, nparams * sizeof(xFixed));
+ if (client->swapped) {
+ swaps(nbytesFilter);
+ swaps(nparamsFilter);
+ SwapLongs((CARD32 *) (output + nbytes), nparams);
+ }
+ nbytes += nparams * sizeof(xFixed);
+ return nbytes;
+}
+
+static void
+transform_encode(ClientPtr client, xRenderTransform * wire,
+ PictTransform * pict)
+{
+ xRenderTransform_from_PictTransform(wire, pict);
+ if (client->swapped)
+ SwapLongs((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
+}
+
+int
+ProcRRGetCrtcTransform(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcTransformReq);
+ xRRGetCrtcTransformReply *reply;
+ RRCrtcPtr crtc;
+ int nextra;
+ RRTransformPtr current, pending;
+ char *extra;
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ pending = &crtc->client_pending_transform;
+ current = &crtc->client_current_transform;
+
+ nextra = (transform_filter_length(pending) +
+ transform_filter_length(current));
+
+ reply = calloc(1, sizeof(xRRGetCrtcTransformReply) + nextra);
+ if (!reply)
+ return BadAlloc;
+
+ extra = (char *) (reply + 1);
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = bytes_to_int32(CrtcTransformExtra + nextra);
+
+ reply->hasTransforms = crtc->transforms;
+
+ transform_encode(client, &reply->pendingTransform, &pending->transform);
+ extra += transform_filter_encode(client, extra,
+ &reply->pendingNbytesFilter,
+ &reply->pendingNparamsFilter, pending);
+
+ transform_encode(client, &reply->currentTransform, &current->transform);
+ extra += transform_filter_encode(client, extra,
+ &reply->currentNbytesFilter,
+ &reply->currentNparamsFilter, current);
+
+ if (client->swapped) {
+ swaps(&reply->sequenceNumber);
+ swapl(&reply->length);
+ }
+ WriteToClient(client, sizeof(xRRGetCrtcTransformReply) + nextra,
+ reply);
+ free(reply);
+ return Success;
+}
+
+static Bool
+check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y)
+{
+ rrScrPriv(pScreen);
+ int i;
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ int left, right, top, bottom;
+
+ if (!crtc->mode)
+ continue;
+
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
+
+ if ((*x >= left) && (*x < right) && (*y >= top) && (*y < bottom))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool
+constrain_all_screen_crtcs(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int *x, int *y)
+{
+ rrScrPriv(pScreen);
+ int i;
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+ int nx, ny;
+ int left, right, top, bottom;
+
+ if (!crtc->mode)
+ continue;
+
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
+#ifndef NXAGENT_SERVER
+ miPointerGetPosition(pDev, &nx, &ny);
+#else /* !defined(NXAGENT_SERVER) */
+
+ miPointerPosition(&nx, &ny);
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom)) {
+ if (*x < left)
+ *x = left;
+ if (*x >= right)
+ *x = right - 1;
+ if (*y < top)
+ *y = top;
+ if (*y >= bottom)
+ *y = bottom - 1;
+
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+RRConstrainCursorHarder(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int mode, int *x,
+ int *y)
+{
+ rrScrPriv(pScreen);
+ Bool ret;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ /* intentional dead space -> let it float */
+ if (pScrPriv->discontiguous)
+ return;
+
+ /* if we're moving inside a crtc, we're fine */
+ ret = check_all_screen_crtcs(pScreen, x, y);
+ if (ret == TRUE)
+ return;
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ ret = check_all_screen_crtcs(slave, x, y);
+ if (ret == TRUE)
+ return;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
+ ret = constrain_all_screen_crtcs(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x, y);
+ if (ret == TRUE)
+ return;
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
+ ret = constrain_all_screen_crtcs(pDev, slave, x, y);
+ if (ret == TRUE)
+ return;
+ }
+#endif /* !defined(NXAGENT_SERVER) */
+}
+
+Bool
+RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
+{
+ rrScrPriv(pDrawable->pScreen);
+ Bool ret = TRUE;
+ PixmapPtr *saved_scanout_pixmap;
+ int i;
+
+ saved_scanout_pixmap = malloc(sizeof(PixmapPtr) * pScrPriv->numCrtcs);
+ if (saved_scanout_pixmap == NULL)
+ return FALSE;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+ Bool size_fits;
+
+ saved_scanout_pixmap[i] = crtc->scanout_pixmap;
+
+ if (!crtc->mode && enable)
+ continue;
+ if (!crtc->scanout_pixmap && !enable)
+ continue;
+
+ size_fits = (crtc->mode &&
+ crtc->x == pDrawable->x &&
+ crtc->y == pDrawable->y &&
+ crtc->mode->mode.width == pDrawable->width &&
+ crtc->mode->mode.height == pDrawable->height);
+
+ /* is the pixmap already set? */
+ if (crtc->scanout_pixmap == pPixmap) {
+ /* if its a disable then don't care about size */
+ if (enable == FALSE) {
+ /* set scanout to NULL */
+ crtc->scanout_pixmap = NULL;
+ }
+ else if (!size_fits) {
+ /* if the size no longer fits then drop off */
+ crtc->scanout_pixmap = NULL;
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
+
+ (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode, crtc->x, crtc->y,
+ crtc->rotation, crtc->numOutputs, crtc->outputs);
+ saved_scanout_pixmap[i] = crtc->scanout_pixmap;
+ ret = FALSE;
+ }
+ else {
+ /* if the size fits then we are already setup */
+ }
+ }
+ else {
+ if (!size_fits)
+ ret = FALSE;
+ else if (enable)
+ crtc->scanout_pixmap = pPixmap;
+ else
+ /* reject an attempt to disable someone else's scanout_pixmap */
+ ret = FALSE;
+ }
+ }
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ if (crtc->scanout_pixmap == saved_scanout_pixmap[i])
+ continue;
+
+ if (ret) {
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, crtc->scanout_pixmap);
+
+ (*pScrPriv->rrCrtcSet) (pDrawable->pScreen, crtc, crtc->mode,
+ crtc->x, crtc->y, crtc->rotation,
+ crtc->numOutputs, crtc->outputs);
+ }
+ else
+ crtc->scanout_pixmap = saved_scanout_pixmap[i];
+ }
+ free(saved_scanout_pixmap);
+
+ return ret;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrdispatch.c b/nx-X11/programs/Xserver/randr/rrdispatch.c
new file mode 100644
index 000000000..68d3b97e6
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrdispatch.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "protocol-versions.h"
+
+Bool
+RRClientKnowsRates(ClientPtr pClient)
+{
+ rrClientPriv(pClient);
+
+ return version_compare(pRRClient->major_version, pRRClient->minor_version,
+ 1, 1) >= 0;
+}
+
+static int
+ProcRRQueryVersion(ClientPtr client)
+{
+ xRRQueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
+ REQUEST(xRRQueryVersionReq);
+ rrClientPriv(client);
+
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+ pRRClient->major_version = stuff->majorVersion;
+ pRRClient->minor_version = stuff->minorVersion;
+
+ if (version_compare(stuff->majorVersion, stuff->minorVersion,
+ SERVER_RANDR_MAJOR_VERSION,
+ SERVER_RANDR_MINOR_VERSION) < 0) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ }
+ else {
+ rep.majorVersion = SERVER_RANDR_MAJOR_VERSION;
+ rep.minorVersion = SERVER_RANDR_MINOR_VERSION;
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+#ifndef NXAGENT_SERVER
+ WriteToClient(client, sizeof(xRRQueryVersionReply), &rep);
+#else
+ WriteToClient(client, sizeof(xRRQueryVersionReply), &rep);
+#endif
+ return Success;
+}
+
+static int
+ProcRRSelectInput(ClientPtr client)
+{
+ REQUEST(xRRSelectInputReq);
+ rrClientPriv(client);
+ RRTimesPtr pTimes;
+ WindowPtr pWin;
+ RREventPtr pRREvent, *pHead;
+ XID clientResource;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixWriteAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+ if (rc != Success)
+ return rc;
+#ifndef NXAGENT_SERVER
+ rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, client, DixWriteAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (rc != Success && rc != BadValue)
+ return rc;
+
+ if (stuff->enable & (RRScreenChangeNotifyMask |
+ RRCrtcChangeNotifyMask |
+ RROutputChangeNotifyMask |
+ RROutputPropertyNotifyMask |
+ RRProviderChangeNotifyMask |
+ RRProviderPropertyNotifyMask |
+ RRResourceChangeNotifyMask)) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ pRREvent = NULL;
+ if (pHead) {
+ /* check for existing entry. */
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+ if (pRREvent->client == client)
+ break;
+ }
+
+ if (!pRREvent) {
+ /* build the entry */
+ pRREvent = (RREventPtr) malloc(sizeof(RREventRec));
+ if (!pRREvent)
+ return BadAlloc;
+ pRREvent->next = 0;
+ pRREvent->client = client;
+ pRREvent->window = pWin;
+ pRREvent->mask = stuff->enable;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID(client->index);
+ pRREvent->clientResource = clientResource;
+ if (!AddResource(clientResource, RRClientType, (void *) pRREvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead) {
+ pHead = (RREventPtr *) malloc(sizeof(RREventPtr));
+ if (!pHead ||
+ !AddResource(pWin->drawable.id, RREventType,
+ (void *) pHead)) {
+ FreeResource(clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pRREvent->next = *pHead;
+ *pHead = pRREvent;
+ }
+ /*
+ * Now see if the client needs an event
+ */
+ if (pScrPriv) {
+ pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
+ if (CompareTimeStamps(pTimes->setTime,
+ pScrPriv->lastSetTime) != 0 ||
+ CompareTimeStamps(pTimes->configTime,
+ pScrPriv->lastConfigTime) != 0) {
+ if (pRREvent->mask & RRScreenChangeNotifyMask) {
+ RRDeliverScreenEvent(client, pWin, pScreen);
+ }
+
+ if (pRREvent->mask & RRCrtcChangeNotifyMask) {
+ int i;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRDeliverCrtcEvent(client, pWin, pScrPriv->crtcs[i]);
+ }
+ }
+
+ if (pRREvent->mask & RROutputChangeNotifyMask) {
+ int i;
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ RRDeliverOutputEvent(client, pWin,
+ pScrPriv->outputs[i]);
+ }
+ }
+
+ /* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't
+ * say if there ought to be notifications of changes to output properties
+ * if those changes occurred before the time RRSelectInput is called.
+ */
+ }
+ }
+ }
+ else if (stuff->enable == 0) {
+ /* delete the interest */
+ if (pHead) {
+ RREventPtr pNewRREvent = 0;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (pRREvent->client == client)
+ break;
+ pNewRREvent = pRREvent;
+ }
+ if (pRREvent) {
+ FreeResource(pRREvent->clientResource, RRClientType);
+ if (pNewRREvent)
+ pNewRREvent->next = pRREvent->next;
+ else
+ *pHead = pRREvent->next;
+ free(pRREvent);
+ }
+ }
+ }
+ else {
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
+ ProcRRQueryVersion, /* 0 */
+/* we skip 1 to make old clients fail pretty immediately */
+ NULL, /* 1 ProcRandrOldGetScreenInfo */
+/* V1.0 apps share the same set screen config request id */
+ ProcRRSetScreenConfig, /* 2 */
+ NULL, /* 3 ProcRandrOldScreenChangeSelectInput */
+/* 3 used to be ScreenChangeSelectInput; deprecated */
+ ProcRRSelectInput, /* 4 */
+ ProcRRGetScreenInfo, /* 5 */
+/* V1.2 additions */
+ ProcRRGetScreenSizeRange, /* 6 */
+ ProcRRSetScreenSize, /* 7 */
+ ProcRRGetScreenResources, /* 8 */
+ ProcRRGetOutputInfo, /* 9 */
+ ProcRRListOutputProperties, /* 10 */
+ ProcRRQueryOutputProperty, /* 11 */
+ ProcRRConfigureOutputProperty, /* 12 */
+ ProcRRChangeOutputProperty, /* 13 */
+ ProcRRDeleteOutputProperty, /* 14 */
+ ProcRRGetOutputProperty, /* 15 */
+ ProcRRCreateMode, /* 16 */
+ ProcRRDestroyMode, /* 17 */
+ ProcRRAddOutputMode, /* 18 */
+ ProcRRDeleteOutputMode, /* 19 */
+ ProcRRGetCrtcInfo, /* 20 */
+ ProcRRSetCrtcConfig, /* 21 */
+ ProcRRGetCrtcGammaSize, /* 22 */
+ ProcRRGetCrtcGamma, /* 23 */
+ ProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ ProcRRGetScreenResourcesCurrent, /* 25 */
+ ProcRRSetCrtcTransform, /* 26 */
+ ProcRRGetCrtcTransform, /* 27 */
+ ProcRRGetPanning, /* 28 */
+ ProcRRSetPanning, /* 29 */
+ ProcRRSetOutputPrimary, /* 30 */
+ ProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ ProcRRGetProviders, /* 32 */
+ ProcRRGetProviderInfo, /* 33 */
+ ProcRRSetProviderOffloadSink, /* 34 */
+ ProcRRSetProviderOutputSource, /* 35 */
+ ProcRRListProviderProperties, /* 36 */
+ ProcRRQueryProviderProperty, /* 37 */
+ ProcRRConfigureProviderProperty, /* 38 */
+ ProcRRChangeProviderProperty, /* 39 */
+ ProcRRDeleteProviderProperty, /* 40 */
+ ProcRRGetProviderProperty, /* 41 */
+ ProcRRGetMonitors, /* 42 */
+ ProcRRSetMonitor, /* 43 */
+ ProcRRDeleteMonitor, /* 44 */
+};
diff --git a/nx-X11/programs/Xserver/randr/rrinfo.c b/nx-X11/programs/Xserver/randr/rrinfo.c
new file mode 100644
index 000000000..24245b7b6
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrinfo.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+
+#ifdef RANDR_10_INTERFACE
+static RRModePtr
+RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh)
+{
+ ScreenPtr pScreen = output->pScreen;
+
+ rrScrPriv(pScreen);
+ xRRModeInfo modeInfo;
+ char name[100];
+ RRModePtr mode;
+ int i;
+ RRModePtr *modes;
+
+ memset(&modeInfo, '\0', sizeof(modeInfo));
+ snprintf(name, sizeof(name), "%dx%d", size->width, size->height);
+
+ modeInfo.width = size->width;
+ modeInfo.height = size->height;
+ modeInfo.hTotal = size->width;
+ modeInfo.vTotal = size->height;
+ modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height *
+ (CARD32) refresh);
+ modeInfo.nameLength = strlen(name);
+ mode = RRModeGet(&modeInfo, name);
+ if (!mode)
+ return NULL;
+ for (i = 0; i < output->numModes; i++)
+ if (output->modes[i] == mode) {
+ RRModeDestroy(mode);
+ return mode;
+ }
+
+ if (output->numModes)
+ modes = reallocarray(output->modes,
+ output->numModes + 1, sizeof(RRModePtr));
+ else
+ modes = malloc(sizeof(RRModePtr));
+ if (!modes) {
+ RRModeDestroy(mode);
+ FreeResource(mode->mode.id, 0);
+ return NULL;
+ }
+ modes[output->numModes++] = mode;
+ output->modes = modes;
+ output->changed = TRUE;
+ pScrPriv->changed = TRUE;
+ pScrPriv->configChanged = TRUE;
+ return mode;
+}
+
+static void
+RRScanOldConfig(ScreenPtr pScreen, Rotation rotations)
+{
+ rrScrPriv(pScreen);
+ RROutputPtr output;
+ RRCrtcPtr crtc;
+ RRModePtr mode, newMode = NULL;
+ int i;
+ CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT;
+ CARD16 maxWidth = 0, maxHeight = 0;
+ CARD16 width, height;
+
+ /*
+ * First time through, create a crtc and output and hook
+ * them together
+ */
+ if (pScrPriv->numOutputs == 0 && pScrPriv->numCrtcs == 0) {
+ crtc = RRCrtcCreate(pScreen, NULL);
+ if (!crtc)
+ return;
+ output = RROutputCreate(pScreen, "default", 7, NULL);
+ if (!output)
+ return;
+ RROutputSetCrtcs(output, &crtc, 1);
+ RROutputSetConnection(output, RR_Connected);
+ RROutputSetSubpixelOrder(output, PictureGetSubpixelOrder(pScreen));
+ }
+
+ output = pScrPriv->outputs[0];
+ if (!output)
+ return;
+ crtc = pScrPriv->crtcs[0];
+ if (!crtc)
+ return;
+
+ /* check rotations */
+ if (rotations != crtc->rotations) {
+ crtc->rotations = rotations;
+ crtc->changed = TRUE;
+ pScrPriv->changed = TRUE;
+ }
+
+ /* regenerate mode list */
+ for (i = 0; i < pScrPriv->nSizes; i++) {
+ RRScreenSizePtr size = &pScrPriv->pSizes[i];
+ int r;
+
+ if (size->nRates) {
+ for (r = 0; r < size->nRates; r++) {
+ mode = RROldModeAdd(output, size, size->pRates[r].rate);
+ if (i == pScrPriv->size &&
+ size->pRates[r].rate == pScrPriv->rate) {
+ newMode = mode;
+ }
+ }
+ free(size->pRates);
+ }
+ else {
+ mode = RROldModeAdd(output, size, 0);
+ if (i == pScrPriv->size)
+ newMode = mode;
+ }
+ }
+ if (pScrPriv->nSizes)
+ free(pScrPriv->pSizes);
+ pScrPriv->pSizes = NULL;
+ pScrPriv->nSizes = 0;
+
+ /* find size bounds */
+ for (i = 0; i < output->numModes + output->numUserModes; i++) {
+ mode = (i < output->numModes ?
+ output->modes[i] :
+ output->userModes[i - output->numModes]);
+ width = mode->mode.width;
+ height = mode->mode.height;
+
+ if (width < minWidth)
+ minWidth = width;
+ if (width > maxWidth)
+ maxWidth = width;
+ if (height < minHeight)
+ minHeight = height;
+ if (height > maxHeight)
+ maxHeight = height;
+ }
+
+ RRScreenSetSizeRange(pScreen, minWidth, minHeight, maxWidth, maxHeight);
+
+ /* notice current mode */
+ if (newMode)
+ RRCrtcNotify(crtc, newMode, 0, 0, pScrPriv->rotation, NULL, 1, &output);
+}
+#endif
+
+/*
+ * Poll the driver for changed information
+ */
+Bool
+RRGetInfo(ScreenPtr pScreen, Bool force_query)
+{
+ rrScrPriv(pScreen);
+ Rotation rotations;
+ int i;
+
+ /* Return immediately if we don't need to re-query and we already have the
+ * information.
+ */
+ if (!force_query) {
+ if (pScrPriv->numCrtcs != 0 || pScrPriv->numOutputs != 0)
+ return TRUE;
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ pScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pScrPriv->numCrtcs; i++)
+ pScrPriv->crtcs[i]->changed = FALSE;
+
+ rotations = 0;
+ pScrPriv->changed = FALSE;
+ pScrPriv->configChanged = FALSE;
+
+ if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
+ return FALSE;
+
+#if RANDR_10_INTERFACE
+ if (pScrPriv->nSizes)
+ RRScanOldConfig(pScreen, rotations);
+#endif
+ RRTellChanged(pScreen);
+ return TRUE;
+}
+
+/*
+ * Register the range of sizes for the screen
+ */
+void
+RRScreenSetSizeRange(ScreenPtr pScreen,
+ CARD16 minWidth,
+ CARD16 minHeight, CARD16 maxWidth, CARD16 maxHeight)
+{
+ rrScrPriv(pScreen);
+
+ if (!pScrPriv)
+ return;
+ if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight &&
+ pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight) {
+ return;
+ }
+
+ pScrPriv->minWidth = minWidth;
+ pScrPriv->minHeight = minHeight;
+ pScrPriv->maxWidth = maxWidth;
+ pScrPriv->maxHeight = maxHeight;
+ RRSetChanged(pScreen);
+ pScrPriv->configChanged = TRUE;
+}
+
+#ifdef RANDR_10_INTERFACE
+static Bool
+RRScreenSizeMatches(RRScreenSizePtr a, RRScreenSizePtr b)
+{
+ if (a->width != b->width)
+ return FALSE;
+ if (a->height != b->height)
+ return FALSE;
+ if (a->mmWidth != b->mmWidth)
+ return FALSE;
+ if (a->mmHeight != b->mmHeight)
+ return FALSE;
+ return TRUE;
+}
+
+RRScreenSizePtr
+RRRegisterSize(ScreenPtr pScreen,
+ short width, short height, short mmWidth, short mmHeight)
+{
+ rrScrPriv(pScreen);
+ int i;
+ RRScreenSize tmp;
+ RRScreenSizePtr pNew;
+
+ if (!pScrPriv)
+ return 0;
+
+ tmp.id = 0;
+ tmp.width = width;
+ tmp.height = height;
+ tmp.mmWidth = mmWidth;
+ tmp.mmHeight = mmHeight;
+ tmp.pRates = 0;
+ tmp.nRates = 0;
+ for (i = 0; i < pScrPriv->nSizes; i++)
+ if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i]))
+ return &pScrPriv->pSizes[i];
+ pNew = reallocarray(pScrPriv->pSizes,
+ pScrPriv->nSizes + 1, sizeof(RRScreenSize));
+ if (!pNew)
+ return 0;
+ pNew[pScrPriv->nSizes++] = tmp;
+ pScrPriv->pSizes = pNew;
+ return &pNew[pScrPriv->nSizes - 1];
+}
+
+Bool
+RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate)
+{
+ rrScrPriv(pScreen);
+ int i;
+ RRScreenRatePtr pNew, pRate;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ for (i = 0; i < pSize->nRates; i++)
+ if (pSize->pRates[i].rate == rate)
+ return TRUE;
+
+ pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate));
+ if (!pNew)
+ return FALSE;
+ pRate = &pNew[pSize->nRates++];
+ pRate->rate = rate;
+ pSize->pRates = pNew;
+ return TRUE;
+}
+
+Rotation
+RRGetRotation(ScreenPtr pScreen)
+{
+ RROutputPtr output = RRFirstOutput(pScreen);
+
+ if (!output)
+ return RR_Rotate_0;
+
+ return output->crtc->rotation;
+}
+
+void
+RRSetCurrentConfig(ScreenPtr pScreen,
+ Rotation rotation, int rate, RRScreenSizePtr pSize)
+{
+ rrScrPriv(pScreen);
+
+ if (!pScrPriv)
+ return;
+ pScrPriv->size = pSize - pScrPriv->pSizes;
+ pScrPriv->rotation = rotation;
+ pScrPriv->rate = rate;
+}
+#endif
diff --git a/nx-X11/programs/Xserver/randr/rrmode.c b/nx-X11/programs/Xserver/randr/rrmode.c
new file mode 100644
index 000000000..92f67afb9
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrmode.c
@@ -0,0 +1,435 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+
+RESTYPE RRModeType;
+
+static Bool
+RRModeEqual(xRRModeInfo * a, xRRModeInfo * b)
+{
+ if (a->width != b->width)
+ return FALSE;
+ if (a->height != b->height)
+ return FALSE;
+ if (a->dotClock != b->dotClock)
+ return FALSE;
+ if (a->hSyncStart != b->hSyncStart)
+ return FALSE;
+ if (a->hSyncEnd != b->hSyncEnd)
+ return FALSE;
+ if (a->hTotal != b->hTotal)
+ return FALSE;
+ if (a->hSkew != b->hSkew)
+ return FALSE;
+ if (a->vSyncStart != b->vSyncStart)
+ return FALSE;
+ if (a->vSyncEnd != b->vSyncEnd)
+ return FALSE;
+ if (a->vTotal != b->vTotal)
+ return FALSE;
+ if (a->nameLength != b->nameLength)
+ return FALSE;
+ if (a->modeFlags != b->modeFlags)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Keep a list so it's easy to find modes in the resource database.
+ */
+static int num_modes;
+static RRModePtr *modes;
+
+static RRModePtr
+RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen)
+{
+ RRModePtr mode, *newModes;
+
+ if (!RRInit())
+ return NULL;
+
+ mode = malloc(sizeof(RRModeRec) + modeInfo->nameLength + 1);
+ if (!mode)
+ return NULL;
+ mode->refcnt = 1;
+ mode->mode = *modeInfo;
+ mode->name = (char *) (mode + 1);
+ memcpy(mode->name, name, modeInfo->nameLength);
+ mode->name[modeInfo->nameLength] = '\0';
+ mode->userScreen = userScreen;
+
+ if (num_modes)
+ newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr));
+
+ else
+ newModes = malloc(sizeof(RRModePtr));
+
+ if (!newModes) {
+ free(mode);
+ return NULL;
+ }
+
+ mode->mode.id = FakeClientID(0);
+ if (!AddResource(mode->mode.id, RRModeType, (void *) mode)) {
+ free(newModes);
+ return NULL;
+ }
+ modes = newModes;
+ modes[num_modes++] = mode;
+
+ /*
+ * give the caller a reference to this mode
+ */
+ ++mode->refcnt;
+#ifdef DEBUG
+ fprintf(stderr,
+ "RRModeCreate: num_modes [%d] new mode [%s] ([%p]) refcnt [%d]\n",
+ num_modes, mode->name, mode, mode->refcnt);
+#endif
+ return mode;
+}
+
+static RRModePtr
+RRModeFindByName(const char *name, CARD16 nameLength)
+{
+ int i;
+ RRModePtr mode;
+
+ for (i = 0; i < num_modes; i++) {
+ mode = modes[i];
+ if (mode->mode.nameLength == nameLength &&
+ !memcmp(name, mode->name, nameLength)) {
+ return mode;
+ }
+ }
+ return NULL;
+}
+
+RRModePtr
+RRModeGet(xRRModeInfo * modeInfo, const char *name)
+{
+ int i;
+
+ for (i = 0; i < num_modes; i++) {
+ RRModePtr mode = modes[i];
+
+ if (RRModeEqual(&mode->mode, modeInfo) &&
+ !memcmp(name, mode->name, modeInfo->nameLength)) {
+ ++mode->refcnt;
+#ifdef DEBUG
+ fprintf(stderr,
+ "RRModeGet: return existing mode [%s] ([%p]) refcnt [%d]\n",
+ mode->name, mode, mode->refcnt);
+#endif
+ return mode;
+ }
+ }
+
+#ifdef DEBUG
+ {
+ RRModePtr mode = RRModeCreate(modeInfo, name, NULL);
+
+ fprintf(stderr, "RRModeGet: return new mode [%s] ([%p]) refcnt [%d]\n",
+ mode->name, mode, mode->refcnt);
+ return mode;
+ }
+#else
+ return RRModeCreate(modeInfo, name, NULL);
+#endif
+}
+
+static RRModePtr
+RRModeCreateUser(ScreenPtr pScreen,
+ xRRModeInfo * modeInfo, const char *name, int *error)
+{
+ RRModePtr mode;
+
+ mode = RRModeFindByName(name, modeInfo->nameLength);
+ if (mode) {
+ *error = BadName;
+ return NULL;
+ }
+
+ mode = RRModeCreate(modeInfo, name, pScreen);
+ if (!mode) {
+ *error = BadAlloc;
+ return NULL;
+ }
+ *error = Success;
+ return mode;
+}
+
+RRModePtr *
+RRModesForScreen(ScreenPtr pScreen, int *num_ret)
+{
+ rrScrPriv(pScreen);
+ int o, c, m;
+ RRModePtr *screen_modes;
+ int num_screen_modes = 0;
+
+ screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr));
+ if (!screen_modes)
+ return NULL;
+
+ /*
+ * Add modes from all outputs
+ */
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+ int n;
+
+ for (m = 0; m < output->numModes + output->numUserModes; m++) {
+ RRModePtr mode = (m < output->numModes ?
+ output->modes[m] :
+ output->userModes[m - output->numModes]);
+ for (n = 0; n < num_screen_modes; n++)
+ if (screen_modes[n] == mode)
+ break;
+ if (n == num_screen_modes)
+ screen_modes[num_screen_modes++] = mode;
+ }
+ }
+ /*
+ * Add modes from all crtcs. The goal is to
+ * make sure all available and active modes
+ * are visible to the client
+ */
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+ RRModePtr mode = crtc->mode;
+ int n;
+
+ if (!mode)
+ continue;
+ for (n = 0; n < num_screen_modes; n++)
+ if (screen_modes[n] == mode)
+ break;
+ if (n == num_screen_modes)
+ screen_modes[num_screen_modes++] = mode;
+ }
+ /*
+ * Add all user modes for this screen
+ */
+ for (m = 0; m < num_modes; m++) {
+ RRModePtr mode = modes[m];
+ int n;
+
+ if (mode->userScreen != pScreen)
+ continue;
+ for (n = 0; n < num_screen_modes; n++)
+ if (screen_modes[n] == mode)
+ break;
+ if (n == num_screen_modes)
+ screen_modes[num_screen_modes++] = mode;
+ }
+
+ *num_ret = num_screen_modes;
+ return screen_modes;
+}
+
+void
+RRModeDestroy(RRModePtr mode)
+{
+ int m;
+
+ if (--mode->refcnt > 0)
+ return;
+ for (m = 0; m < num_modes; m++) {
+ if (modes[m] == mode) {
+ memmove(modes + m, modes + m + 1,
+ (num_modes - m - 1) * sizeof(RRModePtr));
+ num_modes--;
+ if (!num_modes) {
+ free(modes);
+ modes = NULL;
+ }
+ break;
+ }
+ }
+
+ free(mode);
+}
+
+static int
+RRModeDestroyResource(void *value, XID pid)
+{
+ RRModeDestroy((RRModePtr) value);
+ return 1;
+}
+
+/*
+ * Initialize mode type
+ */
+Bool
+RRModeInit(void)
+{
+ assert(num_modes == 0);
+ assert(modes == NULL);
+ RRModeType = CreateNewResourceType(RRModeDestroyResource
+#ifndef NXAGENT_SERVER
+ , "MODE"
+#endif
+ );
+ if (!RRModeType)
+ return FALSE;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RRModeType, "MODE");
+#endif
+ return TRUE;
+}
+
+/*
+ * Initialize mode type error value
+ */
+void
+RRModeInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRModeType, RRErrorBase + BadRRMode);
+#endif
+}
+
+int
+ProcRRCreateMode(ClientPtr client)
+{
+ REQUEST(xRRCreateModeReq);
+ xRRCreateModeReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ xRRModeInfo *modeInfo;
+ long units_after;
+ char *name;
+ int error, rc;
+ RRModePtr mode;
+
+ REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+
+ modeInfo = &stuff->modeInfo;
+ name = (char *) (stuff + 1);
+ units_after = (stuff->length - bytes_to_int32(sizeof(xRRCreateModeReq)));
+
+ /* check to make sure requested name fits within the data provided */
+ if (bytes_to_int32(modeInfo->nameLength) > units_after)
+ return BadLength;
+
+ mode = RRModeCreateUser(pScreen, modeInfo, name, &error);
+ if (!mode)
+ return error;
+
+ rep = (xRRCreateModeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .mode = mode->mode.id
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.mode);
+ }
+ WriteToClient(client, sizeof(xRRCreateModeReply), &rep);
+ /* Drop out reference to this mode */
+ RRModeDestroy(mode);
+ return Success;
+}
+
+int
+ProcRRDestroyMode(ClientPtr client)
+{
+ REQUEST(xRRDestroyModeReq);
+ RRModePtr mode;
+
+ REQUEST_SIZE_MATCH(xRRDestroyModeReq);
+ VERIFY_RR_MODE(stuff->mode, mode, DixDestroyAccess);
+
+ if (!mode->userScreen)
+ return BadMatch;
+ if (mode->refcnt > 1)
+ return BadAccess;
+ FreeResource(stuff->mode, 0);
+ return Success;
+}
+
+int
+ProcRRAddOutputMode(ClientPtr client)
+{
+ REQUEST(xRRAddOutputModeReq);
+ RRModePtr mode;
+ RROutputPtr output;
+
+ REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+ VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
+
+ return RROutputAddUserMode(output, mode);
+}
+
+int
+ProcRRDeleteOutputMode(ClientPtr client)
+{
+ REQUEST(xRRDeleteOutputModeReq);
+ RRModePtr mode;
+ RROutputPtr output;
+
+ REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+ VERIFY_RR_MODE(stuff->mode, mode, DixUseAccess);
+
+ return RROutputDeleteUserMode(output, mode);
+}
diff --git a/nx-X11/programs/Xserver/randr/rrmonitor.c b/nx-X11/programs/Xserver/randr/rrmonitor.c
new file mode 100644
index 000000000..e9031a567
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrmonitor.c
@@ -0,0 +1,787 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+#ifndef NXAGENT_SERVER
+#include "list.h"
+#endif
+
+static Atom
+RRMonitorCrtcName(RRCrtcPtr crtc)
+{
+ char name[20];
+
+ if (crtc->numOutputs) {
+ RROutputPtr output = crtc->outputs[0];
+ return MakeAtom(output->name, output->nameLength, TRUE);
+ }
+ sprintf(name, "Monitor-%08lx", (unsigned long int) crtc->id);
+ return MakeAtom(name, strlen(name), TRUE);
+}
+
+static Bool
+RRMonitorCrtcPrimary(RRCrtcPtr crtc)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+
+ for (o = 0; o < crtc->numOutputs; o++)
+ if (crtc->outputs[o] == pScrPriv->primaryOutput)
+ return TRUE;
+ return FALSE;
+}
+
+#define DEFAULT_PIXELS_PER_MM (96.0 / 25.4)
+
+static void
+RRMonitorGetCrtcGeometry(RRCrtcPtr crtc, RRMonitorGeometryPtr geometry)
+{
+ ScreenPtr screen = crtc->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ BoxRec panned_area;
+
+ /* Check to see if crtc is panned and return the full area when applicable. */
+ if (pScrPriv && pScrPriv->rrGetPanning &&
+ pScrPriv->rrGetPanning(screen, crtc, &panned_area, NULL, NULL) &&
+ (panned_area.x2 > panned_area.x1) &&
+ (panned_area.y2 > panned_area.y1)) {
+ geometry->box = panned_area;
+ }
+ else {
+ int width, height;
+
+ RRCrtcGetScanoutSize(crtc, &width, &height);
+ geometry->box.x1 = crtc->x;
+ geometry->box.y1 = crtc->y;
+ geometry->box.x2 = geometry->box.x1 + width;
+ geometry->box.y2 = geometry->box.y1 + height;
+ }
+ if (crtc->numOutputs && crtc->outputs[0]->mmWidth && crtc->outputs[0]->mmHeight) {
+ RROutputPtr output = crtc->outputs[0];
+ geometry->mmWidth = output->mmWidth;
+ geometry->mmHeight = output->mmHeight;
+ } else {
+ geometry->mmWidth = floor((geometry->box.x2 - geometry->box.x1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ geometry->mmHeight = floor((geometry->box.y2 - geometry->box.y1) / DEFAULT_PIXELS_PER_MM + 0.5);
+ }
+}
+
+static Bool
+RRMonitorSetFromServer(RRCrtcPtr crtc, RRMonitorPtr monitor)
+{
+ int o;
+
+ monitor->name = RRMonitorCrtcName(crtc);
+ monitor->pScreen = crtc->pScreen;
+ monitor->numOutputs = crtc->numOutputs;
+ monitor->outputs = calloc(crtc->numOutputs, sizeof(RRCrtc));
+ if (!monitor->outputs)
+ return FALSE;
+ for (o = 0; o < crtc->numOutputs; o++)
+ monitor->outputs[o] = crtc->outputs[o]->id;
+ monitor->primary = RRMonitorCrtcPrimary(crtc);
+ monitor->automatic = TRUE;
+ RRMonitorGetCrtcGeometry(crtc, &monitor->geometry);
+ return TRUE;
+}
+
+static Bool
+RRMonitorAutomaticGeometry(RRMonitorPtr monitor)
+{
+ return (monitor->geometry.box.x1 == 0 &&
+ monitor->geometry.box.y1 == 0 &&
+ monitor->geometry.box.x2 == 0 &&
+ monitor->geometry.box.y2 == 0);
+}
+
+static void
+RRMonitorGetGeometry(RRMonitorPtr monitor, RRMonitorGeometryPtr geometry)
+{
+ if (RRMonitorAutomaticGeometry(monitor) && monitor->numOutputs > 0) {
+ ScreenPtr screen = monitor->pScreen;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorGeometryRec first = { .box = {0, 0, 0, 0}, .mmWidth = 0, .mmHeight = 0 };
+ RRMonitorGeometryRec this;
+ int c, o, co;
+ int active_crtcs = 0;
+
+ *geometry = first;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ RRCrtcPtr crtc = NULL;
+ Bool in_use = FALSE;
+
+ for (c = 0; !in_use && c < pScrPriv->numCrtcs; c++) {
+ crtc = pScrPriv->crtcs[c];
+ if (!crtc->mode)
+ continue;
+ for (co = 0; !in_use && co < crtc->numOutputs; co++)
+ if (monitor->outputs[o] == crtc->outputs[co]->id)
+ in_use = TRUE;
+ }
+
+ if (!in_use)
+ continue;
+
+ RRMonitorGetCrtcGeometry(crtc, &this);
+
+ if (active_crtcs == 0) {
+ first = this;
+ *geometry = this;
+ } else {
+ geometry->box.x1 = min(this.box.x1, geometry->box.x1);
+ geometry->box.x2 = max(this.box.x2, geometry->box.x2);
+ geometry->box.y1 = min(this.box.y1, geometry->box.y1);
+ geometry->box.y2 = max(this.box.y2, geometry->box.y2);
+ }
+ active_crtcs++;
+ }
+
+ /* Adjust physical sizes to account for total area */
+ if (active_crtcs > 1 && first.box.x2 != first.box.x1 && first.box.y2 != first.box.y1) {
+ geometry->mmWidth = (this.box.x2 - this.box.x1) / (first.box.x2 - first.box.x1) * first.mmWidth;
+ geometry->mmHeight = (this.box.y2 - this.box.y1) / (first.box.y2 - first.box.y1) * first.mmHeight;
+ }
+ } else {
+ *geometry = monitor->geometry;
+ }
+}
+
+static Bool
+RRMonitorSetFromClient(RRMonitorPtr client_monitor, RRMonitorPtr monitor)
+{
+ monitor->name = client_monitor->name;
+ monitor->pScreen = client_monitor->pScreen;
+ monitor->numOutputs = client_monitor->numOutputs;
+ monitor->outputs = calloc(client_monitor->numOutputs, sizeof(RROutput));
+ if (!monitor->outputs && client_monitor->numOutputs)
+ return FALSE;
+ memcpy(monitor->outputs, client_monitor->outputs, client_monitor->numOutputs * sizeof(RROutput));
+ monitor->primary = client_monitor->primary;
+ monitor->automatic = client_monitor->automatic;
+ RRMonitorGetGeometry(client_monitor, &monitor->geometry);
+ return TRUE;
+}
+
+typedef struct _rrMonitorList {
+ int num_client;
+ int num_server;
+ RRCrtcPtr *server_crtc;
+ int num_crtcs;
+ int client_primary;
+ int server_primary;
+} RRMonitorListRec, *RRMonitorListPtr;
+
+static Bool
+RRMonitorInitList(ScreenPtr screen, RRMonitorListPtr mon_list, Bool get_active)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m, o, c, sc;
+ int numCrtcs;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ if (!RRGetInfo(screen, FALSE))
+ return FALSE;
+
+ /* Count the number of crtcs in this and any slave screens */
+ numCrtcs = pScrPriv->numCrtcs;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ numCrtcs += pSlavePriv->numCrtcs;
+ }
+#endif
+ mon_list->num_crtcs = numCrtcs;
+
+ mon_list->server_crtc = calloc(numCrtcs * 2, sizeof(RRCrtcPtr));
+ if (!mon_list->server_crtc)
+ return FALSE;
+
+ /* Collect pointers to all of the active crtcs */
+ c = 0;
+ for (sc = 0; sc < pScrPriv->numCrtcs; sc++, c++) {
+ if (pScrPriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pScrPriv->crtcs[sc];
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+ for (sc = 0; sc < pSlavePriv->numCrtcs; sc++, c++) {
+ if (pSlavePriv->crtcs[sc]->mode != NULL)
+ mon_list->server_crtc[c] = pSlavePriv->crtcs[sc];
+ }
+ }
+#endif
+
+ /* Walk the list of client-defined monitors, clearing the covered
+ * CRTCs from the full list and finding whether one of the
+ * monitors is primary
+ */
+ mon_list->num_client = pScrPriv->numMonitors;
+ mon_list->client_primary = -1;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(monitor, &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ mon_list->num_client--;
+ continue;
+ }
+ }
+ if (monitor->primary && mon_list->client_primary == -1)
+ mon_list->client_primary = m;
+ for (o = 0; o < monitor->numOutputs; o++) {
+ for (c = 0; c < numCrtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+ if (crtc) {
+ int co;
+ for (co = 0; co < crtc->numOutputs; co++)
+ if (crtc->outputs[co]->id == monitor->outputs[o]) {
+ mon_list->server_crtc[c] = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Now look at the active CRTCs, and count
+ * those not covered by a client monitor, as well
+ * as finding whether one of them is marked primary
+ */
+ mon_list->num_server = 0;
+ mon_list->server_primary = -1;
+
+ for (c = 0; c < mon_list->num_crtcs; c++) {
+ RRCrtcPtr crtc = mon_list->server_crtc[c];
+
+ if (!crtc)
+ continue;
+
+ mon_list->num_server++;
+
+ if (RRMonitorCrtcPrimary(crtc) && mon_list->server_primary == -1)
+ mon_list->server_primary = c;
+ }
+ return TRUE;
+}
+
+static void
+RRMonitorFiniList(RRMonitorListPtr list)
+{
+ free(list->server_crtc);
+}
+
+/* Construct a complete list of protocol-visible monitors, including
+ * the manually generated ones as well as those generated
+ * automatically from the remaining CRCTs
+ */
+
+Bool
+RRMonitorMakeList(ScreenPtr screen, Bool get_active, RRMonitorPtr * monitors_ret, int *nmon_ret)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ RRMonitorListRec list;
+ int m, c;
+ RRMonitorPtr mon, monitors;
+ Bool has_primary = FALSE;
+
+ if (!pScrPriv)
+ return FALSE;
+
+ if (!RRMonitorInitList(screen, &list, get_active))
+ return FALSE;
+
+ monitors = calloc(list.num_client + list.num_server, sizeof(RRMonitorRec));
+ if (!monitors) {
+ RRMonitorFiniList(&list);
+ return FALSE;
+ }
+
+ mon = monitors;
+
+ /* Fill in the primary monitor data first
+ */
+ if (list.client_primary >= 0) {
+ RRMonitorSetFromClient(pScrPriv->monitors[list.client_primary], mon);
+ mon++;
+ } else if (list.server_primary >= 0) {
+ RRMonitorSetFromServer(list.server_crtc[list.server_primary], mon);
+ mon++;
+ }
+
+ /* Fill in the client-defined monitors next
+ */
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (m == list.client_primary)
+ continue;
+ if (get_active) {
+ RRMonitorGeometryRec geom;
+
+ RRMonitorGetGeometry(pScrPriv->monitors[m], &geom);
+ if (geom.box.x2 - geom.box.x1 == 0 ||
+ geom.box.y2 - geom.box.y1 == 0) {
+ continue;
+ }
+ }
+ RRMonitorSetFromClient(pScrPriv->monitors[m], mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ /* And finish with the list of crtc-inspired monitors
+ */
+ for (c = 0; c < list.num_crtcs; c++) {
+ RRCrtcPtr crtc = list.server_crtc[c];
+ if (c == list.server_primary && list.client_primary < 0)
+ continue;
+
+ if (!list.server_crtc[c])
+ continue;
+
+ RRMonitorSetFromServer(crtc, mon);
+ if (has_primary)
+ mon->primary = FALSE;
+ else if (mon->primary)
+ has_primary = TRUE;
+ mon++;
+ }
+
+ RRMonitorFiniList(&list);
+ *nmon_ret = list.num_client + list.num_server;
+ *monitors_ret = monitors;
+ return TRUE;
+}
+
+int
+RRMonitorCountList(ScreenPtr screen)
+{
+ RRMonitorListRec list;
+ int nmon;
+
+ if (!RRMonitorInitList(screen, &list, FALSE))
+ return -1;
+ nmon = list.num_client + list.num_server;
+ RRMonitorFiniList(&list);
+ return nmon;
+}
+
+void
+RRMonitorFree(RRMonitorPtr monitor)
+{
+ free(monitor);
+}
+
+RRMonitorPtr
+RRMonitorAlloc(int noutput)
+{
+ RRMonitorPtr monitor;
+
+ monitor = calloc(1, sizeof(RRMonitorRec) + noutput * sizeof(RROutput));
+ if (!monitor)
+ return NULL;
+ monitor->numOutputs = noutput;
+ monitor->outputs = (RROutput *) (monitor + 1);
+ return monitor;
+}
+
+static int
+RRMonitorDelete(ClientPtr client, ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv) {
+ client->errorValue = name;
+ return BadAtom;
+ }
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr monitor = pScrPriv->monitors[m];
+ if (monitor->name == name) {
+ memmove(pScrPriv->monitors + m, pScrPriv->monitors + m + 1,
+ (pScrPriv->numMonitors - (m + 1)) * sizeof(RRMonitorPtr));
+ --pScrPriv->numMonitors;
+ RRMonitorFree(monitor);
+ return Success;
+ }
+ }
+
+ client->errorValue = name;
+ return BadValue;
+}
+
+static Bool
+RRMonitorMatchesOutputName(ScreenPtr screen, Atom name)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int o;
+ const char *str = NameForAtom(name);
+ int len = strlen(str);
+
+ for (o = 0; o < pScrPriv->numOutputs; o++) {
+ RROutputPtr output = pScrPriv->outputs[o];
+
+ if (output->nameLength == len && !memcmp(output->name, str, len))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+ RRMonitorPtr *monitors;
+
+ if (!pScrPriv)
+ return BadAlloc;
+
+ /* 'name' must not match the name of any Output on the screen, or
+ * a Value error results.
+ */
+
+ if (RRMonitorMatchesOutputName(screen, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave, &screen->output_slave_list, output_head) {
+ if (RRMonitorMatchesOutputName(slave, monitor->name)) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+#endif
+
+ /* 'name' must not match the name of any Monitor on the screen, or
+ * a Value error results.
+ */
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ if (pScrPriv->monitors[m]->name == monitor->name) {
+ client->errorValue = monitor->name;
+ return BadValue;
+ }
+ }
+
+ /* Allocate space for the new pointer. This is done before
+ * removing matching monitors as it may fail, and the request
+ * needs to not have any side-effects on failure
+ */
+ if (pScrPriv->numMonitors)
+ monitors = reallocarray(pScrPriv->monitors,
+ pScrPriv->numMonitors + 1,
+ sizeof(RRMonitorPtr));
+ else
+ monitors = malloc(sizeof(RRMonitorPtr));
+
+ if (!monitors)
+ return BadAlloc;
+
+ pScrPriv->monitors = monitors;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++) {
+ RRMonitorPtr existing = pScrPriv->monitors[m];
+ int o, eo;
+
+ /* If 'name' matches an existing Monitor on the screen, the
+ * existing one will be deleted as if RRDeleteMonitor were called.
+ */
+ if (existing->name == monitor->name) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ continue;
+ }
+
+ /* For each output in 'info.outputs', each one is removed from all
+ * pre-existing Monitors. If removing the output causes the list
+ * of outputs for that Monitor to become empty, then that
+ * Monitor will be deleted as if RRDeleteMonitor were called.
+ */
+
+ for (eo = 0; eo < existing->numOutputs; eo++) {
+ for (o = 0; o < monitor->numOutputs; o++) {
+ if (monitor->outputs[o] == existing->outputs[eo]) {
+ memmove(existing->outputs + eo, existing->outputs + eo + 1,
+ (existing->numOutputs - (eo + 1)) * sizeof(RROutput));
+ --existing->numOutputs;
+ --eo;
+ break;
+ }
+ }
+ if (existing->numOutputs == 0) {
+ (void) RRMonitorDelete(client, screen, existing->name);
+ break;
+ }
+ }
+ if (monitor->primary)
+ existing->primary = FALSE;
+ }
+
+ /* Add the new one to the list
+ */
+ pScrPriv->monitors[pScrPriv->numMonitors++] = monitor;
+
+ return Success;
+}
+
+void
+RRMonitorFreeList(RRMonitorPtr monitors, int nmon)
+{
+ int m;
+
+ for (m = 0; m < nmon; m++)
+ free(monitors[m].outputs);
+ free(monitors);
+}
+
+void
+RRMonitorInit(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ if (!pScrPriv)
+ return;
+
+ pScrPriv->numMonitors = 0;
+ pScrPriv->monitors = NULL;
+}
+
+void
+RRMonitorClose(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+ int m;
+
+ if (!pScrPriv)
+ return;
+
+ for (m = 0; m < pScrPriv->numMonitors; m++)
+ RRMonitorFree(pScrPriv->monitors[m]);
+ free(pScrPriv->monitors);
+ pScrPriv->monitors = NULL;
+ pScrPriv->numMonitors = 0;
+}
+
+static CARD32
+RRMonitorTimestamp(ScreenPtr screen)
+{
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(screen);
+
+ /* XXX should take client monitor changes into account */
+ return pScrPriv->lastConfigTime.milliseconds;
+}
+
+int
+ProcRRGetMonitors(ClientPtr client)
+{
+ REQUEST(xRRGetMonitorsReq);
+ xRRGetMonitorsReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ };
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+ RRMonitorPtr monitors;
+ int nmonitors;
+ int noutputs;
+ int m;
+ Bool get_active;
+
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ get_active = stuff->get_active;
+ if (!RRMonitorMakeList(screen, get_active, &monitors, &nmonitors))
+ return BadAlloc;
+
+ rep.timestamp = RRMonitorTimestamp(screen);
+
+ noutputs = 0;
+ for (m = 0; m < nmonitors; m++) {
+ rep.length += SIZEOF(xRRMonitorInfo) >> 2;
+ rep.length += monitors[m].numOutputs;
+ noutputs += monitors[m].numOutputs;
+ }
+
+ rep.nmonitors = nmonitors;
+ rep.noutputs = noutputs;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.nmonitors);
+ swapl(&rep.noutputs);
+ }
+ WriteToClient(client, sizeof(xRRGetMonitorsReply), &rep);
+
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+
+ for (m = 0; m < nmonitors; m++) {
+ RRMonitorPtr monitor = &monitors[m];
+ xRRMonitorInfo info = {
+ .name = monitor->name,
+ .primary = monitor->primary,
+ .automatic = monitor->automatic,
+ .noutput = monitor->numOutputs,
+ .x = monitor->geometry.box.x1,
+ .y = monitor->geometry.box.y1,
+ .width = monitor->geometry.box.x2 - monitor->geometry.box.x1,
+ .height = monitor->geometry.box.y2 - monitor->geometry.box.y1,
+ .widthInMillimeters = monitor->geometry.mmWidth,
+ .heightInMillimeters = monitor->geometry.mmHeight,
+ };
+ if (client->swapped) {
+ swapl(&info.name);
+ swaps(&info.noutput);
+ swaps(&info.x);
+ swaps(&info.y);
+ swaps(&info.width);
+ swaps(&info.height);
+ swapl(&info.widthInMillimeters);
+ swapl(&info.heightInMillimeters);
+ }
+
+ WriteToClient(client, sizeof(xRRMonitorInfo), &info);
+ WriteSwappedDataToClient(client, monitor->numOutputs * sizeof(RROutput),
+ monitor->outputs);
+ }
+
+ RRMonitorFreeList(monitors, nmonitors);
+
+ return Success;
+}
+
+int
+ProcRRSetMonitor(ClientPtr client)
+{
+ REQUEST(xRRSetMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ RRMonitorPtr monitor;
+ int r;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetMonitorReq);
+
+ if (stuff->monitor.noutput != stuff->length - (SIZEOF(xRRSetMonitorReq) >> 2))
+ return BadLength;
+
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->monitor.name))
+ return BadAtom;
+
+ /* Allocate the new monitor */
+ monitor = RRMonitorAlloc(stuff->monitor.noutput);
+ if (!monitor)
+ return BadAlloc;
+
+ /* Fill in the bits from the request */
+ monitor->pScreen = screen;
+ monitor->name = stuff->monitor.name;
+ monitor->primary = stuff->monitor.primary;
+ monitor->automatic = FALSE;
+ memcpy(monitor->outputs, stuff + 1, stuff->monitor.noutput * sizeof(RROutput));
+ monitor->geometry.box.x1 = stuff->monitor.x;
+ monitor->geometry.box.y1 = stuff->monitor.y;
+ monitor->geometry.box.x2 = stuff->monitor.x + stuff->monitor.width;
+ monitor->geometry.box.y2 = stuff->monitor.y + stuff->monitor.height;
+ monitor->geometry.mmWidth = stuff->monitor.widthInMillimeters;
+ monitor->geometry.mmHeight = stuff->monitor.heightInMillimeters;
+
+ r = RRMonitorAdd(client, screen, monitor);
+ if (r == Success)
+ RRSendConfigNotify(screen);
+ else
+ RRMonitorFree(monitor);
+ return r;
+}
+
+int
+ProcRRDeleteMonitor(ClientPtr client)
+{
+ REQUEST(xRRDeleteMonitorReq);
+ WindowPtr window;
+ ScreenPtr screen;
+ int r;
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+#ifndef NXAGENT_SERVER
+ r = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
+#else
+ window = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ r = window ? Success : BadWindow;
+#endif
+
+ if (r != Success)
+ return r;
+ screen = window->drawable.pScreen;
+
+ if (!ValidAtom(stuff->name)) {
+ client->errorValue = stuff->name;
+ return BadAtom;
+ }
+
+ r = RRMonitorDelete(client, screen, stuff->name);
+ if (r == Success)
+ RRSendConfigNotify(screen);
+ return r;
+}
diff --git a/nx-X11/programs/Xserver/randr/rroutput.c b/nx-X11/programs/Xserver/randr/rroutput.c
new file mode 100644
index 000000000..8042b719c
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rroutput.c
@@ -0,0 +1,650 @@
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+
+RESTYPE RROutputType;
+
+/*
+ * Notify the output of some change
+ */
+void
+RROutputChanged(RROutputPtr output, Bool configChanged)
+{
+ /* set changed bits on the master screen only */
+ ScreenPtr pScreen = output->pScreen;
+ rrScrPrivPtr mastersp;
+
+ output->changed = TRUE;
+ if (!pScreen)
+ return;
+
+#ifndef NXAGENT_SERVER
+ if (pScreen->isGPU) {
+ ScreenPtr master = pScreen->current_master;
+ if (!master)
+ return;
+ mastersp = rrGetScrPriv(master);
+ }
+ else
+#endif
+ {
+ mastersp = rrGetScrPriv(pScreen);
+ }
+
+ RRSetChanged(pScreen);
+ if (configChanged)
+ mastersp->configChanged = TRUE;
+}
+
+/*
+ * Create an output
+ */
+
+RROutputPtr
+RROutputCreate(ScreenPtr pScreen,
+ const char *name, int nameLength, void *devPrivate)
+{
+ RROutputPtr output;
+ RROutputPtr *outputs;
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRInit())
+ return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->numOutputs)
+ outputs = reallocarray(pScrPriv->outputs,
+ pScrPriv->numOutputs + 1, sizeof(RROutputPtr));
+ else
+ outputs = malloc(sizeof(RROutputPtr));
+ if (!outputs)
+ return FALSE;
+
+ pScrPriv->outputs = outputs;
+
+ output = malloc(sizeof(RROutputRec) + nameLength + 1);
+ if (!output)
+ return NULL;
+ output->id = FakeClientID(0);
+ output->pScreen = pScreen;
+ output->name = (char *) (output + 1);
+ output->nameLength = nameLength;
+ memcpy(output->name, name, nameLength);
+ output->name[nameLength] = '\0';
+ output->connection = RR_UnknownConnection;
+ output->subpixelOrder = SubPixelUnknown;
+ output->mmWidth = 0;
+ output->mmHeight = 0;
+ output->crtc = NULL;
+ output->numCrtcs = 0;
+ output->crtcs = NULL;
+ output->numClones = 0;
+ output->clones = NULL;
+ output->numModes = 0;
+ output->numPreferred = 0;
+ output->modes = NULL;
+ output->numUserModes = 0;
+ output->userModes = NULL;
+ output->properties = NULL;
+ output->pendingProperties = FALSE;
+ output->changed = FALSE;
+ output->devPrivate = devPrivate;
+
+ if (!AddResource(output->id, RROutputType, (void *) output))
+ return NULL;
+
+ pScrPriv->outputs[pScrPriv->numOutputs++] = output;
+
+ RRResourcesChanged(pScreen);
+
+ return output;
+}
+
+/*
+ * Notify extension that output parameters have been changed
+ */
+Bool
+RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones)
+{
+ RROutputPtr *newClones;
+ int i;
+
+ if (numClones == output->numClones) {
+ for (i = 0; i < numClones; i++)
+ if (output->clones[i] != clones[i])
+ break;
+ if (i == numClones)
+ return TRUE;
+ }
+ if (numClones) {
+ newClones = xallocarray(numClones, sizeof(RROutputPtr));
+ if (!newClones)
+ return FALSE;
+ }
+ else
+ newClones = NULL;
+ free(output->clones);
+ memcpy(newClones, clones, numClones * sizeof(RROutputPtr));
+ output->clones = newClones;
+ output->numClones = numClones;
+ RROutputChanged(output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetModes(RROutputPtr output,
+ RRModePtr * modes, int numModes, int numPreferred)
+{
+ RRModePtr *newModes;
+ int i;
+
+ if (numModes == output->numModes && numPreferred == output->numPreferred) {
+ for (i = 0; i < numModes; i++)
+ if (output->modes[i] != modes[i])
+ break;
+ if (i == numModes) {
+ for (i = 0; i < numModes; i++)
+ RRModeDestroy(modes[i]);
+ return TRUE;
+ }
+ }
+
+ if (numModes) {
+ newModes = xallocarray(numModes, sizeof(RRModePtr));
+ if (!newModes)
+ return FALSE;
+ }
+ else
+ newModes = NULL;
+ if (output->modes) {
+ for (i = 0; i < output->numModes; i++)
+ RRModeDestroy(output->modes[i]);
+ free(output->modes);
+ }
+ memcpy(newModes, modes, numModes * sizeof(RRModePtr));
+ output->modes = newModes;
+ output->numModes = numModes;
+ output->numPreferred = numPreferred;
+ RROutputChanged(output, TRUE);
+ return TRUE;
+}
+
+int
+RROutputAddUserMode(RROutputPtr output, RRModePtr mode)
+{
+ int m;
+ ScreenPtr pScreen = output->pScreen;
+
+ rrScrPriv(pScreen);
+ RRModePtr *newModes;
+
+ /* Check to see if this mode is already listed for this output */
+ for (m = 0; m < output->numModes + output->numUserModes; m++) {
+ RRModePtr e = (m < output->numModes ?
+ output->modes[m] :
+ output->userModes[m - output->numModes]);
+ if (mode == e)
+ return Success;
+ }
+
+ /* Check with the DDX to see if this mode is OK */
+ if (pScrPriv->rrOutputValidateMode)
+ if (!pScrPriv->rrOutputValidateMode(pScreen, output, mode))
+ return BadMatch;
+
+ if (output->userModes)
+ newModes = reallocarray(output->userModes,
+ output->numUserModes + 1, sizeof(RRModePtr));
+ else
+ newModes = malloc(sizeof(RRModePtr));
+ if (!newModes)
+ return BadAlloc;
+
+ output->userModes = newModes;
+ output->userModes[output->numUserModes++] = mode;
+ ++mode->refcnt;
+ RROutputChanged(output, TRUE);
+ RRTellChanged(pScreen);
+ return Success;
+}
+
+int
+RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode)
+{
+ int m;
+
+ /* Find this mode in the user mode list */
+ for (m = 0; m < output->numUserModes; m++) {
+ RRModePtr e = output->userModes[m];
+
+ if (mode == e)
+ break;
+ }
+ /* Not there, access error */
+ if (m == output->numUserModes)
+ return BadAccess;
+
+ /* make sure the mode isn't active for this output */
+ if (output->crtc && output->crtc->mode == mode)
+ return BadMatch;
+
+ memmove(output->userModes + m, output->userModes + m + 1,
+ (output->numUserModes - m - 1) * sizeof(RRModePtr));
+ output->numUserModes--;
+ RRModeDestroy(mode);
+ return Success;
+}
+
+Bool
+RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs)
+{
+ RRCrtcPtr *newCrtcs;
+ int i;
+
+ if (numCrtcs == output->numCrtcs) {
+ for (i = 0; i < numCrtcs; i++)
+ if (output->crtcs[i] != crtcs[i])
+ break;
+ if (i == numCrtcs)
+ return TRUE;
+ }
+ if (numCrtcs) {
+ newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr));
+ if (!newCrtcs)
+ return FALSE;
+ }
+ else
+ newCrtcs = NULL;
+ free(output->crtcs);
+ memcpy(newCrtcs, crtcs, numCrtcs * sizeof(RRCrtcPtr));
+ output->crtcs = newCrtcs;
+ output->numCrtcs = numCrtcs;
+ RROutputChanged(output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetConnection(RROutputPtr output, CARD8 connection)
+{
+ if (output->connection == connection)
+ return TRUE;
+ output->connection = connection;
+ RROutputChanged(output, TRUE);
+ return TRUE;
+}
+
+Bool
+RROutputSetSubpixelOrder(RROutputPtr output, int subpixelOrder)
+{
+ if (output->subpixelOrder == subpixelOrder)
+ return TRUE;
+
+ output->subpixelOrder = subpixelOrder;
+ RROutputChanged(output, FALSE);
+ return TRUE;
+}
+
+Bool
+RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight)
+{
+ if (output->mmWidth == mmWidth && output->mmHeight == mmHeight)
+ return TRUE;
+ output->mmWidth = mmWidth;
+ output->mmHeight = mmHeight;
+ RROutputChanged(output, FALSE);
+ return TRUE;
+}
+
+void
+RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+ RRCrtcPtr crtc = output->crtc;
+ RRModePtr mode = crtc ? crtc->mode : NULL;
+
+ xRROutputChangeNotifyEvent oe = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_OutputChange,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .window = pWin->drawable.id,
+ .output = output->id,
+ .crtc = crtc ? crtc->id : None,
+ .mode = mode ? mode->mode.id : None,
+ .rotation = crtc ? crtc->rotation : RR_Rotate_0,
+ .connection = output->connection,
+ .subpixelOrder = output->subpixelOrder
+ };
+ WriteEventsToClient(client, 1, (xEvent *) &oe);
+}
+
+/*
+ * Destroy a Output at shutdown
+ */
+void
+RROutputDestroy(RROutputPtr output)
+{
+ FreeResource(output->id, 0);
+}
+
+static int
+RROutputDestroyResource(void *value, XID pid)
+{
+ RROutputPtr output = (RROutputPtr) value;
+ ScreenPtr pScreen = output->pScreen;
+ int m;
+
+ if (pScreen) {
+ rrScrPriv(pScreen);
+ int i;
+
+ if (pScrPriv->primaryOutput == output)
+ pScrPriv->primaryOutput = NULL;
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ if (pScrPriv->outputs[i] == output) {
+ memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
+ (pScrPriv->numOutputs - (i + 1)) * sizeof(RROutputPtr));
+ --pScrPriv->numOutputs;
+ break;
+ }
+ }
+
+ RRResourcesChanged(pScreen);
+ }
+ if (output->modes) {
+ for (m = 0; m < output->numModes; m++)
+ RRModeDestroy(output->modes[m]);
+ free(output->modes);
+ }
+
+ for (m = 0; m < output->numUserModes; m++)
+ RRModeDestroy(output->userModes[m]);
+ free(output->userModes);
+
+ free(output->crtcs);
+ free(output->clones);
+ RRDeleteAllOutputProperties(output);
+ free(output);
+ return 1;
+}
+
+/*
+ * Initialize output type
+ */
+Bool
+RROutputInit(void)
+{
+ RROutputType = CreateNewResourceType(RROutputDestroyResource
+#ifndef NXAGENT_SERVER
+ , "OUTPUT"
+#endif
+ );
+ if (!RROutputType)
+ return FALSE;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RROutputType, "OUTPUT");
+#endif
+
+ return TRUE;
+}
+
+/*
+ * Initialize output type error value
+ */
+void
+RROutputInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput);
+#endif
+}
+
+#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
+
+int
+ProcRRGetOutputInfo(ClientPtr client)
+{
+ REQUEST(xRRGetOutputInfoReq);
+ xRRGetOutputInfoReply rep;
+ RROutputPtr output;
+ CARD8 *extra;
+ unsigned long extraLen;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ RRCrtc *crtcs;
+ RRMode *modes;
+ RROutput *clones;
+ char *name;
+ int i;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ pScreen = output->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep = (xRRGetOutputInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(OutputInfoExtra),
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .crtc = output->crtc ? output->crtc->id : None,
+ .mmWidth = output->mmWidth,
+ .mmHeight = output->mmHeight,
+ .connection = output->connection,
+ .subpixelOrder = output->subpixelOrder,
+ .nCrtcs = output->numCrtcs,
+ .nModes = output->numModes + output->numUserModes,
+ .nPreferred = output->numPreferred,
+ .nClones = output->numClones,
+ .nameLength = output->nameLength
+ };
+ extraLen = ((output->numCrtcs +
+ output->numModes + output->numUserModes +
+ output->numClones + bytes_to_int32(rep.nameLength)) << 2);
+
+ if (extraLen) {
+ rep.length += bytes_to_int32(extraLen);
+ extra = calloc(1, extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ modes = (RRMode *) (crtcs + output->numCrtcs);
+ clones = (RROutput *) (modes + output->numModes + output->numUserModes);
+ name = (char *) (clones + output->numClones);
+
+ for (i = 0; i < output->numCrtcs; i++) {
+ crtcs[i] = output->crtcs[i]->id;
+ if (client->swapped)
+ swapl(&crtcs[i]);
+ }
+ for (i = 0; i < output->numModes + output->numUserModes; i++) {
+ if (i < output->numModes)
+ modes[i] = output->modes[i]->mode.id;
+ else
+ modes[i] = output->userModes[i - output->numModes]->mode.id;
+ if (client->swapped)
+ swapl(&modes[i]);
+ }
+ for (i = 0; i < output->numClones; i++) {
+ clones[i] = output->clones[i]->id;
+ if (client->swapped)
+ swapl(&clones[i]);
+ }
+ memcpy(name, output->name, output->nameLength);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.crtc);
+ swapl(&rep.mmWidth);
+ swapl(&rep.mmHeight);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nModes);
+ swaps(&rep.nPreferred);
+ swaps(&rep.nClones);
+ swaps(&rep.nameLength);
+ }
+ WriteToClient(client, sizeof(xRRGetOutputInfoReply), &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+
+ return Success;
+}
+
+static void
+RRSetPrimaryOutput(ScreenPtr pScreen, rrScrPrivPtr pScrPriv, RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ return;
+
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput) {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+
+ /* set the new primary */
+ if (output) {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+
+ pScrPriv->layoutChanged = TRUE;
+
+ RRTellChanged(pScreen);
+}
+
+int
+ProcRRSetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRSetOutputPrimaryReq);
+ RROutputPtr output = NULL;
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ int ret;
+#ifndef NXAGENT_SERVER
+ ScreenPtr slave;
+#endif
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+
+#ifndef NXAGENT_SERVER
+ ret = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ ret = pWin ? Success : BadWindow;
+#endif
+
+ if (ret != Success)
+ return ret;
+
+ if (stuff->output) {
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+#ifndef NXAGENT_SERVER
+ if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+ if (output->pScreen->isGPU &&
+ output->pScreen->current_master != pWin->drawable.pScreen) {
+ client->errorValue = stuff->window;
+ return BadMatch;
+ }
+#endif
+ }
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ {
+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
+
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(slave,
+ &pWin->drawable.pScreen->output_slave_list,
+ output_head) {
+ rrScrPrivPtr pSlavePriv;
+ pSlavePriv = rrGetScrPriv(slave);
+
+ RRSetPrimaryOutput(slave, pSlavePriv, output);
+ }
+#endif
+ }
+
+ return Success;
+}
+
+int
+ProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+ WindowPtr pWin;
+ rrScrPrivPtr pScrPriv;
+ xRRGetOutputPrimaryReply rep;
+ RROutputPtr primary = NULL;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
+ if (pScrPriv)
+ primary = pScrPriv->primaryOutput;
+
+ rep = (xRRGetOutputPrimaryReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .output = primary ? primary->id : None
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.output);
+ }
+
+ WriteToClient(client, sizeof(xRRGetOutputPrimaryReply), &rep);
+
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrpointer.c b/nx-X11/programs/Xserver/randr/rrpointer.c
new file mode 100644
index 000000000..ace7d36a2
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrpointer.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "inputstr.h"
+
+/*
+ * When the pointer moves, check to see if the specified position is outside
+ * any of theavailable CRTCs and move it to a 'sensible' place if so, where
+ * sensible is the closest monitor to the departing edge.
+ *
+ * Returns whether the position was adjusted
+ */
+
+static Bool
+RRCrtcContainsPosition(RRCrtcPtr crtc, int x, int y)
+{
+ RRModePtr mode = crtc->mode;
+ int scan_width, scan_height;
+
+ if (!mode)
+ return FALSE;
+
+ RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
+
+ if (crtc->x <= x && x < crtc->x + scan_width &&
+ crtc->y <= y && y < crtc->y + scan_height)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Find the CRTC nearest the specified position, ignoring 'skip'
+ */
+static void
+RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
+{
+ rrScrPriv(pScreen);
+ int c;
+ RRCrtcPtr nearest = NULL;
+ int best = 0;
+ int best_dx = 0, best_dy = 0;
+
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+ RRModePtr mode = crtc->mode;
+ int dx, dy;
+ int dist;
+ int scan_width, scan_height;
+
+ if (!mode)
+ continue;
+ if (crtc == skip)
+ continue;
+
+ RRCrtcGetScanoutSize(crtc, &scan_width, &scan_height);
+
+ if (x < crtc->x)
+ dx = crtc->x - x;
+ else if (x > crtc->x + scan_width - 1)
+ dx = crtc->x + (scan_width - 1) - x;
+ else
+ dx = 0;
+ if (y < crtc->y)
+ dy = crtc->y - y;
+ else if (y > crtc->y + scan_height - 1)
+ dy = crtc->y + (scan_height - 1) - y;
+ else
+ dy = 0;
+ dist = dx * dx + dy * dy;
+ if (!nearest || dist < best) {
+ nearest = crtc;
+ best_dx = dx;
+ best_dy = dy;
+ best = dist;
+ }
+ }
+ if (best_dx || best_dy)
+ (*pScreen->SetCursorPosition) (
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x + best_dx, y + best_dy,
+ TRUE);
+ pScrPriv->pointerCrtc = nearest;
+}
+
+void
+RRPointerMoved(ScreenPtr pScreen, int x, int y)
+{
+ rrScrPriv(pScreen);
+ RRCrtcPtr pointerCrtc = pScrPriv->pointerCrtc;
+ int c;
+
+ /* Check last known CRTC */
+ if (pointerCrtc && RRCrtcContainsPosition(pointerCrtc, x, y))
+ return;
+
+ /* Check all CRTCs */
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[c];
+
+ if (RRCrtcContainsPosition(crtc, x, y)) {
+ /* Remember containing CRTC */
+ pScrPriv->pointerCrtc = crtc;
+ return;
+ }
+ }
+
+ /* None contain pointer, find nearest */
+ ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
+ RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ inputInfo.pointer,
+#endif /* !defined(NXAGENT_SERVER) */
+ pScreen, x, y, pointerCrtc);
+}
+
+/*
+ * When the screen is reconfigured, move all pointers to the nearest
+ * CRTC
+ */
+void
+RRPointerScreenConfigured(ScreenPtr pScreen)
+{
+ WindowPtr pRoot;
+ ScreenPtr pCurrentScreen;
+ int x, y;
+
+#ifndef NXAGENT_SERVER
+ DeviceIntPtr pDev;
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+ if (IsPointerDevice(pDev)) {
+#endif /* NXAGENT_SERVER */
+ pRoot = GetCurrentRootWindow(
+#ifndef NXAGENT_SERVER
+ pDev
+#endif /* NXAGENT_SERVER */
+ );
+ pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+
+ if (pScreen == pCurrentScreen) {
+ GetSpritePosition(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* NXAGENT_SERVER */
+ &x, &y);
+ RRPointerToNearestCrtc(
+#ifndef NXAGENT_SERVER
+ pDev,
+#endif /* NXAGENT_SERVER */
+ pScreen, x, y, NULL);
+#ifndef NXAGENT_SERVER
+ }
+ }
+#endif /* NXAGENT_SERVER */
+ }
+}
diff --git a/nx-X11/programs/Xserver/randr/rrproperty.c b/nx-X11/programs/Xserver/randr/rrproperty.c
new file mode 100644
index 000000000..aad68273a
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrproperty.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "propertyst.h"
+#include "swaprep.h"
+
+static int
+DeliverPropertyEvent(WindowPtr pWin, void *value)
+{
+ xRROutputPropertyNotifyEvent *event = value;
+ RREventPtr *pHead, pRREvent;
+
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (!(pRREvent->mask & RROutputPropertyNotifyMask))
+ continue;
+
+ event->window = pRREvent->window->drawable.id;
+ WriteEventsToClient(pRREvent->client, 1, (xEvent *) event);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
+{
+ if (!(dispatchException & (DE_RESET | DE_TERMINATE)))
+ WalkTree(pScreen, DeliverPropertyEvent, event);
+}
+
+static void
+RRDestroyOutputProperty(RRPropertyPtr prop)
+{
+ free(prop->valid_values);
+ free(prop->current.data);
+ free(prop->pending.data);
+ free(prop);
+}
+
+static void
+RRDeleteProperty(RROutputRec * output, RRPropertyRec * prop)
+{
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
+
+ RRDestroyOutputProperty(prop);
+}
+
+void
+RRDeleteAllOutputProperties(RROutputPtr output)
+{
+ RRPropertyPtr prop, next;
+
+ for (prop = output->properties; prop; prop = next) {
+ next = prop->next;
+ RRDeleteProperty(output, prop);
+ }
+}
+
+static void
+RRInitOutputPropertyValue(RRPropertyValuePtr property_value)
+{
+ property_value->type = None;
+ property_value->format = 0;
+ property_value->size = 0;
+ property_value->data = NULL;
+}
+
+static RRPropertyPtr
+RRCreateOutputProperty(Atom property)
+{
+ RRPropertyPtr prop;
+
+ prop = (RRPropertyPtr) malloc(sizeof(RRPropertyRec));
+ if (!prop)
+ return NULL;
+ prop->next = NULL;
+ prop->propertyName = property;
+ prop->is_pending = FALSE;
+ prop->range = FALSE;
+ prop->immutable = FALSE;
+ prop->num_valid = 0;
+ prop->valid_values = NULL;
+ RRInitOutputPropertyValue(&prop->current);
+ RRInitOutputPropertyValue(&prop->pending);
+ return prop;
+}
+
+void
+RRDeleteOutputProperty(RROutputPtr output, Atom property)
+{
+ RRPropertyRec *prop, **prev;
+
+ for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
+ if (prop->propertyName == property) {
+ *prev = prop->next;
+ RRDeleteProperty(output, prop);
+ return;
+ }
+}
+
+int
+RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending)
+{
+ RRPropertyPtr prop;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
+ int size_in_bytes;
+ unsigned long total_len;
+ RRPropertyValuePtr prop_value;
+ RRPropertyValueRec new_value;
+ Bool add = FALSE;
+
+ size_in_bytes = format >> 3;
+
+ /* first see if property already exists */
+ prop = RRQueryOutputProperty(output, property);
+ if (!prop) { /* just add to list */
+ prop = RRCreateOutputProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ mode = PropModeReplace;
+ }
+ if (pending && prop->is_pending)
+ prop_value = &prop->pending;
+ else
+ prop_value = &prop->current;
+
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != prop_value->format) && (mode != PropModeReplace))
+ return BadMatch;
+ if ((prop_value->type != type) && (mode != PropModeReplace))
+ return BadMatch;
+ new_value = *prop_value;
+ if (mode == PropModeReplace)
+ total_len = len;
+ else
+ total_len = prop_value->size + len;
+
+ if (mode == PropModeReplace || len > 0) {
+ void *new_data = NULL, *old_data = NULL;
+
+ new_value.data = xallocarray(total_len, size_in_bytes);
+ if (!new_value.data && total_len && size_in_bytes) {
+ if (add)
+ RRDestroyOutputProperty(prop);
+ return BadAlloc;
+ }
+ new_value.size = len;
+ new_value.type = type;
+ new_value.format = format;
+
+ switch (mode) {
+ case PropModeReplace:
+ new_data = new_value.data;
+ old_data = NULL;
+ break;
+ case PropModeAppend:
+ new_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ old_data = new_value.data;
+ break;
+ case PropModePrepend:
+ new_data = new_value.data;
+ old_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ break;
+ }
+ if (new_data)
+ memcpy((char *) new_data, (char *) value, len * size_in_bytes);
+ if (old_data)
+ memcpy((char *) old_data, (char *) prop_value->data,
+ prop_value->size * size_in_bytes);
+
+ if (pending && pScrPriv->rrOutputSetProperty &&
+ !pScrPriv->rrOutputSetProperty(output->pScreen, output,
+ prop->propertyName, &new_value)) {
+ free(new_value.data);
+ if (add)
+ RRDestroyOutputProperty(prop);
+ return BadValue;
+ }
+ free(prop_value->data);
+ *prop_value = new_value;
+ }
+
+ else if (len == 0) {
+ /* do nothing */
+ }
+
+ if (add) {
+ prop->next = output->properties;
+ output->properties = prop;
+ }
+
+ if (pending && prop->is_pending)
+ output->pendingProperties = TRUE;
+
+ if (sendevent) {
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyNewValue,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
+ }
+ return Success;
+}
+
+Bool
+RRPostPendingProperties(RROutputPtr output)
+{
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+ RRPropertyPtr property;
+ Bool ret = TRUE;
+
+ if (!output->pendingProperties)
+ return TRUE;
+
+ output->pendingProperties = FALSE;
+ for (property = output->properties; property; property = property->next) {
+ /* Skip non-pending properties */
+ if (!property->is_pending)
+ continue;
+
+ pending_value = &property->pending;
+ current_value = &property->current;
+
+ /*
+ * If the pending and current values are equal, don't mark it
+ * as changed (which would deliver an event)
+ */
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp(pending_value->data, current_value->data,
+ pending_value->size * (pending_value->format / 8)))
+ continue;
+
+ if (RRChangeOutputProperty(output, property->propertyName,
+ pending_value->type, pending_value->format,
+ PropModeReplace, pending_value->size,
+ pending_value->data, TRUE, FALSE) != Success)
+ ret = FALSE;
+ }
+ return ret;
+}
+
+RRPropertyPtr
+RRQueryOutputProperty(RROutputPtr output, Atom property)
+{
+ RRPropertyPtr prop;
+
+ for (prop = output->properties; prop; prop = prop->next)
+ if (prop->propertyName == property)
+ return prop;
+ return NULL;
+}
+
+RRPropertyValuePtr
+RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending)
+{
+ RRPropertyPtr prop = RRQueryOutputProperty(output, property);
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
+
+ if (!prop)
+ return NULL;
+ if (pending && prop->is_pending)
+ return &prop->pending;
+ else {
+#if RANDR_13_INTERFACE
+ /* If we can, try to update the property value first */
+ if (pScrPriv->rrOutputGetProperty)
+ pScrPriv->rrOutputGetProperty(output->pScreen, output,
+ prop->propertyName);
+#endif
+ return &prop->current;
+ }
+}
+
+int
+RRConfigureOutputProperty(RROutputPtr output, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values)
+{
+ RRPropertyPtr prop = RRQueryOutputProperty(output, property);
+ Bool add = FALSE;
+ INT32 *new_values;
+
+ if (!prop) {
+ prop = RRCreateOutputProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ }
+ else if (prop->immutable && !immutable)
+ return BadAccess;
+
+ /*
+ * ranges must have even number of values
+ */
+ if (range && (num_values & 1)) {
+ if (add)
+ RRDestroyOutputProperty(prop);
+ return BadMatch;
+ }
+
+ new_values = xallocarray(num_values, sizeof(INT32));
+ if (!new_values && num_values) {
+ if (add)
+ RRDestroyOutputProperty(prop);
+ return BadAlloc;
+ }
+ if (num_values)
+ memcpy(new_values, values, num_values * sizeof(INT32));
+
+ /*
+ * Property moving from pending to non-pending
+ * loses any pending values
+ */
+ if (prop->is_pending && !pending) {
+ free(prop->pending.data);
+ RRInitOutputPropertyValue(&prop->pending);
+ }
+
+ prop->is_pending = pending;
+ prop->range = range;
+ prop->immutable = immutable;
+ prop->num_valid = num_values;
+ free(prop->valid_values);
+ prop->valid_values = new_values;
+
+ if (add) {
+ prop->next = output->properties;
+ output->properties = prop;
+ }
+
+ return Success;
+}
+
+int
+ProcRRListOutputProperties(ClientPtr client)
+{
+ REQUEST(xRRListOutputPropertiesReq);
+ Atom *pAtoms = NULL;
+ xRRListOutputPropertiesReply rep;
+ int numProps = 0;
+ RROutputPtr output;
+ RRPropertyPtr prop;
+
+ REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
+
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ for (prop = output->properties; prop; prop = prop->next)
+ numProps++;
+ if (numProps)
+ if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
+ return BadAlloc;
+
+ rep = (xRRListOutputPropertiesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(numProps * sizeof(Atom)),
+ .nAtoms = numProps
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.nAtoms);
+ }
+ WriteToClient(client, sizeof(xRRListOutputPropertiesReply), &rep);
+
+ if (numProps) {
+ /* Copy property name atoms to reply buffer */
+ Atom *temppAtoms = pAtoms;
+ for (prop = output->properties; prop; prop = prop->next)
+ *temppAtoms++ = prop->propertyName;
+
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ free(pAtoms);
+ }
+ return Success;
+}
+
+int
+ProcRRQueryOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRQueryOutputPropertyReq);
+ xRRQueryOutputPropertyReply rep;
+ RROutputPtr output;
+ RRPropertyPtr prop;
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
+
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ prop = RRQueryOutputProperty(output, stuff->property);
+ if (!prop)
+ return BadName;
+
+ if (prop->num_valid) {
+ extra = xallocarray(prop->num_valid, sizeof(INT32));
+ if (!extra)
+ return BadAlloc;
+ }
+
+ rep = (xRRQueryOutputPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = prop->num_valid,
+ .pending = prop->is_pending,
+ .range = prop->range,
+ .immutable = prop->immutable
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+ WriteToClient(client, sizeof(xRRQueryOutputPropertyReply), &rep);
+ if (prop->num_valid) {
+ memcpy(extra, prop->valid_values, prop->num_valid * sizeof(INT32));
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32),
+ extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRConfigureOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRConfigureOutputPropertyReq);
+ RROutputPtr output;
+ int num_valid;
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
+
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ num_valid =
+ stuff->length - bytes_to_int32(sizeof(xRRConfigureOutputPropertyReq));
+ return RRConfigureOutputProperty(output, stuff->property, stuff->pending,
+ stuff->range, FALSE, num_valid,
+ (INT32 *) (stuff + 1));
+}
+
+int
+ProcRRChangeOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRChangeOutputPropertyReq);
+ RROutputPtr output;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend)) {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32)) {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq))))
+ return BadLength;
+ sizeInBytes = format >> 3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xRRChangeOutputPropertyReq, totalSize);
+
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if (!ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ err = RRChangeOutputProperty(output, stuff->property,
+ stuff->type, (int) format,
+ (int) mode, len, (void *) &stuff[1], TRUE,
+ TRUE);
+ if (err != Success)
+ return err;
+ else
+ return Success;
+}
+
+int
+ProcRRDeleteOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRDeleteOutputPropertyReq);
+ RROutputPtr output;
+ RRPropertyPtr prop;
+
+ REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
+ UpdateCurrentTime();
+ VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+
+ prop = RRQueryOutputProperty(output, stuff->property);
+ if (!prop) {
+ client->errorValue = stuff->property;
+ return BadName;
+ }
+
+ if (prop->immutable) {
+ client->errorValue = stuff->property;
+ return BadAccess;
+ }
+
+ RRDeleteOutputProperty(output, stuff->property);
+ return Success;
+}
+
+int
+ProcRRGetOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPropertyReq);
+ RRPropertyPtr prop, *prev;
+ RRPropertyValuePtr prop_value;
+ unsigned long n, len, ind;
+ RROutputPtr output;
+ xRRGetOutputPropertyReply reply;
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ VERIFY_RR_OUTPUT(stuff->output, output,
+ stuff->delete ? DixWriteAccess : DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
+ client->errorValue = stuff->delete;
+ return BadValue;
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ for (prev = &output->properties; (prop = *prev); prev = &prop->next)
+ if (prop->propertyName == stuff->property)
+ break;
+
+ reply = (xRRGetOutputPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence
+ };
+ if (!prop) {
+ reply.nItems = 0;
+ reply.length = 0;
+ reply.bytesAfter = 0;
+ reply.propertyType = None;
+ reply.format = 0;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xRRGetOutputPropertyReply),
+ &reply);
+ return Success;
+ }
+
+ if (prop->immutable && stuff->delete)
+ return BadAccess;
+
+ prop_value = RRGetOutputProperty(output, stuff->property, stuff->pending);
+ if (!prop_value)
+ return BadAtom;
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != prop_value->type) && (stuff->type != AnyPropertyType))
+ ) {
+ reply.bytesAfter = prop_value->size;
+ reply.format = prop_value->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xRRGetOutputPropertyReply),
+ &reply);
+ return Success;
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (prop_value->format / 8) * prop_value->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind) {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ if (len) {
+ extra = malloc(len);
+ if (!extra)
+ return BadAlloc;
+ }
+ reply.bytesAfter = n - (ind + len);
+ reply.format = prop_value->format;
+ reply.length = bytes_to_int32(len);
+ if (prop_value->format)
+ reply.nItems = len / (prop_value->format / 8);
+ else
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ xRROutputPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_OutputProperty,
+ .output = output->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(output->pScreen, (xEvent *) &event);
+ }
+
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xGenericReply), &reply);
+ if (len) {
+ memcpy(extra, (char *) prop_value->data + ind, len);
+ switch (reply.format) {
+ case 32:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+ break;
+ case 16:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
+ break;
+ default:
+ client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
+ break;
+ }
+ WriteSwappedDataToClient(client, len, extra);
+ free(extra);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */
+ *prev = prop->next;
+ RRDestroyOutputProperty(prop);
+ }
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrprovider.c b/nx-X11/programs/Xserver/randr/rrprovider.c
new file mode 100644
index 000000000..1f884a7b2
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrprovider.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright © 2012 Red Hat Inc.
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ *
+ * Authors: Dave Airlie
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+RESTYPE RRProviderType;
+
+/*
+ * Initialize provider type error value
+ */
+void
+RRProviderInitErrorValue(void)
+{
+#ifndef NXAGENT_SERVER
+ SetResourceTypeErrorValue(RRProviderType, RRErrorBase + BadRRProvider);
+#endif
+}
+
+#define ADD_PROVIDER(_pScreen) do { \
+ pScrPriv = rrGetScrPriv((_pScreen)); \
+ if (pScrPriv->provider) { \
+ providers[count_providers] = pScrPriv->provider->id; \
+ if (client->swapped) \
+ swapl(&providers[count_providers]); \
+ count_providers++; \
+ } \
+ } while(0)
+
+int
+ProcRRGetProviders(ClientPtr client)
+{
+ REQUEST(xRRGetProvidersReq);
+ xRRGetProvidersReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+ CARD8 *extra;
+ unsigned int extraLen;
+ RRProvider *providers;
+ int total_providers = 0, count_providers = 0;
+#ifndef NXAGENT_SERVER
+ ScreenPtr iter;
+#endif
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->provider)
+ total_providers++;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ pScrPriv = rrGetScrPriv(iter);
+ total_providers += pScrPriv->provider ? 1 : 0;
+ }
+#endif
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (!pScrPriv)
+ {
+ rep = (xRRGetProvidersReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = currentTime.milliseconds,
+ .nProviders = 0
+ };
+ extra = NULL;
+ extraLen = 0;
+ } else {
+ rep = (xRRGetProvidersReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .nProviders = total_providers,
+ .length = total_providers
+ };
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = calloc(1, extraLen);
+ if (!extra)
+ return BadAlloc;
+ } else
+ extra = NULL;
+
+ providers = (RRProvider *) extra;
+ ADD_PROVIDER(pScreen);
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ ADD_PROVIDER(iter);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ ADD_PROVIDER(iter);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ ADD_PROVIDER(iter);
+ }
+#endif
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swaps(&rep.nProviders);
+ }
+ WriteToClient(client, sizeof(xRRGetProvidersReply), &rep);
+ if (extraLen)
+ {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRGetProviderInfo(ClientPtr client)
+{
+ REQUEST(xRRGetProviderInfoReq);
+ xRRGetProviderInfoReply rep;
+ rrScrPrivPtr pScrPriv;
+#ifndef NXAGENT_SERVER
+ rrScrPrivPtr pScrProvPriv;
+#endif
+ RRProviderPtr provider;
+ ScreenPtr pScreen;
+ CARD8 *extra;
+ unsigned int extraLen = 0;
+ RRCrtc *crtcs;
+ RROutput *outputs;
+ int i;
+ char *name;
+#ifndef NXAGENT_SERVER
+ ScreenPtr provscreen;
+#endif
+ RRProvider *providers;
+ uint32_t *prov_cap;
+
+ REQUEST_SIZE_MATCH(xRRGetProviderInfoReq);
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep = (xRRGetProviderInfoReply) {
+ .type = X_Reply,
+ .status = RRSetConfigSuccess,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .capabilities = provider->capabilities,
+ .nameLength = provider->nameLength,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .nCrtcs = pScrPriv->numCrtcs,
+ .nOutputs = pScrPriv->numOutputs,
+ .nAssociatedProviders = 0
+ };
+
+ /* count associated providers */
+ if (provider->offload_sink)
+ rep.nAssociatedProviders++;
+ if (provider->output_source)
+ rep.nAssociatedProviders++;
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head)
+ rep.nAssociatedProviders++;
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head)
+ rep.nAssociatedProviders++;
+#endif
+
+ rep.length = (pScrPriv->numCrtcs + pScrPriv->numOutputs +
+ (rep.nAssociatedProviders * 2) + bytes_to_int32(rep.nameLength));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = calloc(1, extraLen);
+ if (!extra)
+ return BadAlloc;
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ outputs = (RROutput *) (crtcs + rep.nCrtcs);
+ providers = (RRProvider *) (outputs + rep.nOutputs);
+ prov_cap = (unsigned int *) (providers + rep.nAssociatedProviders);
+ name = (char *) (prov_cap + rep.nAssociatedProviders);
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ crtcs[i] = pScrPriv->crtcs[i]->id;
+ if (client->swapped)
+ swapl(&crtcs[i]);
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ outputs[i] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i]);
+ }
+
+ i = 0;
+ if (provider->offload_sink) {
+ providers[i] = provider->offload_sink->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SinkOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+ if (provider->output_source) {
+ providers[i] = provider->output_source->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SourceOutput;
+ swapl(&prov_cap[i]);
+ i++;
+ }
+#ifndef NXAGENT_SERVER
+ xorg_list_for_each_entry(provscreen, &pScreen->output_slave_list, output_head) {
+ pScrProvPriv = rrGetScrPriv(provscreen);
+ providers[i] = pScrProvPriv->provider->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SinkOutput;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+ xorg_list_for_each_entry(provscreen, &pScreen->offload_slave_list, offload_head) {
+ pScrProvPriv = rrGetScrPriv(provscreen);
+ providers[i] = pScrProvPriv->provider->id;
+ if (client->swapped)
+ swapl(&providers[i]);
+ prov_cap[i] = RR_Capability_SourceOffload;
+ if (client->swapped)
+ swapl(&prov_cap[i]);
+ i++;
+ }
+#endif
+ memcpy(name, provider->name, rep.nameLength);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.capabilities);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nOutputs);
+ swaps(&rep.nameLength);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderInfoReply), &rep);
+ if (extraLen)
+ {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRSetProviderOutputSource(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOutputSourceReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider, source_provider = NULL;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!(provider->capabilities & RR_Capability_SinkOutput))
+ return BadValue;
+
+ if (stuff->source_provider) {
+ VERIFY_RR_PROVIDER(stuff->source_provider, source_provider, DixReadAccess);
+
+ if (!(source_provider->capabilities & RR_Capability_SourceOutput))
+ return BadValue;
+ }
+
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
+
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
+ RRTellChanged(pScreen);
+
+ return Success;
+}
+
+int
+ProcRRSetProviderOffloadSink(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOffloadSinkReq);
+ rrScrPrivPtr pScrPriv;
+ RRProviderPtr provider, sink_provider = NULL;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+ if (!(provider->capabilities & RR_Capability_SourceOffload))
+ return BadValue;
+#ifndef NXAGENT_SERVER
+ if (!provider->pScreen->isGPU)
+ return BadValue;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (stuff->sink_provider) {
+ VERIFY_RR_PROVIDER(stuff->sink_provider, sink_provider, DixReadAccess);
+ if (!(sink_provider->capabilities & RR_Capability_SinkOffload))
+ return BadValue;
+ }
+ pScreen = provider->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider);
+
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
+ RRTellChanged(pScreen);
+
+ return Success;
+}
+
+RRProviderPtr
+RRProviderCreate(ScreenPtr pScreen, const char *name,
+ int nameLength)
+{
+ RRProviderPtr provider;
+ rrScrPrivPtr pScrPriv;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ provider = calloc(1, sizeof(RRProviderRec) + nameLength + 1);
+ if (!provider)
+ return NULL;
+
+ provider->id = FakeClientID(0);
+ provider->pScreen = pScreen;
+ provider->name = (char *) (provider + 1);
+ provider->nameLength = nameLength;
+ memcpy(provider->name, name, nameLength);
+ provider->name[nameLength] = '\0';
+ provider->changed = FALSE;
+
+ if (!AddResource(provider->id, RRProviderType, (void *) provider))
+ return NULL;
+ pScrPriv->provider = provider;
+ return provider;
+}
+
+/*
+ * Destroy a provider at shutdown
+ */
+void
+RRProviderDestroy(RRProviderPtr provider)
+{
+ FreeResource(provider->id, 0);
+}
+
+void
+RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities)
+{
+ provider->capabilities = capabilities;
+}
+
+static int
+RRProviderDestroyResource(void *value, XID pid)
+{
+ RRProviderPtr provider = (RRProviderPtr) value;
+ ScreenPtr pScreen = provider->pScreen;
+
+ if (pScreen)
+ {
+ rrScrPriv(pScreen);
+
+ if (pScrPriv->rrProviderDestroy)
+ (*pScrPriv->rrProviderDestroy) (pScreen, provider);
+ pScrPriv->provider = NULL;
+ }
+ free(provider);
+ return 1;
+}
+
+Bool
+RRProviderInit(void)
+{
+ RRProviderType = CreateNewResourceType(RRProviderDestroyResource
+#ifndef NXAGENT_SERVER
+ , "Provider"
+#endif /* !defined(NXAGENT_SERVER) */
+ );
+ if (!RRProviderType)
+ return FALSE;
+
+#ifdef NXAGENT_SERVER
+ RegisterResourceName(RRProviderType, "Provider");
+#endif
+
+ return TRUE;
+}
+
+extern _X_EXPORT Bool
+RRProviderLookup(XID id, RRProviderPtr * provider_p)
+{
+#ifndef NXAGENT_SERVER
+ int rc = dixLookupResourceByType((void **) provider_p, id,
+ RRProviderType, NullClient, DixReadAccess);
+ if (rc == Success)
+ return TRUE;
+#else /* !defined(NXAGENT_SERVER) */
+ provider_p = (RRProviderPtr *) LookupIDByType(id, RREventType);
+ if (provider_p)
+ return TRUE;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ return FALSE;
+}
+
+void
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRProviderChangeNotifyEvent pe = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ProviderChange,
+#ifdef NXAGENT_SERVER
+ .sequenceNumber = client->sequence,
+#endif
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id,
+ .provider = provider->id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &pe);
+}
diff --git a/nx-X11/programs/Xserver/randr/rrproviderproperty.c b/nx-X11/programs/Xserver/randr/rrproviderproperty.c
new file mode 100644
index 000000000..1849ed29a
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrproviderproperty.c
@@ -0,0 +1,738 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "propertyst.h"
+#include "swaprep.h"
+
+static int
+DeliverPropertyEvent(WindowPtr pWin, void *value)
+{
+ xRRProviderPropertyNotifyEvent *event = value;
+ RREventPtr *pHead, pRREvent;
+
+#ifndef NXAGENT_SERVER
+ dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
+ RREventType, serverClient, DixReadAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+#endif /* !defined(NXAGENT_SERVER) */
+ if (!pHead)
+ return WT_WALKCHILDREN;
+
+ for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+ if (!(pRREvent->mask & RRProviderPropertyNotifyMask))
+ continue;
+
+ event->window = pRREvent->window->drawable.id;
+ WriteEventsToClient(pRREvent->client, 1, (xEvent *) event);
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
+{
+ if (!(dispatchException & (DE_RESET | DE_TERMINATE)))
+ WalkTree(pScreen, DeliverPropertyEvent, event);
+}
+
+static void
+RRDestroyProviderProperty(RRPropertyPtr prop)
+{
+ free(prop->valid_values);
+ free(prop->current.data);
+ free(prop->pending.data);
+ free(prop);
+}
+
+static void
+RRDeleteProperty(RRProviderRec * provider, RRPropertyRec * prop)
+{
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+
+ RRDestroyProviderProperty(prop);
+}
+
+void
+RRDeleteAllProviderProperties(RRProviderPtr provider)
+{
+ RRPropertyPtr prop, next;
+
+ for (prop = provider->properties; prop; prop = next) {
+ next = prop->next;
+ RRDeleteProperty(provider, prop);
+ }
+}
+
+static void
+RRInitProviderPropertyValue(RRPropertyValuePtr property_value)
+{
+ property_value->type = None;
+ property_value->format = 0;
+ property_value->size = 0;
+ property_value->data = NULL;
+}
+
+static RRPropertyPtr
+RRCreateProviderProperty(Atom property)
+{
+ RRPropertyPtr prop;
+
+ prop = (RRPropertyPtr) malloc(sizeof(RRPropertyRec));
+ if (!prop)
+ return NULL;
+ prop->next = NULL;
+ prop->propertyName = property;
+ prop->is_pending = FALSE;
+ prop->range = FALSE;
+ prop->immutable = FALSE;
+ prop->num_valid = 0;
+ prop->valid_values = NULL;
+ RRInitProviderPropertyValue(&prop->current);
+ RRInitProviderPropertyValue(&prop->pending);
+ return prop;
+}
+
+void
+RRDeleteProviderProperty(RRProviderPtr provider, Atom property)
+{
+ RRPropertyRec *prop, **prev;
+
+ for (prev = &provider->properties; (prop = *prev); prev = &(prop->next))
+ if (prop->propertyName == property) {
+ *prev = prop->next;
+ RRDeleteProperty(provider, prop);
+ return;
+ }
+}
+
+int
+RRChangeProviderProperty(RRProviderPtr provider, Atom property, Atom type,
+ int format, int mode, unsigned long len,
+ void *value, Bool sendevent, Bool pending)
+{
+ RRPropertyPtr prop;
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen);
+ int size_in_bytes;
+ int total_size;
+ unsigned long total_len;
+ RRPropertyValuePtr prop_value;
+ RRPropertyValueRec new_value;
+ Bool add = FALSE;
+
+ size_in_bytes = format >> 3;
+
+ /* first see if property already exists */
+ prop = RRQueryProviderProperty(provider, property);
+ if (!prop) { /* just add to list */
+ prop = RRCreateProviderProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ mode = PropModeReplace;
+ }
+ if (pending && prop->is_pending)
+ prop_value = &prop->pending;
+ else
+ prop_value = &prop->current;
+
+ /* To append or prepend to a property the request format and type
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
+
+ if ((format != prop_value->format) && (mode != PropModeReplace))
+ return BadMatch;
+ if ((prop_value->type != type) && (mode != PropModeReplace))
+ return BadMatch;
+ new_value = *prop_value;
+ if (mode == PropModeReplace)
+ total_len = len;
+ else
+ total_len = prop_value->size + len;
+
+ if (mode == PropModeReplace || len > 0) {
+ void *new_data = NULL, *old_data = NULL;
+
+ total_size = total_len * size_in_bytes;
+ new_value.data = (void *) malloc(total_size);
+ if (!new_value.data && total_size) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadAlloc;
+ }
+ new_value.size = len;
+ new_value.type = type;
+ new_value.format = format;
+
+ switch (mode) {
+ case PropModeReplace:
+ new_data = new_value.data;
+ old_data = NULL;
+ break;
+ case PropModeAppend:
+ new_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ old_data = new_value.data;
+ break;
+ case PropModePrepend:
+ new_data = new_value.data;
+ old_data = (void *) (((char *) new_value.data) +
+ (prop_value->size * size_in_bytes));
+ break;
+ }
+ if (new_data)
+ memcpy((char *) new_data, (char *) value, len * size_in_bytes);
+ if (old_data)
+ memcpy((char *) old_data, (char *) prop_value->data,
+ prop_value->size * size_in_bytes);
+
+ if (pending && pScrPriv->rrProviderSetProperty &&
+ !pScrPriv->rrProviderSetProperty(provider->pScreen, provider,
+ prop->propertyName, &new_value)) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ free(new_value.data);
+ return BadValue;
+ }
+ free(prop_value->data);
+ *prop_value = new_value;
+ }
+
+ else if (len == 0) {
+ /* do nothing */
+ }
+
+ if (add) {
+ prop->next = provider->properties;
+ provider->properties = prop;
+ }
+
+ if (pending && prop->is_pending)
+ provider->pendingProperties = TRUE;
+
+ if (sendevent) {
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyNewValue,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+ }
+ return Success;
+}
+
+Bool
+RRPostProviderPendingProperties(RRProviderPtr provider)
+{
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+ RRPropertyPtr property;
+ Bool ret = TRUE;
+
+ if (!provider->pendingProperties)
+ return TRUE;
+
+ provider->pendingProperties = FALSE;
+ for (property = provider->properties; property; property = property->next) {
+ /* Skip non-pending properties */
+ if (!property->is_pending)
+ continue;
+
+ pending_value = &property->pending;
+ current_value = &property->current;
+
+ /*
+ * If the pending and current values are equal, don't mark it
+ * as changed (which would deliver an event)
+ */
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp(pending_value->data, current_value->data,
+ pending_value->size * (pending_value->format / 8)))
+ continue;
+
+ if (RRChangeProviderProperty(provider, property->propertyName,
+ pending_value->type, pending_value->format,
+ PropModeReplace, pending_value->size,
+ pending_value->data, TRUE, FALSE) != Success)
+ ret = FALSE;
+ }
+ return ret;
+}
+
+RRPropertyPtr
+RRQueryProviderProperty(RRProviderPtr provider, Atom property)
+{
+ RRPropertyPtr prop;
+
+ for (prop = provider->properties; prop; prop = prop->next)
+ if (prop->propertyName == property)
+ return prop;
+ return NULL;
+}
+
+RRPropertyValuePtr
+RRGetProviderProperty(RRProviderPtr provider, Atom property, Bool pending)
+{
+ RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
+ rrScrPrivPtr pScrPriv = rrGetScrPriv(provider->pScreen);
+
+ if (!prop)
+ return NULL;
+ if (pending && prop->is_pending)
+ return &prop->pending;
+ else {
+#if RANDR_13_INTERFACE
+ /* If we can, try to update the property value first */
+ if (pScrPriv->rrProviderGetProperty)
+ pScrPriv->rrProviderGetProperty(provider->pScreen, provider,
+ prop->propertyName);
+#endif
+ return &prop->current;
+ }
+}
+
+int
+RRConfigureProviderProperty(RRProviderPtr provider, Atom property,
+ Bool pending, Bool range, Bool immutable,
+ int num_values, INT32 *values)
+{
+ RRPropertyPtr prop = RRQueryProviderProperty(provider, property);
+ Bool add = FALSE;
+ INT32 *new_values;
+
+ if (!prop) {
+ prop = RRCreateProviderProperty(property);
+ if (!prop)
+ return BadAlloc;
+ add = TRUE;
+ }
+ else if (prop->immutable && !immutable)
+ return BadAccess;
+
+ /*
+ * ranges must have even number of values
+ */
+ if (range && (num_values & 1)) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadMatch;
+ }
+
+ new_values = xallocarray(num_values, sizeof(INT32));
+
+ if (!new_values && num_values) {
+ if (add)
+ RRDestroyProviderProperty(prop);
+ return BadAlloc;
+ }
+ if (num_values)
+ memcpy(new_values, values, num_values * sizeof(INT32));
+
+ /*
+ * Property moving from pending to non-pending
+ * loses any pending values
+ */
+ if (prop->is_pending && !pending) {
+ free(prop->pending.data);
+ RRInitProviderPropertyValue(&prop->pending);
+ }
+
+ prop->is_pending = pending;
+ prop->range = range;
+ prop->immutable = immutable;
+ prop->num_valid = num_values;
+ free(prop->valid_values);
+ prop->valid_values = new_values;
+
+ if (add) {
+ prop->next = provider->properties;
+ provider->properties = prop;
+ }
+
+ return Success;
+}
+
+int
+ProcRRListProviderProperties(ClientPtr client)
+{
+ REQUEST(xRRListProviderPropertiesReq);
+ Atom *pAtoms = NULL, *temppAtoms;
+ xRRListProviderPropertiesReply rep;
+ int numProps = 0;
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+
+ REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ for (prop = provider->properties; prop; prop = prop->next)
+ numProps++;
+ if (numProps)
+ if (!(pAtoms = xallocarray(numProps, sizeof(Atom))))
+ return BadAlloc;
+
+ rep = (xRRListProviderPropertiesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(numProps * sizeof(Atom)),
+ .nAtoms = numProps
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.nAtoms);
+ }
+ temppAtoms = pAtoms;
+ for (prop = provider->properties; prop; prop = prop->next)
+ *temppAtoms++ = prop->propertyName;
+
+ WriteToClient(client, sizeof(xRRListProviderPropertiesReply),
+ &rep);
+ if (numProps) {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+ free(pAtoms);
+ }
+ return Success;
+}
+
+int
+ProcRRQueryProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRQueryProviderPropertyReq);
+ xRRQueryProviderPropertyReply rep;
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ prop = RRQueryProviderProperty(provider, stuff->property);
+ if (!prop)
+ return BadName;
+
+ if (prop->num_valid) {
+ extra = xallocarray(prop->num_valid, sizeof(INT32));
+ if (!extra)
+ return BadAlloc;
+ }
+ rep = (xRRQueryProviderPropertyReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = prop->num_valid,
+ .pending = prop->is_pending,
+ .range = prop->range,
+ .immutable = prop->immutable
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+ WriteToClient(client, sizeof(xRRQueryProviderPropertyReply), &rep);
+ if (prop->num_valid) {
+ memcpy(extra, prop->valid_values, prop->num_valid * sizeof(INT32));
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, prop->num_valid * sizeof(INT32),
+ extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRConfigureProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRConfigureProviderPropertyReq);
+ RRProviderPtr provider;
+ int num_valid;
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ num_valid =
+ stuff->length - bytes_to_int32(sizeof(xRRConfigureProviderPropertyReq));
+ return RRConfigureProviderProperty(provider, stuff->property, stuff->pending,
+ stuff->range, FALSE, num_valid,
+ (INT32 *) (stuff + 1));
+}
+
+int
+ProcRRChangeProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRChangeProviderPropertyReq);
+ RRProviderPtr provider;
+ char format, mode;
+ unsigned long len;
+ int sizeInBytes;
+ int totalSize;
+ int err;
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend)) {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32)) {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > bytes_to_int32((0xffffffff - sizeof(xChangePropertyReq))))
+ return BadLength;
+ sizeInBytes = format >> 3;
+ totalSize = len * sizeInBytes;
+ REQUEST_FIXED_SIZE(xRRChangeProviderPropertyReq, totalSize);
+
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if (!ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ err = RRChangeProviderProperty(provider, stuff->property,
+ stuff->type, (int) format,
+ (int) mode, len, (void *) &stuff[1], TRUE,
+ TRUE);
+ if (err != Success)
+ return err;
+ else
+ return Success;
+}
+
+int
+ProcRRDeleteProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRDeleteProviderPropertyReq);
+ RRProviderPtr provider;
+ RRPropertyPtr prop;
+
+ REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq);
+ UpdateCurrentTime();
+ VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+
+ prop = RRQueryProviderProperty(provider, stuff->property);
+ if (!prop) {
+ client->errorValue = stuff->property;
+ return BadName;
+ }
+
+ if (prop->immutable) {
+ client->errorValue = stuff->property;
+ return BadAccess;
+ }
+
+ RRDeleteProviderProperty(provider, stuff->property);
+ return Success;
+}
+
+int
+ProcRRGetProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRGetProviderPropertyReq);
+ RRPropertyPtr prop, *prev;
+ RRPropertyValuePtr prop_value;
+ unsigned long n, len, ind;
+ RRProviderPtr provider;
+ xRRGetProviderPropertyReply reply = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence
+ };
+ char *extra = NULL;
+
+ REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ VERIFY_RR_PROVIDER(stuff->provider, provider,
+ stuff->delete ? DixWriteAccess : DixReadAccess);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return BadAtom;
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
+ client->errorValue = stuff->delete;
+ return BadValue;
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return BadAtom;
+ }
+
+ for (prev = &provider->properties; (prop = *prev); prev = &prop->next)
+ if (prop->propertyName == stuff->property)
+ break;
+
+ if (!prop) {
+ reply.nItems = 0;
+ reply.length = 0;
+ reply.bytesAfter = 0;
+ reply.propertyType = None;
+ reply.format = 0;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderPropertyReply),
+ &reply);
+ return Success;
+ }
+
+ if (prop->immutable && stuff->delete)
+ return BadAccess;
+
+ prop_value = RRGetProviderProperty(provider, stuff->property, stuff->pending);
+ if (!prop_value)
+ return BadAtom;
+
+ /* If the request type and actual type don't match. Return the
+ property information, but not the data. */
+
+ if (((stuff->type != prop_value->type) && (stuff->type != AnyPropertyType))
+ ) {
+ reply.bytesAfter = prop_value->size;
+ reply.format = prop_value->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xRRGetProviderPropertyReply),
+ &reply);
+ return Success;
+ }
+
+/*
+ * Return type, format, value to client
+ */
+ n = (prop_value->format / 8) * prop_value->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /* If longOffset is invalid such that it causes "len" to
+ be negative, it's a value error. */
+
+ if (n < ind) {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ len = min(n - ind, 4 * stuff->longLength);
+
+ if (len) {
+ extra = malloc(len);
+ if (!extra)
+ return BadAlloc;
+ }
+ reply.bytesAfter = n - (ind + len);
+ reply.format = prop_value->format;
+ reply.length = bytes_to_int32(len);
+ if (prop_value->format)
+ reply.nItems = len / (prop_value->format / 8);
+ else
+ reply.nItems = 0;
+ reply.propertyType = prop_value->type;
+
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ xRRProviderPropertyNotifyEvent event = {
+ .type = RREventBase + RRNotify,
+ .subCode = RRNotify_ProviderProperty,
+ .provider = provider->id,
+ .state = PropertyDelete,
+ .atom = prop->propertyName,
+ .timestamp = currentTime.milliseconds
+ };
+ RRDeliverPropertyEvent(provider->pScreen, (xEvent *) &event);
+ }
+
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.propertyType);
+ swapl(&reply.bytesAfter);
+ swapl(&reply.nItems);
+ }
+ WriteToClient(client, sizeof(xGenericReply), &reply);
+ if (len) {
+ memcpy(extra, (char *) prop_value->data + ind, len);
+ switch (reply.format) {
+ case 32:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+ break;
+ case 16:
+ client->pSwapReplyFunc = (ReplySwapPtr) CopySwap16Write;
+ break;
+ default:
+ client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
+ break;
+ }
+ WriteSwappedDataToClient(client, len, extra);
+ free(extra);
+ }
+
+ if (stuff->delete && (reply.bytesAfter == 0)) { /* delete the Property */
+ *prev = prop->next;
+ RRDestroyProviderProperty(prop);
+ }
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrscreen.c b/nx-X11/programs/Xserver/randr/rrscreen.c
new file mode 100644
index 000000000..4f59e9aea
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrscreen.c
@@ -0,0 +1,1207 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+
+static CARD16
+ RR10CurrentSizeID(ScreenPtr pScreen);
+
+/*
+ * Edit connection information block so that new clients
+ * see the current screen size on connect
+ */
+static void
+RREditConnectionInfo(ScreenPtr pScreen)
+{
+ xConnSetup *connSetup;
+ char *vendor;
+ xPixmapFormat *formats;
+ xWindowRoot *root;
+ xDepth *depth;
+ xVisualType *visual;
+ int screen = 0;
+ int d;
+
+ connSetup = (xConnSetup *) ConnectionInfo;
+ vendor = (char *) connSetup + sizeof(xConnSetup);
+ formats = (xPixmapFormat *) ((char *) vendor +
+ pad_to_int32(connSetup->nbytesVendor));
+ root = (xWindowRoot *) ((char *) formats +
+ sizeof(xPixmapFormat) *
+ screenInfo.numPixmapFormats);
+ while (screen != pScreen->myNum) {
+ depth = (xDepth *) ((char *) root + sizeof(xWindowRoot));
+ for (d = 0; d < root->nDepths; d++) {
+ visual = (xVisualType *) ((char *) depth + sizeof(xDepth));
+ depth = (xDepth *) ((char *) visual +
+ depth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *) ((char *) depth);
+ screen++;
+ }
+ root->pixWidth = pScreen->width;
+ root->pixHeight = pScreen->height;
+ root->mmWidth = pScreen->mmWidth;
+ root->mmHeight = pScreen->mmHeight;
+}
+
+void
+RRSendConfigNotify(ScreenPtr pScreen)
+{
+ WindowPtr pWin = pScreen->root;
+ xEvent event = {
+ .u.configureNotify.window = pWin->drawable.id,
+ .u.configureNotify.aboveSibling = None,
+ .u.configureNotify.x = 0,
+ .u.configureNotify.y = 0,
+
+ /* XXX xinerama stuff ? */
+
+ .u.configureNotify.width = pWin->drawable.width,
+ .u.configureNotify.height = pWin->drawable.height,
+ .u.configureNotify.borderWidth = wBorderWidth(pWin),
+ .u.configureNotify.override = pWin->overrideRedirect
+ };
+ event.u.u.type = ConfigureNotify;
+ DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+void
+RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ RRCrtcPtr crtc = pScrPriv->numCrtcs ? pScrPriv->crtcs[0] : NULL;
+ WindowPtr pRoot = pScreen->root;
+
+ xRRScreenChangeNotifyEvent se = {
+ .type = RRScreenChangeNotify + RREventBase,
+ .rotation = (CARD8) (crtc ? crtc->rotation : RR_Rotate_0),
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .root = pRoot->drawable.id,
+ .window = pWin->drawable.id,
+ .subpixelOrder = PictureGetSubpixelOrder(pScreen),
+
+ .sizeID = RR10CurrentSizeID(pScreen)
+ };
+
+ if (se.rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ se.widthInPixels = pScreen->height;
+ se.heightInPixels = pScreen->width;
+ se.widthInMillimeters = pScreen->mmHeight;
+ se.heightInMillimeters = pScreen->mmWidth;
+ }
+ else {
+ se.widthInPixels = pScreen->width;
+ se.heightInPixels = pScreen->height;
+ se.widthInMillimeters = pScreen->mmWidth;
+ se.heightInMillimeters = pScreen->mmHeight;
+ }
+
+ WriteEventsToClient(client, 1, (xEvent *) (char *) &se);
+}
+
+/*
+ * Notify the extension that the screen size has been changed.
+ * The driver is responsible for calling this whenever it has changed
+ * the size of the screen
+ */
+void
+RRScreenSizeNotify(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ /*
+ * Deliver ConfigureNotify events when root changes
+ * pixel size
+ */
+ if (pScrPriv->width == pScreen->width &&
+ pScrPriv->height == pScreen->height &&
+ pScrPriv->mmWidth == pScreen->mmWidth &&
+ pScrPriv->mmHeight == pScreen->mmHeight)
+ return;
+
+ pScrPriv->width = pScreen->width;
+ pScrPriv->height = pScreen->height;
+ pScrPriv->mmWidth = pScreen->mmWidth;
+ pScrPriv->mmHeight = pScreen->mmHeight;
+ RRSetChanged(pScreen);
+/* pScrPriv->sizeChanged = TRUE; */
+
+ RRTellChanged(pScreen);
+ RRSendConfigNotify(pScreen);
+ RREditConnectionInfo(pScreen);
+
+ RRPointerScreenConfigured(pScreen);
+ /*
+ * Fix pointer bounds and location
+ */
+ ScreenRestructured(pScreen);
+}
+
+/*
+ * Request that the screen be resized
+ */
+Bool
+RRScreenSizeSet(ScreenPtr pScreen,
+ CARD16 width, CARD16 height, CARD32 mmWidth, CARD32 mmHeight)
+{
+ rrScrPriv(pScreen);
+
+#if RANDR_12_INTERFACE
+ if (pScrPriv->rrScreenSetSize) {
+ return (*pScrPriv->rrScreenSetSize) (pScreen,
+ width, height, mmWidth, mmHeight);
+ }
+#endif
+#if RANDR_10_INTERFACE
+ if (pScrPriv->rrSetConfig) {
+ return TRUE; /* can't set size separately */
+ }
+#endif
+ return FALSE;
+}
+
+/*
+ * Retrieve valid screen size range
+ */
+int
+ProcRRGetScreenSizeRange(ClientPtr client)
+{
+ REQUEST(xRRGetScreenSizeRangeReq);
+ xRRGetScreenSizeRangeReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ rep = (xRRGetScreenSizeRangeReply) {
+ .type = X_Reply,
+ .pad = 0,
+ .sequenceNumber = client->sequence,
+ .length = 0
+ };
+
+ if (pScrPriv) {
+ if (!RRGetInfo(pScreen, FALSE))
+ return BadAlloc;
+ rep.minWidth = pScrPriv->minWidth;
+ rep.minHeight = pScrPriv->minHeight;
+ rep.maxWidth = pScrPriv->maxWidth;
+ rep.maxHeight = pScrPriv->maxHeight;
+ }
+ else {
+ rep.maxWidth = rep.minWidth = pScreen->width;
+ rep.maxHeight = rep.minHeight = pScreen->height;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.minWidth);
+ swaps(&rep.minHeight);
+ swaps(&rep.maxWidth);
+ swaps(&rep.maxHeight);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenSizeRangeReply), &rep);
+ return Success;
+}
+
+int
+ProcRRSetScreenSize(ClientPtr client)
+{
+ REQUEST(xRRSetScreenSizeReq);
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ int i, rc;
+
+ REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ if (!pScrPriv)
+ return BadMatch;
+
+ if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width) {
+ client->errorValue = stuff->width;
+ return BadValue;
+ }
+ if (stuff->height < pScrPriv->minHeight ||
+ pScrPriv->maxHeight < stuff->height) {
+ client->errorValue = stuff->height;
+ return BadValue;
+ }
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+ RRModePtr mode = crtc->mode;
+
+ if (mode) {
+ int source_width = mode->mode.width;
+ int source_height = mode->mode.height;
+ Rotation rotation = crtc->rotation;
+
+ if (rotation == RR_Rotate_90 || rotation == RR_Rotate_270) {
+ source_width = mode->mode.height;
+ source_height = mode->mode.width;
+ }
+
+ if (crtc->x + source_width > stuff->width ||
+ crtc->y + source_height > stuff->height)
+ return BadMatch;
+ }
+ }
+ if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0) {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (!RRScreenSizeSet(pScreen,
+ stuff->width, stuff->height,
+ stuff->widthInMillimeters,
+ stuff->heightInMillimeters)) {
+ return BadMatch;
+ }
+ return Success;
+}
+
+
+#define update_totals(gpuscreen, pScrPriv) do { \
+ total_crtcs += pScrPriv->numCrtcs; \
+ total_outputs += pScrPriv->numOutputs; \
+ modes = RRModesForScreen(gpuscreen, &num_modes); \
+ if (!modes) \
+ return BadAlloc; \
+ for (j = 0; j < num_modes; j++) \
+ total_name_len += modes[j]->mode.nameLength; \
+ total_modes += num_modes; \
+ free(modes); \
+} while(0)
+
+static inline void
+swap_modeinfos(xRRModeInfo * modeinfos, int i)
+{
+ swapl(&modeinfos[i].id);
+ swaps(&modeinfos[i].width);
+ swaps(&modeinfos[i].height);
+ swapl(&modeinfos[i].dotClock);
+ swaps(&modeinfos[i].hSyncStart);
+ swaps(&modeinfos[i].hSyncEnd);
+ swaps(&modeinfos[i].hTotal);
+ swaps(&modeinfos[i].hSkew);
+ swaps(&modeinfos[i].vSyncStart);
+ swaps(&modeinfos[i].vSyncEnd);
+ swaps(&modeinfos[i].vTotal);
+ swaps(&modeinfos[i].nameLength);
+ swapl(&modeinfos[i].modeFlags);
+}
+
+#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do { \
+ for (j = 0; j < pScrPriv->numCrtcs; j++) { \
+ if (has_primary && \
+ primary_crtc == pScrPriv->crtcs[j]) { \
+ has_primary = 0; \
+ continue; \
+ }\
+ crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \
+ if (client->swapped) \
+ swapl(&crtcs[crtc_count]); \
+ crtc_count++; \
+ } \
+ for (j = 0; j < pScrPriv->numOutputs; j++) { \
+ outputs[output_count] = pScrPriv->outputs[j]->id; \
+ if (client->swapped) \
+ swapl(&outputs[output_count]); \
+ output_count++; \
+ } \
+ { \
+ RRModePtr mode; \
+ modes = RRModesForScreen(gpuscreen, &num_modes); \
+ for (j = 0; j < num_modes; j++) { \
+ mode = modes[j]; \
+ modeinfos[mode_count] = mode->mode; \
+ if (client->swapped) { \
+ swap_modeinfos(modeinfos, mode_count); \
+ } \
+ memcpy(names, mode->name, mode->mode.nameLength); \
+ names += mode->mode.nameLength; \
+ mode_count++; \
+ } \
+ free(modes); \
+ } \
+ } while (0)
+
+#ifndef NXAGENT_SERVER
+static int
+rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
+{
+ int j;
+ int total_crtcs, total_outputs, total_modes, total_name_len;
+ int crtc_count, output_count, mode_count;
+ ScreenPtr iter;
+ rrScrPrivPtr pScrPriv;
+ int num_modes;
+ RRModePtr *modes;
+ xRRGetScreenResourcesReply rep;
+ unsigned long extraLen;
+ CARD8 *extra;
+ RRCrtc *crtcs;
+ RRCrtcPtr primary_crtc = NULL;
+ RROutput *outputs;
+ xRRModeInfo *modeinfos;
+ CARD8 *names;
+ int has_primary = 0;
+
+ /* we need to iterate all the GPU masters and all their output slaves */
+ total_crtcs = 0;
+ total_outputs = 0;
+ total_modes = 0;
+ total_name_len = 0;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (query && pScrPriv)
+ if (!RRGetInfo(pScreen, query))
+ return BadAlloc;
+
+ update_totals(pScreen, pScrPriv);
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+
+ if (query)
+ if (!RRGetInfo(iter, query))
+ return BadAlloc;
+ update_totals(iter, pScrPriv);
+ }
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .nCrtcs = total_crtcs,
+ .nOutputs = total_outputs,
+ .nModes = total_modes,
+ .nbytesNames = total_name_len
+ };
+
+ rep.length = (total_crtcs + total_outputs +
+ total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
+ bytes_to_int32(total_name_len));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = calloc(1,extraLen);
+ if (!extra) {
+ return BadAlloc;
+ }
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ outputs = (RROutput *) (crtcs + total_crtcs);
+ modeinfos = (xRRModeInfo *) (outputs + total_outputs);
+ names = (CARD8 *) (modeinfos + total_modes);
+
+ crtc_count = 0;
+ output_count = 0;
+ mode_count = 0;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+ has_primary = 1;
+ primary_crtc = pScrPriv->primaryOutput->crtc;
+ crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+ if (client->swapped)
+ swapl(&crtcs[0]);
+ crtc_count = 1;
+ }
+ update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pScrPriv = rrGetScrPriv(iter);
+
+ update_arrays(iter, pScrPriv, primary_crtc, has_primary);
+ }
+
+ assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.configTimestamp);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nOutputs);
+ swaps(&rep.nModes);
+ swaps(&rep.nbytesNames);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenResourcesReply), &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+ return Success;
+}
+#endif /* !defined(NXAGENT_SERVER) */
+
+static int
+rrGetScreenResources(ClientPtr client, Bool query)
+{
+ REQUEST(xRRGetScreenResourcesReq);
+ xRRGetScreenResourcesReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ CARD8 *extra;
+ unsigned long extraLen;
+ int i, rc, has_primary = 0;
+ RRCrtc *crtcs;
+ RROutput *outputs;
+ xRRModeInfo *modeinfos;
+ CARD8 *names;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
+
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (query && pScrPriv)
+ if (!RRGetInfo(pScreen, query))
+ return BadAlloc;
+
+#ifndef NXAGENT_SERVER
+ if (!xorg_list_is_empty(&pScreen->output_slave_list))
+ return rrGetMultiScreenResources(client, query, pScreen);
+#endif
+
+ if (!pScrPriv) {
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = currentTime.milliseconds,
+ .configTimestamp = currentTime.milliseconds,
+ .nCrtcs = 0,
+ .nOutputs = 0,
+ .nModes = 0,
+ .nbytesNames = 0
+ };
+ extra = NULL;
+ extraLen = 0;
+ }
+ else {
+ RRModePtr *modes;
+ int num_modes;
+
+ modes = RRModesForScreen(pScreen, &num_modes);
+ if (!modes)
+ return BadAlloc;
+
+ rep = (xRRGetScreenResourcesReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .nCrtcs = pScrPriv->numCrtcs,
+ .nOutputs = pScrPriv->numOutputs,
+ .nModes = num_modes,
+ .nbytesNames = 0
+ };
+
+ for (i = 0; i < num_modes; i++)
+ rep.nbytesNames += modes[i]->mode.nameLength;
+
+ rep.length = (pScrPriv->numCrtcs +
+ pScrPriv->numOutputs +
+ num_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) +
+ bytes_to_int32(rep.nbytesNames));
+
+ extraLen = rep.length << 2;
+ if (extraLen) {
+ extra = calloc(1, extraLen);
+ if (!extra) {
+ free(modes);
+ return BadAlloc;
+ }
+ }
+ else
+ extra = NULL;
+
+ crtcs = (RRCrtc *) extra;
+ outputs = (RROutput *) (crtcs + pScrPriv->numCrtcs);
+ modeinfos = (xRRModeInfo *) (outputs + pScrPriv->numOutputs);
+ names = (CARD8 *) (modeinfos + num_modes);
+
+ if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
+ has_primary = 1;
+ crtcs[0] = pScrPriv->primaryOutput->crtc->id;
+ if (client->swapped)
+ swapl(&crtcs[0]);
+ }
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ if (has_primary &&
+ pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
+ has_primary = 0;
+ continue;
+ }
+ crtcs[i + has_primary] = pScrPriv->crtcs[i]->id;
+ if (client->swapped)
+ swapl(&crtcs[i + has_primary]);
+ }
+
+ for (i = 0; i < pScrPriv->numOutputs; i++) {
+ outputs[i] = pScrPriv->outputs[i]->id;
+ if (client->swapped)
+ swapl(&outputs[i]);
+ }
+
+ for (i = 0; i < num_modes; i++) {
+ RRModePtr mode = modes[i];
+
+ modeinfos[i] = mode->mode;
+ if (client->swapped) {
+ swapl(&modeinfos[i].id);
+ swaps(&modeinfos[i].width);
+ swaps(&modeinfos[i].height);
+ swapl(&modeinfos[i].dotClock);
+ swaps(&modeinfos[i].hSyncStart);
+ swaps(&modeinfos[i].hSyncEnd);
+ swaps(&modeinfos[i].hTotal);
+ swaps(&modeinfos[i].hSkew);
+ swaps(&modeinfos[i].vSyncStart);
+ swaps(&modeinfos[i].vSyncEnd);
+ swaps(&modeinfos[i].vTotal);
+ swaps(&modeinfos[i].nameLength);
+ swapl(&modeinfos[i].modeFlags);
+ }
+ memcpy(names, mode->name, mode->mode.nameLength);
+ names += mode->mode.nameLength;
+ }
+ free(modes);
+ assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
+ }
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.configTimestamp);
+ swaps(&rep.nCrtcs);
+ swaps(&rep.nOutputs);
+ swaps(&rep.nModes);
+ swaps(&rep.nbytesNames);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenResourcesReply),
+ (char *) &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRGetScreenResources(ClientPtr client)
+{
+ return rrGetScreenResources(client, TRUE);
+}
+
+int
+ProcRRGetScreenResourcesCurrent(ClientPtr client)
+{
+ return rrGetScreenResources(client, FALSE);
+}
+
+typedef struct _RR10Data {
+ RRScreenSizePtr sizes;
+ int nsize;
+ int nrefresh;
+ int size;
+ CARD16 refresh;
+} RR10DataRec, *RR10DataPtr;
+
+/*
+ * Convert 1.2 monitor data into 1.0 screen data
+ */
+static RR10DataPtr
+RR10GetData(ScreenPtr pScreen, RROutputPtr output)
+{
+ RR10DataPtr data;
+ RRScreenSizePtr size;
+ int nmode = output->numModes + output->numUserModes;
+ int o, os, l, r;
+ RRScreenRatePtr refresh;
+ CARD16 vRefresh;
+ RRModePtr mode;
+ Bool *used;
+
+ /* Make sure there is plenty of space for any combination */
+ data = malloc(sizeof(RR10DataRec) +
+ sizeof(RRScreenSize) * nmode +
+ sizeof(RRScreenRate) * nmode + sizeof(Bool) * nmode);
+ if (!data)
+ return NULL;
+ size = (RRScreenSizePtr) (data + 1);
+ refresh = (RRScreenRatePtr) (size + nmode);
+ used = (Bool *) (refresh + nmode);
+ memset(used, '\0', sizeof(Bool) * nmode);
+ data->sizes = size;
+ data->nsize = 0;
+ data->nrefresh = 0;
+ data->size = 0;
+ data->refresh = 0;
+
+ /*
+ * find modes not yet listed
+ */
+ for (o = 0; o < output->numModes + output->numUserModes; o++) {
+ if (used[o])
+ continue;
+
+ if (o < output->numModes)
+ mode = output->modes[o];
+ else
+ mode = output->userModes[o - output->numModes];
+
+ l = data->nsize;
+ size[l].id = data->nsize;
+ size[l].width = mode->mode.width;
+ size[l].height = mode->mode.height;
+ if (output->mmWidth && output->mmHeight) {
+ size[l].mmWidth = output->mmWidth;
+ size[l].mmHeight = output->mmHeight;
+ }
+ else {
+ size[l].mmWidth = pScreen->mmWidth;
+ size[l].mmHeight = pScreen->mmHeight;
+ }
+ size[l].nRates = 0;
+ size[l].pRates = &refresh[data->nrefresh];
+ data->nsize++;
+
+ /*
+ * Find all modes with matching size
+ */
+ for (os = o; os < output->numModes + output->numUserModes; os++) {
+ if (os < output->numModes)
+ mode = output->modes[os];
+ else
+ mode = output->userModes[os - output->numModes];
+ if (mode->mode.width == size[l].width &&
+ mode->mode.height == size[l].height) {
+ vRefresh = RRVerticalRefresh(&mode->mode);
+ used[os] = TRUE;
+
+ for (r = 0; r < size[l].nRates; r++)
+ if (vRefresh == size[l].pRates[r].rate)
+ break;
+ if (r == size[l].nRates) {
+ size[l].pRates[r].rate = vRefresh;
+ size[l].pRates[r].mode = mode;
+ size[l].nRates++;
+ data->nrefresh++;
+ }
+ if (mode == output->crtc->mode) {
+ data->size = l;
+ data->refresh = vRefresh;
+ }
+ }
+ }
+ }
+ return data;
+}
+
+int
+ProcRRGetScreenInfo(ClientPtr client)
+{
+ REQUEST(xRRGetScreenInfoReq);
+ xRRGetScreenInfoReply rep;
+ WindowPtr pWin;
+ int rc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ CARD8 *extra;
+ unsigned long extraLen;
+ RROutputPtr output;
+
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv)
+ if (!RRGetInfo(pScreen, TRUE))
+ return BadAlloc;
+
+ output = RRFirstOutput(pScreen);
+
+ if (!pScrPriv || !output) {
+ rep = (xRRGetScreenInfoReply) {
+ .type = X_Reply,
+ .setOfRotations = RR_Rotate_0,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .root = pWin->drawable.pScreen->root->drawable.id,
+ .timestamp = currentTime.milliseconds,
+ .configTimestamp = currentTime.milliseconds,
+ .nSizes = 0,
+ .sizeID = 0,
+ .rotation = RR_Rotate_0,
+ .rate = 0,
+ .nrateEnts = 0
+ };
+ extra = 0;
+ extraLen = 0;
+ }
+ else {
+ int i, j;
+ xScreenSizes *size;
+ CARD16 *rates;
+ CARD8 *data8;
+ Bool has_rate = RRClientKnowsRates(client);
+ RR10DataPtr pData;
+ RRScreenSizePtr pSize;
+
+ pData = RR10GetData(pScreen, output);
+ if (!pData)
+ return BadAlloc;
+
+ rep = (xRRGetScreenInfoReply) {
+ .type = X_Reply,
+ .setOfRotations = output->crtc->rotations,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .root = pWin->drawable.pScreen->root->drawable.id,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .configTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .rotation = output->crtc->rotation,
+ .nSizes = pData->nsize,
+ .nrateEnts = pData->nrefresh + pData->nsize,
+ .sizeID = pData->size,
+ .rate = pData->refresh
+ };
+
+ extraLen = rep.nSizes * sizeof(xScreenSizes);
+ if (has_rate)
+ extraLen += rep.nrateEnts * sizeof(CARD16);
+
+ if (extraLen) {
+ extra = (CARD8 *) calloc(1, extraLen);
+ if (!extra) {
+ free(pData);
+ return BadAlloc;
+ }
+ }
+ else
+ extra = NULL;
+
+ /*
+ * First comes the size information
+ */
+ size = (xScreenSizes *) extra;
+ rates = (CARD16 *) (size + rep.nSizes);
+ for (i = 0; i < pData->nsize; i++) {
+ pSize = &pData->sizes[i];
+ size->widthInPixels = pSize->width;
+ size->heightInPixels = pSize->height;
+ size->widthInMillimeters = pSize->mmWidth;
+ size->heightInMillimeters = pSize->mmHeight;
+ if (client->swapped) {
+ swaps(&size->widthInPixels);
+ swaps(&size->heightInPixels);
+ swaps(&size->widthInMillimeters);
+ swaps(&size->heightInMillimeters);
+ }
+ size++;
+ if (has_rate) {
+ *rates = pSize->nRates;
+ if (client->swapped) {
+ swaps(rates);
+ }
+ rates++;
+ for (j = 0; j < pSize->nRates; j++) {
+ *rates = pSize->pRates[j].rate;
+ if (client->swapped) {
+ swaps(rates);
+ }
+ rates++;
+ }
+ }
+ }
+ free(pData);
+
+ data8 = (CARD8 *) rates;
+
+ if (data8 - (CARD8 *) extra != extraLen)
+ FatalError("RRGetScreenInfo bad extra len %ld != %ld\n",
+ (unsigned long) (data8 - (CARD8 *) extra), extraLen);
+ rep.length = bytes_to_int32(extraLen);
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.timestamp);
+ swapl(&rep.configTimestamp);
+ swaps(&rep.rotation);
+ swaps(&rep.nSizes);
+ swaps(&rep.sizeID);
+ swaps(&rep.rate);
+ swaps(&rep.nrateEnts);
+ }
+ WriteToClient(client, sizeof(xRRGetScreenInfoReply), &rep);
+ if (extraLen) {
+ WriteToClient(client, extraLen, extra);
+ free(extra);
+ }
+ return Success;
+}
+
+int
+ProcRRSetScreenConfig(ClientPtr client)
+{
+ REQUEST(xRRSetScreenConfigReq);
+ xRRSetScreenConfigReply rep;
+ DrawablePtr pDraw;
+ int rc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ TimeStamp time;
+ int i;
+ Rotation rotation;
+ int rate;
+ Bool has_rate;
+ CARD8 status;
+ RROutputPtr output;
+ RRCrtcPtr crtc;
+ RRModePtr mode;
+ RR10DataPtr pData = NULL;
+ RRScreenSizePtr pSize;
+ int width, height;
+
+ UpdateCurrentTime();
+
+ if (RRClientKnowsRates(client)) {
+ REQUEST_SIZE_MATCH(xRRSetScreenConfigReq);
+ has_rate = TRUE;
+ }
+ else {
+ REQUEST_SIZE_MATCH(xRR1_0SetScreenConfigReq);
+ has_rate = FALSE;
+ }
+
+#ifndef NXAGENT_SERVER
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
+#else /* !defined(NXAGENT_SERVER) */
+ pDraw =
+ SecurityLookupDrawable(stuff->drawable, client, DixWriteAccess);
+ rc = pDraw ? Success : BadDrawable;
+#endif /* !defined(NXAGENT_SERVER) */
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pDraw->pScreen;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ time = ClientTimeToServerTime(stuff->timestamp);
+
+ if (!pScrPriv) {
+ time = currentTime;
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ if (!RRGetInfo(pScreen, FALSE))
+ return BadAlloc;
+
+ output = RRFirstOutput(pScreen);
+ if (!output) {
+ time = currentTime;
+ status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ crtc = output->crtc;
+
+ /*
+ * If the client's config timestamp is not the same as the last config
+ * timestamp, then the config information isn't up-to-date and
+ * can't even be validated.
+ *
+ * Note that the client only knows about the milliseconds part of the
+ * timestamp, so using CompareTimeStamps here would cause randr to suddenly
+ * stop working after several hours have passed (freedesktop bug #6502).
+ */
+ if (stuff->configTimestamp != pScrPriv->lastConfigTime.milliseconds) {
+ status = RRSetConfigInvalidConfigTime;
+ goto sendReply;
+ }
+
+ pData = RR10GetData(pScreen, output);
+ if (!pData)
+ return BadAlloc;
+
+ if (stuff->sizeID >= pData->nsize) {
+ /*
+ * Invalid size ID
+ */
+ client->errorValue = stuff->sizeID;
+ free(pData);
+ return BadValue;
+ }
+ pSize = &pData->sizes[stuff->sizeID];
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) stuff->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = stuff->rotation;
+ free(pData);
+ return BadValue;
+ }
+
+ if ((~crtc->rotations) & rotation) {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = stuff->rotation;
+ free(pData);
+ return BadMatch;
+ }
+
+ /*
+ * Validate requested refresh
+ */
+ if (has_rate)
+ rate = (int) stuff->rate;
+ else
+ rate = 0;
+
+ if (rate) {
+ for (i = 0; i < pSize->nRates; i++) {
+ if (pSize->pRates[i].rate == rate)
+ break;
+ }
+ if (i == pSize->nRates) {
+ /*
+ * Invalid rate
+ */
+ client->errorValue = rate;
+ free(pData);
+ return BadValue;
+ }
+ mode = pSize->pRates[i].mode;
+ }
+ else
+ mode = pSize->pRates[0].mode;
+
+ /*
+ * Make sure the requested set-time is not older than
+ * the last set-time
+ */
+ if (CompareTimeStamps(time, pScrPriv->lastSetTime) < 0) {
+ status = RRSetConfigInvalidTime;
+ goto sendReply;
+ }
+
+ /*
+ * If the screen size is changing, adjust all of the other outputs
+ * to fit the new size, mirroring as much as possible
+ */
+ width = mode->mode.width;
+ height = mode->mode.height;
+ if (width < pScrPriv->minWidth || pScrPriv->maxWidth < width) {
+ client->errorValue = width;
+ free(pData);
+ return BadValue;
+ }
+ if (height < pScrPriv->minHeight || pScrPriv->maxHeight < height) {
+ client->errorValue = height;
+ free(pData);
+ return BadValue;
+ }
+
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ width = mode->mode.height;
+ height = mode->mode.width;
+ }
+
+ if (width != pScreen->width || height != pScreen->height) {
+ int c;
+
+ for (c = 0; c < pScrPriv->numCrtcs; c++) {
+ if (!RRCrtcSet(pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
+ 0, NULL)) {
+ status = RRSetConfigFailed;
+ /* XXX recover from failure */
+ goto sendReply;
+ }
+ }
+ if (!RRScreenSizeSet(pScreen, width, height,
+ pScreen->mmWidth, pScreen->mmHeight)) {
+ status = RRSetConfigFailed;
+ /* XXX recover from failure */
+ goto sendReply;
+ }
+ }
+
+ if (!RRCrtcSet(crtc, mode, 0, 0, stuff->rotation, 1, &output))
+ status = RRSetConfigFailed;
+ else {
+ pScrPriv->lastSetTime = time;
+ status = RRSetConfigSuccess;
+ }
+
+ /*
+ * XXX Configure other crtcs to mirror as much as possible
+ */
+
+ sendReply:
+
+ free(pData);
+
+ rep = (xRRSetScreenConfigReply) {
+ .type = X_Reply,
+ .status = status,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .newTimestamp = pScrPriv->lastSetTime.milliseconds,
+ .newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds,
+ .root = pDraw->pScreen->root->drawable.id,
+ /* .subpixelOrder = ?? */
+ };
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.newTimestamp);
+ swapl(&rep.newConfigTimestamp);
+ swapl(&rep.root);
+ }
+ WriteToClient(client, sizeof(xRRSetScreenConfigReply), &rep);
+
+ return Success;
+}
+
+static CARD16
+RR10CurrentSizeID(ScreenPtr pScreen)
+{
+ CARD16 sizeID = 0xffff;
+ RROutputPtr output = RRFirstOutput(pScreen);
+
+ if (output) {
+ RR10DataPtr data = RR10GetData(pScreen, output);
+
+ if (data) {
+ int i;
+
+ for (i = 0; i < data->nsize; i++)
+ if (data->sizes[i].width == pScreen->width &&
+ data->sizes[i].height == pScreen->height) {
+ sizeID = (CARD16) i;
+ break;
+ }
+ free(data);
+ }
+ }
+ return sizeID;
+}
diff --git a/nx-X11/programs/Xserver/randr/rrsdispatch.c b/nx-X11/programs/Xserver/randr/rrsdispatch.c
new file mode 100644
index 000000000..04ac8526c
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrsdispatch.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+
+static int
+SProcRRQueryVersion(ClientPtr client)
+{
+ REQUEST(xRRQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+ swaps(&stuff->length);
+ swapl(&stuff->majorVersion);
+ swapl(&stuff->minorVersion);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenInfo(ClientPtr client)
+{
+ REQUEST(xRRGetScreenInfoReq);
+
+ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetScreenConfig(ClientPtr client)
+{
+ REQUEST(xRRSetScreenConfigReq);
+
+ if (RRClientKnowsRates(client)) {
+ REQUEST_SIZE_MATCH(xRRSetScreenConfigReq);
+ swaps(&stuff->rate);
+ }
+ else {
+ REQUEST_SIZE_MATCH(xRR1_0SetScreenConfigReq);
+ }
+
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ swapl(&stuff->timestamp);
+ swaps(&stuff->sizeID);
+ swaps(&stuff->rotation);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSelectInput(ClientPtr client)
+{
+ REQUEST(xRRSelectInputReq);
+
+ REQUEST_SIZE_MATCH(xRRSelectInputReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swaps(&stuff->enable);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenSizeRange(ClientPtr client)
+{
+ REQUEST(xRRGetScreenSizeRangeReq);
+
+ REQUEST_SIZE_MATCH(xRRGetScreenSizeRangeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetScreenSize(ClientPtr client)
+{
+ REQUEST(xRRSetScreenSizeReq);
+
+ REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->widthInMillimeters);
+ swapl(&stuff->heightInMillimeters);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetScreenResources(ClientPtr client)
+{
+ REQUEST(xRRGetScreenResourcesReq);
+
+ REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetOutputInfo(ClientPtr client)
+{
+ REQUEST(xRRGetOutputInfoReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputInfoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->configTimestamp);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRListOutputProperties(ClientPtr client)
+{
+ REQUEST(xRRListOutputPropertiesReq);
+
+ REQUEST_SIZE_MATCH(xRRListOutputPropertiesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRQueryOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRQueryOutputPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRQueryOutputPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->property);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRConfigureOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRConfigureOutputPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->property);
+ SwapRestL(stuff);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRChangeOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRChangeOutputPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->nUnits);
+ switch (stuff->format) {
+ case 8:
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ default:
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDeleteOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRDeleteOutputPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteOutputPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->property);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetOutputProperty(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->longOffset);
+ swapl(&stuff->longLength);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRCreateMode(ClientPtr client)
+{
+ xRRModeInfo *modeinfo;
+
+ REQUEST(xRRCreateModeReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+
+ modeinfo = &stuff->modeInfo;
+ swapl(&modeinfo->id);
+ swaps(&modeinfo->width);
+ swaps(&modeinfo->height);
+ swapl(&modeinfo->dotClock);
+ swaps(&modeinfo->hSyncStart);
+ swaps(&modeinfo->hSyncEnd);
+ swaps(&modeinfo->hTotal);
+ swaps(&modeinfo->vSyncStart);
+ swaps(&modeinfo->vSyncEnd);
+ swaps(&modeinfo->vTotal);
+ swaps(&modeinfo->nameLength);
+ swapl(&modeinfo->modeFlags);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDestroyMode(ClientPtr client)
+{
+ REQUEST(xRRDestroyModeReq);
+
+ REQUEST_SIZE_MATCH(xRRDestroyModeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->mode);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRAddOutputMode(ClientPtr client)
+{
+ REQUEST(xRRAddOutputModeReq);
+
+ REQUEST_SIZE_MATCH(xRRAddOutputModeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->mode);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRDeleteOutputMode(ClientPtr client)
+{
+ REQUEST(xRRDeleteOutputModeReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteOutputModeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->output);
+ swapl(&stuff->mode);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcInfo(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcInfoReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ swapl(&stuff->configTimestamp);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcConfig(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcConfigReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ swapl(&stuff->timestamp);
+ swapl(&stuff->configTimestamp);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swapl(&stuff->mode);
+ swaps(&stuff->rotation);
+ SwapRestL(stuff);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcGammaSize(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcGammaSizeReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcGamma(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcGammaReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcGamma(ClientPtr client)
+{
+ REQUEST(xRRSetCrtcGammaReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ swaps(&stuff->size);
+ SwapRestS(stuff);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetCrtcTransform(ClientPtr client)
+{
+ int nparams;
+ char *filter;
+ CARD32 *params;
+
+ REQUEST(xRRSetCrtcTransformReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ SwapLongs((CARD32 *) &stuff->transform,
+ bytes_to_int32(sizeof(xRenderTransform)));
+ swaps(&stuff->nbytesFilter);
+ filter = (char *) (stuff + 1);
+ params = (CARD32 *) (filter + pad_to_int32(stuff->nbytesFilter));
+ nparams = ((CARD32 *) stuff + client->req_len) - params;
+ if (nparams < 0)
+ return BadLength;
+
+ SwapLongs(params, nparams);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetCrtcTransform(ClientPtr client)
+{
+ REQUEST(xRRGetCrtcTransformReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRGetPanning(ClientPtr client)
+{
+ REQUEST(xRRGetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRGetPanningReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetPanning(ClientPtr client)
+{
+ REQUEST(xRRSetPanningReq);
+
+ REQUEST_SIZE_MATCH(xRRSetPanningReq);
+ swaps(&stuff->length);
+ swapl(&stuff->crtc);
+ swapl(&stuff->timestamp);
+ swaps(&stuff->left);
+ swaps(&stuff->top);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swaps(&stuff->track_left);
+ swaps(&stuff->track_top);
+ swaps(&stuff->track_width);
+ swaps(&stuff->track_height);
+ swaps(&stuff->border_left);
+ swaps(&stuff->border_top);
+ swaps(&stuff->border_right);
+ swaps(&stuff->border_bottom);
+ return (*ProcRandrVector[stuff->randrReqType]) (client);
+}
+
+static int
+SProcRRSetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRSetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRSetOutputPrimaryReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->output);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetOutputPrimary(ClientPtr client)
+{
+ REQUEST(xRRGetOutputPrimaryReq);
+
+ REQUEST_SIZE_MATCH(xRRGetOutputPrimaryReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviders(ClientPtr client)
+{
+ REQUEST(xRRGetProvidersReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProvidersReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviderInfo(ClientPtr client)
+{
+ REQUEST(xRRGetProviderInfoReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProviderInfoReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->configTimestamp);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetProviderOffloadSink(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOffloadSinkReq);
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOffloadSinkReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->sink_provider);
+ swapl(&stuff->configTimestamp);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetProviderOutputSource(ClientPtr client)
+{
+ REQUEST(xRRSetProviderOutputSourceReq);
+
+ REQUEST_SIZE_MATCH(xRRSetProviderOutputSourceReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->source_provider);
+ swapl(&stuff->configTimestamp);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRListProviderProperties(ClientPtr client)
+{
+ REQUEST(xRRListProviderPropertiesReq);
+
+ REQUEST_SIZE_MATCH(xRRListProviderPropertiesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRQueryProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRQueryProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRQueryProviderPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->property);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRConfigureProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRConfigureProviderPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRConfigureProviderPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->property);
+ /* TODO: no way to specify format? */
+ SwapRestL(stuff);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRChangeProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRChangeProviderPropertyReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->nUnits);
+ switch (stuff->format) {
+ case 8:
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRDeleteProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRDeleteProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteProviderPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->property);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetProviderProperty(ClientPtr client)
+{
+ REQUEST(xRRGetProviderPropertyReq);
+
+ REQUEST_SIZE_MATCH(xRRGetProviderPropertyReq);
+ swaps(&stuff->length);
+ swapl(&stuff->provider);
+ swapl(&stuff->property);
+ swapl(&stuff->type);
+ swapl(&stuff->longOffset);
+ swapl(&stuff->longLength);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRGetMonitors(ClientPtr client)
+{
+ REQUEST(xRRGetMonitorsReq);
+
+ REQUEST_SIZE_MATCH(xRRGetMonitorsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRSetMonitor(ClientPtr client)
+{
+ REQUEST(xRRSetMonitorReq);
+
+ REQUEST_AT_LEAST_SIZE(xRRGetMonitorsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->monitor.name);
+ swaps(&stuff->monitor.noutput);
+ swaps(&stuff->monitor.x);
+ swaps(&stuff->monitor.y);
+ swaps(&stuff->monitor.width);
+ swaps(&stuff->monitor.height);
+ SwapRestL(stuff);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+static int
+SProcRRDeleteMonitor(ClientPtr client)
+{
+ REQUEST(xRRDeleteMonitorReq);
+
+ REQUEST_SIZE_MATCH(xRRDeleteMonitorReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->name);
+ return ProcRandrVector[stuff->randrReqType] (client);
+}
+
+int (*SProcRandrVector[RRNumberRequests]) (ClientPtr) = {
+ SProcRRQueryVersion, /* 0 */
+/* we skip 1 to make old clients fail pretty immediately */
+ NULL, /* 1 SProcRandrOldGetScreenInfo */
+/* V1.0 apps share the same set screen config request id */
+ SProcRRSetScreenConfig, /* 2 */
+ NULL, /* 3 SProcRandrOldScreenChangeSelectInput */
+/* 3 used to be ScreenChangeSelectInput; deprecated */
+ SProcRRSelectInput, /* 4 */
+ SProcRRGetScreenInfo, /* 5 */
+/* V1.2 additions */
+ SProcRRGetScreenSizeRange, /* 6 */
+ SProcRRSetScreenSize, /* 7 */
+ SProcRRGetScreenResources, /* 8 */
+ SProcRRGetOutputInfo, /* 9 */
+ SProcRRListOutputProperties, /* 10 */
+ SProcRRQueryOutputProperty, /* 11 */
+ SProcRRConfigureOutputProperty, /* 12 */
+ SProcRRChangeOutputProperty, /* 13 */
+ SProcRRDeleteOutputProperty, /* 14 */
+ SProcRRGetOutputProperty, /* 15 */
+ SProcRRCreateMode, /* 16 */
+ SProcRRDestroyMode, /* 17 */
+ SProcRRAddOutputMode, /* 18 */
+ SProcRRDeleteOutputMode, /* 19 */
+ SProcRRGetCrtcInfo, /* 20 */
+ SProcRRSetCrtcConfig, /* 21 */
+ SProcRRGetCrtcGammaSize, /* 22 */
+ SProcRRGetCrtcGamma, /* 23 */
+ SProcRRSetCrtcGamma, /* 24 */
+/* V1.3 additions */
+ SProcRRGetScreenResources, /* 25 GetScreenResourcesCurrent */
+ SProcRRSetCrtcTransform, /* 26 */
+ SProcRRGetCrtcTransform, /* 27 */
+ SProcRRGetPanning, /* 28 */
+ SProcRRSetPanning, /* 29 */
+ SProcRRSetOutputPrimary, /* 30 */
+ SProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ SProcRRGetProviders, /* 32 */
+ SProcRRGetProviderInfo, /* 33 */
+ SProcRRSetProviderOffloadSink, /* 34 */
+ SProcRRSetProviderOutputSource, /* 35 */
+ SProcRRListProviderProperties, /* 36 */
+ SProcRRQueryProviderProperty, /* 37 */
+ SProcRRConfigureProviderProperty, /* 38 */
+ SProcRRChangeProviderProperty, /* 39 */
+ SProcRRDeleteProviderProperty, /* 40 */
+ SProcRRGetProviderProperty, /* 41 */
+ SProcRRGetMonitors, /* 42 */
+ SProcRRSetMonitor, /* 43 */
+ SProcRRDeleteMonitor, /* 44 */
+};
diff --git a/nx-X11/programs/Xserver/randr/rrtransform.c b/nx-X11/programs/Xserver/randr/rrtransform.c
new file mode 100644
index 000000000..d32b43aa3
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrtransform.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#include "randrstr.h"
+#include "rrtransform.h"
+
+void
+RRTransformInit(RRTransformPtr transform)
+{
+ pixman_transform_init_identity(&transform->transform);
+ pixman_f_transform_init_identity(&transform->f_transform);
+ pixman_f_transform_init_identity(&transform->f_inverse);
+ transform->filter = NULL;
+ transform->params = NULL;
+ transform->nparams = 0;
+}
+
+void
+RRTransformFini(RRTransformPtr transform)
+{
+ free(transform->params);
+}
+
+Bool
+RRTransformEqual(RRTransformPtr a, RRTransformPtr b)
+{
+ if (a && pixman_transform_is_identity(&a->transform))
+ a = NULL;
+ if (b && pixman_transform_is_identity(&b->transform))
+ b = NULL;
+ if (a == NULL && b == NULL)
+ return TRUE;
+ if (a == NULL || b == NULL)
+ return FALSE;
+ if (memcmp(&a->transform, &b->transform, sizeof(a->transform)) != 0)
+ return FALSE;
+ if (a->filter != b->filter)
+ return FALSE;
+ if (a->nparams != b->nparams)
+ return FALSE;
+ if (memcmp(a->params, b->params, a->nparams * sizeof(xFixed)) != 0)
+ return FALSE;
+ return TRUE;
+}
+
+Bool
+RRTransformSetFilter(RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed * params, int nparams, int width, int height)
+{
+ xFixed *new_params;
+
+ if (nparams) {
+ new_params = xallocarray(nparams, sizeof(xFixed));
+ if (!new_params)
+ return FALSE;
+ memcpy(new_params, params, nparams * sizeof(xFixed));
+ }
+ else
+ new_params = NULL;
+ free(dst->params);
+ dst->filter = filter;
+ dst->params = new_params;
+ dst->nparams = nparams;
+ dst->width = width;
+ dst->height = height;
+ return TRUE;
+}
+
+Bool
+RRTransformCopy(RRTransformPtr dst, RRTransformPtr src)
+{
+ if (src && pixman_transform_is_identity(&src->transform))
+ src = NULL;
+
+ if (src) {
+ if (!RRTransformSetFilter(dst, src->filter,
+ src->params, src->nparams, src->width,
+ src->height))
+ return FALSE;
+ dst->transform = src->transform;
+ dst->f_transform = src->f_transform;
+ dst->f_inverse = src->f_inverse;
+ }
+ else {
+ if (!RRTransformSetFilter(dst, NULL, NULL, 0, 0, 0))
+ return FALSE;
+ pixman_transform_init_identity(&dst->transform);
+ pixman_f_transform_init_identity(&dst->f_transform);
+ pixman_f_transform_init_identity(&dst->f_inverse);
+ }
+ return TRUE;
+}
+
+#define F(x) IntToxFixed(x)
+
+static void
+RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
+{
+ double max = 0, v, scale;
+ int i, j;
+
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ if ((v = fabs(f_transform->m[j][i])) > max)
+ max = v;
+ scale = limit / max;
+ for (j = 0; j < 3; j++)
+ for (i = 0; i < 3; i++)
+ f_transform->m[j][i] *= scale;
+}
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+Bool
+RRTransformCompute(int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+ PictTransformPtr transform,
+ struct pixman_f_transform *f_transform,
+ struct pixman_f_transform *f_inverse)
+{
+ PictTransform t_transform, inverse;
+ struct pixman_f_transform tf_transform, tf_inverse;
+ Bool overflow = FALSE;
+
+ if (!transform)
+ transform = &t_transform;
+ if (!f_transform)
+ f_transform = &tf_transform;
+ if (!f_inverse)
+ f_inverse = &tf_inverse;
+
+ pixman_transform_init_identity(transform);
+ pixman_transform_init_identity(&inverse);
+ pixman_f_transform_init_identity(f_transform);
+ pixman_f_transform_init_identity(f_inverse);
+ if (rotation != RR_Rotate_0) {
+ double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
+ double f_scale_x, f_scale_y, f_scale_dx, f_scale_dy;
+ xFixed rot_cos, rot_sin, rot_dx, rot_dy;
+ xFixed scale_x, scale_y, scale_dx, scale_dy;
+
+ /* rotation */
+ switch (rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ f_rot_cos = 1;
+ f_rot_sin = 0;
+ f_rot_dx = 0;
+ f_rot_dy = 0;
+ rot_cos = F(1);
+ rot_sin = F(0);
+ rot_dx = F(0);
+ rot_dy = F(0);
+ break;
+ case RR_Rotate_90:
+ f_rot_cos = 0;
+ f_rot_sin = 1;
+ f_rot_dx = height;
+ f_rot_dy = 0;
+ rot_cos = F(0);
+ rot_sin = F(1);
+ rot_dx = F(height);
+ rot_dy = F(0);
+ break;
+ case RR_Rotate_180:
+ f_rot_cos = -1;
+ f_rot_sin = 0;
+ f_rot_dx = width;
+ f_rot_dy = height;
+ rot_cos = F(~0u);
+ rot_sin = F(0);
+ rot_dx = F(width);
+ rot_dy = F(height);
+ break;
+ case RR_Rotate_270:
+ f_rot_cos = 0;
+ f_rot_sin = -1;
+ f_rot_dx = 0;
+ f_rot_dy = width;
+ rot_cos = F(0);
+ rot_sin = F(~0u);
+ rot_dx = F(0);
+ rot_dy = F(width);
+ break;
+ }
+
+ pixman_transform_rotate(transform, &inverse, rot_cos, rot_sin);
+ pixman_transform_translate(transform, &inverse, rot_dx, rot_dy);
+ pixman_f_transform_rotate(f_transform, f_inverse, f_rot_cos, f_rot_sin);
+ pixman_f_transform_translate(f_transform, f_inverse, f_rot_dx,
+ f_rot_dy);
+
+ /* reflection */
+ f_scale_x = 1;
+ f_scale_dx = 0;
+ f_scale_y = 1;
+ f_scale_dy = 0;
+ scale_x = F(1);
+ scale_dx = 0;
+ scale_y = F(1);
+ scale_dy = 0;
+ if (rotation & RR_Reflect_X) {
+ f_scale_x = -1;
+ scale_x = F(~0u);
+ if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
+ f_scale_dx = width;
+ scale_dx = F(width);
+ }
+ else {
+ f_scale_dx = height;
+ scale_dx = F(height);
+ }
+ }
+ if (rotation & RR_Reflect_Y) {
+ f_scale_y = -1;
+ scale_y = F(~0u);
+ if (rotation & (RR_Rotate_0 | RR_Rotate_180)) {
+ f_scale_dy = height;
+ scale_dy = F(height);
+ }
+ else {
+ f_scale_dy = width;
+ scale_dy = F(width);
+ }
+ }
+
+ pixman_transform_scale(transform, &inverse, scale_x, scale_y);
+ pixman_f_transform_scale(f_transform, f_inverse, f_scale_x, f_scale_y);
+ pixman_transform_translate(transform, &inverse, scale_dx, scale_dy);
+ pixman_f_transform_translate(f_transform, f_inverse, f_scale_dx,
+ f_scale_dy);
+ }
+
+#ifdef RANDR_12_INTERFACE
+ if (rr_transform) {
+ if (!pixman_transform_multiply
+ (transform, &rr_transform->transform, transform))
+ overflow = TRUE;
+ pixman_f_transform_multiply(f_transform, &rr_transform->f_transform,
+ f_transform);
+ pixman_f_transform_multiply(f_inverse, f_inverse,
+ &rr_transform->f_inverse);
+ }
+#endif
+ /*
+ * Compute the class of the resulting transform
+ */
+ if (!overflow && pixman_transform_is_identity(transform)) {
+ pixman_transform_init_translate(transform, F(x), F(y));
+
+ pixman_f_transform_init_translate(f_transform, x, y);
+ pixman_f_transform_init_translate(f_inverse, -x, -y);
+ return FALSE;
+ }
+ else {
+ pixman_f_transform_translate(f_transform, f_inverse, x, y);
+ if (!pixman_transform_translate(transform, &inverse, F(x), F(y)))
+ overflow = TRUE;
+ if (overflow) {
+ struct pixman_f_transform f_scaled;
+
+ f_scaled = *f_transform;
+ RRTransformRescale(&f_scaled, 16384.0);
+ pixman_transform_from_pixman_f_transform(transform, &f_scaled);
+ }
+ return TRUE;
+ }
+}
diff --git a/nx-X11/programs/Xserver/randr/rrtransform.h b/nx-X11/programs/Xserver/randr/rrtransform.h
new file mode 100644
index 000000000..02865fcd5
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrtransform.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifndef _RRTRANSFORM_H_
+#define _RRTRANSFORM_H_
+
+#include <nx-X11/extensions/randr.h>
+#include "picturestr.h"
+
+typedef struct _rrTransform RRTransformRec, *RRTransformPtr;
+
+struct _rrTransform {
+ PictTransform transform;
+ struct pict_f_transform f_transform;
+ struct pict_f_transform f_inverse;
+ PictFilterPtr filter;
+ xFixed *params;
+ int nparams;
+ int width;
+ int height;
+};
+
+extern _X_EXPORT void
+ RRTransformInit(RRTransformPtr transform);
+
+extern _X_EXPORT void
+ RRTransformFini(RRTransformPtr transform);
+
+extern _X_EXPORT Bool
+ RRTransformEqual(RRTransformPtr a, RRTransformPtr b);
+
+extern _X_EXPORT Bool
+
+RRTransformSetFilter(RRTransformPtr dst,
+ PictFilterPtr filter,
+ xFixed * params, int nparams, int width, int height);
+
+extern _X_EXPORT Bool
+ RRTransformCopy(RRTransformPtr dst, RRTransformPtr src);
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+extern _X_EXPORT Bool
+
+RRTransformCompute(int x,
+ int y,
+ int width,
+ int height,
+ Rotation rotation,
+ RRTransformPtr rr_transform,
+ PictTransformPtr transform,
+ struct pict_f_transform *f_transform,
+ struct pict_f_transform *f_inverse);
+
+#endif /* _RRTRANSFORM_H_ */
diff --git a/nx-X11/programs/Xserver/randr/rrxinerama.c b/nx-X11/programs/Xserver/randr/rrxinerama.c
new file mode 100644
index 000000000..b75b2ace9
--- /dev/null
+++ b/nx-X11/programs/Xserver/randr/rrxinerama.c
@@ -0,0 +1,479 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* nx-X11, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE which comes in the source */
+/* distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+/*
+ * This Xinerama implementation comes from the SiS driver which has
+ * the following notice:
+ */
+/*
+ * SiS driver main code
+ *
+ * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * - driver entirely rewritten since 2001, only basic structure taken from
+ * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of
+ * sis_dga.c; these were mostly taken over; sis_dri.c was changed for
+ * new versions of the DRI layer)
+ *
+ * This notice covers the entire driver code unless indicated otherwise.
+ *
+ * Formerly based on code which was
+ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
+ * Written by:
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>,
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+ * David Thomas <davtom@dream.org.uk>.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+#include "panoramiXproto.h"
+#include "protocol-versions.h"
+
+/* Xinerama is not multi-screen capable; just report about screen 0 */
+#define RR_XINERAMA_SCREEN 0
+
+static int ProcRRXineramaQueryVersion(ClientPtr client);
+static int ProcRRXineramaGetState(ClientPtr client);
+static int ProcRRXineramaGetScreenCount(ClientPtr client);
+static int ProcRRXineramaGetScreenSize(ClientPtr client);
+static int ProcRRXineramaIsActive(ClientPtr client);
+static int ProcRRXineramaQueryScreens(ClientPtr client);
+static int SProcRRXineramaDispatch(ClientPtr client);
+
+extern Bool noRRXineramaExtension;
+
+/* Proc */
+
+int
+ProcRRXineramaQueryVersion(ClientPtr client)
+{
+ xPanoramiXQueryVersionReply rep = {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .majorVersion = SERVER_RRXINERAMA_MAJOR_VERSION,
+ .minorVersion = SERVER_RRXINERAMA_MINOR_VERSION
+ };
+
+ REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), &rep);
+ return Success;
+}
+
+int
+ProcRRXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int rc;
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+ Bool active = FALSE;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ if (pScrPriv) {
+ /* XXX do we need more than this? */
+ active = TRUE;
+ }
+
+ rep = (xPanoramiXGetStateReply) {
+ .type = X_Reply,
+ .state = active,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .window = stuff->window
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.window);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetStateReply), &rep);
+ return Success;
+}
+
+static int
+RRXineramaScreenCount(ScreenPtr pScreen)
+{
+ return RRMonitorCountList(pScreen);
+}
+
+static Bool
+RRXineramaScreenActive(ScreenPtr pScreen)
+{
+ return RRXineramaScreenCount(pScreen) > 0;
+}
+
+int
+ProcRRXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int rc;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+ if (rc != Success)
+ return rc;
+
+ rep = (xPanoramiXGetScreenCountReply) {
+ .type = X_Reply,
+ .ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen),
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .window = stuff->window
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.window);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), &rep);
+ return Success;
+}
+
+int
+ProcRRXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin, pRoot;
+ ScreenPtr pScreen;
+ xPanoramiXGetScreenSizeReply rep;
+ register int rc;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+#ifndef NXAGENT_SERVER
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+#else
+ pWin = SecurityLookupWindow(stuff->window, client, DixReadAccess);
+ rc = pWin ? Success : BadWindow;
+#endif
+
+ if (rc != Success)
+ return rc;
+
+ pScreen = pWin->drawable.pScreen;
+ pRoot = pScreen->root;
+
+ rep = (xPanoramiXGetScreenSizeReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = 0,
+ .width = pRoot->drawable.width,
+ .height = pRoot->drawable.height,
+ .window = stuff->window,
+ .screen = stuff->screen
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.width);
+ swapl(&rep.height);
+ swapl(&rep.window);
+ swapl(&rep.screen);
+ }
+ WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), &rep);
+ return Success;
+}
+
+int
+ProcRRXineramaIsActive(ClientPtr client)
+{
+ xXineramaIsActiveReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep = (xXineramaIsActiveReply) {
+ .type = X_Reply,
+ .length = 0,
+ .sequenceNumber = client->sequence,
+ .state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN])
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.state);
+ }
+ WriteToClient(client, sizeof(xXineramaIsActiveReply), &rep);
+ return Success;
+}
+
+static void
+RRXineramaWriteMonitor(ClientPtr client, RRMonitorPtr monitor)
+{
+ xXineramaScreenInfo scratch;
+
+ scratch.x_org = monitor->geometry.box.x1;
+ scratch.y_org = monitor->geometry.box.y1;
+ scratch.width = monitor->geometry.box.x2 - monitor->geometry.box.x1;
+ scratch.height = monitor->geometry.box.y2 - monitor->geometry.box.y1;
+
+ if (client->swapped) {
+ swaps(&scratch.x_org);
+ swaps(&scratch.y_org);
+ swaps(&scratch.width);
+ swaps(&scratch.height);
+ }
+
+ WriteToClient(client, sz_XineramaScreenInfo, &scratch);
+}
+
+int
+ProcRRXineramaQueryScreens(ClientPtr client)
+{
+ xXineramaQueryScreensReply rep;
+ ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
+ int m;
+ RRMonitorPtr monitors = NULL;
+ int nmonitors = 0;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ if (RRXineramaScreenActive(pScreen)) {
+ RRGetInfo(pScreen, FALSE);
+ if (!RRMonitorMakeList(pScreen, TRUE, &monitors, &nmonitors))
+ return BadAlloc;
+ }
+
+ rep = (xXineramaQueryScreensReply) {
+ .type = X_Reply,
+ .sequenceNumber = client->sequence,
+ .length = bytes_to_int32(nmonitors * sz_XineramaScreenInfo),
+ .number = nmonitors
+ };
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.number);
+ }
+ WriteToClient(client, sizeof(xXineramaQueryScreensReply), &rep);
+
+ for (m = 0; m < nmonitors; m++)
+ RRXineramaWriteMonitor(client, &monitors[m]);
+
+ if (monitors)
+ RRMonitorFreeList(monitors, nmonitors);
+
+ return Success;
+}
+
+static int
+ProcRRXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return ProcRRXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return ProcRRXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return ProcRRXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return ProcRRXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return ProcRRXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return ProcRRXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+/* SProc */
+
+static int
+SProcRRXineramaQueryVersion(ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
+ return ProcRRXineramaQueryVersion(client);
+}
+
+static int
+SProcRRXineramaGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ swapl(&stuff->window);
+ return ProcRRXineramaGetState(client);
+}
+
+static int
+SProcRRXineramaGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ swapl(&stuff->window);
+ return ProcRRXineramaGetScreenCount(client);
+}
+
+static int
+SProcRRXineramaGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ swapl(&stuff->window);
+ swapl(&stuff->screen);
+ return ProcRRXineramaGetScreenSize(client);
+}
+
+static int
+SProcRRXineramaIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return ProcRRXineramaIsActive(client);
+}
+
+static int
+SProcRRXineramaQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return ProcRRXineramaQueryScreens(client);
+}
+
+int
+SProcRRXineramaDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_PanoramiXQueryVersion:
+ return SProcRRXineramaQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SProcRRXineramaGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SProcRRXineramaGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SProcRRXineramaGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SProcRRXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return SProcRRXineramaQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+void
+RRXineramaExtensionInit(void)
+{
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ return;
+#endif
+
+ if (noRRXineramaExtension)
+ return;
+
+ /*
+ * Xinerama isn't capable enough to have multiple protocol screens each
+ * with their own output geometry. So if there's more than one protocol
+ * screen, just don't even try.
+ */
+ if (screenInfo.numScreens > 1)
+ return;
+
+ (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
+ ProcRRXineramaDispatch,
+ SProcRRXineramaDispatch, NULL, StandardMinorOpcode);
+}
diff --git a/nx-X11/programs/Xserver/record/Imakefile b/nx-X11/programs/Xserver/record/Imakefile
new file mode 100644
index 000000000..40c29fe6f
--- /dev/null
+++ b/nx-X11/programs/Xserver/record/Imakefile
@@ -0,0 +1,26 @@
+ NULL =
+
+
+#include <Server.tmpl>
+
+ SRCS = record.c set.c
+ OBJS = record.o set.o
+ INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ DEFINES = \
+ -DNDEBUG \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(record,$(OBJS))
+LintLibraryTarget(record,$(SRCS))
+NormalLintTarget($(SRCS))
+
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/record/record.c b/nx-X11/programs/Xserver/record/record.c
new file mode 100644
index 000000000..48b1964e6
--- /dev/null
+++ b/nx-X11/programs/Xserver/record/record.c
@@ -0,0 +1,3047 @@
+
+/*
+
+Copyright 1995, 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: David P. Wiggins, The Open Group
+
+This work benefited from earlier work done by Martha Zimet of NCD
+and Jim Haggerty of Metheus.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#define _XRECORD_SERVER_
+#include <nx-X11/extensions/recordstr.h>
+#include "set.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+#ifdef PANORAMIX
+#include "globals.h"
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#include "cursor.h"
+#endif
+
+#include "protocol-versions.h"
+
+static RESTYPE RTContext; /* internal resource type for Record contexts */
+static int RecordErrorBase; /* first Record error number */
+
+/* How many bytes of protocol data to buffer in a context. Don't set to less
+ * than 32.
+ */
+#define REPLY_BUF_SIZE 1024
+
+/* Record Context structure */
+
+typedef struct {
+ XID id; /* resource id of context */
+ ClientPtr pRecordingClient; /* client that has context enabled */
+ struct _RecordClientsAndProtocolRec *pListOfRCAP; /* all registered info */
+ ClientPtr pBufClient; /* client whose protocol is in replyBuffer*/
+ unsigned int continuedReply:1; /* recording a reply that is split up? */
+ char elemHeaders; /* element header flags (time/seq no.) */
+ char bufCategory; /* category of protocol in replyBuffer */
+ int numBufBytes; /* number of bytes in replyBuffer */
+ char replyBuffer[REPLY_BUF_SIZE]; /* buffered recorded protocol */
+ int inFlush; /* are we inside RecordFlushReplyBuffer */
+} RecordContextRec, *RecordContextPtr;
+
+/* RecordMinorOpRec - to hold minor opcode selections for extension requests
+ * and replies
+ */
+
+typedef union {
+ int count; /* first element of array: how many "major" structs to follow */
+ struct { /* rest of array elements are this */
+ short first; /* first major opcode */
+ short last; /* last major opcode */
+ RecordSetPtr pMinOpSet; /* minor opcode set for above major range */
+ } major;
+} RecordMinorOpRec, *RecordMinorOpPtr;
+
+
+/* RecordClientsAndProtocolRec, nicknamed RCAP - holds all the client and
+ * protocol selections passed in a single CreateContext or RegisterClients.
+ * Generally, a context will have one of these from the create and an
+ * additional one for each RegisterClients. RCAPs are freed when all their
+ * clients are unregistered.
+ */
+
+typedef struct _RecordClientsAndProtocolRec {
+ RecordContextPtr pContext; /* context that owns this RCAP */
+ struct _RecordClientsAndProtocolRec *pNextRCAP; /* next RCAP on context */
+ RecordSetPtr pRequestMajorOpSet; /* requests to record */
+ RecordMinorOpPtr pRequestMinOpInfo; /* extension requests to record */
+ RecordSetPtr pReplyMajorOpSet; /* replies to record */
+ RecordMinorOpPtr pReplyMinOpInfo; /* extension replies to record */
+ RecordSetPtr pDeviceEventSet; /* device events to record */
+ RecordSetPtr pDeliveredEventSet; /* delivered events to record */
+ RecordSetPtr pErrorSet; /* errors to record */
+ XID * pClientIDs; /* array of clients to record */
+ short numClients; /* number of clients in pClientIDs */
+ short sizeClients; /* size of pClientIDs array */
+ unsigned int clientStarted:1; /* record new client connections? */
+ unsigned int clientDied:1; /* record client disconnections? */
+ unsigned int clientIDsSeparatelyAllocated:1; /* pClientIDs malloced? */
+} RecordClientsAndProtocolRec, *RecordClientsAndProtocolPtr;
+
+/* how much bigger to make pRCAP->pClientIDs when reallocing */
+#define CLIENT_ARRAY_GROWTH_INCREMENT 4
+
+/* counts the total number of RCAPs belonging to enabled contexts. */
+static int numEnabledRCAPs;
+
+/* void VERIFY_CONTEXT(RecordContextPtr, XID, ClientPtr)
+ * In the spirit of the VERIFY_* macros in dix.h, this macro fills in
+ * the context pointer if the given ID is a valid Record Context, else it
+ * returns an error.
+ */
+#define VERIFY_CONTEXT(_pContext, _contextid, _client) { \
+ (_pContext) = (RecordContextPtr)LookupIDByType((_contextid), RTContext); \
+ if (!(_pContext)) { \
+ (_client)->errorValue = (_contextid); \
+ return RecordErrorBase + XRecordBadContext; \
+ } \
+}
+
+static int RecordDeleteContext(
+ void * /*value*/,
+ XID /*id*/
+);
+
+
+/***************************************************************************/
+
+/* client private stuff */
+
+/* To make declarations less obfuscated, have a typedef for a pointer to a
+ * Proc function.
+ */
+typedef int (*ProcFunctionPtr)(
+ ClientPtr /*pClient*/
+);
+
+/* Record client private. Generally a client only has one of these if
+ * any of its requests are being recorded.
+ */
+typedef struct {
+/* ptr to client's proc vector before Record stuck its nose in */
+ ProcFunctionPtr *originalVector;
+
+/* proc vector with pointers for recorded requests redirected to the
+ * function RecordARequest
+ */
+ ProcFunctionPtr recordVector[256];
+} RecordClientPrivateRec, *RecordClientPrivatePtr;
+
+static int RecordClientPrivateIndex;
+
+/* RecordClientPrivatePtr RecordClientPrivate(ClientPtr)
+ * gets the client private of the given client. Syntactic sugar.
+ */
+#define RecordClientPrivate(_pClient) (RecordClientPrivatePtr) \
+ ((_pClient)->devPrivates[RecordClientPrivateIndex].ptr)
+
+
+/***************************************************************************/
+
+/* global list of all contexts */
+
+static RecordContextPtr *ppAllContexts;
+
+static int numContexts;/* number of contexts in ppAllContexts */
+
+/* number of currently enabled contexts. All enabled contexts are bunched
+ * up at the front of the ppAllContexts array, from ppAllContexts[0] to
+ * ppAllContexts[numEnabledContexts-1], to eliminate time spent skipping
+ * past disabled contexts.
+ */
+static int numEnabledContexts;
+
+/* RecordFindContextOnAllContexts
+ *
+ * Arguments:
+ * pContext is the context to search for.
+ *
+ * Returns:
+ * The index into the array ppAllContexts at which pContext is stored.
+ * If pContext is not found in ppAllContexts, returns -1.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordFindContextOnAllContexts(pContext)
+ RecordContextPtr pContext;
+{
+ int i;
+
+ assert(numContexts >= numEnabledContexts);
+ for (i = 0; i < numContexts; i++)
+ {
+ if (ppAllContexts[i] == pContext)
+ return i;
+ }
+ return -1;
+} /* RecordFindContextOnAllContexts */
+
+
+/***************************************************************************/
+
+/* RecordFlushReplyBuffer
+ *
+ * Arguments:
+ * pContext is the context to flush.
+ * data1 is a pointer to additional data, and len1 is its length in bytes.
+ * data2 is a pointer to additional data, and len2 is its length in bytes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If the context is enabled, any buffered (recorded) protocol is written
+ * to the recording client, and the number of buffered bytes is set to
+ * zero. If len1 is not zero, data1/len1 are then written to the
+ * recording client, and similarly for data2/len2 (written after
+ * data1/len1).
+ */
+static void
+RecordFlushReplyBuffer(
+ RecordContextPtr pContext,
+ void * data1,
+ int len1,
+ void * data2,
+ int len2
+)
+{
+ if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone || pContext->inFlush)
+ return;
+ ++pContext->inFlush;
+ if (pContext->numBufBytes)
+ WriteToClient(pContext->pRecordingClient, pContext->numBufBytes,
+ (char *)pContext->replyBuffer);
+ pContext->numBufBytes = 0;
+ if (len1)
+ WriteToClient(pContext->pRecordingClient, len1, data1);
+ if (len2)
+ WriteToClient(pContext->pRecordingClient, len2, data2);
+ --pContext->inFlush;
+} /* RecordFlushReplyBuffer */
+
+
+/* RecordAProtocolElement
+ *
+ * Arguments:
+ * pContext is the context that is recording a protocol element.
+ * pClient is the client whose protocol is being recorded. For
+ * device events and EndOfData, pClient is NULL.
+ * category is the category of the protocol element, as defined
+ * by the RECORD spec.
+ * data is a pointer to the protocol data, and datalen is its length
+ * in bytes.
+ * futurelen is the number of bytes that will be sent in subsequent
+ * calls to this function to complete this protocol element.
+ * In those subsequent calls, futurelen will be -1 to indicate
+ * that the current data is a continuation of the same protocol
+ * element.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The context may be flushed. The new protocol element will be
+ * added to the context's protocol buffer with appropriate element
+ * headers prepended (sequence number and timestamp). If the data
+ * is continuation data (futurelen == -1), element headers won't
+ * be added. If the protocol element and headers won't fit in
+ * the context's buffer, it is sent directly to the recording
+ * client (after any buffered data).
+ */
+static void
+RecordAProtocolElement(RecordContextPtr pContext, ClientPtr pClient,
+ int category, void * data, int datalen, int futurelen)
+{
+ CARD32 elemHeaderData[2];
+ int numElemHeaders = 0;
+ Bool recordingClientSwapped = pContext->pRecordingClient->swapped;
+ CARD32 serverTime = 0;
+ Bool gotServerTime = FALSE;
+ int replylen;
+
+ if (futurelen >= 0)
+ { /* start of new protocol element */
+ xRecordEnableContextReply *pRep = (xRecordEnableContextReply *)
+ pContext->replyBuffer;
+ if (pContext->pBufClient != pClient ||
+ pContext->bufCategory != category)
+ {
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ pContext->pBufClient = pClient;
+ pContext->bufCategory = category;
+ }
+
+ if (!pContext->numBufBytes)
+ {
+ serverTime = GetTimeInMillis();
+ gotServerTime = TRUE;
+ pRep->type = X_Reply;
+ pRep->category = category;
+ pRep->sequenceNumber = pContext->pRecordingClient->sequence;
+ pRep->length = 0;
+ pRep->elementHeader = pContext->elemHeaders;
+ pRep->serverTime = serverTime;
+ if (pClient)
+ {
+ pRep->clientSwapped =
+ (pClient->swapped != recordingClientSwapped);
+ pRep->idBase = pClient->clientAsMask;
+ pRep->recordedSequenceNumber = pClient->sequence;
+ }
+ else /* it's a device event, StartOfData, or EndOfData */
+ {
+ pRep->clientSwapped = (category != XRecordFromServer) &&
+ recordingClientSwapped;
+ pRep->idBase = 0;
+ pRep->recordedSequenceNumber = 0;
+ }
+
+ if (recordingClientSwapped)
+ {
+ swaps(&pRep->sequenceNumber);
+ swapl(&pRep->length);
+ swapl(&pRep->idBase);
+ swapl(&pRep->serverTime);
+ swapl(&pRep->recordedSequenceNumber);
+ }
+ pContext->numBufBytes = SIZEOF(xRecordEnableContextReply);
+ }
+
+ /* generate element headers if needed */
+
+ if ( ( (pContext->elemHeaders & XRecordFromClientTime)
+ && category == XRecordFromClient)
+ ||
+ ( (pContext->elemHeaders & XRecordFromServerTime)
+ && category == XRecordFromServer))
+ {
+ if (gotServerTime)
+ elemHeaderData[numElemHeaders] = serverTime;
+ else
+ elemHeaderData[numElemHeaders] = GetTimeInMillis();
+ if (recordingClientSwapped)
+ swapl(&elemHeaderData[numElemHeaders]);
+ numElemHeaders++;
+ }
+
+ if ( (pContext->elemHeaders & XRecordFromClientSequence)
+ &&
+ (category == XRecordFromClient || category == XRecordClientDied))
+ {
+ elemHeaderData[numElemHeaders] = pClient->sequence;
+ if (recordingClientSwapped)
+ swapl(&elemHeaderData[numElemHeaders]);
+ numElemHeaders++;
+ }
+
+ /* adjust reply length */
+
+ replylen = pRep->length;
+ if (recordingClientSwapped) swapl(&replylen);
+ replylen += numElemHeaders + (datalen >> 2) + (futurelen >> 2);
+ if (recordingClientSwapped) swapl(&replylen);
+ pRep->length = replylen;
+ } /* end if not continued reply */
+
+ numElemHeaders *= 4;
+
+ /* if space available >= space needed, buffer the data */
+
+ if (REPLY_BUF_SIZE - pContext->numBufBytes >= datalen + numElemHeaders)
+ {
+ if (numElemHeaders)
+ {
+ memcpy(pContext->replyBuffer + pContext->numBufBytes,
+ elemHeaderData, numElemHeaders);
+ pContext->numBufBytes += numElemHeaders;
+ }
+ if (datalen)
+ {
+ memcpy(pContext->replyBuffer + pContext->numBufBytes,
+ data, datalen);
+ pContext->numBufBytes += datalen;
+ }
+ }
+ else
+ RecordFlushReplyBuffer(pContext, (void *)elemHeaderData,
+ numElemHeaders, (void *)data, datalen);
+
+} /* RecordAProtocolElement */
+
+
+/* RecordFindClientOnContext
+ *
+ * Arguments:
+ * pContext is the context to search.
+ * clientspec is the resource ID mask identifying the client to search
+ * for, or XRecordFutureClients.
+ * pposition is a pointer to an int, or NULL. See Returns.
+ *
+ * Returns:
+ * The RCAP on which clientspec was found, or NULL if not found on
+ * any RCAP on the given context.
+ * If pposition was not NULL and the returned RCAP is not NULL,
+ * *pposition will be set to the index into the returned the RCAP's
+ * pClientIDs array that holds clientspec.
+ *
+ * Side Effects: none.
+ */
+static RecordClientsAndProtocolPtr
+RecordFindClientOnContext(
+ RecordContextPtr pContext,
+ XID clientspec,
+ int *pposition
+)
+{
+ RecordClientsAndProtocolPtr pRCAP;
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ int i;
+ for (i = 0; i < pRCAP->numClients; i++)
+ {
+ if (pRCAP->pClientIDs[i] == clientspec)
+ {
+ if (pposition)
+ *pposition = i;
+ return pRCAP;
+ }
+ }
+ }
+ return NULL;
+} /* RecordFindClientOnContext */
+
+
+/* RecordABigRequest
+ *
+ * Arguments:
+ * pContext is the recording context.
+ * client is the client being recorded.
+ * stuff is a pointer to the big request of client (see the Big Requests
+ * extension for details.)
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The big request is recorded with the correct length field re-inserted.
+ *
+ * Note: this function exists mainly to make RecordARequest smaller.
+ */
+static void
+RecordABigRequest(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xReq *stuff;
+{
+ CARD32 bigLength;
+ int bytesLeft;
+
+ /* note: client->req_len has been frobbed by ReadRequestFromClient
+ * (os/io.c) to discount the extra 4 bytes taken by the extended length
+ * field in a big request. The actual request length to record is
+ * client->req_len + 1 (measured in CARD32s).
+ */
+
+ /* record the request header */
+ bytesLeft = client->req_len << 2;
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (void *)stuff, SIZEOF(xReq), bytesLeft);
+
+ /* reinsert the extended length field that was squished out */
+ bigLength = client->req_len + (sizeof(bigLength) >> 2);
+ if (client->swapped)
+ swapl(&bigLength);
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (void *)&bigLength, sizeof(bigLength), /* continuation */ -1);
+ bytesLeft -= sizeof(bigLength);
+
+ /* record the rest of the request after the length */
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (void *)(stuff + 1), bytesLeft, /* continuation */ -1);
+} /* RecordABigRequest */
+
+
+/* RecordARequest
+ *
+ * Arguments:
+ * client is a client that the server has dispatched a request to by
+ * calling client->requestVector[request opcode] .
+ * The request is in client->requestBuffer.
+ *
+ * Returns:
+ * Whatever is returned by the "real" Proc function for this request.
+ * The "real" Proc function is the function that was in
+ * client->requestVector[request opcode] before it was replaced by
+ * RecordARequest. (See the function RecordInstallHooks.)
+ *
+ * Side Effects:
+ * The request is recorded by all contexts that have registered this
+ * request for this client. The real Proc function is called.
+ */
+static int
+RecordARequest(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int i;
+ RecordClientPrivatePtr pClientPriv;
+ REQUEST(xReq);
+ int majorop;
+
+ majorop = stuff->reqType;
+ for (i = 0; i < numEnabledContexts; i++)
+ {
+ pContext = ppAllContexts[i];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP && pRCAP->pRequestMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core request */
+
+ if (stuff->length == 0)
+ RecordABigRequest(pContext, client, stuff);
+ else
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (void *)stuff, client->req_len << 2, 0);
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ if (stuff->length == 0)
+ RecordABigRequest(pContext, client, stuff);
+ else
+ RecordAProtocolElement(pContext, client,
+ XRecordFromClient, (void *)stuff,
+ client->req_len << 2, 0);
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension request */
+ } /* end this RCAP wants this major opcode */
+ } /* end for each context */
+ pClientPriv = RecordClientPrivate(client);
+ assert(pClientPriv);
+ return (* pClientPriv->originalVector[majorop])(client);
+} /* RecordARequest */
+
+
+/* RecordASkippedRequest
+ *
+ * Arguments:
+ * pcbl is &SkippedRequestCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a SkippedRequestInfoRec (include/os.h)
+ * which provides information about requests that the server is
+ * skipping. The client's proc vector won't be called for skipped
+ * requests, so that's why we have to catch them here.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The skipped requests are recorded by all contexts that have
+ * registered those requests for this client.
+ *
+ * Note: most servers don't skip requests, so calls to this will probably
+ * be rare. For more information on skipped requests, search for
+ * the word skip in ddx.tbl.ms (the porting layer document).
+ */
+static void
+RecordASkippedRequest(pcbl , nulldata, calldata)
+ CallbackListPtr *pcbl;
+ void * nulldata;
+ void * calldata;
+{
+ SkippedRequestInfoRec *psi = (SkippedRequestInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ xReqPtr stuff = psi->req;
+ ClientPtr client = psi->client;
+ int numSkippedRequests = psi->numskipped;
+ int reqlen;
+ int i;
+ int majorop;
+
+ while (numSkippedRequests--)
+ {
+ majorop = stuff->reqType;
+ reqlen = ReqLen(stuff, client);
+ /* handle big request */
+ if (stuff->length == 0)
+ reqlen += 4;
+ for (i = 0; i < numEnabledContexts; i++)
+ {
+ pContext = ppAllContexts[i];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP && pRCAP->pRequestMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core request */
+
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (void *)stuff, reqlen, 0);
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ RecordAProtocolElement(pContext, client,
+ XRecordFromClient, (void *)stuff,
+ reqlen, 0);
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension request */
+ } /* end this RCAP wants this major opcode */
+ } /* end for each context */
+
+ /* go to next request */
+ stuff = (xReqPtr)( ((char *)stuff) + reqlen);
+
+ } /* end for each skipped request */
+} /* RecordASkippedRequest */
+
+
+/* RecordAReply
+ *
+ * Arguments:
+ * pcbl is &ReplyCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a ReplyInfoRec (include/os.h)
+ * which provides information about replies that are being sent
+ * to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The reply is recorded by all contexts that have registered this
+ * reply type for this client. If more data belonging to the same
+ * reply is expected, and if the reply is being recorded by any
+ * context, pContext->continuedReply is set to 1.
+ * If pContext->continuedReply was already 1 and this is the last
+ * chunk of data belonging to this reply, it is set to 0.
+ */
+static void
+RecordAReply(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ void * nulldata;
+ void * calldata;
+{
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci;
+ int majorop;
+ ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+ ClientPtr client = pri->client;
+ REQUEST(xReq);
+
+ majorop = stuff->reqType;
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP)
+ {
+ if (pContext->continuedReply)
+ {
+ RecordAProtocolElement(pContext, client, XRecordFromServer,
+ (void *)pri->replyData, pri->dataLenBytes, /* continuation */ -1);
+ if (!pri->bytesRemaining)
+ pContext->continuedReply = 0;
+ }
+ else if (pri->startOfReply && pRCAP->pReplyMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pReplyMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core reply */
+ RecordAProtocolElement(pContext, client, XRecordFromServer,
+ (void *)pri->replyData, pri->dataLenBytes, pri->bytesRemaining);
+ if (pri->bytesRemaining)
+ pContext->continuedReply = 1;
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pReplyMinOpInfo;
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ RecordAProtocolElement(pContext, client,
+ XRecordFromServer, (void *)pri->replyData,
+ pri->dataLenBytes, pri->bytesRemaining);
+ if (pri->bytesRemaining)
+ pContext->continuedReply = 1;
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension reply */
+ } /* end continued reply vs. start of reply */
+ } /* end client is registered on this context */
+ } /* end for each context */
+} /* RecordAReply */
+
+
+/* RecordADeliveredEventOrError
+ *
+ * Arguments:
+ * pcbl is &EventCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a EventInfoRec (include/dix.h)
+ * which provides information about events that are being sent
+ * to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The event or error is recorded by all contexts that have registered
+ * it for this client.
+ */
+static void
+RecordADeliveredEventOrError(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ void * nulldata;
+ void * calldata;
+{
+ EventInfoRec *pei = (EventInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci; /* enabled context index */
+ ClientPtr pClient = pei->client;
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ pRCAP = RecordFindClientOnContext(pContext, pClient->clientAsMask,
+ NULL);
+ if (pRCAP && (pRCAP->pDeliveredEventSet || pRCAP->pErrorSet))
+ {
+ int ev; /* event index */
+ xEvent *pev = pei->events;
+ for (ev = 0; ev < pei->count; ev++, pev++)
+ {
+ int recordit;
+ if (pev->u.u.type == X_Error)
+ {
+ recordit = RecordIsMemberOfSet(pRCAP->pErrorSet,
+ ((xError *)(pev))->errorCode);
+ }
+ else
+ {
+ recordit = RecordIsMemberOfSet(pRCAP->pDeliveredEventSet,
+ pev->u.u.type & 0177);
+ }
+ if (recordit)
+ {
+ xEvent swappedEvent;
+ xEvent *pEvToRecord = pev;
+
+ if (pClient->swapped)
+ {
+ (*EventSwapVector[pev->u.u.type & 0177])
+ (pev, &swappedEvent);
+ pEvToRecord = &swappedEvent;
+
+ }
+ RecordAProtocolElement(pContext, pClient,
+ XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
+ }
+ } /* end for each event */
+ } /* end this client is on this context */
+ } /* end for each enabled context */
+} /* RecordADeliveredEventOrError */
+
+
+/* RecordADeviceEvent
+ *
+ * Arguments:
+ * pcbl is &DeviceEventCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a DeviceEventInfoRec (include/dix.h)
+ * which provides information about device events that occur.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The device event is recorded by all contexts that have registered
+ * it for this client.
+ */
+static void
+RecordADeviceEvent(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ void * nulldata;
+ void * calldata;
+{
+ DeviceEventInfoRec *pei = (DeviceEventInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci; /* enabled context index */
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ if (pRCAP->pDeviceEventSet)
+ {
+ int ev; /* event index */
+ xEvent *pev = pei->events;
+ for (ev = 0; ev < pei->count; ev++, pev++)
+ {
+ if (RecordIsMemberOfSet(pRCAP->pDeviceEventSet,
+ pev->u.u.type & 0177))
+ {
+ xEvent swappedEvent;
+ xEvent *pEvToRecord = pev;
+#ifdef PANORAMIX
+ xEvent shiftedEvent;
+
+ if (!noPanoramiXExtension &&
+ (pev->u.u.type == MotionNotify ||
+ pev->u.u.type == ButtonPress ||
+ pev->u.u.type == ButtonRelease ||
+ pev->u.u.type == KeyPress ||
+ pev->u.u.type == KeyRelease)) {
+ int scr = XineramaGetCursorScreen();
+ memcpy(&shiftedEvent, pev, sizeof(xEvent));
+ shiftedEvent.u.keyButtonPointer.rootX +=
+ panoramiXdataPtr[scr].x -
+ panoramiXdataPtr[0].x;
+ shiftedEvent.u.keyButtonPointer.rootY +=
+ panoramiXdataPtr[scr].y -
+ panoramiXdataPtr[0].y;
+ pEvToRecord = &shiftedEvent;
+ }
+#endif /* PANORAMIX */
+
+ if (pContext->pRecordingClient->swapped)
+ {
+ (*EventSwapVector[pEvToRecord->u.u.type & 0177])
+ (pEvToRecord, &swappedEvent);
+ pEvToRecord = &swappedEvent;
+ }
+
+ RecordAProtocolElement(pContext, NULL,
+ XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
+ /* make sure device events get flushed in the absence
+ * of other client activity
+ */
+ SetCriticalOutputPending();
+ }
+ } /* end for each event */
+ } /* end this RCAP selects device events */
+ } /* end for each RCAP on this context */
+ } /* end for each enabled context */
+} /* RecordADeviceEvent */
+
+
+/* RecordFlushAllContexts
+ *
+ * Arguments:
+ * pcbl is &FlushCallback.
+ * nulldata and calldata are NULL.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * All buffered reply data of all enabled contexts is written to
+ * the recording clients.
+ */
+static void
+RecordFlushAllContexts(
+ CallbackListPtr *pcbl,
+ void * nulldata,
+ void * calldata
+)
+{
+ int eci; /* enabled context index */
+ RecordContextPtr pContext;
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+
+ /* In most cases we leave it to RecordFlushReplyBuffer to make
+ * this check, but this function could be called very often, so we
+ * check before calling hoping to save the function call cost
+ * most of the time.
+ */
+ if (pContext->numBufBytes)
+ RecordFlushReplyBuffer(ppAllContexts[eci], NULL, 0, NULL, 0);
+ }
+} /* RecordFlushAllContexts */
+
+
+/* RecordInstallHooks
+ *
+ * Arguments:
+ * pRCAP is an RCAP on an enabled or being-enabled context.
+ * oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * Recording hooks needed by RCAP are installed.
+ * If oneclient is zero, recording hooks needed for all clients and
+ * protocol on the RCAP are installed. If oneclient is non-zero,
+ * only those hooks needed for the specified client are installed.
+ *
+ * Client requestVectors may be altered. numEnabledRCAPs will be
+ * incremented if oneclient == 0. Callbacks may be added to
+ * various callback lists.
+ */
+static int
+RecordInstallHooks(pRCAP, oneclient)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID oneclient;
+{
+ int i = 0;
+ XID client;
+
+ if (oneclient)
+ client = oneclient;
+ else
+ client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+ while (client)
+ {
+ if (client != XRecordFutureClients)
+ {
+ if (pRCAP->pRequestMajorOpSet)
+ {
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+ ClientPtr pClient = clients[CLIENT_ID(client)];
+
+ if (pClient && !RecordClientPrivate(pClient))
+ {
+ RecordClientPrivatePtr pClientPriv;
+ /* no Record proc vector; allocate one */
+ pClientPriv = (RecordClientPrivatePtr)
+ malloc(sizeof(RecordClientPrivateRec));
+ if (!pClientPriv)
+ return BadAlloc;
+ /* copy old proc vector to new */
+ memcpy(pClientPriv->recordVector, pClient->requestVector,
+ sizeof (pClientPriv->recordVector));
+ pClientPriv->originalVector = pClient->requestVector;
+ pClient->devPrivates[RecordClientPrivateIndex].ptr =
+ (void *)pClientPriv;
+ pClient->requestVector = pClientPriv->recordVector;
+ }
+ while ((pIter = RecordIterateSet(pRCAP->pRequestMajorOpSet,
+ pIter, &interval)))
+ {
+ unsigned int j;
+ for (j = interval.first; j <= interval.last; j++)
+ pClient->requestVector[j] = RecordARequest;
+ }
+ }
+ }
+ if (oneclient)
+ client = 0;
+ else
+ client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+ }
+
+ assert(numEnabledRCAPs >= 0);
+ if (!oneclient && ++numEnabledRCAPs == 1)
+ { /* we're enabling the first context */
+ if (!AddCallback(&EventCallback, RecordADeliveredEventOrError, NULL))
+ return BadAlloc;
+ if (!AddCallback(&DeviceEventCallback, RecordADeviceEvent, NULL))
+ return BadAlloc;
+ if (!AddCallback(&ReplyCallback, RecordAReply, NULL))
+ return BadAlloc;
+ if (!AddCallback(&SkippedRequestsCallback, RecordASkippedRequest,
+ NULL))
+ return BadAlloc;
+ if (!AddCallback(&FlushCallback, RecordFlushAllContexts, NULL))
+ return BadAlloc;
+ /* Alternate context flushing scheme: delete the line above
+ * and call RegisterBlockAndWakeupHandlers here passing
+ * RecordFlushAllContexts. Is this any better?
+ */
+ }
+ return Success;
+} /* RecordInstallHooks */
+
+
+/* RecordUninstallHooks
+ *
+ * Arguments:
+ * pRCAP is an RCAP on an enabled or being-disabled context.
+ * oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by RCAP may be uninstalled.
+ * If oneclient is zero, recording hooks needed for all clients and
+ * protocol on the RCAP may be uninstalled. If oneclient is non-zero,
+ * only those hooks needed for the specified client may be uninstalled.
+ *
+ * Client requestVectors may be altered. numEnabledRCAPs will be
+ * decremented if oneclient == 0. Callbacks may be deleted from
+ * various callback lists.
+ */
+static void
+RecordUninstallHooks(pRCAP, oneclient)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID oneclient;
+{
+ int i = 0;
+ XID client;
+
+ if (oneclient)
+ client = oneclient;
+ else
+ client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+ while (client)
+ {
+ if (client != XRecordFutureClients)
+ {
+ if (pRCAP->pRequestMajorOpSet)
+ {
+ ClientPtr pClient = clients[CLIENT_ID(client)];
+ int c;
+ Bool otherRCAPwantsProcVector = FALSE;
+ RecordClientPrivatePtr pClientPriv =
+ RecordClientPrivate(pClient);
+
+ assert (pClient && RecordClientPrivate(pClient));
+ memcpy(pClientPriv->recordVector, pClientPriv->originalVector,
+ sizeof (pClientPriv->recordVector));
+
+ for (c = 0; c < numEnabledContexts; c++)
+ {
+ RecordClientsAndProtocolPtr pOtherRCAP;
+ RecordContextPtr pContext = ppAllContexts[c];
+
+ if (pContext == pRCAP->pContext) continue;
+ pOtherRCAP = RecordFindClientOnContext(pContext, client,
+ NULL);
+ if (pOtherRCAP && pOtherRCAP->pRequestMajorOpSet)
+ {
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+
+ otherRCAPwantsProcVector = TRUE;
+ while ((pIter = RecordIterateSet(
+ pOtherRCAP->pRequestMajorOpSet,
+ pIter, &interval)))
+ {
+ unsigned int j;
+ for (j = interval.first; j <= interval.last; j++)
+ pClient->requestVector[j] = RecordARequest;
+ }
+ }
+ }
+ if (!otherRCAPwantsProcVector)
+ { /* nobody needs it, so free it */
+ pClient->requestVector = pClientPriv->originalVector;
+ pClient->devPrivates[RecordClientPrivateIndex].ptr = NULL;
+ free(pClientPriv);
+ }
+ } /* end if this RCAP specifies any requests */
+ } /* end if not future clients */
+ if (oneclient)
+ client = 0;
+ else
+ client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+ }
+
+ assert(numEnabledRCAPs >= 1);
+ if (!oneclient && --numEnabledRCAPs == 0)
+ { /* we're disabling the last context */
+ DeleteCallback(&EventCallback, RecordADeliveredEventOrError, NULL);
+ DeleteCallback(&DeviceEventCallback, RecordADeviceEvent, NULL);
+ DeleteCallback(&ReplyCallback, RecordAReply, NULL);
+ DeleteCallback(&SkippedRequestsCallback, RecordASkippedRequest, NULL);
+ DeleteCallback(&FlushCallback, RecordFlushAllContexts, NULL);
+ /* Alternate context flushing scheme: delete the line above
+ * and call RemoveBlockAndWakeupHandlers here passing
+ * RecordFlushAllContexts. Is this any better?
+ */
+ /* Having deleted the callback, call it one last time. -gildea */
+ RecordFlushAllContexts(&FlushCallback, NULL, NULL);
+ }
+} /* RecordUninstallHooks */
+
+
+/* RecordDeleteClientFromRCAP
+ *
+ * Arguments:
+ * pRCAP is an RCAP to delete the client from.
+ * position is the index into the array pRCAP->pClientIDs of the
+ * client to delete.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by client will be uninstalled if the context
+ * is enabled. The designated client will be removed from the
+ * pRCAP->pClientIDs array. If it was the only client on the RCAP,
+ * the RCAP is removed from the context and freed. (Invariant: RCAPs
+ * have at least one client.)
+ */
+static void
+RecordDeleteClientFromRCAP(pRCAP, position)
+ RecordClientsAndProtocolPtr pRCAP;
+ int position;
+{
+ if (pRCAP->pContext->pRecordingClient)
+ RecordUninstallHooks(pRCAP, pRCAP->pClientIDs[position]);
+ if (position != pRCAP->numClients - 1)
+ pRCAP->pClientIDs[position] = pRCAP->pClientIDs[pRCAP->numClients - 1];
+ if (--pRCAP->numClients == 0)
+ { /* no more clients; remove RCAP from context's list */
+ RecordContextPtr pContext = pRCAP->pContext;
+ if (pContext->pRecordingClient)
+ RecordUninstallHooks(pRCAP, 0);
+ if (pContext->pListOfRCAP == pRCAP)
+ pContext->pListOfRCAP = pRCAP->pNextRCAP;
+ else
+ {
+ RecordClientsAndProtocolPtr prevRCAP;
+ for (prevRCAP = pContext->pListOfRCAP;
+ prevRCAP->pNextRCAP != pRCAP;
+ prevRCAP = prevRCAP->pNextRCAP)
+ ;
+ prevRCAP->pNextRCAP = pRCAP->pNextRCAP;
+ }
+ /* free the RCAP */
+ if (pRCAP->clientIDsSeparatelyAllocated)
+ free(pRCAP->pClientIDs);
+ free(pRCAP);
+ }
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordAddClientToRCAP
+ *
+ * Arguments:
+ * pRCAP is an RCAP to add the client to.
+ * clientspec is the resource ID mask identifying a client, or
+ * XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by client will be installed if the context
+ * is enabled. The designated client will be added to the
+ * pRCAP->pClientIDs array, which may be realloced.
+ * pRCAP->clientIDsSeparatelyAllocated may be set to 1 if there
+ * is no more room to hold clients internal to the RCAP.
+ */
+static void
+RecordAddClientToRCAP(pRCAP, clientspec)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID clientspec;
+{
+ if (pRCAP->numClients == pRCAP->sizeClients)
+ {
+ if (pRCAP->clientIDsSeparatelyAllocated)
+ {
+ XID *pNewIDs = (XID *)realloc(pRCAP->pClientIDs,
+ (pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT) *
+ sizeof(XID));
+ if (!pNewIDs)
+ return;
+ pRCAP->pClientIDs = pNewIDs;
+ pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+ }
+ else
+ {
+ XID *pNewIDs = (XID *)malloc((pRCAP->sizeClients +
+ CLIENT_ARRAY_GROWTH_INCREMENT) * sizeof(XID));
+ if (!pNewIDs)
+ return;
+ memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients *sizeof(XID));
+ pRCAP->pClientIDs = pNewIDs;
+ pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+ pRCAP->clientIDsSeparatelyAllocated = 1;
+ }
+ }
+ pRCAP->pClientIDs[pRCAP->numClients++] = clientspec;
+ if (pRCAP->pContext->pRecordingClient)
+ RecordInstallHooks(pRCAP, clientspec);
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordDeleteClientFromContext
+ *
+ * Arguments:
+ * pContext is the context to delete from.
+ * clientspec is the resource ID mask identifying a client, or
+ * XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If clientspec is on any RCAP of the context, it is deleted from that
+ * RCAP. (A given clientspec can only be on one RCAP of a context.)
+ */
+static void
+RecordDeleteClientFromContext(pContext, clientspec)
+ RecordContextPtr pContext;
+ XID clientspec;
+{
+ RecordClientsAndProtocolPtr pRCAP;
+ int position;
+
+ if ((pRCAP = RecordFindClientOnContext(pContext, clientspec, &position)))
+ RecordDeleteClientFromRCAP(pRCAP, position);
+} /* RecordDeleteClientFromContext */
+
+
+/* RecordSanityCheckClientSpecifiers
+ *
+ * Arguments:
+ * clientspecs is an array of alleged CLIENTSPECs passed by the client.
+ * nspecs is the number of elements in clientspecs.
+ * errorspec, if non-zero, is the resource id base of a client that
+ * must not appear in clienspecs.
+ *
+ * Returns: BadMatch if any of the clientspecs are invalid, else Success.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckClientSpecifiers(clientspecs, nspecs, errorspec)
+ XID *clientspecs;
+ int nspecs;
+ XID errorspec;
+{
+ int i;
+ int clientIndex;
+
+ for (i = 0; i < nspecs; i++)
+ {
+ if (clientspecs[i] == XRecordCurrentClients ||
+ clientspecs[i] == XRecordFutureClients ||
+ clientspecs[i] == XRecordAllClients)
+ continue;
+ if (errorspec && (CLIENT_BITS(clientspecs[i]) == errorspec) )
+ return BadMatch;
+ clientIndex = CLIENT_ID(clientspecs[i]);
+ if (clientIndex && clients[clientIndex] &&
+ clients[clientIndex]->clientState == ClientStateRunning)
+ {
+ if (clientspecs[i] == clients[clientIndex]->clientAsMask)
+ continue;
+ if (!LookupIDByClass(clientspecs[i], RC_ANY))
+ return BadMatch;
+ }
+ else
+ return BadMatch;
+ }
+ return Success;
+} /* RecordSanityCheckClientSpecifiers */
+
+
+/* RecordCanonicalizeClientSpecifiers
+ *
+ * Arguments:
+ * pClientspecs is an array of CLIENTSPECs that have been sanity
+ * checked.
+ * pNumClientspecs is a pointer to the number of elements in pClientspecs.
+ * excludespec, if non-zero, is the resource id base of a client that
+ * should not be included in the expansion of XRecordAllClients or
+ * XRecordCurrentClients.
+ *
+ * Returns:
+ * A pointer to an array of CLIENTSPECs that is the same as the
+ * passed array with the following modifications:
+ * - all but the client id bits of resource IDs are stripped off.
+ * - duplicates removed.
+ * - XRecordAllClients expanded to a list of all currently connected
+ * clients + XRecordFutureClients - excludespec (if non-zero)
+ * - XRecordCurrentClients expanded to a list of all currently
+ * connected clients - excludespec (if non-zero)
+ * The returned array may be the passed array modified in place, or
+ * it may be an malloc'ed array. The caller should keep a pointer to the
+ * original array and free the returned array if it is different.
+ *
+ * *pNumClientspecs is set to the number of elements in the returned
+ * array.
+ *
+ * Side Effects:
+ * pClientspecs may be modified in place.
+ */
+static XID *
+RecordCanonicalizeClientSpecifiers(pClientspecs, pNumClientspecs, excludespec)
+ XID *pClientspecs;
+ int *pNumClientspecs;
+ XID excludespec;
+{
+ int i;
+ int numClients = *pNumClientspecs;
+
+ /* first pass strips off the resource index bits, leaving just the
+ * client id bits. This makes searching for a particular client simpler
+ * (and faster.)
+ */
+ for (i = 0; i < numClients; i++)
+ {
+ XID cs = pClientspecs[i];
+ if (cs > XRecordAllClients)
+ pClientspecs[i] = CLIENT_BITS(cs);
+ }
+
+ for (i = 0; i < numClients; i++)
+ {
+ if (pClientspecs[i] == XRecordAllClients ||
+ pClientspecs[i] == XRecordCurrentClients)
+ { /* expand All/Current */
+ int j, nc;
+ XID *pCanon = (XID *)malloc(sizeof(XID) * (currentMaxClients + 1));
+ if (!pCanon) return NULL;
+ for (nc = 0, j = 1; j < currentMaxClients; j++)
+ {
+ ClientPtr client = clients[j];
+ if (client != NullClient &&
+ client->clientState == ClientStateRunning &&
+ client->clientAsMask != excludespec)
+ {
+ pCanon[nc++] = client->clientAsMask;
+ }
+ }
+ if (pClientspecs[i] == XRecordAllClients)
+ pCanon[nc++] = XRecordFutureClients;
+ *pNumClientspecs = nc;
+ return pCanon;
+ }
+ else /* not All or Current */
+ {
+ int j;
+ for (j = i + 1; j < numClients; )
+ {
+ if (pClientspecs[i] == pClientspecs[j])
+ {
+ pClientspecs[j] = pClientspecs[--numClients];
+ }
+ else
+ j++;
+ }
+ }
+ } /* end for each clientspec */
+ *pNumClientspecs = numClients;
+ return pClientspecs;
+} /* RecordCanonicalizeClientSpecifiers */
+
+
+/****************************************************************************/
+
+/* stuff for RegisterClients */
+
+/* RecordPadAlign
+ *
+ * Arguments:
+ * size is the number of bytes taken by an object.
+ * align is a byte boundary (e.g. 4, 8)
+ *
+ * Returns:
+ * the number of pad bytes to add at the end of an object of the
+ * given size so that an object placed immediately behind it will
+ * begin on an <align>-byte boundary.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordPadAlign(int size, int align)
+{
+ return (align - (size & (align - 1))) & (align - 1);
+} /* RecordPadAlign */
+
+
+/* RecordSanityCheckRegisterClients
+ *
+ * Arguments:
+ * pContext is the context being registered on.
+ * client is the client that issued a RecordCreateContext or
+ * RecordRegisterClients request.
+ * stuff is a pointer to the request.
+ *
+ * Returns:
+ * Any one of several possible error values if any of the request
+ * arguments are invalid. Success if everything is OK.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckRegisterClients(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xRecordRegisterClientsReq *stuff;
+{
+ int err;
+ xRecordRange *pRange;
+ int i;
+ XID recordingClient;
+
+ if (((client->req_len << 2) - SIZEOF(xRecordRegisterClientsReq)) !=
+ 4 * stuff->nClients + SIZEOF(xRecordRange) * stuff->nRanges)
+ return BadLength;
+
+ if (stuff->elementHeader &
+ ~(XRecordFromClientSequence|XRecordFromClientTime|XRecordFromServerTime))
+ {
+ client->errorValue = stuff->elementHeader;
+ return BadValue;
+ }
+
+ recordingClient = pContext->pRecordingClient ?
+ pContext->pRecordingClient->clientAsMask : 0;
+ err = RecordSanityCheckClientSpecifiers((XID *)&stuff[1], stuff->nClients,
+ recordingClient);
+ if (err != Success) return err;
+
+ pRange = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+ for (i = 0; i < stuff->nRanges; i++, pRange++)
+ {
+ if (pRange->coreRequestsFirst > pRange->coreRequestsLast)
+ {
+ client->errorValue = pRange->coreRequestsFirst;
+ return BadValue;
+ }
+ if (pRange->coreRepliesFirst > pRange->coreRepliesLast)
+ {
+ client->errorValue = pRange->coreRepliesFirst;
+ return BadValue;
+ }
+ if ((pRange->extRequestsMajorFirst || pRange->extRequestsMajorLast) &&
+ (pRange->extRequestsMajorFirst < 128 ||
+ pRange->extRequestsMajorLast < 128 ||
+ pRange->extRequestsMajorFirst > pRange->extRequestsMajorLast))
+ {
+ client->errorValue = pRange->extRequestsMajorFirst;
+ return BadValue;
+ }
+ if (pRange->extRequestsMinorFirst > pRange->extRequestsMinorLast)
+ {
+ client->errorValue = pRange->extRequestsMinorFirst;
+ return BadValue;
+ }
+ if ((pRange->extRepliesMajorFirst || pRange->extRepliesMajorLast) &&
+ (pRange->extRepliesMajorFirst < 128 ||
+ pRange->extRepliesMajorLast < 128 ||
+ pRange->extRepliesMajorFirst > pRange->extRepliesMajorLast))
+ {
+ client->errorValue = pRange->extRepliesMajorFirst;
+ return BadValue;
+ }
+ if (pRange->extRepliesMinorFirst > pRange->extRepliesMinorLast)
+ {
+ client->errorValue = pRange->extRepliesMinorFirst;
+ return BadValue;
+ }
+ if ((pRange->deliveredEventsFirst || pRange->deliveredEventsLast) &&
+ (pRange->deliveredEventsFirst < 2 ||
+ pRange->deliveredEventsLast < 2 ||
+ pRange->deliveredEventsFirst > pRange->deliveredEventsLast))
+ {
+ client->errorValue = pRange->deliveredEventsFirst;
+ return BadValue;
+ }
+ if ((pRange->deviceEventsFirst || pRange->deviceEventsLast) &&
+ (pRange->deviceEventsFirst < 2 ||
+ pRange->deviceEventsLast < 2 ||
+ pRange->deviceEventsFirst > pRange->deviceEventsLast))
+ {
+ client->errorValue = pRange->deviceEventsFirst;
+ return BadValue;
+ }
+ if (pRange->errorsFirst > pRange->errorsLast)
+ {
+ client->errorValue = pRange->errorsFirst;
+ return BadValue;
+ }
+ if (pRange->clientStarted != xFalse && pRange->clientStarted != xTrue)
+ {
+ client->errorValue = pRange->clientStarted;
+ return BadValue;
+ }
+ if (pRange->clientDied != xFalse && pRange->clientDied != xTrue)
+ {
+ client->errorValue = pRange->clientDied;
+ return BadValue;
+ }
+ } /* end for each range */
+ return Success;
+} /* end RecordSanityCheckRegisterClients */
+
+/* This is a tactical structure used to gather information about all the sets
+ * (RecordSetPtr) that need to be created for an RCAP in the process of
+ * digesting a list of RECORDRANGEs (converting it to the internal
+ * representation).
+ */
+typedef struct
+{
+ int nintervals; /* number of intervals in following array */
+ RecordSetInterval *intervals; /* array of intervals for this set */
+ int size; /* size of intevals array; >= nintervals */
+ int align; /* alignment restriction for set */
+ int offset; /* where to store set pointer rel. to start of RCAP */
+ short first, last; /* if for extension, major opcode interval */
+} SetInfoRec, *SetInfoPtr;
+
+/* These constant are used to index into an array of SetInfoRec. */
+enum {REQ, /* set info for requests */
+ REP, /* set info for replies */
+ ERR, /* set info for errors */
+ DEV, /* set info for device events */
+ DLEV, /* set info for delivered events */
+ PREDEFSETS}; /* number of predefined array entries */
+
+
+/* RecordAllocIntervals
+ *
+ * Arguments:
+ * psi is a pointer to a SetInfoRec whose intervals pointer is NULL.
+ * nIntervals is the desired size of the intervals array.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, psi->intervals is a pointer to size
+ * RecordSetIntervals, all zeroed, and psi->size is set to size.
+ */
+static int
+RecordAllocIntervals(psi, nIntervals)
+ SetInfoPtr psi;
+ int nIntervals;
+{
+ assert(!psi->intervals);
+ psi->intervals = (RecordSetInterval *)
+ malloc(nIntervals * sizeof(RecordSetInterval));
+ if (!psi->intervals)
+ return BadAlloc;
+ bzero(psi->intervals, nIntervals * sizeof(RecordSetInterval));
+ psi->size = nIntervals;
+ return Success;
+} /* end RecordAllocIntervals */
+
+
+/* RecordConvertRangesToIntervals
+ *
+ * Arguments:
+ * psi is a pointer to the SetInfoRec we are building.
+ * pRanges is an array of xRecordRanges.
+ * nRanges is the number of elements in pRanges.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * two bytes (1 for first, 1 for last) we are interested in.
+ * pExtSetInfo, if non-NULL, indicates that the two bytes mentioned
+ * above are followed by four bytes (2 for first, 2 for last)
+ * representing a minor opcode range, and this information should be
+ * stored in one of the SetInfoRecs starting at pExtSetInfo.
+ * pnExtSetInfo is the number of elements in the pExtSetInfo array.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * The slice of pRanges indicated by byteoffset is stored in psi.
+ * If pExtSetInfo is non-NULL, minor opcode intervals are stored
+ * in an existing SetInfoRec if the major opcode interval matches, else
+ * they are stored in a new SetInfoRec, and *pnExtSetInfo is
+ * increased accordingly.
+ */
+static int
+RecordConvertRangesToIntervals(
+ SetInfoPtr psi,
+ xRecordRange *pRanges,
+ int nRanges,
+ int byteoffset,
+ SetInfoPtr pExtSetInfo,
+ int *pnExtSetInfo
+)
+{
+ int i;
+ CARD8 *pCARD8;
+ int first, last;
+ int err;
+
+ for (i = 0; i < nRanges; i++, pRanges++)
+ {
+ pCARD8 = ((CARD8 *)pRanges) + byteoffset;
+ first = pCARD8[0];
+ last = pCARD8[1];
+ if (first || last)
+ {
+ if (!psi->intervals)
+ {
+ err = RecordAllocIntervals(psi, 2 * (nRanges - i));
+ if (err != Success)
+ return err;
+ }
+ psi->intervals[psi->nintervals].first = first;
+ psi->intervals[psi->nintervals].last = last;
+ psi->nintervals++;
+ assert(psi->nintervals <= psi->size);
+ if (pExtSetInfo)
+ {
+ SetInfoPtr pesi = pExtSetInfo;
+ CARD16 *pCARD16 = (CARD16 *)(pCARD8 + 2);
+ int j;
+
+ for (j = 0; j < *pnExtSetInfo; j++, pesi++)
+ {
+ if ( (first == pesi->first) && (last == pesi->last) )
+ break;
+ }
+ if (j == *pnExtSetInfo)
+ {
+ err = RecordAllocIntervals(pesi, 2 * (nRanges - i));
+ if (err != Success)
+ return err;
+ pesi->first = first;
+ pesi->last = last;
+ (*pnExtSetInfo)++;
+ }
+ pesi->intervals[pesi->nintervals].first = pCARD16[0];
+ pesi->intervals[pesi->nintervals].last = pCARD16[1];
+ pesi->nintervals++;
+ assert(pesi->nintervals <= pesi->size);
+ }
+ }
+ }
+ return Success;
+} /* end RecordConvertRangesToIntervals */
+
+#define offset_of(_structure, _field) \
+ ((char *)(& (_structure . _field)) - (char *)(&_structure))
+
+/* RecordRegisterClients
+ *
+ * Arguments:
+ * pContext is the context on which to register the clients.
+ * client is the client that issued the RecordCreateContext or
+ * RecordRegisterClients request.
+ * stuff is a pointer to the request.
+ *
+ * Returns:
+ * Any one of several possible error values defined by the protocol.
+ * Success if everything is OK.
+ *
+ * Side Effects:
+ * If different element headers are specified, the context is flushed.
+ * If any of the specified clients are already registered on the
+ * context, they are first unregistered. A new RCAP is created to
+ * hold the specified protocol and clients, and it is linked onto the
+ * context. If the context is enabled, appropriate hooks are installed
+ * to record the new clients and protocol.
+ */
+static int
+RecordRegisterClients(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xRecordRegisterClientsReq *stuff;
+{
+ int err;
+ int i;
+ SetInfoPtr si;
+ int maxSets;
+ int nExtReqSets = 0;
+ int nExtRepSets = 0;
+ int extReqSetsOffset = 0;
+ int extRepSetsOffset = 0;
+ SetInfoPtr pExtReqSets, pExtRepSets;
+ int clientListOffset;
+ XID *pCanonClients;
+ int clientStarted = 0, clientDied = 0;
+ xRecordRange *pRanges, rr;
+ int nClients;
+ int sizeClients;
+ int totRCAPsize;
+ RecordClientsAndProtocolPtr pRCAP;
+ int pad;
+ XID recordingClient;
+
+ /* do all sanity checking up front */
+
+ err = RecordSanityCheckRegisterClients(pContext, client, stuff);
+ if (err != Success)
+ return err;
+
+ /* if element headers changed, flush buffer */
+
+ if (pContext->elemHeaders != stuff->elementHeader)
+ {
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ pContext->elemHeaders = stuff->elementHeader;
+ }
+
+ nClients = stuff->nClients;
+ if (!nClients)
+ /* if empty clients list, we're done. */
+ return Success;
+
+ recordingClient = pContext->pRecordingClient ?
+ pContext->pRecordingClient->clientAsMask : 0;
+ pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+ &nClients, recordingClient);
+ if (!pCanonClients)
+ return BadAlloc;
+
+ /* We may have to create as many as one set for each "predefined"
+ * protocol types, plus one per range for extension reuests, plus one per
+ * range for extension replies.
+ */
+ maxSets = PREDEFSETS + 2 * stuff->nRanges;
+ si = (SetInfoPtr)malloc(sizeof(SetInfoRec) * maxSets);
+ if (!si)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+ bzero(si, sizeof(SetInfoRec) * maxSets);
+
+ /* theoretically you must do this because NULL may not be all-bits-zero */
+ for (i = 0; i < maxSets; i++)
+ si[i].intervals = NULL;
+
+ pExtReqSets = si + PREDEFSETS;
+ pExtRepSets = pExtReqSets + stuff->nRanges;
+
+ pRanges = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+
+ err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+ offset_of(rr, coreRequestsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+ offset_of(rr, extRequestsMajorFirst), pExtReqSets, &nExtReqSets);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+ offset_of(rr, coreRepliesFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+ offset_of(rr, extRepliesMajorFirst), pExtRepSets, &nExtRepSets);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[ERR], pRanges, stuff->nRanges,
+ offset_of(rr, errorsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[DLEV], pRanges, stuff->nRanges,
+ offset_of(rr, deliveredEventsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[DEV], pRanges, stuff->nRanges,
+ offset_of(rr, deviceEventsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ /* collect client-started and client-died */
+
+ for (i = 0; i < stuff->nRanges; i++)
+ {
+ if (pRanges[i].clientStarted) clientStarted = TRUE;
+ if (pRanges[i].clientDied) clientDied = TRUE;
+ }
+
+ /* We now have all the information collected to create all the sets,
+ * and we can compute the total memory required for the RCAP.
+ */
+
+ totRCAPsize = sizeof(RecordClientsAndProtocolRec);
+
+ /* leave a little room to grow before forcing a separate allocation */
+ sizeClients = nClients + CLIENT_ARRAY_GROWTH_INCREMENT;
+ pad = RecordPadAlign(totRCAPsize, sizeof(XID));
+ clientListOffset = totRCAPsize + pad;
+ totRCAPsize += pad + sizeClients * sizeof(XID);
+
+ if (nExtReqSets)
+ {
+ pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+ extReqSetsOffset = totRCAPsize + pad;
+ totRCAPsize += pad + (nExtReqSets + 1) * sizeof(RecordMinorOpRec);
+ }
+ if (nExtRepSets)
+ {
+ pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+ extRepSetsOffset = totRCAPsize + pad;
+ totRCAPsize += pad + (nExtRepSets + 1) * sizeof(RecordMinorOpRec);
+ }
+
+ for (i = 0; i < maxSets; i++)
+ {
+ if (si[i].nintervals)
+ {
+ si[i].size = RecordSetMemoryRequirements(
+ si[i].intervals, si[i].nintervals, &si[i].align);
+ pad = RecordPadAlign(totRCAPsize, si[i].align);
+ si[i].offset = pad + totRCAPsize;
+ totRCAPsize += pad + si[i].size;
+ }
+ }
+
+ /* allocate memory for the whole RCAP */
+
+ pRCAP = (RecordClientsAndProtocolPtr)malloc(totRCAPsize);
+ if (!pRCAP)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* fill in the RCAP */
+
+ pRCAP->pContext = pContext;
+ pRCAP->pClientIDs = (XID *)((char *)pRCAP + clientListOffset);
+ pRCAP->numClients = nClients;
+ pRCAP->sizeClients = sizeClients;
+ pRCAP->clientIDsSeparatelyAllocated = 0;
+ for (i = 0; i < nClients; i++)
+ {
+ RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+ pRCAP->pClientIDs[i] = pCanonClients[i];
+ }
+
+ /* create all the sets */
+
+ if (si[REQ].intervals)
+ {
+ pRCAP->pRequestMajorOpSet =
+ RecordCreateSet(si[REQ].intervals, si[REQ].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[REQ].offset), si[REQ].size);
+ }
+ else pRCAP->pRequestMajorOpSet = NULL;
+
+ if (si[REP].intervals)
+ {
+ pRCAP->pReplyMajorOpSet =
+ RecordCreateSet(si[REP].intervals, si[REP].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[REP].offset), si[REP].size);
+ }
+ else pRCAP->pReplyMajorOpSet = NULL;
+
+ if (si[ERR].intervals)
+ {
+ pRCAP->pErrorSet =
+ RecordCreateSet(si[ERR].intervals, si[ERR].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[ERR].offset), si[ERR].size);
+ }
+ else pRCAP->pErrorSet = NULL;
+
+ if (si[DEV].intervals)
+ {
+ pRCAP->pDeviceEventSet =
+ RecordCreateSet(si[DEV].intervals, si[DEV].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[DEV].offset), si[DEV].size);
+ }
+ else pRCAP->pDeviceEventSet = NULL;
+
+ if (si[DLEV].intervals)
+ {
+ pRCAP->pDeliveredEventSet =
+ RecordCreateSet(si[DLEV].intervals, si[DLEV].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[DLEV].offset), si[DLEV].size);
+ }
+ else pRCAP->pDeliveredEventSet = NULL;
+
+ if (nExtReqSets)
+ {
+ pRCAP->pRequestMinOpInfo = (RecordMinorOpPtr)
+ ((char *)pRCAP + extReqSetsOffset);
+ pRCAP->pRequestMinOpInfo[0].count = nExtReqSets;
+ for (i = 0; i < nExtReqSets; i++, pExtReqSets++)
+ {
+ pRCAP->pRequestMinOpInfo[i+1].major.first = pExtReqSets->first;
+ pRCAP->pRequestMinOpInfo[i+1].major.last = pExtReqSets->last;
+ pRCAP->pRequestMinOpInfo[i+1].major.pMinOpSet =
+ RecordCreateSet(pExtReqSets->intervals,
+ pExtReqSets->nintervals,
+ (RecordSetPtr)((char *)pRCAP + pExtReqSets->offset),
+ pExtReqSets->size);
+ }
+ }
+ else pRCAP->pRequestMinOpInfo = NULL;
+
+ if (nExtRepSets)
+ {
+ pRCAP->pReplyMinOpInfo = (RecordMinorOpPtr)
+ ((char *)pRCAP + extRepSetsOffset);
+ pRCAP->pReplyMinOpInfo[0].count = nExtRepSets;
+ for (i = 0; i < nExtRepSets; i++, pExtRepSets++)
+ {
+ pRCAP->pReplyMinOpInfo[i+1].major.first = pExtRepSets->first;
+ pRCAP->pReplyMinOpInfo[i+1].major.last = pExtRepSets->last;
+ pRCAP->pReplyMinOpInfo[i+1].major.pMinOpSet =
+ RecordCreateSet(pExtRepSets->intervals,
+ pExtRepSets->nintervals,
+ (RecordSetPtr)((char *)pRCAP + pExtRepSets->offset),
+ pExtRepSets->size);
+ }
+ }
+ else pRCAP->pReplyMinOpInfo = NULL;
+
+ pRCAP->clientStarted = clientStarted;
+ pRCAP->clientDied = clientDied;
+
+ /* link the RCAP onto the context */
+
+ pRCAP->pNextRCAP = pContext->pListOfRCAP;
+ pContext->pListOfRCAP = pRCAP;
+
+ if (pContext->pRecordingClient) /* context enabled */
+ RecordInstallHooks(pRCAP, 0);
+
+bailout:
+ if (si)
+ {
+ for (i = 0; i < maxSets; i++)
+ if (si[i].intervals)
+ free(si[i].intervals);
+ free(si);
+ }
+ if (pCanonClients && pCanonClients != (XID *)&stuff[1])
+ free(pCanonClients);
+ return err;
+} /* RecordRegisterClients */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcRecordQueryVersion(client)
+ ClientPtr client;
+{
+ /* REQUEST(xRecordQueryVersionReq); */
+ xRecordQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = SERVER_RECORD_MAJOR_VERSION;
+ rep.minorVersion = SERVER_RECORD_MINOR_VERSION;
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xRecordQueryVersionReply),
+ &rep);
+ return (client->noClientException);
+} /* ProcRecordQueryVersion */
+
+
+static int
+ProcRecordCreateContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordCreateContextReq);
+ RecordContextPtr pContext;
+ RecordContextPtr *ppNewAllContexts = NULL;
+ int err = BadAlloc;
+
+ REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+ LEGAL_NEW_RESOURCE(stuff->context, client);
+
+ pContext = (RecordContextPtr)malloc(sizeof(RecordContextRec));
+ if (!pContext)
+ goto bailout;
+
+ /* make sure there is room in ppAllContexts to store the new context */
+
+ ppNewAllContexts = (RecordContextPtr *)
+ realloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1));
+ if (!ppNewAllContexts)
+ goto bailout;
+ ppAllContexts = ppNewAllContexts;
+
+ pContext->id = stuff->context;
+ pContext->pRecordingClient = NULL;
+ pContext->pListOfRCAP = NULL;
+ pContext->elemHeaders = 0;
+ pContext->bufCategory = 0;
+ pContext->numBufBytes = 0;
+ pContext->pBufClient = NULL;
+ pContext->continuedReply = 0;
+ pContext->inFlush = 0;
+
+ err = RecordRegisterClients(pContext, client,
+ (xRecordRegisterClientsReq *)stuff);
+ if (err != Success)
+ goto bailout;
+
+ if (AddResource(pContext->id, RTContext, pContext))
+ {
+ ppAllContexts[numContexts++] = pContext;
+ return Success;
+ }
+ else
+ {
+ RecordDeleteContext((void *)pContext, pContext->id);
+ err = BadAlloc;
+ }
+bailout:
+ if (pContext)
+ free(pContext);
+ return err;
+} /* ProcRecordCreateContext */
+
+
+static int
+ProcRecordRegisterClients(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordRegisterClientsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+
+ return RecordRegisterClients(pContext, client, stuff);
+} /* ProcRecordRegisterClients */
+
+
+static int
+ProcRecordUnregisterClients(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ int err;
+ REQUEST(xRecordUnregisterClientsReq);
+ XID *pCanonClients;
+ int nClients;
+ int i;
+
+ REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+ if ((client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) !=
+ 4 * stuff->nClients)
+ return BadLength;
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ err = RecordSanityCheckClientSpecifiers((XID *)&stuff[1],
+ stuff->nClients, 0);
+ if (err != Success)
+ return err;
+
+ nClients = stuff->nClients;
+ pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+ &nClients, 0);
+ if (!pCanonClients)
+ return BadAlloc;
+
+ for (i = 0; i < nClients; i++)
+ {
+ RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+ }
+ if (pCanonClients != (XID *)&stuff[1])
+ free(pCanonClients);
+ return Success;
+} /* ProcRecordUnregisterClients */
+
+
+/****************************************************************************/
+
+/* stuff for GetContext */
+
+/* This is a tactical structure used to hold the xRecordRanges as they are
+ * being reconstituted from the sets in the RCAPs.
+ */
+
+typedef struct {
+ xRecordRange *pRanges; /* array of xRecordRanges for one RCAP */
+ int size; /* number of elements in pRanges, >= nRanges */
+ int nRanges; /* number of occupied element of pRanges */
+} GetContextRangeInfoRec, *GetContextRangeInfoPtr;
+
+
+/* RecordAllocRanges
+ *
+ * Arguments:
+ * pri is a pointer to a GetContextRangeInfoRec to allocate for.
+ * nRanges is the number of xRecordRanges desired for pri.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, pri->pRanges points to at least nRanges
+ * ranges. pri->nRanges is set to nRanges. pri->size is the actual
+ * number of ranges. Newly allocated ranges are zeroed.
+ */
+static int
+RecordAllocRanges(pri, nRanges)
+ GetContextRangeInfoPtr pri;
+ int nRanges;
+{
+ int newsize;
+ xRecordRange *pNewRange;
+#define SZINCR 8
+
+ newsize = max(pri->size + SZINCR, nRanges);
+ pNewRange = (xRecordRange *)realloc(pri->pRanges,
+ newsize * sizeof(xRecordRange));
+ if (!pNewRange)
+ return BadAlloc;
+
+ pri->pRanges = pNewRange;
+ pri->size = newsize;
+ bzero(&pri->pRanges[pri->size - SZINCR], SZINCR * sizeof(xRecordRange));
+ if (pri->nRanges < nRanges)
+ pri->nRanges = nRanges;
+ return Success;
+} /* RecordAllocRanges */
+
+
+/* RecordConvertSetToRanges
+ *
+ * Arguments:
+ * pSet is the set to be converted.
+ * pri is where the result should be stored.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * two vales (first, last) we are interested in.
+ * card8 is TRUE if the vales are one byte each and FALSE if two bytes
+ * each.
+ * imax is the largest set value to store in pri->pRanges.
+ * pStartIndex, if non-NULL, is the index of the first range in
+ * pri->pRanges that should be stored to. If NULL,
+ * start at index 0.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, the slice of pri->pRanges indicated by
+ * byteoffset and card8 is filled in with the intervals from pSet.
+ * if pStartIndex was non-NULL, *pStartIndex is filled in with one
+ * more than the index of the last xRecordRange that was touched.
+ */
+static int
+RecordConvertSetToRanges(
+ RecordSetPtr pSet,
+ GetContextRangeInfoPtr pri,
+ int byteoffset,
+ Bool card8,
+ unsigned int imax,
+ int *pStartIndex
+)
+{
+ int nRanges;
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+ CARD8 *pCARD8;
+ CARD16 *pCARD16;
+ int err;
+
+ if (!pSet)
+ return Success;
+
+ nRanges = pStartIndex ? *pStartIndex : 0;
+ while ((pIter = RecordIterateSet(pSet, pIter, &interval)))
+ {
+ if (interval.first > imax) break;
+ if (interval.last > imax) interval.last = imax;
+ nRanges++;
+ if (nRanges > pri->size)
+ {
+ err = RecordAllocRanges(pri, nRanges);
+ if (err != Success)
+ return err;
+ }
+ else
+ pri->nRanges = max(pri->nRanges, nRanges);
+ if (card8)
+ {
+ pCARD8 = ((CARD8 *)&pri->pRanges[nRanges-1]) + byteoffset;
+ *pCARD8++ = interval.first;
+ *pCARD8 = interval.last;
+ }
+ else
+ {
+ pCARD16 = (CARD16 *)
+ (((char *)&pri->pRanges[nRanges-1]) + byteoffset);
+ *pCARD16++ = interval.first;
+ *pCARD16 = interval.last;
+ }
+ }
+ if (pStartIndex)
+ *pStartIndex = nRanges;
+ return Success;
+} /* RecordConvertSetToRanges */
+
+
+/* RecordConvertMinorOpInfoToRanges
+ *
+ * Arguments:
+ * pMinOpInfo is the minor opcode info to convert to xRecordRanges.
+ * pri is where the result should be stored.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * four vales (CARD8 major_first, CARD8 major_last,
+ * CARD16 minor_first, CARD16 minor_last) we are going to store.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, the slice of pri->pRanges indicated by
+ * byteoffset is filled in with the information from pMinOpInfo.
+ */
+static int
+RecordConvertMinorOpInfoToRanges(
+ RecordMinorOpPtr pMinOpInfo,
+ GetContextRangeInfoPtr pri,
+ int byteoffset
+)
+{
+ int nsets;
+ int start;
+ int i;
+ int err;
+
+ if (!pMinOpInfo)
+ return Success;
+
+ nsets = pMinOpInfo->count;
+ pMinOpInfo++;
+ start = 0;
+ for (i = 0; i < nsets; i++)
+ {
+ int j, s;
+ s = start;
+ err = RecordConvertSetToRanges(pMinOpInfo[i].major.pMinOpSet, pri,
+ byteoffset + 2, FALSE, 65535, &start);
+ if (err != Success) return err;
+ for (j = s; j < start; j++)
+ {
+ CARD8 *pCARD8 = ((CARD8 *)&pri->pRanges[j]) + byteoffset;
+ *pCARD8++ = pMinOpInfo[i].major.first;
+ *pCARD8 = pMinOpInfo[i].major.last;
+ }
+ }
+ return Success;
+} /* RecordConvertMinorOpInfoToRanges */
+
+
+/* RecordSwapRanges
+ *
+ * Arguments:
+ * pRanges is an array of xRecordRanges.
+ * nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The 16 bit fields of each xRecordRange are byte swapped.
+ */
+static void
+RecordSwapRanges(pRanges, nRanges)
+ xRecordRange *pRanges;
+ int nRanges;
+{
+ int i;
+ for (i = 0; i < nRanges; i++, pRanges++)
+ {
+ swaps(&pRanges->extRequestsMinorFirst);
+ swaps(&pRanges->extRequestsMinorLast);
+ swaps(&pRanges->extRepliesMinorFirst);
+ swaps(&pRanges->extRepliesMinorLast);
+ }
+} /* RecordSwapRanges */
+
+
+static int
+ProcRecordGetContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordGetContextReq);
+ xRecordGetContextReply rep;
+ RecordClientsAndProtocolPtr pRCAP;
+ int nRCAPs = 0;
+ GetContextRangeInfoPtr pRangeInfo;
+ GetContextRangeInfoPtr pri;
+ int i;
+ int err;
+
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+
+ /* how many RCAPs are there on this context? */
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ nRCAPs++;
+
+ /* allocate and initialize space for record range info */
+
+ pRangeInfo = (GetContextRangeInfoPtr)malloc(
+ nRCAPs * sizeof(GetContextRangeInfoRec));
+ if (!pRangeInfo && nRCAPs > 0)
+ return BadAlloc;
+ for (i = 0; i < nRCAPs; i++)
+ {
+ pRangeInfo[i].pRanges = NULL;
+ pRangeInfo[i].size = 0;
+ pRangeInfo[i].nRanges = 0;
+ }
+
+ /* convert the RCAP (internal) representation of the recorded protocol
+ * to the wire protocol (external) representation, storing the information
+ * for the ith RCAP in pri[i]
+ */
+
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ xRecordRange rr;
+
+ err = RecordConvertSetToRanges(pRCAP->pRequestMajorOpSet, pri,
+ offset_of(rr, coreRequestsFirst), TRUE, 127, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pReplyMajorOpSet, pri,
+ offset_of(rr, coreRepliesFirst), TRUE, 127, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pDeliveredEventSet, pri,
+ offset_of(rr, deliveredEventsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pDeviceEventSet, pri,
+ offset_of(rr, deviceEventsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pErrorSet, pri,
+ offset_of(rr, errorsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertMinorOpInfoToRanges(pRCAP->pRequestMinOpInfo,
+ pri, offset_of(rr, extRequestsMajorFirst));
+ if (err != Success) goto bailout;
+
+ err = RecordConvertMinorOpInfoToRanges(pRCAP->pReplyMinOpInfo,
+ pri, offset_of(rr, extRepliesMajorFirst));
+ if (err != Success) goto bailout;
+
+ if (pRCAP->clientStarted || pRCAP->clientDied)
+ {
+ if (pri->nRanges == 0)
+ RecordAllocRanges(pri, 1);
+ pri->pRanges[0].clientStarted = pRCAP->clientStarted;
+ pri->pRanges[0].clientDied = pRCAP->clientDied;
+ }
+ }
+
+ /* calculate number of clients and reply length */
+
+ rep.nClients = 0;
+ rep.length = 0;
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ rep.nClients += pRCAP->numClients;
+ rep.length += pRCAP->numClients *
+ ( (sizeof(xRecordClientInfo) >> 2) +
+ pri->nRanges * (sizeof(xRecordRange) >> 2));
+ }
+
+ /* write the reply header */
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.enabled = pContext->pRecordingClient != NULL;
+ rep.elementHeader = pContext->elemHeaders;
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.nClients);
+ }
+ WriteToClient(client, sizeof(xRecordGetContextReply),
+ &rep);
+
+ /* write all the CLIENT_INFOs */
+
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ xRecordClientInfo rci;
+ rci.nRanges = pri->nRanges;
+ if (client->swapped)
+ {
+ swapl(&rci.nRanges);
+ RecordSwapRanges(pri->pRanges, pri->nRanges);
+ }
+ for (i = 0; i < pRCAP->numClients; i++)
+ {
+ rci.clientResource = pRCAP->pClientIDs[i];
+ if (client->swapped) swapl(&rci.clientResource);
+ WriteToClient(client, sizeof(xRecordClientInfo), &rci);
+ WriteToClient(client, sizeof(xRecordRange) * pri->nRanges,
+ (char *)pri->pRanges);
+ }
+ }
+ err = client->noClientException;
+
+bailout:
+ for (i = 0; i < nRCAPs; i++)
+ {
+ if (pRangeInfo[i].pRanges) free(pRangeInfo[i].pRanges);
+ }
+ free(pRangeInfo);
+ return err;
+} /* ProcRecordGetContext */
+
+
+static int
+ProcRecordEnableContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordEnableContextReq);
+ int i;
+ RecordClientsAndProtocolPtr pRCAP;
+
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ if (pContext->pRecordingClient)
+ return BadMatch; /* already enabled */
+
+ /* install record hooks for each RCAP */
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ int err = RecordInstallHooks(pRCAP, 0);
+ if (err != Success)
+ { /* undo the previous installs */
+ RecordClientsAndProtocolPtr pUninstallRCAP;
+ for (pUninstallRCAP = pContext->pListOfRCAP;
+ pUninstallRCAP != pRCAP;
+ pUninstallRCAP = pUninstallRCAP->pNextRCAP)
+ {
+ RecordUninstallHooks(pUninstallRCAP, 0);
+ }
+ return err;
+ }
+ }
+
+ /* Disallow further request processing on this connection until
+ * the context is disabled.
+ */
+ IgnoreClient(client);
+ pContext->pRecordingClient = client;
+
+ /* Don't allow the data connection to record itself; unregister it. */
+ RecordDeleteClientFromContext(pContext,
+ pContext->pRecordingClient->clientAsMask);
+
+ /* move the newly enabled context to the front part of ppAllContexts,
+ * where all the enabled contexts are
+ */
+ i = RecordFindContextOnAllContexts(pContext);
+ assert(i >= numEnabledContexts);
+ if (i != numEnabledContexts)
+ {
+ ppAllContexts[i] = ppAllContexts[numEnabledContexts];
+ ppAllContexts[numEnabledContexts] = pContext;
+ }
+
+ ++numEnabledContexts;
+ assert(numEnabledContexts > 0);
+
+ /* send StartOfData */
+ RecordAProtocolElement(pContext, NULL, XRecordStartOfData, NULL, 0, 0);
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ return Success;
+} /* ProcRecordEnableContext */
+
+
+/* RecordDisableContext
+ *
+ * Arguments:
+ * pContext is the context to disable.
+ * nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If the context was enabled, it is disabled. An EndOfData
+ * message is sent to the recording client. Recording hooks for
+ * this context are uninstalled. The context is moved to the
+ * rear part of the ppAllContexts array. numEnabledContexts is
+ * decremented. Request processing for the formerly recording client
+ * is resumed.
+ */
+static void
+RecordDisableContext(pContext)
+ RecordContextPtr pContext;
+{
+ RecordClientsAndProtocolPtr pRCAP;
+ int i;
+
+ if (!pContext->pRecordingClient) return;
+ if (!pContext->pRecordingClient->clientGone)
+ {
+ RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0);
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ /* Re-enable request processing on this connection. */
+ AttendClient(pContext->pRecordingClient);
+ }
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ RecordUninstallHooks(pRCAP, 0);
+ }
+
+ pContext->pRecordingClient = NULL;
+
+ /* move the newly disabled context to the rear part of ppAllContexts,
+ * where all the disabled contexts are
+ */
+ i = RecordFindContextOnAllContexts(pContext);
+ assert( (i != -1) && (i < numEnabledContexts) );
+ if (i != (numEnabledContexts - 1) )
+ {
+ ppAllContexts[i] = ppAllContexts[numEnabledContexts-1];
+ ppAllContexts[numEnabledContexts-1] = pContext;
+ }
+ --numEnabledContexts;
+ assert(numEnabledContexts >= 0);
+} /* RecordDisableContext */
+
+
+static int
+ProcRecordDisableContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordDisableContextReq);
+
+ REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ RecordDisableContext(pContext);
+ return Success;
+} /* ProcRecordDisableContext */
+
+
+/* RecordDeleteContext
+ *
+ * Arguments:
+ * value is the context to delete.
+ * id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ * Disables the context, frees all associated memory, and removes
+ * it from the ppAllContexts array.
+ */
+static int
+RecordDeleteContext(value, id)
+ void * value;
+ XID id;
+{
+ int i;
+ RecordContextPtr pContext = (RecordContextPtr)value;
+ RecordClientsAndProtocolPtr pRCAP;
+
+ RecordDisableContext(pContext);
+
+ /* Remove all the clients from all the RCAPs.
+ * As a result, the RCAPs will be freed.
+ */
+
+ while ((pRCAP = pContext->pListOfRCAP))
+ {
+ int numClients = pRCAP->numClients;
+ /* when the last client is deleted, the RCAP will go away. */
+ while(numClients--)
+ {
+ RecordDeleteClientFromRCAP(pRCAP, numClients);
+ }
+ }
+
+ free(pContext);
+
+ /* remove context from AllContexts list */
+
+ if (-1 != (i = RecordFindContextOnAllContexts(pContext)))
+ {
+ ppAllContexts[i] = ppAllContexts[numContexts - 1];
+ if (--numContexts == 0)
+ {
+ free(ppAllContexts);
+ ppAllContexts = NULL;
+ }
+ }
+ return Success;
+} /* RecordDeleteContext */
+
+
+static int
+ProcRecordFreeContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordFreeContextReq);
+
+ REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ FreeResource(stuff->context, RT_NONE);
+ return Success;
+} /* ProcRecordFreeContext */
+
+
+static int
+ProcRecordDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_RecordQueryVersion:
+ return ProcRecordQueryVersion(client);
+ case X_RecordCreateContext:
+ return ProcRecordCreateContext(client);
+ case X_RecordRegisterClients:
+ return ProcRecordRegisterClients(client);
+ case X_RecordUnregisterClients:
+ return ProcRecordUnregisterClients(client);
+ case X_RecordGetContext:
+ return ProcRecordGetContext(client);
+ case X_RecordEnableContext:
+ return ProcRecordEnableContext(client);
+ case X_RecordDisableContext:
+ return ProcRecordDisableContext(client);
+ case X_RecordFreeContext:
+ return ProcRecordFreeContext(client);
+ default:
+ return BadRequest;
+ }
+} /* ProcRecordDispatch */
+
+
+static int
+SProcRecordQueryVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordQueryVersionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+ swaps(&stuff->majorVersion);
+ swaps(&stuff->minorVersion);
+ return ProcRecordQueryVersion(client);
+} /* SProcRecordQueryVersion */
+
+
+static int
+SwapCreateRegister(xRecordRegisterClientsReq *stuff)
+{
+ int i;
+ XID *pClientID;
+
+ swapl(&stuff->context);
+ swapl(&stuff->nClients);
+ swapl(&stuff->nRanges);
+ pClientID = (XID *)&stuff[1];
+ if (stuff->nClients > stuff->length - (sz_xRecordRegisterClientsReq >> 2))
+ return BadLength;
+ for (i = 0; i < stuff->nClients; i++, pClientID++)
+ {
+ swapl(pClientID);
+ }
+ if (stuff->nRanges > stuff->length - (sz_xRecordRegisterClientsReq >> 2)
+ - stuff->nClients)
+ return BadLength;
+ RecordSwapRanges((xRecordRange *)pClientID, stuff->nRanges);
+ return Success;
+} /* SwapCreateRegister */
+
+
+static int
+SProcRecordCreateContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordCreateContextReq);
+ int status;
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+ if ((status = SwapCreateRegister((void *)stuff)) != Success)
+ return status;
+ return ProcRecordCreateContext(client);
+} /* SProcRecordCreateContext */
+
+
+static int
+SProcRecordRegisterClients(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordRegisterClientsReq);
+ int status;
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+ if ((status = SwapCreateRegister((void *)stuff)) != Success)
+ return status;
+ return ProcRecordRegisterClients(client);
+} /* SProcRecordRegisterClients */
+
+
+static int
+SProcRecordUnregisterClients(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordUnregisterClientsReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+ swapl(&stuff->context);
+ swapl(&stuff->nClients);
+ SwapRestL(stuff);
+ return ProcRecordUnregisterClients(client);
+} /* SProcRecordUnregisterClients */
+
+
+static int
+SProcRecordGetContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordGetContextReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ swapl(&stuff->context);
+ return ProcRecordGetContext(client);
+} /* SProcRecordGetContext */
+
+static int
+SProcRecordEnableContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordEnableContextReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecordEnableContextReq);
+ swapl(&stuff->context);
+ return ProcRecordEnableContext(client);
+} /* SProcRecordEnableContext */
+
+
+static int
+SProcRecordDisableContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordDisableContextReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+ swapl(&stuff->context);
+ return ProcRecordDisableContext(client);
+} /* SProcRecordDisableContext */
+
+
+static int
+SProcRecordFreeContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordFreeContextReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+ swapl(&stuff->context);
+ return ProcRecordFreeContext(client);
+} /* SProcRecordFreeContext */
+
+
+static int
+SProcRecordDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_RecordQueryVersion:
+ return SProcRecordQueryVersion(client);
+ case X_RecordCreateContext:
+ return SProcRecordCreateContext(client);
+ case X_RecordRegisterClients:
+ return SProcRecordRegisterClients(client);
+ case X_RecordUnregisterClients:
+ return SProcRecordUnregisterClients(client);
+ case X_RecordGetContext:
+ return SProcRecordGetContext(client);
+ case X_RecordEnableContext:
+ return SProcRecordEnableContext(client);
+ case X_RecordDisableContext:
+ return SProcRecordDisableContext(client);
+ case X_RecordFreeContext:
+ return SProcRecordFreeContext(client);
+ default:
+ return BadRequest;
+ }
+} /* SProcRecordDispatch */
+
+/* XXX goes in header file */
+extern void SwapConnSetupInfo(), SwapConnSetupPrefix();
+
+/* RecordConnectionSetupInfo
+ *
+ * Arguments:
+ * pContext is an enabled context that specifies recording of
+ * connection setup info.
+ * pci holds the connection setup info.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The connection setup info is sent to the recording client.
+ */
+static void
+RecordConnectionSetupInfo(pContext, pci)
+ RecordContextPtr pContext;
+ NewClientInfoRec *pci;
+{
+ int prefixsize = SIZEOF(xConnSetupPrefix);
+ int restsize = pci->prefix->length * 4;
+
+ if (pci->client->swapped)
+ {
+ char * pConnSetup = (char *)malloc(prefixsize + restsize);
+ if (!pConnSetup)
+ return;
+ SwapConnSetupPrefix(pci->prefix, pConnSetup);
+ SwapConnSetupInfo(pci->setup, pConnSetup + prefixsize);
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (void *)pConnSetup, prefixsize + restsize, 0);
+ free(pConnSetup);
+ }
+ else
+ {
+ /* don't alloc and copy as in the swapped case; just send the
+ * data in two pieces
+ */
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (void *)pci->prefix, prefixsize, restsize);
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (void *)pci->setup, restsize, /* continuation */ -1);
+ }
+} /* RecordConnectionSetupInfo */
+
+
+/* RecordDeleteContext
+ *
+ * Arguments:
+ * pcbl is &ClientStateCallback.
+ * nullata is NULL.
+ * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ * which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If a new client has connected and any contexts have specified
+ * XRecordFutureClients, the new client is registered on those contexts.
+ * If any of those contexts specify recording of the connection setup
+ * info, it is recorded.
+ *
+ * If an existing client has disconnected, it is deleted from any
+ * contexts that it was registered on. If any of those contexts
+ * specified XRecordClientDied, they record a ClientDied protocol element.
+ * If the disconnectiong client happened to be the data connection of an
+ * enabled context, the context is disabled.
+ */
+
+static void
+RecordAClientStateChange(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ void * nulldata;
+ void * calldata;
+{
+ NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+ int i;
+ ClientPtr pClient = pci->client;
+
+ switch (pClient->clientState)
+ {
+ case ClientStateRunning: /* new client */
+ for (i = 0; i < numContexts; i++)
+ {
+ RecordClientsAndProtocolPtr pRCAP;
+ RecordContextPtr pContext = ppAllContexts[i];
+
+ if ((pRCAP = RecordFindClientOnContext(pContext,
+ XRecordFutureClients, NULL)))
+ {
+ RecordAddClientToRCAP(pRCAP, pClient->clientAsMask);
+ if (pContext->pRecordingClient && pRCAP->clientStarted)
+ RecordConnectionSetupInfo(pContext, pci);
+ }
+ }
+ break;
+
+ case ClientStateGone:
+ case ClientStateRetained: /* client disconnected */
+ for (i = 0; i < numContexts; i++)
+ {
+ RecordClientsAndProtocolPtr pRCAP;
+ RecordContextPtr pContext = ppAllContexts[i];
+ int pos;
+
+ if (pContext->pRecordingClient == pClient)
+ RecordDisableContext(pContext);
+ if ((pRCAP = RecordFindClientOnContext(pContext,
+ pClient->clientAsMask, &pos)))
+ {
+ if (pContext->pRecordingClient && pRCAP->clientDied)
+ RecordAProtocolElement(pContext, pClient,
+ XRecordClientDied, NULL, 0, 0);
+ RecordDeleteClientFromRCAP(pRCAP, pos);
+ }
+ }
+ break;
+
+ default:
+ break;
+ } /* end switch on client state */
+} /* RecordAClientStateChange */
+
+
+/* RecordCloseDown
+ *
+ * Arguments:
+ * extEntry is the extension information for RECORD.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by RECORD at server shutdown time.
+ *
+ */
+static void
+RecordCloseDown(extEntry)
+ ExtensionEntry *extEntry;
+{
+ DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+} /* RecordCloseDown */
+
+
+/* RecordExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Enables the RECORD extension if possible.
+ */
+void
+RecordExtensionInit()
+{
+ ExtensionEntry *extentry;
+
+ RTContext = CreateNewResourceType(RecordDeleteContext);
+ if (!RTContext)
+ return;
+
+ RecordClientPrivateIndex = AllocateClientPrivateIndex();
+ if (!AllocateClientPrivate(RecordClientPrivateIndex, 0))
+ return;
+
+ ppAllContexts = NULL;
+ numContexts = numEnabledContexts = numEnabledRCAPs = 0;
+
+ if (!AddCallback(&ClientStateCallback, RecordAClientStateChange, NULL))
+ return;
+
+ extentry = AddExtension(RECORD_NAME, RecordNumEvents, RecordNumErrors,
+ ProcRecordDispatch, SProcRecordDispatch,
+ RecordCloseDown, StandardMinorOpcode);
+ if (!extentry)
+ {
+ DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+ return;
+ }
+ RecordErrorBase = extentry->errorBase;
+
+} /* RecordExtensionInit */
+
diff --git a/nx-X11/programs/Xserver/record/set.c b/nx-X11/programs/Xserver/record/set.c
new file mode 100644
index 000000000..afb1024dd
--- /dev/null
+++ b/nx-X11/programs/Xserver/record/set.c
@@ -0,0 +1,691 @@
+
+/*
+
+Copyright 1995, 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.
+
+*/
+
+/*
+
+ See the header set.h for a description of the set ADT.
+
+ Implementation Strategy
+
+ A bit vector is an obvious choice to represent the set, but may take
+ too much memory, depending on the numerically largest member in the
+ set. One expected common case is for the client to ask for *all*
+ protocol. This means it would ask for minor opcodes 0 through 65535.
+ Representing this as a bit vector takes 8K -- and there may be
+ multiple minor opcode intervals, as many as one per major (extension)
+ opcode). In such cases, a list-of-intervals representation would be
+ preferable to reduce memory consumption. Both representations will be
+ implemented, and RecordCreateSet will decide heuristically which one
+ to use based on the set members.
+
+ Note: When compiling for use in the server, do not use -DTESTING.
+ When compiling for stand-alone testing of the set ADT, use -DTESTING.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#ifndef TESTING
+#include "misc.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+
+/* stuff that you normally get from the X Server's environment */
+
+typedef int Bool;
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef unsigned short CARD16;
+
+#ifndef max
+#define max(_a, _b) ( ((_a) > (_b)) ? (_a) : (_b) )
+#endif
+
+#endif /* TESTING */
+
+#include "set.h"
+
+static int
+maxMemberInInterval(pIntervals, nIntervals)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+{
+ int i;
+ int maxMember = -1;
+ for (i = 0; i < nIntervals; i++)
+ {
+ if (maxMember < (int)pIntervals[i].last)
+ maxMember = pIntervals[i].last;
+ }
+ return maxMember;
+}
+
+static void
+NoopDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+}
+
+/***************************************************************************/
+
+/* set operations for bit vector representation */
+
+typedef struct {
+ RecordSetRec baseSet;
+ int maxMember;
+ /* followed by the bit vector itself */
+} BitVectorSet, *BitVectorSetPtr;
+
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+
+static void
+BitVectorDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+ free(pSet);
+}
+
+static unsigned long
+BitVectorIsMemberOfSet(pSet, pm)
+ RecordSetPtr pSet;
+ int pm;
+{
+ BitVectorSetPtr pbvs = (BitVectorSetPtr)pSet;
+ unsigned long *pbitvec;
+
+ if ((int)pm > pbvs->maxMember) return FALSE;
+ pbitvec = (unsigned long *)(&pbvs[1]);
+ return (pbitvec[pm / BITS_PER_LONG] & ((unsigned long)1 << (pm % BITS_PER_LONG)));
+}
+
+
+static int
+BitVectorFindBit(pSet, iterbit, bitval)
+ RecordSetPtr pSet;
+ int iterbit;
+ Bool bitval;
+{
+ BitVectorSetPtr pbvs = (BitVectorSetPtr)pSet;
+ unsigned long *pbitvec = (unsigned long *)(&pbvs[1]);
+ int startlong;
+ int startbit;
+ int walkbit;
+ int maxMember;
+ unsigned long skipval;
+ unsigned long bits;
+ unsigned long usefulbits;
+
+ startlong = iterbit / BITS_PER_LONG;
+ pbitvec += startlong;
+ startbit = startlong * BITS_PER_LONG;
+ skipval = bitval ? 0L : ~0L;
+ maxMember = pbvs->maxMember;
+
+
+ if (startbit > maxMember) return -1;
+ bits = *pbitvec;
+ usefulbits = ~(((unsigned long)1 << (iterbit - startbit)) - 1);
+ if ( (bits & usefulbits) == (skipval & usefulbits) )
+ {
+ pbitvec++;
+ startbit += BITS_PER_LONG;
+
+ while (startbit <= maxMember && *pbitvec == skipval)
+ {
+ pbitvec++;
+ startbit += BITS_PER_LONG;
+ }
+ if (startbit > maxMember) return -1;
+ }
+
+ walkbit = (startbit < iterbit) ? iterbit - startbit : 0;
+
+ bits = *pbitvec;
+ while (walkbit < BITS_PER_LONG && ((!(bits & ((unsigned long)1 << walkbit))) == bitval))
+ walkbit++;
+
+ return startbit + walkbit;
+}
+
+
+static RecordSetIteratePtr
+BitVectorIterateSet(pSet, pIter, pInterval)
+ RecordSetPtr pSet;
+ RecordSetIteratePtr pIter;
+ RecordSetInterval *pInterval;
+{
+ int iterbit = (int)(long)pIter;
+ int b;
+
+ b = BitVectorFindBit(pSet, iterbit, TRUE);
+ if (b == -1) return (RecordSetIteratePtr)0;
+ pInterval->first = b;
+
+ b = BitVectorFindBit(pSet, b, FALSE);
+ pInterval->last = (b < 0) ? ((BitVectorSetPtr)pSet)->maxMember : b - 1;
+ return (RecordSetIteratePtr)(long)(pInterval->last + 1);
+}
+
+RecordSetOperations BitVectorSetOperations = {
+ BitVectorDestroySet, BitVectorIsMemberOfSet, BitVectorIterateSet };
+
+RecordSetOperations BitVectorNoFreeOperations = {
+ NoopDestroySet, BitVectorIsMemberOfSet, BitVectorIterateSet };
+
+static int
+BitVectorSetMemoryRequirements(pIntervals, nIntervals, maxMember, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int maxMember;
+ int *alignment;
+{
+ int nlongs;
+
+ *alignment = sizeof(unsigned long);
+ nlongs = (maxMember + BITS_PER_LONG) / BITS_PER_LONG;
+ return (sizeof(BitVectorSet) + nlongs * sizeof(unsigned long));
+}
+
+static RecordSetPtr
+BitVectorCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ BitVectorSetPtr pbvs;
+ int i, j;
+ unsigned long *pbitvec;
+
+ /* allocate all storage needed by this set in one chunk */
+
+ if (pMem)
+ {
+ memset(pMem, 0, memsize);
+ pbvs = (BitVectorSetPtr)pMem;
+ pbvs->baseSet.ops = &BitVectorNoFreeOperations;
+ }
+ else
+ {
+ pbvs = (BitVectorSetPtr)calloc(1, memsize);
+ if (!pbvs) return NULL;
+ pbvs->baseSet.ops = &BitVectorSetOperations;
+ }
+
+ pbvs->maxMember = maxMemberInInterval(pIntervals, nIntervals);
+
+ /* fill in the set */
+
+ pbitvec = (unsigned long *)(&pbvs[1]);
+ for (i = 0; i < nIntervals; i++)
+ {
+ for (j = pIntervals[i].first; j <= (int)pIntervals[i].last; j++)
+ {
+ pbitvec[j/BITS_PER_LONG] |= ((unsigned long)1 << (j % BITS_PER_LONG));
+ }
+ }
+ return (RecordSetPtr)pbvs;
+}
+
+
+/***************************************************************************/
+
+/* set operations for interval list representation */
+
+typedef struct {
+ RecordSetRec baseSet;
+ int nIntervals;
+ /* followed by the intervals (RecordSetInterval) */
+} IntervalListSet, *IntervalListSetPtr;
+
+static void
+IntervalListDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+ free(pSet);
+}
+
+static unsigned long
+IntervalListIsMemberOfSet(pSet, pm)
+ RecordSetPtr pSet;
+ int pm;
+{
+ IntervalListSetPtr prls = (IntervalListSetPtr)pSet;
+ RecordSetInterval *pInterval = (RecordSetInterval *)(&prls[1]);
+ int hi, lo, probe;
+
+ /* binary search */
+ lo = 0; hi = prls->nIntervals - 1;
+ while (lo <= hi)
+ {
+ probe = (hi + lo) / 2;
+ if (pm >= pInterval[probe].first && pm <= pInterval[probe].last) return 1;
+ else if (pm < pInterval[probe].first) hi = probe - 1;
+ else lo = probe + 1;
+ }
+ return 0;
+}
+
+
+static RecordSetIteratePtr
+IntervalListIterateSet(pSet, pIter, pIntervalReturn)
+ RecordSetPtr pSet;
+ RecordSetIteratePtr pIter;
+ RecordSetInterval *pIntervalReturn;
+{
+ RecordSetInterval *pInterval = (RecordSetInterval *)pIter;
+ IntervalListSetPtr prls = (IntervalListSetPtr)pSet;
+
+ if (pInterval == NULL)
+ {
+ pInterval = (RecordSetInterval *)(&prls[1]);
+ }
+
+ if ( (pInterval - (RecordSetInterval *)(&prls[1])) < prls->nIntervals )
+ {
+ *pIntervalReturn = *pInterval;
+ return (RecordSetIteratePtr)(++pInterval);
+ }
+ else
+ return (RecordSetIteratePtr)NULL;
+}
+
+RecordSetOperations IntervalListSetOperations = {
+ IntervalListDestroySet, IntervalListIsMemberOfSet, IntervalListIterateSet };
+
+RecordSetOperations IntervalListNoFreeOperations = {
+ NoopDestroySet, IntervalListIsMemberOfSet, IntervalListIterateSet };
+
+static int
+IntervalListMemoryRequirements(pIntervals, nIntervals, maxMember, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int maxMember;
+ int *alignment;
+{
+ *alignment = sizeof(unsigned long);
+ return sizeof(IntervalListSet) + nIntervals * sizeof(RecordSetInterval);
+}
+
+static RecordSetPtr
+IntervalListCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ IntervalListSetPtr prls;
+ int i, j, k;
+ RecordSetInterval *stackIntervals = NULL;
+ CARD16 first;
+
+ if (nIntervals > 0)
+ {
+ stackIntervals = (RecordSetInterval *)malloc(
+ sizeof(RecordSetInterval) * nIntervals);
+ if (!stackIntervals) return NULL;
+
+ /* sort intervals, store in stackIntervals (insertion sort) */
+
+ for (i = 0; i < nIntervals; i++)
+ {
+ first = pIntervals[i].first;
+ for (j = 0; j < i; j++)
+ {
+ if (first < stackIntervals[j].first)
+ break;
+ }
+ for (k = i; k > j; k--)
+ {
+ stackIntervals[k] = stackIntervals[k-1];
+ }
+ stackIntervals[j] = pIntervals[i];
+ }
+
+ /* merge abutting/overlapping intervals */
+
+ for (i = 0; i < nIntervals - 1; )
+ {
+ if ( (stackIntervals[i].last + (unsigned int)1) <
+ stackIntervals[i + 1].first)
+ {
+ i++; /* disjoint intervals */
+ }
+ else
+ {
+ stackIntervals[i].last = max(stackIntervals[i].last,
+ stackIntervals[i + 1].last);
+ nIntervals--;
+ for (j = i + 1; j < nIntervals; j++)
+ stackIntervals[j] = stackIntervals[j + 1];
+ }
+ }
+ }
+
+ /* allocate and fill in set structure */
+
+ if (pMem)
+ {
+ prls = (IntervalListSetPtr)pMem;
+ prls->baseSet.ops = &IntervalListNoFreeOperations;
+ }
+ else
+ {
+ prls = (IntervalListSetPtr)
+ malloc(sizeof(IntervalListSet) + nIntervals * sizeof(RecordSetInterval));
+ if (!prls) goto bailout;
+ prls->baseSet.ops = &IntervalListSetOperations;
+ }
+ memcpy(&prls[1], stackIntervals, nIntervals * sizeof(RecordSetInterval));
+ prls->nIntervals = nIntervals;
+bailout:
+ if (stackIntervals) free(stackIntervals);
+ return (RecordSetPtr)prls;
+}
+
+#ifdef TESTING
+typedef enum {
+ BitVectorImplementation, IntervalListImplementation} RecordSetImplementation;
+
+RecordSetImplementation _RecordSetImpl;
+
+static void
+_RecordForceSetImplementation(setimpl)
+ RecordSetImplementation setimpl;
+{
+ _RecordSetImpl = setimpl;
+}
+#endif
+
+typedef RecordSetPtr (*RecordCreateSetProcPtr)(
+ RecordSetInterval *pIntervals,
+ int nIntervals,
+ void *pMem,
+ int memsize
+);
+
+static int
+_RecordSetMemoryRequirements(pIntervals, nIntervals, alignment, ppCreateSet)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int *alignment;
+ RecordCreateSetProcPtr *ppCreateSet;
+{
+ int bmsize, rlsize, bma, rla;
+ int maxMember;
+
+ /* find maximum member of set so we know how big to make the bit vector */
+ maxMember = maxMemberInInterval(pIntervals, nIntervals);
+
+ bmsize = BitVectorSetMemoryRequirements(pIntervals, nIntervals, maxMember,
+ &bma);
+ rlsize = IntervalListMemoryRequirements(pIntervals, nIntervals, maxMember,
+ &rla);
+#ifdef TESTING
+ if (_RecordSetImpl == BitVectorImplementation)
+#else
+ if ( ( (nIntervals > 1) && (maxMember <= 255) )
+ || (bmsize < rlsize) )
+#endif
+ {
+ *alignment = bma;
+ *ppCreateSet = BitVectorCreateSet;
+ return bmsize;
+ }
+ else
+ {
+ *alignment = rla;
+ *ppCreateSet = IntervalListCreateSet;
+ return rlsize;
+ }
+}
+
+/***************************************************************************/
+
+/* user-visible functions */
+
+int
+RecordSetMemoryRequirements(pIntervals, nIntervals, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int *alignment;
+{
+ RecordCreateSetProcPtr pCreateSet;
+ return _RecordSetMemoryRequirements(pIntervals, nIntervals, alignment,
+ &pCreateSet);
+}
+
+RecordSetPtr
+RecordCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ RecordCreateSetProcPtr pCreateSet;
+ int alignment;
+ int size;
+
+ size = _RecordSetMemoryRequirements(pIntervals, nIntervals, &alignment,
+ &pCreateSet);
+ if (pMem)
+ {
+ if ( ((long)pMem & (alignment-1) ) || memsize < size)
+ return NULL;
+ }
+ return (*pCreateSet)(pIntervals, nIntervals, pMem, size);
+}
+
+/***************************************************************************/
+
+#ifdef TESTING
+
+/*
+
+Test Strategy
+
+Having two set representations is convenient for testing because we
+can play them against each other. The test code will be able to
+specify which implementation to use. This breaks the encapsulation,
+but that seems acceptable for testing. The crux of the test loop
+looks like this:
+
+loop:
+ generate random list of Intervals
+
+ create set A using bit vector implementation
+ create set B using Interval list implementation
+
+ for each possible set member
+ if set A and set B disagree on whether this is a member error;
+
+ iterate over both sets, comparing the intervals returned by each.
+ if intervals or number of intervals are different error;
+
+ iterate over intervals of set A
+ for i = interval.first to interval.last
+ if i is not a member of set B error;
+
+ iterate over intervals of set B
+ for i = interval.first to interval.last
+ if i is not a member of set A error;
+
+ destroy sets A, B
+
+*/
+
+int GenerateRandomIntervals(pIntervals, maxintervals)
+ RecordSetInterval *pIntervals;
+ int maxintervals;
+{
+ int i, nIntervals;
+
+ nIntervals = rand() % maxintervals;
+
+ for (i = 0; i < nIntervals; i++)
+ {
+ pIntervals[i].first = rand();
+ pIntervals[i].last = pIntervals[i].first + rand();
+ }
+ return nIntervals;
+}
+
+#define MAXINTERVALS 100
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ RecordSetPtr bs, rs;
+ RecordSetInterval br, rr;
+ RecordSetIteratePtr bi, ri;
+ CARD16 i;
+ int testcount;
+ RecordSetInterval intervals[MAXINTERVALS];
+ int nIntervals;
+ int bsize, rsize;
+ int balign, ralign;
+ int pad;
+
+ for (testcount = 0; 1; testcount++)
+ {
+ nIntervals = GenerateRandomIntervals(intervals, MAXINTERVALS);
+ printf("%d nIntervals %d\n", testcount, nIntervals);
+
+ if (testcount & 1)
+ {
+ _RecordForceSetImplementation(BitVectorImplementation);
+ bsize = RecordSetMemoryRequirements(intervals, nIntervals, &balign);
+ _RecordForceSetImplementation(IntervalListImplementation);
+ rsize = RecordSetMemoryRequirements(intervals, nIntervals, &ralign);
+ pad = (ralign - (bsize & (ralign - 1))) & (ralign - 1);
+ bs = (RecordSetPtr)malloc(bsize + pad + rsize );
+ if (!bs)
+ {
+ fprintf(stderr, "%d: failed to alloc memory for sets\n",
+ testcount);
+ continue;
+ }
+ rs = (RecordSetPtr)(((char *)bs) + bsize + pad);
+ }
+ else
+ {
+ bs = rs = NULL;
+ bsize = rsize = 0;
+ }
+
+ _RecordForceSetImplementation(BitVectorImplementation);
+ bs = RecordCreateSet(intervals, nIntervals, bs, bsize);
+ _RecordForceSetImplementation(IntervalListImplementation);
+ rs = RecordCreateSet(intervals, nIntervals, rs, rsize);
+
+ if (!bs || !rs)
+ {
+ fprintf(stderr, "%d: failed to create sets\n", testcount);
+ continue;
+ }
+
+ for (i = 0; i < 65535; i++)
+ {
+ unsigned long b, r;
+
+ b = RecordIsMemberOfSet(bs, i);
+ r = RecordIsMemberOfSet(rs, i);
+ if ( (b && !r) || (!b && r) )
+ {
+ fprintf(stderr, "%d: isMemberOfSet %d\n",
+ testcount, (int)i);
+ }
+ }
+
+ bi = RecordIterateSet(bs, NULL, &br);
+ ri = RecordIterateSet(rs, NULL, &rr);
+
+ while (bi && ri)
+ {
+ if ( (rr.first != br.first) || (rr.last != br.last) )
+ {
+ fprintf(stderr, "%d: iterateSet interval value mismatch\n",
+ testcount);
+ }
+ bi = RecordIterateSet(bs, bi, &br);
+ ri = RecordIterateSet(rs, ri, &rr);
+ }
+ if (bi != ri)
+ {
+ fprintf(stderr, "%d: iterateSet interval count mismatch\n",
+ testcount);
+ }
+
+
+ bi = NULL;
+ while (bi = RecordIterateSet(bs, bi, &br))
+ {
+ for (i = br.first; i <= br.last; i++)
+ {
+ if (!RecordIsMemberOfSet(rs, i))
+ {
+ fprintf(stderr, "%d: iterateSet b / isMemberOfSet r %d\n",
+ testcount, (int)i);
+ }
+ }
+ }
+
+ ri = NULL;
+ while (ri = RecordIterateSet(rs, ri, &rr))
+ {
+ for (i = rr.first; i <= rr.last; i++)
+ {
+ if (!RecordIsMemberOfSet(bs, i) )
+ {
+ fprintf(stderr, "%d: iterateSet r / isMemberOfSet b %d\n",
+ testcount, (int)i);
+ }
+ }
+ }
+
+ RecordDestroySet(bs);
+ RecordDestroySet(rs);
+
+ if (testcount & 1)
+ {
+ free(bs);
+ }
+ }
+}
+
+#endif /* TESTING */
diff --git a/nx-X11/programs/Xserver/record/set.h b/nx-X11/programs/Xserver/record/set.h
new file mode 100644
index 000000000..3246a16ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/record/set.h
@@ -0,0 +1,147 @@
+/*
+
+Copyright 1995, 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.
+
+*/
+
+/*
+ A Set Abstract Data Type (ADT) for the RECORD Extension
+ David P. Wiggins
+ 7/25/95
+
+ The RECORD extension server code needs to maintain sets of numbers
+ that designate protocol message types. In most cases the interval of
+ numbers starts at 0 and does not exceed 255, but in a few cases (minor
+ opcodes of extension requests) the maximum is 65535. This disparity
+ suggests that a single set representation may not be suitable for all
+ sets, especially given that server memory is precious. We introduce a
+ set ADT to hide implementation differences so that multiple
+ simultaneous set representations can exist. A single interface is
+ presented to the set user regardless of the implementation in use for
+ a particular set.
+
+ The existing RECORD SI appears to require only four set operations:
+ create (given a list of members), destroy, see if a particular number
+ is a member of the set, and iterate over the members of a set. Though
+ many more set operations are imaginable, to keep the code space down,
+ we won't provide any more operations than are needed.
+
+ The following types and functions/macros define the ADT.
+*/
+
+/* an interval of set members */
+typedef struct {
+ CARD16 first;
+ CARD16 last;
+} RecordSetInterval;
+
+typedef struct _RecordSetRec *RecordSetPtr; /* primary set type */
+
+typedef void *RecordSetIteratePtr;
+
+/* table of function pointers for set operations.
+ set users should never declare a variable of this type.
+*/
+typedef struct {
+ void (*DestroySet)(
+ RecordSetPtr pSet
+);
+ unsigned long (*IsMemberOfSet)(
+ RecordSetPtr pSet,
+ int possible_member
+);
+ RecordSetIteratePtr (*IterateSet)(
+ RecordSetPtr pSet,
+ RecordSetIteratePtr pIter,
+ RecordSetInterval *interval
+);
+} RecordSetOperations;
+
+/* "base class" for sets.
+ set users should never declare a variable of this type.
+ */
+typedef struct _RecordSetRec {
+ RecordSetOperations *ops;
+} RecordSetRec;
+
+RecordSetPtr RecordCreateSet(
+ RecordSetInterval *intervals,
+ int nintervals,
+ void *pMem,
+ int memsize
+);
+/*
+ RecordCreateSet creates and returns a new set having members specified
+ by intervals and nintervals. nintervals is the number of RecordSetInterval
+ structures pointed to by intervals. The elements belonging to the new
+ set are determined as follows. For each RecordSetInterval structure, the
+ elements between first and last inclusive are members of the new set.
+ If a RecordSetInterval's first field is greater than its last field, the
+ results are undefined. It is valid to create an empty set (nintervals ==
+ 0). If RecordCreateSet returns NULL, the set could not be created due
+ to resource constraints.
+*/
+
+int RecordSetMemoryRequirements(
+ RecordSetInterval * /*pIntervals*/,
+ int /*nintervals*/,
+ int * /*alignment*/
+);
+
+#define RecordDestroySet(_pSet) \
+ /* void */ (*_pSet->ops->DestroySet)(/* RecordSetPtr */ _pSet)
+/*
+ RecordDestroySet frees all resources used by _pSet. _pSet should not be
+ used after it is destroyed.
+*/
+
+#define RecordIsMemberOfSet(_pSet, _m) \
+ /* unsigned long */ (*_pSet->ops->IsMemberOfSet)(/* RecordSetPtr */ _pSet, \
+ /* int */ _m)
+/*
+ RecordIsMemberOfSet returns a non-zero value if _m is a member of
+ _pSet, else it returns zero.
+*/
+
+#define RecordIterateSet(_pSet, _pIter, _interval) \
+ /* RecordSetIteratePtr */ (*_pSet->ops->IterateSet)(/* RecordSetPtr */ _pSet,\
+ /* RecordSetIteratePtr */ _pIter, /* RecordSetInterval */ _interval)
+/*
+ RecordIterateSet returns successive intervals of members of _pSet. If
+ _pIter is NULL, the first interval of set members is copied into _interval.
+ The return value should be passed as _pIter in the next call to
+ RecordIterateSet to obtain the next interval. When the return value is
+ NULL, there were no more intervals in the set, and nothing is copied into
+ the _interval parameter. Intervals appear in increasing numerical order
+ with no overlap between intervals. As such, the list of intervals produced
+ by RecordIterateSet may not match the list of intervals that were passed
+ in RecordCreateSet. Typical usage:
+
+ pIter = NULL;
+ while (pIter = RecordIterateSet(pSet, pIter, &interval))
+ {
+ process interval;
+ }
+*/
diff --git a/nx-X11/programs/Xserver/render/Imakefile b/nx-X11/programs/Xserver/render/Imakefile
new file mode 100644
index 000000000..235acf1ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/Imakefile
@@ -0,0 +1,66 @@
+ NULL =
+
+#include <Server.tmpl>
+
+#if (!(defined(NXAgentServer) && NXAgentServer))
+NXAGENT_SKIP_SRCS = \
+ glyph.c \
+ mitrap.c \
+ picture.c \
+ render.c \
+ $(NULL)
+NXAGENT_SKIP_OBJS = \
+ glyph.o \
+ mitrap.o \
+ picture.o \
+ render.o \
+ $(NULL)
+#else
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ SRCS = animcur.c \
+ filter.c \
+ glyph.c \
+ matrix.c \
+ miindex.c \
+ mipict.c \
+ mirect.c \
+ mitri.c \
+ renderedge.c \
+ $(NXAGENT_SKIP_SRCS) \
+ $(NULL)
+
+ OBJS = animcur.o \
+ filter.o \
+ glyph.o \
+ matrix.o \
+ miindex.o \
+ mipict.o \
+ mirect.o \
+ mitri.o \
+ renderedge.o \
+ $(NXAGENT_SKIP_OBJS) \
+ $(NULL)
+
+ INCLUDES = -I. -I../include -I../mi \
+ -I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ -I../Xext \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+ DEFINES = \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryTarget(render,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(render,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(glyphstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mipict.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(picture.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(picturestr.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/nx-X11/programs/Xserver/render/animcur.c b/nx-X11/programs/Xserver/render/animcur.c
new file mode 100644
index 000000000..7336cdeff
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/animcur.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+/*
+ * Animated cursors for X. Not specific to Render in any way, but
+ * stuck there because Render has the other cool cursor extension.
+ * Besides, everyone has Render.
+ *
+ * Implemented as a simple layer over the core cursor code; it
+ * creates composite cursors out of a set of static cursors and
+ * delta times between each image.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xmd.h>
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "dixfontstr.h"
+#include "opaque.h"
+#include "picturestr.h"
+
+typedef struct _AnimCurElt {
+ CursorPtr pCursor; /* cursor to show */
+ CARD32 delay; /* in ms */
+} AnimCurElt;
+
+typedef struct _AnimCur {
+ int nelt; /* number of elements in the elts array */
+ AnimCurElt *elts; /* actually allocated right after the structure */
+} AnimCurRec, *AnimCurPtr;
+
+typedef struct _AnimScrPriv {
+ CursorPtr pCursor;
+ int elt;
+ CARD32 time;
+
+ CloseScreenProcPtr CloseScreen;
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+
+ CursorLimitsProcPtr CursorLimits;
+ DisplayCursorProcPtr DisplayCursor;
+ SetCursorPositionProcPtr SetCursorPosition;
+ RealizeCursorProcPtr RealizeCursor;
+ UnrealizeCursorProcPtr UnrealizeCursor;
+ RecolorCursorProcPtr RecolorCursor;
+} AnimCurScreenRec, *AnimCurScreenPtr;
+
+typedef struct _AnimCurState {
+ CursorPtr pCursor;
+ ScreenPtr pScreen;
+ int elt;
+ CARD32 time;
+} AnimCurStateRec, *AnimCurStatePtr;
+
+static AnimCurStateRec animCurState;
+
+static unsigned char empty[4];
+
+static CursorBits animCursorBits = {
+ empty, empty, 2, 1, 1, 0, 0, 1
+};
+
+int AnimCurScreenPrivateIndex = -1;
+int AnimCurGeneration;
+
+#define IsAnimCur(c) ((c)->bits == &animCursorBits)
+#define GetAnimCur(c) ((AnimCurPtr) ((c) + 1))
+#define GetAnimCurScreen(s) ((AnimCurScreenPtr) ((s)->devPrivates[AnimCurScreenPrivateIndex].ptr))
+#define GetAnimCurScreenIfSet(s) ((AnimCurScreenPrivateIndex != -1) ? GetAnimCurScreen(s) : NULL)
+#define SetAnimCurScreen(s,p) ((s)->devPrivates[AnimCurScreenPrivateIndex].ptr = (void *) (p))
+
+#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
+
+static Bool
+AnimCurDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor);
+
+static Bool
+AnimCurSetCursorPosition (ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent);
+
+static Bool
+AnimCurCloseScreen (ScreenPtr pScreen)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap(as, pScreen, CloseScreen);
+
+ Unwrap(as, pScreen, BlockHandler);
+
+ Unwrap(as, pScreen, CursorLimits);
+ Unwrap(as, pScreen, DisplayCursor);
+ Unwrap(as, pScreen, SetCursorPosition);
+ Unwrap(as, pScreen, RealizeCursor);
+ Unwrap(as, pScreen, UnrealizeCursor);
+ Unwrap(as, pScreen, RecolorCursor);
+ SetAnimCurScreen(pScreen,0);
+ ret = (*pScreen->CloseScreen) (pScreen);
+ free (as);
+ if (screenInfo.numScreens <= 1)
+ AnimCurScreenPrivateIndex = -1;
+ return ret;
+}
+
+static void
+AnimCurCursorLimits (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ BoxPtr pHotBox,
+ BoxPtr pTopLeftBox)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ Unwrap (as, pScreen, CursorLimits);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+
+ (*pScreen->CursorLimits) (pScreen, ac->elts[0].pCursor, pHotBox, pTopLeftBox);
+ }
+ else
+ {
+ (*pScreen->CursorLimits) (pScreen, pCursor, pHotBox, pTopLeftBox);
+ }
+ Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits);
+}
+
+/*
+ * This has to be a screen block handler instead of a generic
+ * block handler so that it is well ordered with respect to the DRI
+ * block handler responsible for releasing the hardware to DRI clients
+ */
+
+static void
+AnimCurScreenBlockHandler (int screenNum,
+ void * blockData,
+ void * pTimeout,
+ void * pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ if (pScreen == animCurState.pScreen)
+ {
+ CARD32 now = GetTimeInMillis ();
+
+ if ((INT32) (now - animCurState.time) >= 0)
+ {
+ AnimCurPtr ac = GetAnimCur(animCurState.pCursor);
+ int elt = (animCurState.elt + 1) % ac->nelt;
+ DisplayCursorProcPtr DisplayCursor;
+
+ /*
+ * Not a simple Unwrap/Wrap as this
+ * isn't called along the DisplayCursor
+ * wrapper chain.
+ */
+ DisplayCursor = pScreen->DisplayCursor;
+ pScreen->DisplayCursor = as->DisplayCursor;
+ (void) (*pScreen->DisplayCursor) (pScreen, ac->elts[elt].pCursor);
+ as->DisplayCursor = pScreen->DisplayCursor;
+ pScreen->DisplayCursor = DisplayCursor;
+
+ animCurState.elt = elt;
+ animCurState.time = now + ac->elts[elt].delay;
+ }
+ AdjustWaitForDelay (pTimeout, animCurState.time - now);
+ }
+ Unwrap (as, pScreen, BlockHandler);
+ (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+ Wrap (as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+}
+
+static Bool
+AnimCurDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, DisplayCursor);
+ if (IsAnimCur(pCursor))
+ {
+ if (pCursor != animCurState.pCursor)
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+
+ ret = (*pScreen->DisplayCursor) (pScreen, ac->elts[0].pCursor);
+ if (ret)
+ {
+ animCurState.elt = 0;
+ animCurState.time = GetTimeInMillis () + ac->elts[0].delay;
+ animCurState.pCursor = pCursor;
+ animCurState.pScreen = pScreen;
+ }
+ }
+ else
+ ret = TRUE;
+ }
+ else
+ {
+ animCurState.pCursor = 0;
+ animCurState.pScreen = 0;
+ ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
+ }
+ Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor);
+ return ret;
+}
+
+static Bool
+AnimCurSetCursorPosition (ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, SetCursorPosition);
+ if (animCurState.pCursor)
+ animCurState.pScreen = pScreen;
+ ret = (*pScreen->SetCursorPosition) (pScreen, x, y, generateEvent);
+ Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
+ return ret;
+}
+
+static Bool
+AnimCurRealizeCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, RealizeCursor);
+ if (IsAnimCur(pCursor))
+ ret = TRUE;
+ else
+ ret = (*pScreen->RealizeCursor) (pScreen, pCursor);
+ Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor);
+ return ret;
+}
+
+static Bool
+AnimCurUnrealizeCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+ Bool ret;
+
+ Unwrap (as, pScreen, UnrealizeCursor);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+ int i;
+
+ if (pScreen->myNum == 0)
+ for (i = 0; i < ac->nelt; i++)
+ FreeCursor (ac->elts[i].pCursor, 0);
+ ret = TRUE;
+ }
+ else
+ ret = (*pScreen->UnrealizeCursor) (pScreen, pCursor);
+ Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
+ return ret;
+}
+
+static void
+AnimCurRecolorCursor (ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Bool displayed)
+{
+ AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
+
+ Unwrap (as, pScreen, RecolorCursor);
+ if (IsAnimCur(pCursor))
+ {
+ AnimCurPtr ac = GetAnimCur(pCursor);
+ int i;
+
+ for (i = 0; i < ac->nelt; i++)
+ (*pScreen->RecolorCursor) (pScreen, ac->elts[i].pCursor,
+ displayed &&
+ animCurState.elt == i);
+ }
+ else
+ (*pScreen->RecolorCursor) (pScreen, pCursor, displayed);
+ Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor);
+}
+
+Bool
+AnimCurInit (ScreenPtr pScreen)
+{
+ AnimCurScreenPtr as;
+
+ if (AnimCurGeneration != serverGeneration)
+ {
+ AnimCurScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (AnimCurScreenPrivateIndex < 0)
+ return FALSE;
+ AnimCurGeneration = serverGeneration;
+ animCurState.pCursor = 0;
+ animCurState.pScreen = 0;
+ animCurState.elt = 0;
+ animCurState.time = 0;
+ }
+ as = (AnimCurScreenPtr) malloc (sizeof (AnimCurScreenRec));
+ if (!as)
+ return FALSE;
+ Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
+
+ Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+
+ Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
+ Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
+ Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
+ Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
+ Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
+ Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
+ SetAnimCurScreen(pScreen,as);
+ return TRUE;
+}
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor)
+{
+ CursorPtr pCursor;
+ int i;
+ AnimCurPtr ac;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ if (!GetAnimCurScreenIfSet (screenInfo.screens[i]))
+ return BadImplementation;
+
+ for (i = 0; i < ncursor; i++)
+ if (IsAnimCur (cursors[i]))
+ return BadMatch;
+
+ pCursor = (CursorPtr) malloc (sizeof (CursorRec) +
+ sizeof (AnimCurRec) +
+ ncursor * sizeof (AnimCurElt));
+ if (!pCursor)
+ return BadAlloc;
+ pCursor->bits = &animCursorBits;
+ animCursorBits.refcnt++;
+ pCursor->refcnt = 1;
+
+ pCursor->foreRed = cursors[0]->foreRed;
+ pCursor->foreGreen = cursors[0]->foreGreen;
+ pCursor->foreBlue = cursors[0]->foreBlue;
+
+ pCursor->backRed = cursors[0]->backRed;
+ pCursor->backGreen = cursors[0]->backGreen;
+ pCursor->backBlue = cursors[0]->backBlue;
+
+ /*
+ * Fill in the AnimCurRec
+ */
+ ac = GetAnimCur (pCursor);
+ ac->nelt = ncursor;
+ ac->elts = (AnimCurElt *) (ac + 1);
+
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i]->refcnt++;
+ ac->elts[i].pCursor = cursors[i];
+ ac->elts[i].delay = deltas[i];
+ }
+
+ *ppCursor = pCursor;
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/render/filter.c b/nx-X11/programs/Xserver/render/filter.c
new file mode 100644
index 000000000..71b893a75
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/filter.c
@@ -0,0 +1,364 @@
+/*
+ * $Id: filter.c,v 1.10 2005/07/03 08:53:54 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+
+static char **filterNames;
+static int nfilterNames;
+
+/*
+ * standard but not required filters don't have constant indices
+ */
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit)
+{
+ int i;
+ char *name;
+ char **names;
+
+ if (len < 0)
+ len = strlen (filter);
+ for (i = 0; i < nfilterNames; i++)
+ if (!CompareISOLatin1Lowered ((unsigned char *) filterNames[i], -1, (unsigned char *) filter, len))
+ return i;
+ if (!makeit)
+ return -1;
+ name = malloc (len + 1);
+ if (!name)
+ return -1;
+ memcpy (name, filter, len);
+ name[len] = '\0';
+ if (filterNames)
+ names = realloc (filterNames, (nfilterNames + 1) * sizeof (char *));
+ else
+ names = malloc (sizeof (char *));
+ if (!names)
+ {
+ free (name);
+ return -1;
+ }
+ filterNames = names;
+ i = nfilterNames++;
+ filterNames[i] = name;
+ return i;
+}
+
+static Bool
+PictureSetDefaultIds (void)
+{
+ /* careful here -- this list must match the #define values */
+
+ if (PictureGetFilterId (FilterNearest, -1, TRUE) != PictFilterNearest)
+ return FALSE;
+ if (PictureGetFilterId (FilterBilinear, -1, TRUE) != PictFilterBilinear)
+ return FALSE;
+
+ if (PictureGetFilterId (FilterFast, -1, TRUE) != PictFilterFast)
+ return FALSE;
+ if (PictureGetFilterId (FilterGood, -1, TRUE) != PictFilterGood)
+ return FALSE;
+ if (PictureGetFilterId (FilterBest, -1, TRUE) != PictFilterBest)
+ return FALSE;
+
+ if (PictureGetFilterId (FilterConvolution, -1, TRUE) != PictFilterConvolution)
+ return FALSE;
+ return TRUE;
+}
+
+char *
+PictureGetFilterName (int id)
+{
+ if (0 <= id && id < nfilterNames)
+ return filterNames[id];
+ else
+ return 0;
+}
+
+static void
+PictureFreeFilterIds (void)
+{
+ int i;
+
+ for (i = 0; i < nfilterNames; i++)
+ free (filterNames[i]);
+ free (filterNames);
+ nfilterNames = 0;
+ filterNames = 0;
+}
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int id = PictureGetFilterId (filter, -1, TRUE);
+ int i;
+ PictFilterPtr filters;
+
+ if (id < 0)
+ return -1;
+ /*
+ * It's an error to attempt to reregister a filter
+ */
+ for (i = 0; i < ps->nfilters; i++)
+ if (ps->filters[i].id == id)
+ return -1;
+ if (ps->filters)
+ filters = realloc (ps->filters, (ps->nfilters + 1) * sizeof (PictFilterRec));
+ else
+ filters = malloc (sizeof (PictFilterRec));
+ if (!filters)
+ return -1;
+ ps->filters = filters;
+ i = ps->nfilters++;
+ ps->filters[i].name = PictureGetFilterName (id);
+ ps->filters[i].id = id;
+ ps->filters[i].ValidateParams = ValidateParams;
+ return id;
+}
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int filter_id = PictureGetFilterId (filter, -1, FALSE);
+ int alias_id = PictureGetFilterId (alias, -1, TRUE);
+ int i;
+
+ if (filter_id < 0 || alias_id < 0)
+ return FALSE;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ if (ps->filterAliases[i].alias_id == alias_id)
+ break;
+ if (i == ps->nfilterAliases)
+ {
+ PictFilterAliasPtr aliases;
+
+ if (ps->filterAliases)
+ aliases = realloc (ps->filterAliases,
+ (ps->nfilterAliases + 1) *
+ sizeof (PictFilterAliasRec));
+ else
+ aliases = malloc (sizeof (PictFilterAliasRec));
+ if (!aliases)
+ return FALSE;
+ ps->filterAliases = aliases;
+ ps->filterAliases[i].alias = PictureGetFilterName (alias_id);
+ ps->filterAliases[i].alias_id = alias_id;
+ ps->nfilterAliases++;
+ }
+ ps->filterAliases[i].filter_id = filter_id;
+ return TRUE;
+}
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int id = PictureGetFilterId (name, len, FALSE);
+ int i;
+
+ if (id < 0)
+ return 0;
+ /* Check for an alias, allow them to recurse */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ if (ps->filterAliases[i].alias_id == id)
+ {
+ id = ps->filterAliases[i].filter_id;
+ i = 0;
+ }
+ /* find the filter */
+ for (i = 0; i < ps->nfilters; i++)
+ if (ps->filters[i].id == id)
+ return &ps->filters[i];
+ return 0;
+}
+
+static Bool
+convolutionFilterValidateParams (ScreenPtr pScreen,
+ int filter,
+ xFixed *params,
+ int nparams,
+ int* width,
+ int* height)
+{
+ int w, h;
+
+ if (nparams < 3)
+ return FALSE;
+
+ if (xFixedFrac (params[0]) || xFixedFrac (params[1]))
+ return FALSE;
+
+ w = xFixedToInt (params[0]);
+ h = xFixedToInt (params[1]);
+
+ nparams -= 2;
+ if (w * h > nparams)
+ return FALSE;
+
+ *width = w;
+ *height = h;
+ return TRUE;
+}
+
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen)
+{
+ if (!filterNames)
+ if (!PictureSetDefaultIds ())
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterNearest, 0) < 0)
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterBilinear, 0) < 0)
+ return FALSE;
+
+ if (!PictureSetFilterAlias (pScreen, FilterNearest, FilterFast))
+ return FALSE;
+ if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterGood))
+ return FALSE;
+ if (!PictureSetFilterAlias (pScreen, FilterBilinear, FilterBest))
+ return FALSE;
+
+ if (PictureAddFilter (pScreen, FilterConvolution, convolutionFilterValidateParams) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+PictureResetFilters (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ free (ps->filters);
+ free (ps->filterAliases);
+ PictureFreeFilterIds ();
+}
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams)
+{
+ PictFilterPtr pFilter;
+ ScreenPtr pScreen;
+
+ if (pPicture->pDrawable) {
+ pScreen = pPicture->pDrawable->pScreen;
+ }
+ else {
+ pScreen = screenInfo.screens[0];
+ }
+
+ pFilter = PictureFindFilter (pScreen, name, len);
+
+ if (!pFilter)
+ return BadName;
+
+ if (pPicture->pDrawable == NULL) {
+ int s;
+
+ /* For source pictures, the picture isn't tied to a screen. So, ensure
+ * that all screens can handle a filter we set for the picture.
+ */
+ for (s = 1; s < screenInfo.numScreens; s++) {
+ PictFilterPtr pScreenFilter;
+
+ pScreenFilter = PictureFindFilter(screenInfo.screens[s], name, len);
+ if (!pScreenFilter || pScreenFilter->id != pFilter->id)
+ return BadMatch;
+ }
+ }
+
+ return SetPicturePictFilter (pPicture, pFilter, params, nparams);
+}
+
+int
+SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
+ xFixed *params, int nparams)
+{
+ ScreenPtr pScreen;
+ int i;
+
+ if (pPicture->pDrawable)
+ pScreen = pPicture->pDrawable->pScreen;
+ else
+ pScreen = screenInfo.screens[0];
+
+ if (pFilter->ValidateParams) {
+ int width, height;
+
+ if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams, &width, &height))
+ return BadMatch;
+ }
+ else if (nparams) {
+ return BadMatch;
+ }
+
+ if (nparams != pPicture->filter_nparams) {
+ xFixed *new_params = malloc (nparams * sizeof (xFixed));
+
+ if (!new_params && nparams)
+ return BadAlloc;
+ free (pPicture->filter_params);
+ pPicture->filter_params = new_params;
+ pPicture->filter_nparams = nparams;
+ }
+ for (i = 0; i < nparams; i++)
+ pPicture->filter_params[i] = params[i];
+ pPicture->filter = pFilter->id;
+
+ if (pPicture->pDrawable)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int result;
+
+ result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
+ params, nparams);
+
+ return result;
+ }
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ return Success;
+}
diff --git a/nx-X11/programs/Xserver/render/glyph.c b/nx-X11/programs/Xserver/render/glyph.c
new file mode 100644
index 000000000..9c9a485ea
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/glyph.c
@@ -0,0 +1,696 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+#include "mipict.h"
+
+#include <stdint.h>
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 }
+};
+
+#define NGLYPHHASHSETS (sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+ int i;
+
+ for (i = 0; i < NGLYPHHASHSETS; i++)
+ if (glyphHashSets[i].entries >= filled)
+ return &glyphHashSets[i];
+ return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+ return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+ _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, void * ptr)
+{
+ void **new;
+
+ if (n > glyphSet->maxPrivate) {
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (void *)(&glyphSet[1])) {
+ new = (void **) realloc (glyphSet->devPrivates,
+ (n + 1) * sizeof (void *));
+ if (!new)
+ return FALSE;
+ } else {
+ new = (void **) malloc ((n + 1) * sizeof (void *));
+ if (!new)
+ return FALSE;
+ if (glyphSet->devPrivates)
+ memcpy (new,
+ glyphSet->devPrivates,
+ (glyphSet->maxPrivate + 1) * sizeof (void *));
+ }
+ glyphSet->devPrivates = new;
+ /* Zero out new, uninitialize privates */
+ while (++glyphSet->maxPrivate < n)
+ glyphSet->devPrivates[glyphSet->maxPrivate] = (void *)0;
+ }
+ glyphSet->devPrivates[n] = ptr;
+ return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+ CARD32 elt, step, s;
+ GlyphPtr glyph;
+ GlyphRefPtr table, gr, del;
+ CARD32 tableSize = hash->hashSet->size;
+
+ table = hash->table;
+ elt = signature % tableSize;
+ step = 0;
+ del = 0;
+ for (;;)
+ {
+ gr = &table[elt];
+ s = gr->signature;
+ glyph = gr->glyph;
+ if (!glyph)
+ {
+ if (del)
+ gr = del;
+ break;
+ }
+ if (glyph == DeletedGlyph)
+ {
+ if (!del)
+ del = gr;
+ else if (gr == del)
+ break;
+ }
+ else if (s == signature &&
+ (!match ||
+ memcmp (&compare->info, &glyph->info, compare->size) == 0))
+ {
+ break;
+ }
+ if (!step)
+ {
+ step = signature % hash->hashSet->rehash;
+ if (!step)
+ step = 1;
+ }
+ elt += step;
+ if (elt >= tableSize)
+ elt -= tableSize;
+ }
+ return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+ CARD32 *bits = (CARD32 *) &(glyph->info);
+ CARD32 hash;
+ int n = glyph->size / sizeof (CARD32);
+
+ hash = 0;
+ while (n--)
+ hash ^= *bits++;
+ return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+ ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+ GlyphPtr g;
+ int i, j;
+
+ for (i = 0; i < hash->hashSet->size; i++)
+ {
+ g = hash->table[i].glyph;
+ if (!g || g == DeletedGlyph)
+ continue;
+ for (j = i + 1; j < hash->hashSet->size; j++)
+ if (hash->table[j].glyph == g)
+ DuplicateRef (g, where);
+ }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+ CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+ if (--glyph->refcnt == 0)
+ {
+ GlyphRefPtr gr;
+ int i;
+ int first;
+
+ first = -1;
+ for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+ if (globalGlyphs[format].table[i].glyph == glyph)
+ {
+ if (first != -1)
+ DuplicateRef (glyph, "FreeGlyph check");
+ first = i;
+ }
+
+ gr = FindGlyphRef (&globalGlyphs[format],
+ HashGlyph (glyph), TRUE, glyph);
+ if (gr - globalGlyphs[format].table != first)
+ DuplicateRef (glyph, "Found wrong one");
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ gr->signature = 0;
+ globalGlyphs[format].tableEntries--;
+ }
+ free (glyph);
+ }
+}
+
+#ifndef NXAGENT_SERVER
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+ GlyphRefPtr gr;
+ CARD32 hash;
+
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+ /* Locate existing matching glyph */
+ hash = HashGlyph (glyph);
+ gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ {
+ free (glyph);
+ glyph = gr->glyph;
+ }
+ else
+ {
+ gr->glyph = glyph;
+ gr->signature = hash;
+ globalGlyphs[glyphSet->fdepth].tableEntries++;
+ }
+
+ /* Insert/replace glyphset value */
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ ++glyph->refcnt;
+ if (gr->glyph && gr->glyph != DeletedGlyph)
+ FreeGlyph (gr->glyph, glyphSet->fdepth);
+ else
+ glyphSet->hash.tableEntries++;
+ gr->glyph = glyph;
+ gr->signature = id;
+ CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+#endif /* NXAGENT_SERVER */
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+
+ gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+ glyph = gr->glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ gr->glyph = DeletedGlyph;
+ glyphSet->hash.tableEntries--;
+ FreeGlyph (glyph, glyphSet->fdepth);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifndef NXAGENT_SERVER
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+ GlyphPtr glyph;
+
+ glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+ if (glyph == DeletedGlyph)
+ glyph = 0;
+ return glyph;
+}
+#endif /* NXAGENT_SERVER */
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+ int size;
+ GlyphPtr glyph;
+ size_t padded_width;
+
+ padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+ if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+ return 0;
+ size = gi->height * padded_width;
+ glyph = (GlyphPtr) malloc (size + sizeof (GlyphRec));
+ if (!glyph)
+ return 0;
+ glyph->refcnt = 0;
+ glyph->size = size + sizeof (xGlyphInfo);
+ glyph->info = *gi;
+ return glyph;
+}
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+ hash->table = (GlyphRefPtr) malloc (hashSet->size * sizeof (GlyphRefRec));
+ if (!hash->table)
+ return FALSE;
+ memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+ hash->hashSet = hashSet;
+ hash->tableEntries = 0;
+ return TRUE;
+}
+
+
+#ifndef NXAGENT_SERVER
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+ CARD32 tableEntries;
+ GlyphHashSetPtr hashSet;
+ GlyphHashRec newHash;
+ GlyphRefPtr gr;
+ GlyphPtr glyph;
+ int i;
+ int oldSize;
+ CARD32 s;
+
+ tableEntries = hash->tableEntries + change;
+ hashSet = FindGlyphHashSet (tableEntries);
+ if (hashSet == hash->hashSet)
+ return TRUE;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash top");
+ if (!AllocateGlyphHash (&newHash, hashSet))
+ return FALSE;
+ if (hash->table)
+ {
+ oldSize = hash->hashSet->size;
+ for (i = 0; i < oldSize; i++)
+ {
+ glyph = hash->table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ {
+ s = hash->table[i].signature;
+ gr = FindGlyphRef (&newHash, s, global, glyph);
+ gr->signature = s;
+ gr->glyph = glyph;
+ ++newHash.tableEntries;
+ }
+ }
+ free (hash->table);
+ }
+ *hash = newHash;
+ if (global)
+ CheckDuplicates (hash, "ResizeGlyphHash bottom");
+ return TRUE;
+}
+#endif /* NXAGENT_SERVER */
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+ return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+ GlyphSetPtr glyphSet;
+ int size;
+
+ if (!globalGlyphs[fdepth].hashSet)
+ {
+ if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+ return FALSE;
+ }
+
+ size = (sizeof (GlyphSetRec) +
+ (sizeof (void *) * _GlyphSetPrivateAllocateIndex));
+ glyphSet = malloc (size);
+ if (!glyphSet)
+ return FALSE;
+ bzero((char *)glyphSet, size);
+ glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+ if (_GlyphSetPrivateAllocateIndex)
+ glyphSet->devPrivates = (void *)(&glyphSet[1]);
+
+ if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+ {
+ free (glyphSet);
+ return FALSE;
+ }
+ glyphSet->refcnt = 1;
+ glyphSet->fdepth = fdepth;
+ glyphSet->format = format;
+ return glyphSet;
+}
+
+int
+FreeGlyphSet (void *value,
+ XID gid)
+{
+ GlyphSetPtr glyphSet = (GlyphSetPtr) value;
+
+ if (--glyphSet->refcnt == 0)
+ {
+ CARD32 i, tableSize = glyphSet->hash.hashSet->size;
+ GlyphRefPtr table = glyphSet->hash.table;
+ GlyphPtr glyph;
+
+ for (i = 0; i < tableSize; i++)
+ {
+ glyph = table[i].glyph;
+ if (glyph && glyph != DeletedGlyph)
+ FreeGlyph (glyph, glyphSet->fdepth);
+ }
+ if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+ {
+ free (globalGlyphs[glyphSet->fdepth].table);
+ globalGlyphs[glyphSet->fdepth].table = 0;
+ globalGlyphs[glyphSet->fdepth].hashSet = 0;
+ }
+ else
+ ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+ free (table);
+
+ if (glyphSet->devPrivates &&
+ glyphSet->devPrivates != (void *)(&glyphSet[1]))
+ free(glyphSet->devPrivates);
+
+ free (glyphSet);
+ }
+ return Success;
+}
+
+void
+GlyphExtents(int nlist, GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
+{
+ int x1, x2, y1, y2;
+ int n;
+ GlyphPtr glyph;
+ int x, y;
+
+ x = 0;
+ y = 0;
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--) {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+CompositeGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr lists, GlyphPtr * glyphs)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture(pSrc);
+ ValidatePicture(pDst);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists,
+ glyphs);
+}
+
+#ifndef NXAGENT_SERVER
+void
+miGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+{
+ PixmapPtr pPixmap = 0;
+ PicturePtr pPicture;
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int xDst = list->xOff, yDst = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents;
+ CARD32 component_alpha;
+
+ if (maskFormat) {
+ GCPtr pGC;
+ xRectangle rect;
+
+ GlyphExtents(nlist, list, glyphs, &extents);
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+ pMaskPixmap =
+ (*pScreen->CreatePixmap) (pScreen, width, height,
+ maskFormat->depth);
+ if (!pMaskPixmap)
+ return;
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture(0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pMask) {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ pGC = GetScratchGC(pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC(&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC(pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else {
+ pMask = pDst;
+ x = 0;
+ y = 0;
+ }
+ pPicture = 0;
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ while (n--) {
+ glyph = *glyphs++;
+ if (!pPicture) {
+ pPixmap =
+ GetScratchPixmapHeader(pScreen, glyph->info.width,
+ glyph->info.height,
+ list->format->depth,
+ list->format->depth, 0,
+ (void *) (glyph + 1));
+ if (!pPixmap)
+ return;
+ component_alpha = NeedsComponent(list->format->format);
+ pPicture = CreatePicture(0, &pPixmap->drawable, list->format,
+ CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pPicture) {
+ FreeScratchPixmapHeader(pPixmap);
+ return;
+ }
+ }
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width,
+ glyph->info.height, 0, 0, -1,
+ (void *) (glyph + 1));
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (maskFormat) {
+ CompositePicture(PictOpAdd,
+ pPicture,
+ None,
+ pMask,
+ 0, 0,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width, glyph->info.height);
+ }
+ else {
+ CompositePicture(op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (x - glyph->info.x) - xDst,
+ ySrc + (y - glyph->info.y) - yDst,
+ 0, 0,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width, glyph->info.height);
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ list++;
+ if (pPicture) {
+ FreeScratchPixmapHeader(pPixmap);
+ FreePicture((void *) pPicture, 0);
+ pPicture = 0;
+ pPixmap = 0;
+ }
+ }
+ if (maskFormat) {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture(op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - xDst,
+ ySrc + y - yDst, 0, 0, x, y, width, height);
+ FreePicture((void *) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+}
+#endif
diff --git a/nx-X11/programs/Xserver/render/glyphstr.h b/nx-X11/programs/Xserver/render/glyphstr.h
new file mode 100644
index 000000000..5c4ed4933
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/glyphstr.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <nx-X11/extensions/renderproto.h>
+#include "picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1 0
+#define GlyphFormat4 1
+#define GlyphFormat8 2
+#define GlyphFormat16 3
+#define GlyphFormat32 4
+#define GlyphFormatNum 5
+
+typedef struct _Glyph {
+ CARD32 refcnt;
+ CARD32 size; /* info + bitmap */
+ xGlyphInfo info;
+ /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+#ifdef NXAGENT_SERVER
+#include "../hw/nxagent/NXglyphstr_GlyphRef.h"
+#else
+typedef struct _GlyphRef {
+ CARD32 signature;
+ GlyphPtr glyph;
+} GlyphRefRec, *GlyphRefPtr;
+#endif /* NXAGENT_SERVER */
+
+#define DeletedGlyph ((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+ CARD32 entries;
+ CARD32 size;
+ CARD32 rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+ GlyphRefPtr table;
+ GlyphHashSetPtr hashSet;
+ CARD32 tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+#ifdef NXAGENT_SERVER
+#include "../hw/nxagent/NXglyphstr_GlyphSet.h"
+#else
+typedef struct _GlyphSet {
+ CARD32 refcnt;
+ PictFormatPtr format;
+ int fdepth;
+ GlyphHashRec hash;
+ int maxPrivate;
+ void **devPrivates;
+} GlyphSetRec, *GlyphSetPtr;
+#endif /* NXAGENT_SERVER */
+
+#define GlyphSetGetPrivate(pGlyphSet,n) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ (void *) 0 : \
+ (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr) \
+ ((n) > (pGlyphSet)->maxPrivate ? \
+ _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) : \
+ ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+ INT16 xOff;
+ INT16 yOff;
+ CARD8 len;
+ PictFormatPtr format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, void * ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (void *value,
+ XID gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/render/matrix.c b/nx-X11/programs/Xserver/render/matrix.c
new file mode 100644
index 000000000..83cd66c43
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/matrix.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2007 Keith Packard
+ *
+ * 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, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+
+void
+PictTransform_from_xRenderTransform(PictTransformPtr pict,
+ xRenderTransform * render)
+{
+ pict->matrix[0][0] = render->matrix11;
+ pict->matrix[0][1] = render->matrix12;
+ pict->matrix[0][2] = render->matrix13;
+
+ pict->matrix[1][0] = render->matrix21;
+ pict->matrix[1][1] = render->matrix22;
+ pict->matrix[1][2] = render->matrix23;
+
+ pict->matrix[2][0] = render->matrix31;
+ pict->matrix[2][1] = render->matrix32;
+ pict->matrix[2][2] = render->matrix33;
+}
+
+void
+xRenderTransform_from_PictTransform(xRenderTransform * render,
+ PictTransformPtr pict)
+{
+ render->matrix11 = pict->matrix[0][0];
+ render->matrix12 = pict->matrix[0][1];
+ render->matrix13 = pict->matrix[0][2];
+
+ render->matrix21 = pict->matrix[1][0];
+ render->matrix22 = pict->matrix[1][1];
+ render->matrix23 = pict->matrix[1][2];
+
+ render->matrix31 = pict->matrix[2][0];
+ render->matrix32 = pict->matrix[2][1];
+ render->matrix33 = pict->matrix[2][2];
+}
+
+Bool
+PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector)
+{
+ return pixman_transform_point(transform, vector);
+}
+
+Bool
+PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector)
+{
+ return pixman_transform_point_3d(transform, vector);
+}
diff --git a/nx-X11/programs/Xserver/render/miindex.c b/nx-X11/programs/Xserver/render/miindex.c
new file mode 100644
index 000000000..5b5f35b19
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/miindex.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _MIINDEX_H_
+#define _MIINDEX_H_
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+#include "colormapst.h"
+
+#define NUM_CUBE_LEVELS 4
+#define NUM_GRAY_LEVELS 13
+
+static Bool
+miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump)
+{
+ int r, g, b;
+ unsigned short red, green, blue;
+ Pixel pixel;
+ Bool used[MI_MAX_INDEXED];
+ int needed;
+ int policy;
+ int cube, gray;
+ int i, n;
+
+ if (pColormap->mid != pColormap->pScreen->defColormap)
+ {
+ policy = PictureCmapPolicyAll;
+ }
+ else
+ {
+ int avail = pColormap->pVisual->ColormapEntries;
+ policy = PictureCmapPolicy;
+ if (policy == PictureCmapPolicyDefault)
+ {
+ if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ policy = PictureCmapPolicyColor;
+ else if (avail >= 64)
+ policy = PictureCmapPolicyGray;
+ else
+ policy = PictureCmapPolicyMono;
+ }
+ }
+ /*
+ * Make sure enough cells are free for the chosen policy
+ */
+ for (;;)
+ {
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ needed = 0;
+ break;
+ case PictureCmapPolicyColor:
+ needed = 71;
+ break;
+ case PictureCmapPolicyGray:
+ needed = 11;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ needed = 0;
+ break;
+ }
+ if (needed <= pColormap->freeRed)
+ break;
+ policy--;
+ }
+
+ /*
+ * Compute size of cube and gray ramps
+ */
+ cube = gray = 0;
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ /*
+ * Allocate as big a cube as possible
+ */
+ if ((pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ {
+ for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++)
+ ;
+ cube--;
+ if (cube == 1)
+ cube = 0;
+ }
+ else
+ cube = 0;
+ /*
+ * Figure out how many gray levels to use so that they
+ * line up neatly with the cube
+ */
+ if (cube)
+ {
+ needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube);
+ /* levels to fill in with */
+ gray = needed / (cube - 1);
+ /* total levels */
+ gray = (gray + 1) * (cube - 1) + 1;
+ }
+ else
+ gray = pColormap->pVisual->ColormapEntries;
+ break;
+
+ case PictureCmapPolicyColor:
+ cube = NUM_CUBE_LEVELS;
+ /* fall through ... */
+ case PictureCmapPolicyGray:
+ gray = NUM_GRAY_LEVELS;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ gray = 2;
+ break;
+ }
+
+ memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool));
+ for (r = 0; r < cube; r++)
+ for (g = 0; g < cube; g++)
+ for (b = 0; b < cube; b++)
+ {
+ red = (r * 65535 + (cube-1)/2) / (cube - 1);
+ green = (g * 65535 + (cube-1)/2) / (cube - 1);
+ blue = (b * 65535 + (cube-1)/2) / (cube - 1);
+ if (AllocColor (pColormap, &red, &green,
+ &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ for (g = 0; g < gray; g++)
+ {
+ red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1);
+ if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ n = 0;
+ for (i = 0; i < pColormap->pVisual->ColormapEntries; i++)
+ if (used[i])
+ pixels[n++] = i;
+
+ *nump = n;
+
+ return TRUE;
+}
+
+/* 0 <= red, green, blue < 32 */
+static Pixel
+FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num,
+ int red, int green, int blue)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr, dg, db;
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ dr = ((v >> 19) & 0x1f);
+ dg = ((v >> 11) & 0x1f);
+ db = ((v >> 3) & 0x1f);
+ dr = dr - red;
+ dg = dg - green;
+ db = db - blue;
+ dist = dr * dr + dg * dg + db * db;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+/* 0 <= gray < 32768 */
+static Pixel
+FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr;
+ int r;
+
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ r = v & 0xff;
+ r = r | (r << 8);
+ dr = gray - (r >> 1);
+ dist = dr * dr;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ ColormapPtr pColormap = pFormat->index.pColormap;
+ VisualPtr pVisual = pColormap->pVisual;
+ miIndexedPtr pIndexed;
+ Pixel pixels[MI_MAX_INDEXED];
+ xrgb rgb[MI_MAX_INDEXED];
+ int num;
+ int i;
+ Pixel p, r, g, b;
+
+ if (pVisual->ColormapEntries > MI_MAX_INDEXED)
+ return FALSE;
+
+ if (pVisual->class & DynamicClass)
+ {
+ if (!miBuildRenderColormap (pColormap, pixels, &num))
+ return FALSE;
+ }
+ else
+ {
+ num = pVisual->ColormapEntries;
+ for (p = 0; p < num; p++)
+ pixels[p] = p;
+ }
+
+ pIndexed = malloc (sizeof (miIndexedRec));
+ if (!pIndexed)
+ return FALSE;
+
+ pFormat->index.nvalues = num;
+ pFormat->index.pValues = malloc (num * sizeof (xIndexValue));
+ if (!pFormat->index.pValues)
+ {
+ free (pIndexed);
+ return FALSE;
+ }
+
+
+ /*
+ * Build mapping from pixel value to ARGB
+ */
+ QueryColors (pColormap, num, pixels, rgb);
+ for (i = 0; i < num; i++)
+ {
+ p = pixels[i];
+ pFormat->index.pValues[i].pixel = p;
+ pFormat->index.pValues[i].red = rgb[i].red;
+ pFormat->index.pValues[i].green = rgb[i].green;
+ pFormat->index.pValues[i].blue = rgb[i].blue;
+ pFormat->index.pValues[i].alpha = 0xffff;
+ pIndexed->rgba[p] = (0xff000000 |
+ ((rgb[i].red & 0xff00) << 8) |
+ ((rgb[i].green & 0xff00) ) |
+ ((rgb[i].blue & 0xff00) >> 8));
+ }
+
+ /*
+ * Build mapping from RGB to pixel value. This could probably be
+ * done a bit quicker...
+ */
+ switch (pVisual->class | DynamicClass) {
+ case GrayScale:
+ pIndexed->color = FALSE;
+ for (r = 0; r < 32768; r++)
+ pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r);
+ break;
+ case PseudoColor:
+ pIndexed->color = TRUE;
+ p = 0;
+ for (r = 0; r < 32; r++)
+ for (g = 0; g < 32; g++)
+ for (b = 0; b < 32; b++)
+ {
+ pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num,
+ r, g, b);
+ p++;
+ }
+ break;
+ }
+ pFormat->index.devPrivate = pIndexed;
+ return TRUE;
+}
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ if (pFormat->index.devPrivate)
+ {
+ free (pFormat->index.devPrivate);
+ pFormat->index.devPrivate = 0;
+ }
+ if (pFormat->index.pValues)
+ {
+ free (pFormat->index.pValues);
+ pFormat->index.pValues = 0;
+ }
+}
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef)
+{
+ miIndexedPtr pIndexed = pFormat->index.devPrivate;
+
+ if (pIndexed)
+ {
+ while (ndef--)
+ {
+ pIndexed->rgba[pdef->pixel] = (0xff000000 |
+ ((pdef->red & 0xff00) << 8) |
+ ((pdef->green & 0xff00) ) |
+ ((pdef->blue & 0xff00) >> 8));
+ pdef++;
+ }
+ }
+}
+
+#endif /* _MIINDEX_H_ */
diff --git a/nx-X11/programs/Xserver/render/mipict.c b/nx-X11/programs/Xserver/render/mipict.c
new file mode 100644
index 000000000..9b8f0cfda
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/mipict.c
@@ -0,0 +1,644 @@
+/*
+ * Copyright © 1999 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifndef __GNUC__
+#define __inline
+#endif
+
+int
+miCreatePicture (PicturePtr pPicture)
+{
+ return Success;
+}
+
+void
+miDestroyPicture (PicturePtr pPicture)
+{
+ if (pPicture->freeCompClip)
+ RegionDestroy(pPicture->pCompositeClip);
+}
+
+void
+miDestroyPictureClip (PicturePtr pPicture)
+{
+ switch (pPicture->clientClipType) {
+ case CT_NONE:
+ return;
+ case CT_PIXMAP:
+ (*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
+ break;
+ default:
+ /*
+ * we know we'll never have a list of rectangles, since ChangeClip
+ * immediately turns them into a region
+ */
+ RegionDestroy(pPicture->clientClip);
+ break;
+ }
+ pPicture->clientClip = NULL;
+ pPicture->clientClipType = CT_NONE;
+}
+
+int
+miChangePictureClip (PicturePtr pPicture,
+ int type,
+ void * value,
+ int n)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ void * clientClip;
+ int clientClipType;
+
+ switch (type) {
+ case CT_PIXMAP:
+ /* convert the pixmap to a region */
+ clientClip = (void *) BitmapToRegion(pScreen, (PixmapPtr) value);
+ if (!clientClip)
+ return BadAlloc;
+ clientClipType = CT_REGION;
+ (*pScreen->DestroyPixmap) ((PixmapPtr) value);
+ break;
+ case CT_REGION:
+ clientClip = value;
+ clientClipType = CT_REGION;
+ break;
+ case CT_NONE:
+ clientClip = 0;
+ clientClipType = CT_NONE;
+ break;
+ default:
+ clientClip = (void *) RegionFromRects(n,
+ (xRectangle *) value,
+ type);
+ if (!clientClip)
+ return BadAlloc;
+ clientClipType = CT_REGION;
+ free(value);
+ break;
+ }
+ (*ps->DestroyPictureClip) (pPicture);
+ pPicture->clientClip = clientClip;
+ pPicture->clientClipType = clientClipType;
+ pPicture->stateChanges |= CPClipMask;
+ return Success;
+}
+
+void
+miChangePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ return;
+}
+
+void
+miValidatePicture (PicturePtr pPicture,
+ Mask mask)
+{
+ DrawablePtr pDrawable = pPicture->pDrawable;
+
+ if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
+ (pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pPicture->subWindowMode == IncludeInferiors)
+ {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else
+ {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pPicture->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy
+ * (or maybe re-use) it later. this way, we avoid unnecessary
+ * copying of regions. (this wins especially if many clients clip
+ * by children and have no client clip.)
+ */
+ if (pPicture->clientClipType == CT_NONE)
+ {
+ if (freeCompClip)
+ RegionDestroy(pPicture->pCompositeClip);
+ pPicture->pCompositeClip = pregWin;
+ pPicture->freeCompClip = freeTmpClip;
+ }
+ else
+ {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ RegionTranslate(pPicture->clientClip,
+ pDrawable->x + pPicture->clipOrigin.x,
+ pDrawable->y + pPicture->clipOrigin.y);
+
+ if (freeCompClip)
+ {
+ RegionIntersect(pPicture->pCompositeClip,
+ pregWin, pPicture->clientClip);
+ if (freeTmpClip)
+ RegionDestroy(pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ RegionIntersect(pregWin, pregWin, pPicture->clientClip);
+ pPicture->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pPicture->pCompositeClip = RegionCreate(NullBox, 0);
+ RegionIntersect(pPicture->pCompositeClip,
+ pregWin, pPicture->clientClip);
+ }
+ pPicture->freeCompClip = TRUE;
+ RegionTranslate(pPicture->clientClip,
+ -(pDrawable->x + pPicture->clipOrigin.x),
+ -(pDrawable->y + pPicture->clipOrigin.y));
+ }
+ } /* end of composite clip for a window */
+ else
+ {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ /* If you want pixmaps in offscreen memory, yes */
+ pixbounds.x1 = pDrawable->x;
+ pixbounds.y1 = pDrawable->y;
+ pixbounds.x2 = pDrawable->x + pDrawable->width;
+ pixbounds.y2 = pDrawable->y + pDrawable->height;
+
+ if (pPicture->freeCompClip)
+ {
+ RegionReset(pPicture->pCompositeClip, &pixbounds);
+ }
+ else
+ {
+ pPicture->freeCompClip = TRUE;
+ pPicture->pCompositeClip = RegionCreate(&pixbounds, 1);
+ }
+
+ if (pPicture->clientClipType == CT_REGION)
+ {
+ if(pDrawable->x || pDrawable->y) {
+ RegionTranslate(pPicture->clientClip,
+ pDrawable->x + pPicture->clipOrigin.x,
+ pDrawable->y + pPicture->clipOrigin.y);
+ RegionIntersect(pPicture->pCompositeClip,
+ pPicture->pCompositeClip, pPicture->clientClip);
+ RegionTranslate(pPicture->clientClip,
+ -(pDrawable->x + pPicture->clipOrigin.x),
+ -(pDrawable->y + pPicture->clipOrigin.y));
+ } else {
+ RegionTranslate(pPicture->pCompositeClip,
+ -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
+ RegionIntersect(pPicture->pCompositeClip,
+ pPicture->pCompositeClip, pPicture->clientClip);
+ RegionTranslate(pPicture->pCompositeClip,
+ pPicture->clipOrigin.x, pPicture->clipOrigin.y);
+ }
+ }
+ } /* end of composite clip for pixmap */
+ }
+}
+
+int
+miChangePictureTransform (PicturePtr pPicture,
+ PictTransform *transform)
+{
+ return Success;
+}
+
+int
+miChangePictureFilter (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams)
+{
+ return Success;
+}
+
+#define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
+
+static __inline Bool
+miClipPictureReg (RegionPtr pRegion,
+ RegionPtr pClip,
+ int dx,
+ int dy)
+{
+ if (RegionNumRects(pRegion) == 1 &&
+ RegionNumRects(pClip) == 1)
+ {
+ BoxPtr pRbox = RegionRects(pRegion);
+ BoxPtr pCbox = RegionRects(pClip);
+ int v;
+
+ if (pRbox->x1 < (v = pCbox->x1 + dx))
+ pRbox->x1 = BOUND(v);
+ if (pRbox->x2 > (v = pCbox->x2 + dx))
+ pRbox->x2 = BOUND(v);
+ if (pRbox->y1 < (v = pCbox->y1 + dy))
+ pRbox->y1 = BOUND(v);
+ if (pRbox->y2 > (v = pCbox->y2 + dy))
+ pRbox->y2 = BOUND(v);
+ if (pRbox->x1 >= pRbox->x2 ||
+ pRbox->y1 >= pRbox->y2)
+ {
+ RegionEmpty(pRegion);
+ }
+ }
+ else if (!RegionNotEmpty(pClip))
+ return FALSE;
+ else
+ {
+ if (dx || dy)
+ RegionTranslate(pRegion, -dx, -dy);
+ if (!RegionIntersect(pRegion, pRegion, pClip))
+ return FALSE;
+ if (dx || dy)
+ RegionTranslate(pRegion, dx, dy);
+ }
+ return RegionNotEmpty(pRegion);
+}
+
+static __inline Bool
+miClipPictureSrc (RegionPtr pRegion,
+ PicturePtr pPicture,
+ int dx,
+ int dy)
+{
+ /* XXX what to do with clipping from transformed pictures? */
+ if (pPicture->transform || !pPicture->pDrawable)
+ return TRUE;
+ if (pPicture->repeat)
+ {
+ if (pPicture->clientClipType != CT_NONE)
+ {
+ RegionTranslate(pRegion,
+ dx - pPicture->clipOrigin.x,
+ dy - pPicture->clipOrigin.y);
+ if (!RegionIntersect(pRegion, pRegion,
+ (RegionPtr) pPicture->clientClip))
+ return FALSE;
+ RegionTranslate(pRegion,
+ - (dx - pPicture->clipOrigin.x),
+ - (dy - pPicture->clipOrigin.y));
+ }
+ return TRUE;
+ }
+ else
+ {
+ return miClipPictureReg (pRegion,
+ pPicture->pCompositeClip,
+ dx,
+ dy);
+ }
+}
+
+static void
+miCompositeSourceValidate (PicturePtr pPicture,
+ INT16 x,
+ INT16 y,
+ CARD16 width,
+ CARD16 height)
+{
+ DrawablePtr pDrawable = pPicture->pDrawable;
+ ScreenPtr pScreen;
+
+ if (!pDrawable)
+ return;
+
+ pScreen = pDrawable->pScreen;
+
+ if (pScreen->SourceValidate)
+ {
+ x -= pPicture->pDrawable->x;
+ y -= pPicture->pDrawable->y;
+ if (pPicture->transform)
+ {
+ xPoint points[4];
+ int i;
+ int xmin, ymin, xmax, ymax;
+
+#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; }
+ VectorSet (0, x, y);
+ VectorSet (1, x + width, y);
+ VectorSet (2, x, y + height);
+ VectorSet (3, x + width, y + height);
+ xmin = ymin = 32767;
+ xmax = ymax = -32737;
+ for (i = 0; i < 4; i++)
+ {
+ PictVector t;
+ t.vector[0] = IntToxFixed (points[i].x);
+ t.vector[1] = IntToxFixed (points[i].y);
+ t.vector[2] = xFixed1;
+ if (PictureTransformPoint (pPicture->transform, &t))
+ {
+ int tx = xFixedToInt (t.vector[0]);
+ int ty = xFixedToInt (t.vector[1]);
+ if (tx < xmin) xmin = tx;
+ if (tx > xmax) xmax = tx;
+ if (ty < ymin) ymin = ty;
+ if (ty > ymax) ymax = ty;
+ }
+ }
+ x = xmin;
+ y = ymin;
+ width = xmax - xmin;
+ height = ymax - ymin;
+ }
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+ }
+}
+
+/*
+ * returns FALSE if the final region is empty. Indistinguishable from
+ * an allocation failure, but rendering ignores those anyways.
+ */
+
+Bool
+miComputeCompositeRegion (RegionPtr pRegion,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ int v;
+
+ pRegion->extents.x1 = xDst;
+ v = xDst + width;
+ pRegion->extents.x2 = BOUND(v);
+ pRegion->extents.y1 = yDst;
+ v = yDst + height;
+ pRegion->extents.y2 = BOUND(v);
+ pRegion->data = 0;
+ /* Check for empty operation */
+ if (pRegion->extents.x1 >= pRegion->extents.x2 ||
+ pRegion->extents.y1 >= pRegion->extents.y2)
+ {
+ RegionEmpty(pRegion);
+ return FALSE;
+ }
+ /* clip against dst */
+ if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ if (pDst->alphaMap)
+ {
+ if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
+ -pDst->alphaOrigin.x,
+ -pDst->alphaOrigin.y))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ }
+ /* clip against src */
+ if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ if (pSrc->alphaMap)
+ {
+ if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
+ xDst - (xSrc + pSrc->alphaOrigin.x),
+ yDst - (ySrc + pSrc->alphaOrigin.y)))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ }
+ /* clip against mask */
+ if (pMask)
+ {
+ if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ if (pMask->alphaMap)
+ {
+ if (!miClipPictureSrc (pRegion, pMask->alphaMap,
+ xDst - (xMask + pMask->alphaOrigin.x),
+ yDst - (yMask + pMask->alphaOrigin.y)))
+ {
+ RegionUninit(pRegion);
+ return FALSE;
+ }
+ }
+ }
+ miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
+ if (pMask)
+ miCompositeSourceValidate (pMask, xMask, yMask, width, height);
+ return TRUE;
+}
+
+void
+miRenderColorToPixel (PictFormatPtr format,
+ xRenderColor *color,
+ CARD32 *pixel)
+{
+ CARD32 r, g, b, a;
+ miIndexedPtr pIndexed;
+
+ switch (format->type) {
+ case PictTypeDirect:
+ r = color->red >> (16 - Ones (format->direct.redMask));
+ g = color->green >> (16 - Ones (format->direct.greenMask));
+ b = color->blue >> (16 - Ones (format->direct.blueMask));
+ a = color->alpha >> (16 - Ones (format->direct.alphaMask));
+ r = r << format->direct.red;
+ g = g << format->direct.green;
+ b = b << format->direct.blue;
+ a = a << format->direct.alpha;
+ *pixel = r|g|b|a;
+ break;
+ case PictTypeIndexed:
+ pIndexed = (miIndexedPtr) (format->index.devPrivate);
+ if (pIndexed->color)
+ {
+ r = color->red >> 11;
+ g = color->green >> 11;
+ b = color->blue >> 11;
+ *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b);
+ }
+ else
+ {
+ r = color->red >> 8;
+ g = color->green >> 8;
+ b = color->blue >> 8;
+ *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b);
+ }
+ break;
+ }
+}
+
+static CARD16
+miFillColor (CARD32 pixel, int bits)
+{
+ while (bits < 16)
+ {
+ pixel |= pixel << bits;
+ bits <<= 1;
+ }
+ return (CARD16) pixel;
+}
+
+Bool
+miIsSolidAlpha (PicturePtr pSrc)
+{
+ ScreenPtr pScreen;
+ char line[1];
+
+ if (!pSrc->pDrawable)
+ return FALSE;
+
+ pScreen = pSrc->pDrawable->pScreen;
+
+ /* Alpha-only */
+ if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
+ return FALSE;
+ /* repeat */
+ if (!pSrc->repeat)
+ return FALSE;
+ /* 1x1 */
+ if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
+ return FALSE;
+ line[0] = 1;
+ (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line);
+ switch (pSrc->pDrawable->bitsPerPixel) {
+ case 1:
+ return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80;
+ case 4:
+ return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0;
+ case 8:
+ return (CARD8) line[0] == 0xff;
+ default:
+ return FALSE;
+ }
+}
+
+void
+miRenderPixelToColor (PictFormatPtr format,
+ CARD32 pixel,
+ xRenderColor *color)
+{
+ CARD32 r, g, b, a;
+ miIndexedPtr pIndexed;
+
+ switch (format->type) {
+ case PictTypeDirect:
+ r = (pixel >> format->direct.red) & format->direct.redMask;
+ g = (pixel >> format->direct.green) & format->direct.greenMask;
+ b = (pixel >> format->direct.blue) & format->direct.blueMask;
+ a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
+ color->red = miFillColor (r, Ones (format->direct.redMask));
+ color->green = miFillColor (g, Ones (format->direct.greenMask));
+ color->blue = miFillColor (b, Ones (format->direct.blueMask));
+ color->alpha = miFillColor (a, Ones (format->direct.alphaMask));
+ break;
+ case PictTypeIndexed:
+ pIndexed = (miIndexedPtr) (format->index.devPrivate);
+ pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)];
+ r = (pixel >> 16) & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel ) & 0xff;
+ color->red = miFillColor (r, 8);
+ color->green = miFillColor (g, 8);
+ color->blue = miFillColor (b, 8);
+ color->alpha = 0xffff;
+ break;
+ }
+}
+
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+
+ if (!PictureInit (pScreen, formats, nformats))
+ return FALSE;
+ ps = GetPictureScreen(pScreen);
+ ps->CreatePicture = miCreatePicture;
+ ps->DestroyPicture = miDestroyPicture;
+ ps->ChangePictureClip = miChangePictureClip;
+ ps->DestroyPictureClip = miDestroyPictureClip;
+ ps->ChangePicture = miChangePicture;
+ ps->ValidatePicture = miValidatePicture;
+ ps->InitIndexed = miInitIndexed;
+ ps->CloseIndexed = miCloseIndexed;
+ ps->UpdateIndexed = miUpdateIndexed;
+ ps->ChangePictureTransform = miChangePictureTransform;
+ ps->ChangePictureFilter = miChangePictureFilter;
+
+ /* MI rendering routines */
+ ps->Composite = 0; /* requires DDX support */
+ ps->Glyphs = miGlyphs;
+ ps->CompositeRects = miCompositeRects;
+ ps->Trapezoids = miTrapezoids;
+ ps->Triangles = miTriangles;
+ ps->TriStrip = miTriStrip;
+ ps->TriFan = miTriFan;
+
+ ps->RasterizeTrapezoid = 0; /* requires DDX support */
+ ps->AddTraps = 0; /* requires DDX support */
+ ps->AddTriangles = 0; /* requires DDX support */
+
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/render/mipict.h b/nx-X11/programs/Xserver/render/mipict.h
new file mode 100644
index 000000000..6a6554033
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/mipict.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _MIPICT_H_
+#define _MIPICT_H_
+
+#include "picturestr.h"
+
+#define MI_MAX_INDEXED 256 /* XXX depth must be <= 8 */
+
+#if MI_MAX_INDEXED <= 256
+typedef CARD8 miIndexType;
+#endif
+
+typedef struct _miIndexed {
+ Bool color;
+ CARD32 rgba[MI_MAX_INDEXED];
+ miIndexType ent[32768];
+} miIndexedRec, *miIndexedPtr;
+
+#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
+ (((s) >> 6) & 0x03e0) | \
+ (((s) >> 9) & 0x7c00))
+#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
+#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
+
+#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
+
+int
+miCreatePicture (PicturePtr pPicture);
+
+void
+miDestroyPicture (PicturePtr pPicture);
+
+void
+miDestroyPictureClip (PicturePtr pPicture);
+
+int
+miChangePictureClip (PicturePtr pPicture,
+ int type,
+ void * value,
+ int n);
+
+void
+miChangePicture (PicturePtr pPicture,
+ Mask mask);
+
+void
+miValidatePicture (PicturePtr pPicture,
+ Mask mask);
+
+int
+miChangePictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+int
+miChangePictureFilter (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+Bool
+miClipPicture (RegionPtr pRegion,
+ PicturePtr pPicture,
+ INT16 xReg,
+ INT16 yReg,
+ INT16 xPict,
+ INT16 yPict);
+
+Bool
+miComputeCompositeRegion (RegionPtr pRegion,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+void
+miGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+void
+miRenderColorToPixel (PictFormatPtr pPict,
+ xRenderColor *color,
+ CARD32 *pixel);
+
+void
+miRenderPixelToColor (PictFormatPtr pPict,
+ CARD32 pixel,
+ xRenderColor *color);
+
+Bool
+miIsSolidAlpha (PicturePtr pSrc);
+
+void
+miCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
+
+void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
+
+void
+miRasterizeTriangle (PicturePtr pMask,
+ xTriangle *tri,
+ int x_off,
+ int y_off);
+
+void
+miTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height);
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+#endif /* _MIPICT_H_ */
diff --git a/nx-X11/programs/Xserver/render/mirect.c b/nx-X11/programs/Xserver/render/mirect.c
new file mode 100644
index 000000000..49da8d4f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/mirect.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+static void
+miColorRects (PicturePtr pDst,
+ PicturePtr pClipPict,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects,
+ int xoff,
+ int yoff)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ CARD32 pixel;
+ GCPtr pGC;
+ CARD32 tmpval[5];
+ RegionPtr pClip;
+ unsigned long mask;
+
+ miRenderColorToPixel (pDst->pFormat, color, &pixel);
+
+ pGC = GetScratchGC (pDst->pDrawable->depth, pScreen);
+ if (!pGC)
+ return;
+ tmpval[0] = GXcopy;
+ tmpval[1] = pixel;
+ tmpval[2] = pDst->subWindowMode;
+ mask = GCFunction | GCForeground | GCSubwindowMode;
+ if (pClipPict->clientClipType == CT_REGION)
+ {
+ tmpval[3] = pDst->clipOrigin.x - xoff;
+ tmpval[4] = pDst->clipOrigin.y - yoff;
+ mask |= GCClipXOrigin|GCClipYOrigin;
+
+ pClip = RegionCreate(NULL, 1);
+ RegionCopy(pClip,
+ (RegionPtr) pClipPict->clientClip);
+ (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
+ }
+
+ ChangeGC (pGC, mask, tmpval);
+ ValidateGC (pDst->pDrawable, pGC);
+ if (xoff || yoff)
+ {
+ int i;
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x -= xoff;
+ rects[i].y -= yoff;
+ }
+ }
+ (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
+ if (xoff || yoff)
+ {
+ int i;
+ for (i = 0; i < nRect; i++)
+ {
+ rects[i].x += xoff;
+ rects[i].y += yoff;
+ }
+ }
+ FreeScratchGC (pGC);
+}
+
+void
+miCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+
+ if (color->alpha == 0xffff)
+ {
+ if (op == PictOpOver)
+ op = PictOpSrc;
+ }
+ if (op == PictOpClear)
+ color->red = color->green = color->blue = color->alpha = 0;
+
+ if (op == PictOpSrc || op == PictOpClear)
+ {
+ miColorRects (pDst, pDst, color, nRect, rects, 0, 0);
+ if (pDst->alphaMap)
+ miColorRects (pDst->alphaMap, pDst,
+ color, nRect, rects,
+ pDst->alphaOrigin.x,
+ pDst->alphaOrigin.y);
+ }
+ else
+ {
+ PictFormatPtr rgbaFormat;
+ PixmapPtr pPixmap;
+ PicturePtr pSrc;
+ xRectangle one;
+ int error;
+ Pixel pixel;
+ GCPtr pGC;
+ CARD32 tmpval[2];
+
+ rgbaFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!rgbaFormat)
+ goto bail1;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1,
+ rgbaFormat->depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ goto bail2;
+
+ miRenderColorToPixel (rgbaFormat, color, &pixel);
+
+ pGC = GetScratchGC (rgbaFormat->depth, pScreen);
+ if (!pGC)
+ goto bail3;
+ tmpval[0] = GXcopy;
+ tmpval[1] = pixel;
+
+ ChangeGC (pGC, GCFunction | GCForeground, tmpval);
+ ValidateGC (&pPixmap->drawable, pGC);
+ one.x = 0;
+ one.y = 0;
+ one.width = 1;
+ one.height = 1;
+ (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
+
+ tmpval[0] = xTrue;
+ pSrc = CreatePicture (0, &pPixmap->drawable, rgbaFormat,
+ CPRepeat, tmpval, 0, &error);
+
+ if (!pSrc)
+ goto bail4;
+
+ while (nRect--)
+ {
+ CompositePicture (op, pSrc, 0, pDst, 0, 0, 0, 0,
+ rects->x,
+ rects->y,
+ rects->width,
+ rects->height);
+ rects++;
+ }
+
+ FreePicture ((void *) pSrc, 0);
+bail4:
+ FreeScratchGC (pGC);
+bail3:
+ (*pScreen->DestroyPixmap) (pPixmap);
+bail2:
+bail1:
+ ;
+ }
+}
diff --git a/nx-X11/programs/Xserver/render/mitrap.c b/nx-X11/programs/Xserver/render/mitrap.c
new file mode 100644
index 000000000..2155641ce
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/mitrap.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat,
+ CARD16 width,
+ CARD16 height)
+{
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ GCPtr pGC;
+ int error;
+ xRectangle rect;
+
+ if (width > 32767 || height > 32767)
+ return 0;
+
+ if (!pPictFormat)
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ if (!pPictFormat)
+ return 0;
+ }
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ pPictFormat->depth, 0);
+ if (!pPixmap)
+ return 0;
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return 0;
+ }
+ ValidateGC (&pPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+ pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+ 0, 0, serverClient, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+ xFixed dx = l->p2.x - l->p1.x;
+ xFixed_32_32 ex = (xFixed_32_32) (y - l->p1.y) * dx;
+ xFixed dy = l->p2.y - l->p1.y;
+ if (ceil)
+ ex += (dy - 1);
+ return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+ box->y1 = MAXSHORT;
+ box->y2 = MINSHORT;
+ box->x1 = MAXSHORT;
+ box->x2 = MINSHORT;
+ for (; ntrap; ntrap--, traps++)
+ {
+ INT16 x1, y1, x2, y2;
+
+ if (!xTrapezoidValid(traps))
+ continue;
+ y1 = xFixedToInt (traps->top);
+ if (y1 < box->y1)
+ box->y1 = y1;
+
+ y2 = xFixedToInt (xFixedCeil (traps->bottom));
+ if (y2 > box->y2)
+ box->y2 = y2;
+
+ x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+ miLineFixedX (&traps->left, traps->bottom, FALSE)));
+ if (x1 < box->x1)
+ box->x1 = x1;
+
+ x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+ miLineFixedX (&traps->right, traps->bottom, TRUE))));
+ if (x2 > box->x2)
+ box->x2 = x2;
+ }
+}
+
+#ifndef NXAGENT_SERVER
+void
+miTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ BoxRec bounds;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ miTrapezoidBounds (ntrap, traps, &bounds);
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps,
+ -bounds.x1, -bounds.y1);
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ }
+}
+#endif
diff --git a/nx-X11/programs/Xserver/render/mitri.c b/nx-X11/programs/Xserver/render/mitri.c
new file mode 100644
index 000000000..a39e23623
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/mitri.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
+{
+ bounds->x1 = xFixedToInt (points->x);
+ bounds->x2 = xFixedToInt (xFixedCeil (points->x));
+ bounds->y1 = xFixedToInt (points->y);
+ bounds->y2 = xFixedToInt (xFixedCeil (points->y));
+ points++;
+ npoint--;
+ while (npoint-- > 0)
+ {
+ INT16 x1 = xFixedToInt (points->x);
+ INT16 x2 = xFixedToInt (xFixedCeil (points->x));
+ INT16 y1 = xFixedToInt (points->y);
+ INT16 y2 = xFixedToInt (xFixedCeil (points->y));
+
+ if (x1 < bounds->x1)
+ bounds->x1 = x1;
+ else if (x2 > bounds->x2)
+ bounds->x2 = x2;
+ if (y1 < bounds->y1)
+ bounds->y1 = y1;
+ else if (y2 > bounds->y2)
+ bounds->y2 = y2;
+ points++;
+ }
+}
+
+void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
+{
+ miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
+}
+
+void
+miTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ /*
+ * Check for solid alpha add
+ */
+ if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ {
+ (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
+ }
+ else if (maskFormat)
+ {
+ BoxRec bounds;
+ PicturePtr pPicture;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = tris[0].p1.x >> 16;
+ yDst = tris[0].p1.y >> 16;
+
+ miTriangleBounds (ntri, tris, &bounds);
+ if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
+ return;
+ pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+ (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+
+ for (; ntri; ntri--, tris++)
+ miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
+ }
+}
+
+void
+miTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xTriangle *tris, *tri;
+ int ntri;
+
+ if (npoint < 3)
+ return;
+ ntri = npoint - 2;
+ tris = malloc (ntri * sizeof (xTriangle));
+ if (!tris)
+ return;
+ for (tri = tris; npoint >= 3; npoint--, points++, tri++)
+ {
+ tri->p1 = points[0];
+ tri->p2 = points[1];
+ tri->p3 = points[2];
+ }
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ free (tris);
+}
+
+void
+miTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xTriangle *tris, *tri;
+ xPointFixed *first;
+ int ntri;
+
+ if (npoint < 3)
+ return;
+ ntri = npoint - 2;
+ tris = malloc (ntri * sizeof (xTriangle));
+ if (!tris)
+ return;
+ first = points++;
+ for (tri = tris; npoint >= 3; npoint--, points++, tri++)
+ {
+ tri->p1 = *first;
+ tri->p2 = points[0];
+ tri->p3 = points[1];
+ }
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+ free (tris);
+}
diff --git a/nx-X11/programs/Xserver/render/picture.c b/nx-X11/programs/Xserver/render/picture.c
new file mode 100644
index 000000000..e82319bc9
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/picture.c
@@ -0,0 +1,1883 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifndef NXAGENT_SERVER
+#include "picturestr.h"
+#endif
+
+int PictureScreenPrivateIndex = -1;
+int PictureWindowPrivateIndex;
+int PictureGeneration;
+RESTYPE PictureType;
+RESTYPE PictFormatType;
+RESTYPE GlyphSetType;
+int PictureCmapPolicy = PictureCmapPolicyDefault;
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+ picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+ return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ unsigned int oldamount;
+
+ /* Round up sizes for proper alignment */
+ amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+ if (index2 >= ps->PicturePrivateLen)
+ {
+ unsigned int *nsizes;
+
+ nsizes = (unsigned int *)realloc(ps->PicturePrivateSizes,
+ (index2 + 1) * sizeof(unsigned int));
+ if (!nsizes)
+ return FALSE;
+ while (ps->PicturePrivateLen <= index2)
+ {
+ nsizes[ps->PicturePrivateLen++] = 0;
+ ps->totalPictureSize += sizeof(DevUnion);
+ }
+ ps->PicturePrivateSizes = nsizes;
+ }
+ oldamount = ps->PicturePrivateSizes[index2];
+ if (amount > oldamount)
+ {
+ ps->PicturePrivateSizes[index2] = amount;
+ ps->totalPictureSize += (amount - oldamount);
+ }
+
+ return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+
+ while ((pPicture = GetPictureWindow(pWindow)))
+ {
+ SetPictureWindow(pWindow, pPicture->pNext);
+ if (pPicture->id)
+ FreeResource (pPicture->id, PictureType);
+ FreePicture ((void *) pPicture, pPicture->id);
+ }
+ pScreen->DestroyWindow = ps->DestroyWindow;
+ ret = (*pScreen->DestroyWindow) (pWindow);
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ return ret;
+}
+
+Bool
+PictureCloseScreen (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ Bool ret;
+ int n;
+
+ pScreen->CloseScreen = ps->CloseScreen;
+ ret = (*pScreen->CloseScreen) (pScreen);
+ PictureResetFilters (pScreen);
+ for (n = 0; n < ps->nformats; n++)
+ if (ps->formats[n].type == PictTypeIndexed)
+ (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+ SetPictureScreen(pScreen, 0);
+ if (ps->PicturePrivateSizes)
+ free (ps->PicturePrivateSizes);
+ free (ps->formats);
+ free (ps);
+ return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ pScreen->StoreColors = ps->StoreColors;
+ (*pScreen->StoreColors) (pColormap, ndef, pdef);
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+ {
+ PictFormatPtr format = ps->formats;
+ int nformats = ps->nformats;
+
+ while (nformats--)
+ {
+ if (format->type == PictTypeIndexed &&
+ format->index.pColormap == pColormap)
+ {
+ (*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+ break;
+ }
+ format++;
+ }
+ }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ int d, v;
+ DepthPtr pDepth;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ return 0;
+}
+
+typedef struct _formatInit {
+ CARD32 format;
+ CARD8 depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec formats[256],
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+#ifndef NXAGENT_SERVER
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+ int nformats, f;
+ PictFormatPtr pFormats;
+ FormatInitRec formats[1024];
+ CARD32 format;
+ CARD8 depth;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int type;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+ nformats = 0;
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+ formats[nformats].format = PICT_x8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = visualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+ bpp = BitsPerPixel (depth);
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ type = PICT_TYPE_OTHER;
+ /*
+ * Current rendering code supports only two direct formats,
+ * fields must be packed together at the bottom of the pixel
+ * and must be either RGB or BGR
+ */
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ type = PICT_TYPE_ARGB;
+ }
+ else if (pVisual->offsetRed == 0 &&
+ pVisual->offsetGreen == r &&
+ pVisual->offsetBlue == r + g)
+ {
+ type = PICT_TYPE_ABGR;
+ }
+ if (type != PICT_TYPE_OTHER)
+ {
+ format = PICT_FORMAT(bpp, type, 0, r, g, b);
+ nformats = addFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ case StaticGray:
+ case GrayScale:
+ format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+ nformats = addFormat (formats, nformats, format, depth);
+ break;
+ }
+ }
+ /*
+ * Walk supported depths and add useful Direct formats
+ */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+ switch (bpp) {
+ case 16:
+ /* depth 12 formats */
+ if (pDepth->depth >= 12)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x4b4g4r4, pDepth->depth);
+ }
+ /* depth 15 formats */
+ if (pDepth->depth >= 15)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x1b5g5r5, pDepth->depth);
+ }
+ /* depth 16 formats */
+ if (pDepth->depth >= 16)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_a1r5g5b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a1b5g5r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b5g6r5, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4r4g4b4, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_a4b4g4r4, pDepth->depth);
+ }
+ break;
+ case 24:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_b8g8r8, pDepth->depth);
+ }
+ break;
+ case 32:
+ if (pDepth->depth >= 24)
+ {
+ nformats = addFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ nformats = addFormat (formats, nformats,
+ PICT_x8b8g8r8, pDepth->depth);
+ }
+ break;
+ }
+ }
+
+
+ pFormats = (PictFormatPtr) malloc (nformats * sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ switch (PICT_FORMAT_TYPE(format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_B(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_B(format);
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = 0;
+ break;
+
+ case PICT_TYPE_ABGR:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+ PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+ pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
+ PICT_FORMAT_R(format));
+
+ pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+ pFormats[f].direct.green = PICT_FORMAT_R(format);
+
+ pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+ pFormats[f].direct.red = 0;
+ break;
+
+ case PICT_TYPE_A:
+ pFormats[f].type = PictTypeDirect;
+
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+ /* remaining fields already set to zero */
+ break;
+
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ pFormats[f].type = PictTypeIndexed;
+ pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ break;
+ }
+ }
+ *nformatp = nformats;
+ return pFormats;
+}
+#endif
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+ int i;
+ VisualPtr pVisual;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid == visual)
+ return pVisual;
+ }
+ return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return FALSE;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->type == PictTypeIndexed && !format->index.pColormap)
+ {
+ if (format->index.vid == pScreen->rootVisual)
+ format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+ else
+ {
+ VisualPtr pVisual;
+
+ pVisual = PictureFindVisual (pScreen, format->index.vid);
+ if (CreateColormap (FakeClientID (0), pScreen,
+ pVisual,
+ &format->index.pColormap, AllocNone,
+ 0) != Success)
+ {
+ return FALSE;
+ }
+ }
+ if (!(*ps->InitIndexed) (pScreen, format))
+ return FALSE;
+ }
+ format++;
+ }
+ return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+ int s;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ {
+ if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+ return FALSE;
+ (void) AnimCurInit (screenInfo.screens[s]);
+ }
+
+ return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return FALSE;
+ ps->subpixel = subpixel;
+ return TRUE;
+
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!ps)
+ return SubPixelUnknown;
+ return ps->subpixel;
+}
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+ int type;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ switch (pVisual->class) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ type = PictTypeIndexed;
+ break;
+ case TrueColor:
+ case DirectColor:
+ type = PictTypeDirect;
+ break;
+ default:
+ return 0;
+ }
+ while (nformat--)
+ {
+ if (format->depth == depth && format->type == type)
+ {
+ if (type == PictTypeIndexed)
+ {
+ if (format->index.vid == pVisual->vid)
+ return format;
+ }
+ else
+ {
+ if (format->direct.redMask << format->direct.red ==
+ pVisual->redMask &&
+ format->direct.greenMask << format->direct.green ==
+ pVisual->greenMask &&
+ format->direct.blueMask << format->direct.blue ==
+ pVisual->blueMask)
+ {
+ return format;
+ }
+ }
+ }
+ format++;
+ }
+ return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictFormatPtr format;
+ int nformat;
+
+ if (!ps)
+ return 0;
+ format = ps->formats;
+ nformat = ps->nformats;
+ while (nformat--)
+ {
+ if (format->depth == depth && format->format == (f & 0xffffff))
+ return format;
+ format++;
+ }
+ return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+ if ( strcmp (name, "default" ) == 0)
+ return PictureCmapPolicyDefault;
+ else if ( strcmp (name, "mono" ) == 0)
+ return PictureCmapPolicyMono;
+ else if ( strcmp (name, "gray" ) == 0)
+ return PictureCmapPolicyGray;
+ else if ( strcmp (name, "color" ) == 0)
+ return PictureCmapPolicyColor;
+ else if ( strcmp (name, "all" ) == 0)
+ return PictureCmapPolicyAll;
+ else
+ return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+ int n;
+ CARD32 type, a, r, g, b;
+
+ if (PictureGeneration != serverGeneration)
+ {
+ PictureType = CreateNewResourceType (FreePicture);
+ if (!PictureType)
+ return FALSE;
+ PictFormatType = CreateNewResourceType (FreePictFormat);
+ if (!PictFormatType)
+ return FALSE;
+ GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+ if (!GlyphSetType)
+ return FALSE;
+ PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+ if (PictureScreenPrivateIndex < 0)
+ return FALSE;
+ PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+ PictureGeneration = serverGeneration;
+#ifdef XResExtension
+ RegisterResourceName (PictureType, "PICTURE");
+ RegisterResourceName (PictFormatType, "PICTFORMAT");
+ RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+ }
+ if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+ return FALSE;
+
+ if (!formats)
+ {
+ formats = PictureCreateDefaultFormats (pScreen, &nformats);
+ if (!formats)
+ return FALSE;
+ }
+ for (n = 0; n < nformats; n++)
+ {
+ if (!AddResource (formats[n].id, PictFormatType, (void *) (formats+n)))
+ {
+ free (formats);
+ return FALSE;
+ }
+ if (formats[n].type == PictTypeIndexed)
+ {
+ VisualPtr pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+ if ((pVisual->class | DynamicClass) == PseudoColor)
+ type = PICT_TYPE_COLOR;
+ else
+ type = PICT_TYPE_GRAY;
+ a = r = g = b = 0;
+ }
+ else
+ {
+ if ((formats[n].direct.redMask|
+ formats[n].direct.blueMask|
+ formats[n].direct.greenMask) == 0)
+ type = PICT_TYPE_A;
+ else if (formats[n].direct.red > formats[n].direct.blue)
+ type = PICT_TYPE_ARGB;
+ else
+ type = PICT_TYPE_ABGR;
+ a = Ones (formats[n].direct.alphaMask);
+ r = Ones (formats[n].direct.redMask);
+ g = Ones (formats[n].direct.greenMask);
+ b = Ones (formats[n].direct.blueMask);
+ }
+ formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+ }
+ ps = (PictureScreenPtr) malloc (sizeof (PictureScreenRec));
+ if (!ps)
+ {
+ free (formats);
+ return FALSE;
+ }
+ SetPictureScreen(pScreen, ps);
+ if (!GlyphInit (pScreen))
+ {
+ SetPictureScreen(pScreen, 0);
+ free (formats);
+ free (ps);
+ return FALSE;
+ }
+
+ ps->totalPictureSize = sizeof (PictureRec);
+ ps->PicturePrivateSizes = 0;
+ ps->PicturePrivateLen = 0;
+
+ ps->formats = formats;
+ ps->fallback = formats;
+ ps->nformats = nformats;
+
+ ps->filters = 0;
+ ps->nfilters = 0;
+ ps->filterAliases = 0;
+ ps->nfilterAliases = 0;
+
+ ps->subpixel = SubPixelUnknown;
+
+ ps->CloseScreen = pScreen->CloseScreen;
+ ps->DestroyWindow = pScreen->DestroyWindow;
+ ps->StoreColors = pScreen->StoreColors;
+ pScreen->DestroyWindow = PictureDestroyWindow;
+ pScreen->CloseScreen = PictureCloseScreen;
+ pScreen->StoreColors = PictureStoreColors;
+
+ if (!PictureSetDefaultFilters (pScreen))
+ {
+ PictureResetFilters (pScreen);
+ SetPictureScreen(pScreen, 0);
+ free (formats);
+ free (ps);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr pPicture)
+{
+ pPicture->refcnt = 1;
+ pPicture->repeat = 0;
+ pPicture->graphicsExposures = FALSE;
+ pPicture->subWindowMode = ClipByChildren;
+ pPicture->polyEdge = PolyEdgeSharp;
+ pPicture->polyMode = PolyModePrecise;
+ pPicture->freeCompClip = FALSE;
+ pPicture->clientClipType = CT_NONE;
+ pPicture->componentAlpha = FALSE;
+ pPicture->repeatType = RepeatNone;
+
+ pPicture->alphaMap = 0;
+ pPicture->alphaOrigin.x = 0;
+ pPicture->alphaOrigin.y = 0;
+
+ pPicture->clipOrigin.x = 0;
+ pPicture->clipOrigin.y = 0;
+ pPicture->clientClip = 0;
+
+ pPicture->transform = 0;
+
+ pPicture->dither = None;
+ pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+ pPicture->filter_params = 0;
+ pPicture->filter_nparams = 0;
+
+ pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+ pPicture->pSourcePict = 0;
+}
+
+#ifndef NXAGENT_SERVER
+PicturePtr
+AllocatePicture (ScreenPtr pScreen)
+{
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PicturePtr pPicture;
+ char *ptr;
+ DevUnion *ppriv;
+ unsigned int *sizes;
+ unsigned int size;
+ int i;
+
+ pPicture = (PicturePtr) malloc (ps->totalPictureSize);
+ if (!pPicture)
+ return 0;
+ ppriv = (DevUnion *)(pPicture + 1);
+ pPicture->devPrivates = ppriv;
+ sizes = ps->PicturePrivateSizes;
+ ptr = (char *)(ppriv + ps->PicturePrivateLen);
+ for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+ {
+ if ( (size = *sizes) )
+ {
+ ppriv->ptr = (void *)ptr;
+ ptr += size;
+ }
+ else
+ ppriv->ptr = (void *)NULL;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask vmask,
+ XID *vlist,
+ ClientPtr client,
+ int *error)
+{
+ PicturePtr pPicture;
+ PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
+
+ pPicture = AllocatePicture (pDrawable->pScreen);
+ if (!pPicture)
+ {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pDrawable = pDrawable;
+ pPicture->pFormat = pFormat;
+ pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ ++((PixmapPtr)pDrawable)->refcnt;
+ pPicture->pNext = 0;
+ }
+ else
+ {
+ pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+ SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+ }
+
+ SetPictureToDefaults (pPicture);
+
+ if (vmask)
+ *error = ChangePicture (pPicture, vmask, vlist, 0, client);
+ else
+ *error = Success;
+ if (*error == Success)
+ *error = (*ps->CreatePicture) (pPicture);
+ if (*error != Success)
+ {
+ FreePicture (pPicture, (XID) 0);
+ pPicture = 0;
+ }
+ return pPicture;
+}
+#endif
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+ return
+ (c.alpha >> 8 << 24) |
+ (c.red >> 8 << 16) |
+ (c.green & 0xff00) |
+ (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+ unsigned int a = x >> 24;
+ unsigned int t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+ unsigned int y, unsigned int b)
+{
+ CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+ t >>= 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+ x &= 0xff00ff00;
+ x |= t;
+ return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+ int begin_pos, end_pos;
+ xFixed incr, dpos;
+ int pos, current_stop;
+ PictGradientStopPtr stops = pGradient->linear.stops;
+ int nstops = pGradient->linear.nstops;
+
+ /* The position where the gradient begins and ends */
+ begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+ end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+ pos = 0; /* The position in the color table. */
+
+ /* Up to first point */
+ while (pos <= begin_pos) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+ ++pos;
+ }
+
+ incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+ dpos = incr * pos; /* The position in terms of 0-1. */
+
+ current_stop = 0; /* We always interpolate between current and current + 1. */
+
+ /* Gradient area */
+ while (pos < end_pos) {
+ unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+ unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+ int dist = (int)(256*(dpos - stops[current_stop].x)
+ / (stops[current_stop+1].x - stops[current_stop].x));
+ int idist = 256 - dist;
+
+ pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+ ++pos;
+ dpos += incr;
+
+ if (dpos > stops[current_stop + 1].x)
+ ++current_stop;
+ }
+
+ /* After last point */
+ while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+ pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+ ++pos;
+ }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+ xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+ int i;
+ xFixed dpos;
+
+ if (stopCount <= 0) {
+ *error = BadValue;
+ return;
+ }
+
+ dpos = -1;
+ for (i = 0; i < stopCount; ++i) {
+ if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ *error = BadValue;
+ return;
+ }
+ dpos = stopPoints[i];
+ }
+
+ pGradient->linear.stops = malloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->linear.stops) {
+ *error = BadAlloc;
+ return;
+ }
+
+ pGradient->linear.nstops = stopCount;
+
+ for (i = 0; i < stopCount; ++i) {
+ pGradient->linear.stops[i].x = stopPoints[i];
+ pGradient->linear.stops[i].color = stopColors[i];
+ }
+ initGradientColorTable(pGradient, error);
+}
+
+#ifndef NXAGENT_SERVER
+static PicturePtr createSourcePicture(void)
+{
+ PicturePtr pPicture;
+ pPicture = (PicturePtr) malloc(sizeof(PictureRec));
+ pPicture->pDrawable = 0;
+ pPicture->pFormat = 0;
+ pPicture->pNext = 0;
+
+ SetPictureToDefaults(pPicture);
+ return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+ PicturePtr pPicture;
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictSolidFill));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ free(pPicture);
+ return 0;
+ }
+ pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+ pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+ return pPicture;
+}
+#endif
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ if (p1->x == p2->x && p1->y == p2->y) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictLinearGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ free(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+ pPicture->pSourcePict->linear.p1 = *p1;
+ pPicture->pSourcePict->linear.p2 = *p2;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ free(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+ xFixed innerRadius, xFixed outerRadius,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+ PictRadialGradient *radial;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+ {
+ double dx = (double)(inner->x - outer->x);
+ double dy = (double)(inner->y - outer->y);
+ if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+ *error = BadValue;
+ return 0;
+ }
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictRadialGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ free(pPicture);
+ return 0;
+ }
+ radial = &pPicture->pSourcePict->radial;
+
+ radial->type = SourcePictTypeRadial;
+ {
+ double x = (double)innerRadius / (double)outerRadius;
+ radial->dx = (outer->x - inner->x);
+ radial->dy = (outer->y - inner->y);
+ radial->fx = (inner->x) - x*radial->dx;
+ radial->fy = (inner->y) - x*radial->dy;
+ radial->m = 1./(1+x);
+ radial->b = -x*radial->m;
+ radial->dx /= 65536.;
+ radial->dy /= 65536.;
+ radial->fx /= 65536.;
+ radial->fy /= 65536.;
+ x = outerRadius/65536.;
+ radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+ }
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ free(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+ int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+ PicturePtr pPicture;
+
+ if (nStops < 2) {
+ *error = BadValue;
+ return 0;
+ }
+
+ pPicture = createSourcePicture();
+ if (!pPicture) {
+ *error = BadAlloc;
+ return 0;
+ }
+
+ pPicture->id = pid;
+ pPicture->pSourcePict = (SourcePictPtr) malloc(sizeof(PictConicalGradient));
+ if (!pPicture->pSourcePict) {
+ *error = BadAlloc;
+ free(pPicture);
+ return 0;
+ }
+
+ pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+ pPicture->pSourcePict->conical.center = *center;
+ pPicture->pSourcePict->conical.angle = angle;
+
+ initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+ if (*error) {
+ free(pPicture);
+ return 0;
+ }
+ return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client)
+{
+ ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+ PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+ BITS32 index2;
+ int error = 0;
+ BITS32 maskQ;
+
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ maskQ = vmask;
+ while (vmask && !error)
+ {
+ index2 = (BITS32) lowbit (vmask);
+ vmask &= ~index2;
+ pPicture->stateChanges |= index2;
+ switch (index2)
+ {
+ case CPRepeat:
+ {
+ unsigned int newr;
+ newr = NEXT_VAL(unsigned int);
+ if (newr <= RepeatReflect)
+ {
+ pPicture->repeat = (newr != RepeatNone);
+ pPicture->repeatType = newr;
+ }
+ else
+ {
+ client->errorValue = newr;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPAlphaMap:
+ {
+ PicturePtr pAlpha;
+
+ if (vlist)
+ {
+ Picture pid = NEXT_VAL(Picture);
+
+ if (pid == None)
+ pAlpha = 0;
+ else
+ {
+ pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+ pid,
+ PictureType,
+ DixWriteAccess|DixReadAccess);
+ if (!pAlpha)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ client->errorValue = pid;
+ error = BadMatch;
+ break;
+ }
+ }
+ }
+ else
+ pAlpha = NEXT_PTR(PicturePtr);
+ if (!error)
+ {
+ if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+ pAlpha->refcnt++;
+ if (pPicture->alphaMap)
+ FreePicture ((void *) pPicture->alphaMap, (XID) 0);
+ pPicture->alphaMap = pAlpha;
+ }
+ }
+ break;
+ case CPAlphaXOrigin:
+ pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPAlphaYOrigin:
+ pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipXOrigin:
+ pPicture->clipOrigin.x = NEXT_VAL(INT16);
+ break;
+ case CPClipYOrigin:
+ pPicture->clipOrigin.y = NEXT_VAL(INT16);
+ break;
+ case CPClipMask:
+ {
+ Pixmap pid;
+ PixmapPtr pPixmap;
+ int clipType;
+ if (!pScreen)
+ return BadDrawable;
+
+ if (vlist)
+ {
+ pid = NEXT_VAL(Pixmap);
+ if (pid == None)
+ {
+ clipType = CT_NONE;
+ pPixmap = NullPixmap;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+ pid,
+ RT_PIXMAP,
+ DixReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = pid;
+ error = BadPixmap;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pPixmap = NEXT_PTR(PixmapPtr);
+ if (pPixmap)
+ clipType = CT_PIXMAP;
+ else
+ clipType = CT_NONE;
+ }
+
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ else
+ {
+ clipType = CT_PIXMAP;
+ pPixmap->refcnt++;
+ }
+ }
+ error = (*ps->ChangePictureClip)(pPicture, clipType,
+ (void *)pPixmap, 0);
+ break;
+ }
+ case CPGraphicsExposure:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe <= xTrue)
+ pPicture->graphicsExposures = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPSubwindowMode:
+ {
+ unsigned int news;
+ news = NEXT_VAL(unsigned int);
+ if (news == ClipByChildren || news == IncludeInferiors)
+ pPicture->subWindowMode = news;
+ else
+ {
+ client->errorValue = news;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyEdge:
+ {
+ unsigned int newe;
+ newe = NEXT_VAL(unsigned int);
+ if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+ pPicture->polyEdge = newe;
+ else
+ {
+ client->errorValue = newe;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPPolyMode:
+ {
+ unsigned int newm;
+ newm = NEXT_VAL(unsigned int);
+ if (newm == PolyModePrecise || newm == PolyModeImprecise)
+ pPicture->polyMode = newm;
+ else
+ {
+ client->errorValue = newm;
+ error = BadValue;
+ }
+ }
+ break;
+ case CPDither:
+ pPicture->dither = NEXT_VAL(Atom);
+ break;
+ case CPComponentAlpha:
+ {
+ unsigned int newca;
+
+ newca = NEXT_VAL (unsigned int);
+ if (newca <= xTrue)
+ pPicture->componentAlpha = newca;
+ else
+ {
+ client->errorValue = newca;
+ error = BadValue;
+ }
+ }
+ break;
+ default:
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ }
+ if (ps)
+ (*ps->ChangePicture) (pPicture, maskQ);
+ return error;
+}
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+
+ clientClip = RegionFromRects(
+ nRect, rects, CT_UNSORTED);
+ if (!clientClip)
+ return BadAlloc;
+ result =(*ps->ChangePictureClip) (pPicture, CT_REGION,
+ (void *) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ RegionPtr clientClip;
+ int result;
+ int type;
+
+ if (pRegion)
+ {
+ type = CT_REGION;
+ clientClip = RegionCreate(
+ RegionExtents(pRegion),
+ RegionNumRects(pRegion));
+ if (!clientClip)
+ return BadAlloc;
+ if (!RegionCopy(clientClip, pRegion))
+ {
+ RegionDestroy(clientClip);
+ return BadAlloc;
+ }
+ }
+ else
+ {
+ type = CT_NONE;
+ clientClip = 0;
+ }
+
+ result =(*ps->ChangePictureClip) (pPicture, type,
+ (void *) clientClip, 0);
+ if (result == Success)
+ {
+ pPicture->clipOrigin.x = xOrigin;
+ pPicture->clipOrigin.y = yOrigin;
+ pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ }
+ return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform)
+{
+ static const PictTransform identity = { {
+ { xFixed1, 0x00000, 0x00000 },
+ { 0x00000, xFixed1, 0x00000 },
+ { 0x00000, 0x00000, xFixed1 },
+ } };
+
+ if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+ transform = 0;
+
+ if (transform)
+ {
+ if (!pPicture->transform)
+ {
+ pPicture->transform = (PictTransform *) malloc (sizeof (PictTransform));
+ if (!pPicture->transform)
+ return BadAlloc;
+ }
+ *pPicture->transform = *transform;
+ }
+ else
+ {
+ if (pPicture->transform)
+ {
+ free (pPicture->transform);
+ pPicture->transform = 0;
+ }
+ }
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ return Success;
+}
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst)
+{
+ PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+ Mask origMask = mask;
+
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pDst->stateChanges |= mask;
+
+ while (mask) {
+ Mask bit = lowbit(mask);
+
+ switch (bit)
+ {
+ case CPRepeat:
+ pDst->repeat = pSrc->repeat;
+ pDst->repeatType = pSrc->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+ pSrc->alphaMap->refcnt++;
+ if (pDst->alphaMap)
+ FreePicture ((void *) pDst->alphaMap, (XID) 0);
+ pDst->alphaMap = pSrc->alphaMap;
+ break;
+ case CPAlphaXOrigin:
+ pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pDst->clipOrigin.x = pSrc->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pDst->clipOrigin.y = pSrc->clipOrigin.y;
+ break;
+ case CPClipMask:
+ switch (pSrc->clientClipType) {
+ case CT_NONE:
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ break;
+ case CT_REGION:
+ if (!pSrc->clientClip) {
+ (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+ } else {
+ RegionPtr clientClip;
+ RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+ clientClip = RegionCreate(
+ RegionExtents(srcClientClip),
+ RegionNumRects(srcClientClip));
+ (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+ }
+ break;
+ default:
+ /* XXX: CT_PIXMAP unimplemented */
+ break;
+ }
+ break;
+ case CPGraphicsExposure:
+ pDst->graphicsExposures = pSrc->graphicsExposures;
+ break;
+ case CPPolyEdge:
+ pDst->polyEdge = pSrc->polyEdge;
+ break;
+ case CPPolyMode:
+ pDst->polyMode = pSrc->polyMode;
+ break;
+ case CPDither:
+ pDst->dither = pSrc->dither;
+ break;
+ case CPComponentAlpha:
+ pDst->componentAlpha = pSrc->componentAlpha;
+ break;
+ }
+ mask &= ~bit;
+ }
+
+ (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+ if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ (*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+ pPicture->stateChanges = 0;
+ pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+ }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+ ValidateOnePicture (pPicture);
+ if (pPicture->alphaMap)
+ ValidateOnePicture (pPicture->alphaMap);
+}
+
+#ifndef NXAGENT_SERVER
+int
+FreePicture (void * value,
+ XID pid)
+{
+ PicturePtr pPicture = (PicturePtr) value;
+
+ if (--pPicture->refcnt == 0)
+ {
+ if (pPicture->transform)
+ free (pPicture->transform);
+ if (!pPicture->pDrawable) {
+ if (pPicture->pSourcePict) {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ free(pPicture->pSourcePict->linear.stops);
+ free(pPicture->pSourcePict);
+ }
+ } else {
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ if (pPicture->alphaMap)
+ FreePicture ((void *) pPicture->alphaMap, (XID) 0);
+ (*ps->DestroyPicture) (pPicture);
+ (*ps->DestroyPictureClip) (pPicture);
+ if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
+ PicturePtr *pPrev;
+
+ for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+ *pPrev;
+ pPrev = &(*pPrev)->pNext)
+ {
+ if (*pPrev == pPicture)
+ {
+ *pPrev = pPicture->pNext;
+ break;
+ }
+ }
+ }
+ else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+ }
+ }
+ free (pPicture);
+ }
+ return Success;
+}
+#endif
+
+int
+FreePictFormat (void * pPictFormat,
+ XID pid)
+{
+ return Success;
+}
+
+/**
+ * ReduceCompositeOp is used to choose simpler ops for cases where alpha
+ * channels are always one and so math on the alpha channel per pixel becomes
+ * unnecessary. It may also avoid destination reads sometimes if apps aren't
+ * being careful to avoid these cases.
+ */
+static CARD8
+ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+ Bool no_src_alpha, no_dst_alpha;
+
+ no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) &&
+ PICT_FORMAT_A(pSrc->format) == 0 &&
+ pSrc->alphaMap == NULL &&
+ pMask == NULL;
+ no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) &&
+ PICT_FORMAT_A(pDst->format) == 0 &&
+ pDst->alphaMap == NULL;
+
+ /* TODO, maybe: Conjoint and Disjoint op reductions? */
+
+ /* Deal with simplifications where the source alpha is always 1. */
+ if (no_src_alpha)
+ {
+ switch (op) {
+ case PictOpOver:
+ op = PictOpSrc;
+ break;
+ case PictOpInReverse:
+ op = PictOpDst;
+ break;
+ case PictOpOutReverse:
+ op = PictOpClear;
+ break;
+ case PictOpAtop:
+ op = PictOpIn;
+ break;
+ case PictOpAtopReverse:
+ op = PictOpOverReverse;
+ break;
+ case PictOpXor:
+ op = PictOpOut;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Deal with simplifications when the destination alpha is always 1 */
+ if (no_dst_alpha)
+ {
+ switch (op) {
+ case PictOpOverReverse:
+ op = PictOpDst;
+ break;
+ case PictOpIn:
+ op = PictOpSrc;
+ break;
+ case PictOpOut:
+ op = PictOpClear;
+ break;
+ case PictOpAtop:
+ op = PictOpOver;
+ break;
+ case PictOpXor:
+ op = PictOpOutReverse;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Reduce some con/disjoint ops to the basic names. */
+ switch (op) {
+ case PictOpDisjointClear:
+ case PictOpConjointClear:
+ op = PictOpClear;
+ break;
+ case PictOpDisjointSrc:
+ case PictOpConjointSrc:
+ op = PictOpSrc;
+ break;
+ case PictOpDisjointDst:
+ case PictOpConjointDst:
+ op = PictOpDst;
+ break;
+ default:
+ break;
+ }
+
+ return op;
+}
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ if (pMask)
+ ValidatePicture (pMask);
+ ValidatePicture (pDst);
+
+ op = ReduceCompositeOp (op, pSrc, pMask, pDst);
+ if (op == PictOpDst)
+ return;
+
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+}
+
+void
+CompositeRects(CARD8 op,
+ PicturePtr pDst,
+ xRenderColor * color, int nRect, xRectangle *rects)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pDst);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points)
+{
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+
+ ValidatePicture (pSrc);
+ ValidatePicture (pDst);
+ (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ ValidatePicture (pPicture);
+ (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
diff --git a/nx-X11/programs/Xserver/render/picture.h b/nx-X11/programs/Xserver/render/picture.h
new file mode 100644
index 000000000..5dde2d0bc
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/picture.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _PICTURE_H_
+#define _PICTURE_H_
+
+typedef struct _DirectFormat *DirectFormatPtr;
+typedef struct _PictFormat *PictFormatPtr;
+typedef struct _Picture *PicturePtr;
+
+/*
+ * While the protocol is generous in format support, the
+ * sample implementation allows only packed RGB and GBR
+ * representations for data to simplify software rendering,
+ */
+#define PICT_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
+ ((type) << 16) | \
+ ((a) << 12) | \
+ ((r) << 8) | \
+ ((g) << 4) | \
+ ((b)))
+
+/*
+ * gray/color formats use a visual index instead of argb
+ */
+#define PICT_VISFORMAT(bpp,type,vi) (((bpp) << 24) | \
+ ((type) << 16) | \
+ ((vi)))
+
+#define PICT_FORMAT_BPP(f) (((f) >> 24) )
+#define PICT_FORMAT_TYPE(f) (((f) >> 16) & 0xff)
+#define PICT_FORMAT_A(f) (((f) >> 12) & 0x0f)
+#define PICT_FORMAT_R(f) (((f) >> 8) & 0x0f)
+#define PICT_FORMAT_G(f) (((f) >> 4) & 0x0f)
+#define PICT_FORMAT_B(f) (((f) ) & 0x0f)
+#define PICT_FORMAT_RGB(f) (((f) ) & 0xfff)
+#define PICT_FORMAT_VIS(f) (((f) ) & 0xffff)
+
+#define PICT_TYPE_OTHER 0
+#define PICT_TYPE_A 1
+#define PICT_TYPE_ARGB 2
+#define PICT_TYPE_ABGR 3
+#define PICT_TYPE_COLOR 4
+#define PICT_TYPE_GRAY 5
+
+#define PICT_FORMAT_COLOR(f) (PICT_FORMAT_TYPE(f) & 2)
+
+/* 32bpp formats */
+#define PICT_a8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,8,8,8,8)
+#define PICT_x8r8g8b8 PICT_FORMAT(32,PICT_TYPE_ARGB,0,8,8,8)
+#define PICT_a8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,8,8,8,8)
+#define PICT_x8b8g8r8 PICT_FORMAT(32,PICT_TYPE_ABGR,0,8,8,8)
+
+/* 24bpp formats */
+#define PICT_r8g8b8 PICT_FORMAT(24,PICT_TYPE_ARGB,0,8,8,8)
+#define PICT_b8g8r8 PICT_FORMAT(24,PICT_TYPE_ABGR,0,8,8,8)
+
+/* 16bpp formats */
+#define PICT_r5g6b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,6,5)
+#define PICT_b5g6r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,6,5)
+
+#define PICT_a1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,1,5,5,5)
+#define PICT_x1r5g5b5 PICT_FORMAT(16,PICT_TYPE_ARGB,0,5,5,5)
+#define PICT_a1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5)
+#define PICT_x1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5)
+#define PICT_a4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4)
+#define PICT_x4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4)
+#define PICT_a4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4)
+#define PICT_x4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4)
+
+/* 8bpp formats */
+#define PICT_a8 PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0)
+#define PICT_r3g3b2 PICT_FORMAT(8,PICT_TYPE_ARGB,0,3,3,2)
+#define PICT_b2g3r3 PICT_FORMAT(8,PICT_TYPE_ABGR,0,3,3,2)
+#define PICT_a2r2g2b2 PICT_FORMAT(8,PICT_TYPE_ARGB,2,2,2,2)
+#define PICT_a2b2g2r2 PICT_FORMAT(8,PICT_TYPE_ABGR,2,2,2,2)
+
+#define PICT_c8 PICT_FORMAT(8,PICT_TYPE_COLOR,0,0,0,0)
+#define PICT_g8 PICT_FORMAT(8,PICT_TYPE_GRAY,0,0,0,0)
+
+/* 4bpp formats */
+#define PICT_a4 PICT_FORMAT(4,PICT_TYPE_A,4,0,0,0)
+#define PICT_r1g2b1 PICT_FORMAT(4,PICT_TYPE_ARGB,0,1,2,1)
+#define PICT_b1g2r1 PICT_FORMAT(4,PICT_TYPE_ABGR,0,1,2,1)
+#define PICT_a1r1g1b1 PICT_FORMAT(4,PICT_TYPE_ARGB,1,1,1,1)
+#define PICT_a1b1g1r1 PICT_FORMAT(4,PICT_TYPE_ABGR,1,1,1,1)
+
+#define PICT_c4 PICT_FORMAT(4,PICT_TYPE_COLOR,0,0,0,0)
+#define PICT_g4 PICT_FORMAT(4,PICT_TYPE_GRAY,0,0,0,0)
+
+/* 1bpp formats */
+#define PICT_a1 PICT_FORMAT(1,PICT_TYPE_A,1,0,0,0)
+
+#define PICT_g1 PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0)
+
+/*
+ * For dynamic indexed visuals (GrayScale and PseudoColor), these control the
+ * selection of colors allocated for drawing to Pictures. The default
+ * policy depends on the size of the colormap:
+ *
+ * Size Default Policy
+ * ----------------------------
+ * < 64 PolicyMono
+ * < 256 PolicyGray
+ * 256 PolicyColor (only on PseudoColor)
+ *
+ * The actual allocation code lives in miindex.c, and so is
+ * austensibly server dependent, but that code does:
+ *
+ * PolicyMono Allocate no additional colors, use black and white
+ * PolicyGray Allocate 13 gray levels (11 cells used)
+ * PolicyColor Allocate a 4x4x4 cube and 13 gray levels (71 cells used)
+ * PolicyAll Allocate as big a cube as possible, fill with gray (all)
+ *
+ * Here's a picture to help understand how many colors are
+ * actually allocated (this is just the gray ramp):
+ *
+ * gray level
+ * all 0000 1555 2aaa 4000 5555 6aaa 8000 9555 aaaa bfff d555 eaaa ffff
+ * b/w 0000 ffff
+ * 4x4x4 5555 aaaa
+ * extra 1555 2aaa 4000 6aaa 8000 9555 bfff d555 eaaa
+ *
+ * The default colormap supplies two gray levels (black/white), the
+ * 4x4x4 cube allocates another two and nine more are allocated to fill
+ * in the 13 levels. When the 4x4x4 cube is not allocated, a total of
+ * 11 cells are allocated.
+ */
+
+#define PictureCmapPolicyInvalid -1
+#define PictureCmapPolicyDefault 0
+#define PictureCmapPolicyMono 1
+#define PictureCmapPolicyGray 2
+#define PictureCmapPolicyColor 3
+#define PictureCmapPolicyAll 4
+
+extern int PictureCmapPolicy;
+
+int PictureParseCmapPolicy (const char *name);
+
+extern int RenderErrBase;
+extern int RenderClientPrivateIndex;
+
+/* Fixed point updates from Carl Worth, USC, Information Sciences Institute */
+
+#if defined(WIN32) && !defined(__GNUC__)
+typedef __int64 xFixed_32_32;
+#else
+# if defined (_LP64) || \
+ defined(__alpha__) || defined(__alpha) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__sparc64__) || \
+ defined(__s390x__) || \
+ defined(amd64) || defined (__amd64__)
+typedef long xFixed_32_32;
+# else
+# if defined(__GNUC__) && \
+ ((__GNUC__ > 2) || \
+ ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ > 7)))
+__extension__
+# endif
+typedef long long int xFixed_32_32;
+# endif
+#endif
+
+typedef xFixed_32_32 xFixed_48_16;
+
+#define MAX_FIXED_48_16 ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16 (-((xFixed_48_16) 1 << 31))
+
+typedef CARD32 xFixed_1_31;
+typedef CARD32 xFixed_1_16;
+typedef INT32 xFixed_16_16;
+
+/*
+ * An unadorned "xFixed" is the same as xFixed_16_16,
+ * (since it's quite common in the code)
+ */
+typedef xFixed_16_16 xFixed;
+#define XFIXED_BITS 16
+
+#define xFixedToInt(f) (int) ((f) >> XFIXED_BITS)
+#define IntToxFixed(i) ((xFixed) (i) << XFIXED_BITS)
+#define xFixedE ((xFixed) 1)
+#define xFixed1 (IntToxFixed(1))
+#define xFixed1MinusE (xFixed1 - xFixedE)
+#define xFixedFrac(f) ((f) & xFixed1MinusE)
+#define xFixedFloor(f) ((f) & ~xFixed1MinusE)
+#define xFixedCeil(f) xFixedFloor((f) + xFixed1MinusE)
+
+#define xFixedFraction(f) ((f) & xFixed1MinusE)
+#define xFixedMod2(f) ((f) & (xFixed1 | xFixed1MinusE))
+
+/* whether 't' is a well defined not obviously empty trapezoid */
+#define xTrapezoidValid(t) ((t)->left.p1.y != (t)->left.p2.y && \
+ (t)->right.p1.y != (t)->right.p2.y && \
+ (int) ((t)->bottom - (t)->top) > 0)
+
+/*
+ * Standard NTSC luminance conversions:
+ *
+ * y = r * 0.299 + g * 0.587 + b * 0.114
+ *
+ * Approximate this for a bit more speed:
+ *
+ * y = (r * 153 + g * 301 + b * 58) / 512
+ *
+ * This gives 17 bits of luminance; to get 15 bits, lop the low two
+ */
+
+#define CvtR8G8B8toY15(s) (((((s) >> 16) & 0xff) * 153 + \
+ (((s) >> 8) & 0xff) * 301 + \
+ (((s) ) & 0xff) * 58) >> 2)
+
+#endif /* _PICTURE_H_ */
diff --git a/nx-X11/programs/Xserver/render/picturestr.h b/nx-X11/programs/Xserver/render/picturestr.h
new file mode 100644
index 000000000..f5c367bb4
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/picturestr.h
@@ -0,0 +1,686 @@
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "glyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+ CARD16 red, redMask;
+ CARD16 green, greenMask;
+ CARD16 blue, blueMask;
+ CARD16 alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+ VisualID vid;
+ ColormapPtr pColormap;
+ int nvalues;
+ xIndexValue *pValues;
+ void *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+ CARD32 id;
+ CARD32 format; /* except bpp */
+ unsigned char type;
+ unsigned char depth;
+ DirectFormatRec direct;
+ IndexFormatRec index;
+} PictFormatRec;
+
+typedef struct pixman_vector PictVector, *PictVectorPtr;
+typedef struct pixman_transform PictTransform, *PictTransformPtr;
+
+#define pict_f_transform pixman_f_transform
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+#ifdef NXAGENT_SERVER
+#include "../hw/nxagent/NXpicturestr_PictSolidFill.h"
+#else
+typedef struct _PictSolidFill {
+ unsigned int type;
+ CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+#endif /* NXAGENT_SERVER */
+
+typedef struct _PictGradientStop {
+ xFixed x;
+ xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed p1;
+ xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ double fx;
+ double fy;
+ double dx;
+ double dy;
+ double a;
+ double m;
+ double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+ unsigned int type;
+ int nstops;
+ PictGradientStopPtr stops;
+ CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ xPointFixed center;
+ xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+ unsigned int type;
+ PictSolidFill solidFill;
+ PictGradient gradient;
+ PictLinearGradient linear;
+ PictRadialGradient radial;
+ PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ CARD32 format; /* PICT_FORMAT */
+ int refcnt;
+ CARD32 id;
+ PicturePtr pNext; /* chain on same drawable */
+
+ unsigned int repeat : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int polyEdge : 1;
+ unsigned int polyMode : 1;
+ unsigned int freeCompClip : 1;
+ unsigned int clientClipType : 2;
+ unsigned int componentAlpha : 1;
+ unsigned int repeatType : 2;
+ unsigned int unused : 21;
+
+ PicturePtr alphaMap;
+ DDXPointRec alphaOrigin;
+
+ DDXPointRec clipOrigin;
+ void *clientClip;
+
+ Atom dither;
+
+ unsigned long stateChanges;
+ unsigned long serialNumber;
+
+ RegionPtr pCompositeClip;
+
+ DevUnion *devPrivates;
+
+ PictTransform *transform;
+
+ int filter;
+ xFixed *filter_params;
+ int filter_nparams;
+ SourcePictPtr pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
+ xFixed *params, int nparams,
+ int *width, int *height);
+typedef struct {
+ char *name;
+ int id;
+ PictFilterValidateParamsProcPtr ValidateParams;
+ int width, height;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest 0
+#define PictFilterBilinear 1
+
+#define PictFilterFast 2
+#define PictFilterGood 3
+#define PictFilterBest 4
+
+#define PictFilterConvolution 5
+
+typedef struct {
+ char *alias;
+ int alias_id;
+ int filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int (*CreatePictureProcPtr) (PicturePtr pPicture);
+typedef void (*DestroyPictureProcPtr) (PicturePtr pPicture);
+typedef int (*ChangePictureClipProcPtr) (PicturePtr pPicture,
+ int clipType,
+ void *value,
+ int n);
+typedef void (*DestroyPictureClipProcPtr)(PicturePtr pPicture);
+
+typedef int (*ChangePictureTransformProcPtr) (PicturePtr pPicture,
+ PictTransform *transform);
+
+typedef int (*ChangePictureFilterProcPtr) (PicturePtr pPicture,
+ int filter,
+ xFixed *params,
+ int nparams);
+
+typedef void (*DestroyPictureFilterProcPtr) (PicturePtr pPicture);
+
+typedef void (*ChangePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*ValidatePictureProcPtr) (PicturePtr pPicture,
+ Mask mask);
+typedef void (*CompositeProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+typedef void (*GlyphsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+typedef void (*CompositeRectsProcPtr) (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+typedef void (*RasterizeTrapezoidProcPtr)(PicturePtr pMask,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off);
+
+typedef void (*TrapezoidsProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+typedef void (*TrianglesProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntri,
+ xTriangle *tris);
+
+typedef void (*TriStripProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef void (*TriFanProcPtr) (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoint,
+ xPointFixed *points);
+
+typedef Bool (*InitIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*CloseIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat);
+
+typedef void (*UpdateIndexedProcPtr) (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef);
+
+typedef void (*AddTrapsProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntrap,
+ xTrap *traps);
+
+typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
+
+typedef struct _PictureScreen {
+ int totalPictureSize;
+ unsigned int *PicturePrivateSizes;
+ int PicturePrivateLen;
+
+ PictFormatPtr formats;
+ PictFormatPtr fallback;
+ int nformats;
+
+ CreatePictureProcPtr CreatePicture;
+ DestroyPictureProcPtr DestroyPicture;
+ ChangePictureClipProcPtr ChangePictureClip;
+ DestroyPictureClipProcPtr DestroyPictureClip;
+
+ ChangePictureProcPtr ChangePicture;
+ ValidatePictureProcPtr ValidatePicture;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+ DestroyWindowProcPtr DestroyWindow;
+ CloseScreenProcPtr CloseScreen;
+
+ StoreColorsProcPtr StoreColors;
+
+ InitIndexedProcPtr InitIndexed;
+ CloseIndexedProcPtr CloseIndexed;
+ UpdateIndexedProcPtr UpdateIndexed;
+
+ int subpixel;
+
+ PictFilterPtr filters;
+ int nfilters;
+ PictFilterAliasPtr filterAliases;
+ int nfilterAliases;
+
+ ChangePictureTransformProcPtr ChangePictureTransform;
+
+ /**
+ * Called immediately after a picture's transform is changed through the
+ * SetPictureFilter request. Not called for source-only pictures.
+ */
+ ChangePictureFilterProcPtr ChangePictureFilter;
+
+ DestroyPictureFilterProcPtr DestroyPictureFilter;
+
+ TrapezoidsProcPtr Trapezoids;
+ TrianglesProcPtr Triangles;
+ TriStripProcPtr TriStrip;
+ TriFanProcPtr TriFan;
+
+ RasterizeTrapezoidProcPtr RasterizeTrapezoid;
+
+ AddTrianglesProcPtr AddTriangles;
+
+ AddTrapsProcPtr AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int PictureScreenPrivateIndex;
+extern int PictureWindowPrivateIndex;
+extern RESTYPE PictureType;
+extern RESTYPE PictFormatType;
+extern RESTYPE GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (void *) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (void *) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
+ xFixed *params, int nparams);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len,
+ xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture pid,
+ DrawablePtr pDrawable,
+ PictFormatPtr pFormat,
+ Mask mask,
+ XID *list,
+ ClientPtr client,
+ int *error);
+
+int
+ChangePicture (PicturePtr pPicture,
+ Mask vmask,
+ XID *vlist,
+ DevUnion *ulist,
+ ClientPtr client);
+
+int
+SetPictureClipRects (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ int nRect,
+ xRectangle *rects);
+
+int
+SetPictureClipRegion (PicturePtr pPicture,
+ int xOrigin,
+ int yOrigin,
+ RegionPtr pRegion);
+
+int
+SetPictureTransform (PicturePtr pPicture,
+ PictTransform *transform);
+
+void
+CopyPicture (PicturePtr pSrc,
+ Mask mask,
+ PicturePtr pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (void *pPicture,
+ XID pid);
+
+int
+FreePictFormat (void *pPictFormat,
+ XID pid);
+
+void
+CompositePicture (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+void
+CompositeGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs);
+
+void
+CompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void
+CompositeTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps);
+
+void
+CompositeTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntriangles,
+ xTriangle *triangles);
+
+void
+CompositeTriStrip (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+void
+CompositeTriFan (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int npoints,
+ xPointFixed *points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+ PictVectorPtr vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr pPicture,
+ INT16 xOff,
+ INT16 yOff,
+ int ntraps,
+ xTrap *traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+ xRenderColor *color,
+ int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+ xPointFixed *p1,
+ xPointFixed *p2,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+ xPointFixed *inner,
+ xPointFixed *outer,
+ xFixed innerRadius,
+ xFixed outerRadius,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+ xPointFixed *center,
+ xFixed angle,
+ int nStops,
+ xFixed *stops,
+ xRenderColor *colors,
+ int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+/*
+ * matrix.c
+ */
+
+extern _X_EXPORT void
+PictTransform_from_xRenderTransform(PictTransformPtr pict,
+ xRenderTransform * render);
+
+extern _X_EXPORT void
+xRenderTransform_from_PictTransform(xRenderTransform * render,
+ PictTransformPtr pict);
+
+extern _X_EXPORT Bool
+ PictureTransformPoint(PictTransformPtr transform, PictVectorPtr vector);
+
+extern _X_EXPORT Bool
+ PictureTransformPoint3d(PictTransformPtr transform, PictVectorPtr vector);
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/render/render.c b/nx-X11/programs/Xserver/render/render.c
new file mode 100644
index 000000000..fb9208ad1
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/render.c
@@ -0,0 +1,3323 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * 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, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <nx-X11/extensions/render.h>
+#include <nx-X11/extensions/renderproto.h>
+#include "picturestr.h"
+#include "glyphstr.h"
+#include <nx-X11/Xfuncproto.h>
+#include "cursorstr.h"
+
+#include "protocol-versions.h"
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ ProcRenderQueryVersion,
+ ProcRenderQueryPictFormats,
+ ProcRenderQueryPictIndexValues,
+ ProcRenderQueryDithers,
+ ProcRenderCreatePicture,
+ ProcRenderChangePicture,
+ ProcRenderSetPictureClipRectangles,
+ ProcRenderFreePicture,
+ ProcRenderComposite,
+ ProcRenderScale,
+ ProcRenderTrapezoids,
+ ProcRenderTriangles,
+ ProcRenderTriStrip,
+ ProcRenderTriFan,
+ ProcRenderColorTrapezoids,
+ ProcRenderColorTriangles,
+ ProcRenderTransform,
+ ProcRenderCreateGlyphSet,
+ ProcRenderReferenceGlyphSet,
+ ProcRenderFreeGlyphSet,
+ ProcRenderAddGlyphs,
+ ProcRenderAddGlyphsFromPicture,
+ ProcRenderFreeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderCompositeGlyphs,
+ ProcRenderFillRectangles,
+ ProcRenderCreateCursor,
+ ProcRenderSetPictureTransform,
+ ProcRenderQueryFilters,
+ ProcRenderSetPictureFilter,
+ ProcRenderCreateAnimCursor,
+ ProcRenderAddTraps,
+ ProcRenderCreateSolidFill,
+ ProcRenderCreateLinearGradient,
+ ProcRenderCreateRadialGradient,
+ ProcRenderCreateConicalGradient
+};
+
+int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+ SProcRenderQueryVersion,
+ SProcRenderQueryPictFormats,
+ SProcRenderQueryPictIndexValues,
+ SProcRenderQueryDithers,
+ SProcRenderCreatePicture,
+ SProcRenderChangePicture,
+ SProcRenderSetPictureClipRectangles,
+ SProcRenderFreePicture,
+ SProcRenderComposite,
+ SProcRenderScale,
+ SProcRenderTrapezoids,
+ SProcRenderTriangles,
+ SProcRenderTriStrip,
+ SProcRenderTriFan,
+ SProcRenderColorTrapezoids,
+ SProcRenderColorTriangles,
+ SProcRenderTransform,
+ SProcRenderCreateGlyphSet,
+ SProcRenderReferenceGlyphSet,
+ SProcRenderFreeGlyphSet,
+ SProcRenderAddGlyphs,
+ SProcRenderAddGlyphsFromPicture,
+ SProcRenderFreeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderCompositeGlyphs,
+ SProcRenderFillRectangles,
+ SProcRenderCreateCursor,
+ SProcRenderSetPictureTransform,
+ SProcRenderQueryFilters,
+ SProcRenderSetPictureFilter,
+ SProcRenderCreateAnimCursor,
+ SProcRenderAddTraps,
+ SProcRenderCreateSolidFill,
+ SProcRenderCreateLinearGradient,
+ SProcRenderCreateRadialGradient,
+ SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+
+#if 0
+static CARD8 RenderReqCode;
+#endif
+int RenderErrBase;
+int RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+ int major_version;
+ int minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient) ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr *list,
+ void * closure,
+ void * data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ RenderClientPtr pRenderClient = GetRenderClient (pClient);
+
+ pRenderClient->major_version = 0;
+ pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+
+ if (!PictureType)
+ return;
+ if (!PictureFinishInit ())
+ return;
+ RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (RenderClientPrivateIndex,
+ sizeof (RenderClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+ return;
+
+ extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+ ProcRenderDispatch, SProcRenderDispatch,
+ RenderResetProc, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+#if 0
+ RenderReqCode = (CARD8) extEntry->base;
+#endif
+ RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+ ResetPicturePrivateIndex();
+ ResetGlyphSetPrivateIndex();
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryVersionReply rep;
+
+ REQUEST(xRenderQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+
+ pRenderClient->major_version = stuff->majorVersion;
+ pRenderClient->minor_version = stuff->minorVersion;
+
+ memset(&rep, 0, sizeof(xRenderQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_RENDER_MAJOR_VERSION;
+ rep.minorVersion = SERVER_RENDER_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xRenderQueryVersionReply), &rep);
+ return (client->noClientException);
+}
+#endif /* NXAGENT_SERVER */
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ DepthPtr pDepth;
+ int d, v;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+ }
+ return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+ VisualPtr pVisual;
+ int v;
+
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = pScreen->visuals + v;
+ if (pVisual->vid == vid)
+ return pVisual;
+ }
+ return 0;
+}
+
+extern char *ConnectionInfo;
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+ RenderClientPtr pRenderClient = GetRenderClient (client);
+ xRenderQueryPictFormatsReply *reply;
+ xPictScreen *pictScreen;
+ xPictDepth *pictDepth;
+ xPictVisual *pictVisual;
+ xPictFormInfo *pictForm;
+ CARD32 *pictSubpixel;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ DepthPtr pDepth;
+ int v, d;
+ PictureScreenPtr ps;
+ PictFormatPtr pFormat;
+ int nformat;
+ int ndepth;
+ int nvisual;
+ int rlength;
+ int s;
+ int n;
+ int numScreens;
+ int numSubpixel;
+/* REQUEST(xRenderQueryPictFormatsReq); */
+
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+ numScreens = screenInfo.numScreens;
+#endif
+ ndepth = nformat = nvisual = 0;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = pScreen->allowedDepths + d;
+ ++ndepth;
+
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+ ++nvisual;
+ }
+ }
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ nformat += ps->nformats;
+ }
+ if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+ numSubpixel = 0;
+ else
+ numSubpixel = numScreens;
+
+ rlength = (sizeof (xRenderQueryPictFormatsReply) +
+ nformat * sizeof (xPictFormInfo) +
+ numScreens * sizeof (xPictScreen) +
+ ndepth * sizeof (xPictDepth) +
+ nvisual * sizeof (xPictVisual) +
+ numSubpixel * sizeof (CARD32));
+ reply = (xRenderQueryPictFormatsReply *) malloc (rlength);
+ if (!reply)
+ return BadAlloc;
+ memset(reply, 0, rlength);
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numFormats = nformat;
+ reply->numScreens = numScreens;
+ reply->numDepths = ndepth;
+ reply->numVisuals = nvisual;
+ reply->numSubpixel = numSubpixel;
+
+ pictForm = (xPictFormInfo *) (reply + 1);
+
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (nformat = 0, pFormat = ps->formats;
+ nformat < ps->nformats;
+ nformat++, pFormat++)
+ {
+ pictForm->id = pFormat->id;
+ pictForm->type = pFormat->type;
+ pictForm->depth = pFormat->depth;
+ pictForm->direct.red = pFormat->direct.red;
+ pictForm->direct.redMask = pFormat->direct.redMask;
+ pictForm->direct.green = pFormat->direct.green;
+ pictForm->direct.greenMask = pFormat->direct.greenMask;
+ pictForm->direct.blue = pFormat->direct.blue;
+ pictForm->direct.blueMask = pFormat->direct.blueMask;
+ pictForm->direct.alpha = pFormat->direct.alpha;
+ pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ pictForm->colormap = pFormat->index.pColormap->mid;
+ else
+ pictForm->colormap = None;
+ if (client->swapped)
+ {
+ swapl (&pictForm->id);
+ swaps (&pictForm->direct.red);
+ swaps (&pictForm->direct.redMask);
+ swaps (&pictForm->direct.green);
+ swaps (&pictForm->direct.greenMask);
+ swaps (&pictForm->direct.blue);
+ swaps (&pictForm->direct.blueMask);
+ swaps (&pictForm->direct.alpha);
+ swaps (&pictForm->direct.alphaMask);
+ swapl (&pictForm->colormap);
+ }
+ pictForm++;
+ }
+ }
+ }
+
+ pictScreen = (xPictScreen *) pictForm;
+ for (s = 0; s < numScreens; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ pictDepth = (xPictDepth *) (pictScreen + 1);
+ ndepth = 0;
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pictVisual = (xPictVisual *) (pictDepth + 1);
+ pDepth = pScreen->allowedDepths + d;
+
+ nvisual = 0;
+ for (v = 0; v < pDepth->numVids; v++)
+ {
+ pVisual = findVisual (pScreen, pDepth->vids[v]);
+ if (pVisual && (pFormat = PictureMatchVisual (pScreen,
+ pDepth->depth,
+ pVisual)))
+ {
+ pictVisual->visual = pVisual->vid;
+ pictVisual->format = pFormat->id;
+ if (client->swapped)
+ {
+ swapl (&pictVisual->visual);
+ swapl (&pictVisual->format);
+ }
+ pictVisual++;
+ nvisual++;
+ }
+ }
+ pictDepth->depth = pDepth->depth;
+ pictDepth->nPictVisuals = nvisual;
+ if (client->swapped)
+ {
+ swaps (&pictDepth->nPictVisuals);
+ }
+ ndepth++;
+ pictDepth = (xPictDepth *) pictVisual;
+ }
+ pictScreen->nDepth = ndepth;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ pictScreen->fallback = ps->fallback->id;
+ else
+ pictScreen->fallback = 0;
+ if (client->swapped)
+ {
+ swapl (&pictScreen->nDepth);
+ swapl (&pictScreen->fallback);
+ }
+ pictScreen = (xPictScreen *) pictDepth;
+ }
+ pictSubpixel = (CARD32 *) pictScreen;
+
+ for (s = 0; s < numSubpixel; s++)
+ {
+ pScreen = screenInfo.screens[s];
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ *pictSubpixel = ps->subpixel;
+ else
+ *pictSubpixel = SubPixelUnknown;
+ if (client->swapped)
+ {
+ swapl (pictSubpixel);
+ }
+ ++pictSubpixel;
+ }
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber);
+ swapl (&reply->length);
+ swapl (&reply->numFormats);
+ swapl (&reply->numScreens);
+ swapl (&reply->numDepths);
+ swapl (&reply->numVisuals);
+ swapl (&reply->numSubpixel);
+ }
+ WriteToClient(client, rlength, reply);
+ free (reply);
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ PictFormatPtr pFormat;
+ int num;
+ int rlength;
+ int i;
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ xRenderQueryPictIndexValuesReply *reply;
+ xIndexValue *values;
+
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ DixReadAccess);
+
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->type != PictTypeIndexed)
+ {
+ client->errorValue = stuff->format;
+ return BadMatch;
+ }
+ num = pFormat->index.nvalues;
+ rlength = (sizeof (xRenderQueryPictIndexValuesReply) +
+ num * sizeof(xIndexValue));
+ reply = (xRenderQueryPictIndexValuesReply *) malloc (rlength);
+ if (!reply)
+ return BadAlloc;
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->numIndexValues = num;
+
+ values = (xIndexValue *) (reply + 1);
+
+ memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+
+ if (client->swapped)
+ {
+ for (i = 0; i < num; i++)
+ {
+ swapl (&values[i].pixel);
+ swaps (&values[i].red);
+ swaps (&values[i].green);
+ swaps (&values[i].blue);
+ swaps (&values[i].alpha);
+ }
+ swaps (&reply->sequenceNumber);
+ swapl (&reply->length);
+ swapl (&reply->numIndexValues);
+ }
+
+ WriteToClient(client, rlength, reply);
+ free(reply);
+ return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ int len;
+ int error;
+ REQUEST(xRenderCreatePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+ DixWriteAccess);
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ if (pFormat->depth != pDrawable->depth)
+ return BadMatch;
+ len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ pPicture = CreatePicture (stuff->pid,
+ pDrawable,
+ pFormat,
+ stuff->mask,
+ (XID *) (stuff + 1),
+ client,
+ &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderChangePictureReq);
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ (DevUnion *) 0, client);
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ PicturePtr pPicture;
+ int nr;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+
+ nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+ if (nr & 4)
+ return BadLength;
+ nr >>= 3;
+ result = SetPictureClipRects (pPicture,
+ stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *) &stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+ PicturePtr pPicture;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess,
+ RenderErrBase + BadPicture);
+ FreeResource (stuff->picture, RT_NONE);
+ return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+ if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+ return TRUE;
+ if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+ return TRUE;
+ if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+ return TRUE;
+ return FALSE;
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderComposite (ClientPtr client)
+{
+ PicturePtr pSrc, pMask, pDst;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ (pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ return BadMatch;
+ CompositePicture (stuff->op,
+ pSrc,
+ pMask,
+ pDst,
+ stuff->xSrc,
+ stuff->ySrc,
+ stuff->xMask,
+ stuff->yMask,
+ stuff->xDst,
+ stuff->yDst,
+ stuff->width,
+ stuff->height);
+ return Success;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+ if (ntraps % sizeof (xTrapezoid))
+ return BadLength;
+ ntraps /= sizeof (xTrapezoid);
+ if (ntraps)
+ CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntraps, (xTrapezoid *) &stuff[1]);
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+ int ntris;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+ if (ntris % sizeof (xTriangle))
+ return BadLength;
+ ntris /= sizeof (xTriangle);
+ if (ntris)
+ CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ ntris, (xTriangle *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+ int npoints;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+ npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+ if (npoints & 4)
+ return(BadLength);
+ npoints >>= 3;
+ if (npoints >= 3)
+ CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+ stuff->xSrc, stuff->ySrc,
+ npoints, (xPointFixed *) &stuff[1]);
+ return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ PictFormatPtr format;
+ int f;
+ REQUEST(xRenderCreateGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+ format = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->format,
+ PictFormatType,
+ DixReadAccess);
+ if (!format)
+ {
+ client->errorValue = stuff->format;
+ return RenderErrBase + BadPictFormat;
+ }
+ switch (format->depth) {
+ case 1:
+ f = GlyphFormat1;
+ break;
+ case 4:
+ f = GlyphFormat4;
+ break;
+ case 8:
+ f = GlyphFormat8;
+ break;
+ case 16:
+ f = GlyphFormat16;
+ break;
+ case 32:
+ f = GlyphFormat32;
+ break;
+ default:
+ return BadMatch;
+ }
+ if (format->type != PictTypeDirect)
+ return BadMatch;
+ glyphSet = AllocateGlyphSet (f, format);
+ if (!glyphSet)
+ return BadAlloc;
+ if (!AddResource (stuff->gsid, GlyphSetType, (void *)glyphSet))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderReferenceGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+ LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->existing,
+ GlyphSetType,
+ DixWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->existing;
+ return RenderErrBase + BadGlyphSet;
+ }
+ glyphSet->refcnt++;
+ if (!AddResource (stuff->gsid, GlyphSetType, (void *)glyphSet))
+ return BadAlloc;
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+#define NLOCALDELTA 64
+#define NLOCALGLYPH 256
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderFreeGlyphSetReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixDestroyAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ FreeResource (stuff->glyphset, RT_NONE);
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+typedef struct _GlyphNew {
+ Glyph id;
+ GlyphPtr glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ REQUEST(xRenderAddGlyphsReq);
+ GlyphNewRec glyphsLocal[NLOCALGLYPH];
+ GlyphNewPtr glyphsBase, glyphs;
+ GlyphPtr glyph = NULL;
+ int remain, nglyphs;
+ CARD32 *gids;
+ xGlyphInfo *gi;
+ CARD8 *bits;
+ int size;
+ int err = BadAlloc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ nglyphs = stuff->nglyphs;
+ if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+ return BadAlloc;
+
+ if (nglyphs <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphNewPtr) malloc (nglyphs * sizeof (GlyphNewRec));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+
+ remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+ glyphs = glyphsBase;
+
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + nglyphs);
+ bits = (CARD8 *) (gi + nglyphs);
+ remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+ while (remain >= 0 && nglyphs)
+ {
+ glyph = AllocateGlyph (gi, glyphSet->fdepth);
+ if (!glyph)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+
+ glyphs->glyph = glyph;
+ glyphs->id = *gids;
+
+ size = glyph->size - sizeof (xGlyphInfo);
+ if (remain < size)
+ break;
+ memcpy ((CARD8 *) (glyph + 1), bits, size);
+
+ if (size & 3)
+ size += 4 - (size & 3);
+ bits += size;
+ remain -= size;
+ gi++;
+ gids++;
+ glyphs++;
+ nglyphs--;
+ }
+ if (nglyphs || remain)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ nglyphs = stuff->nglyphs;
+ if (!ResizeGlyphSet (glyphSet, nglyphs))
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ glyphs = glyphsBase;
+ while (nglyphs--) {
+ AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+ glyphs++;
+ }
+
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ return client->noClientException;
+bail:
+ while (glyphs != glyphsBase)
+ {
+ --glyphs;
+ free (glyphs->glyph);
+ }
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ GlyphSetPtr glyphSet;
+ int nglyph;
+ CARD32 *gids;
+ CARD32 glyph;
+
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixWriteAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+ nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+ gids = (CARD32 *) (stuff + 1);
+ while (nglyph-- > 0)
+ {
+ glyph = *gids++;
+ if (!DeleteGlyph (glyphSet, glyph))
+ {
+ client->errorValue = glyph;
+ return RenderErrBase + BadGlyph;
+ }
+ }
+ return client->noClientException;
+}
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+ GlyphSetPtr glyphSet;
+ GlyphSet gs;
+ PicturePtr pSrc, pDst;
+ PictFormatPtr pFormat;
+ GlyphListRec listsLocal[NLOCALDELTA];
+ GlyphListPtr lists, listsBase;
+ GlyphPtr glyphsLocal[NLOCALGLYPH];
+ Glyph glyph;
+ GlyphPtr *glyphs, *glyphsBase;
+ xGlyphElt *elt;
+ CARD8 *buffer, *end;
+ int nglyph;
+ int nlist;
+ int space;
+ int size;
+ int n;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+ if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+ return BadMatch;
+ if (stuff->maskFormat)
+ {
+ pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+ stuff->maskFormat,
+ PictFormatType,
+ DixReadAccess);
+ if (!pFormat)
+ {
+ client->errorValue = stuff->maskFormat;
+ return RenderErrBase + BadPictFormat;
+ }
+ }
+ else
+ pFormat = 0;
+
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ stuff->glyphset,
+ GlyphSetType,
+ DixReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = stuff->glyphset;
+ return RenderErrBase + BadGlyphSet;
+ }
+
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ nglyph = 0;
+ nlist = 0;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ buffer += 4;
+ }
+ else
+ {
+ nlist++;
+ nglyph += elt->len;
+ space = size * elt->len;
+ if (space & 3)
+ space += 4 - (space & 3);
+ buffer += space;
+ }
+ }
+ if (nglyph <= NLOCALGLYPH)
+ glyphsBase = glyphsLocal;
+ else
+ {
+ glyphsBase = (GlyphPtr *) malloc (nglyph * sizeof (GlyphPtr));
+ if (!glyphsBase)
+ return BadAlloc;
+ }
+ if (nlist <= NLOCALDELTA)
+ listsBase = listsLocal;
+ else
+ {
+ listsBase = (GlyphListPtr) malloc (nlist * sizeof (GlyphListRec));
+ if (!listsBase)
+ return BadAlloc;
+ }
+ buffer = (CARD8 *) (stuff + 1);
+ glyphs = glyphsBase;
+ lists = listsBase;
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ if (elt->len == 0xff)
+ {
+ if (buffer + sizeof (GlyphSet) < end)
+ {
+ memcpy(&gs, buffer, sizeof(GlyphSet));
+ glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ gs,
+ GlyphSetType,
+ DixReadAccess);
+ if (!glyphSet)
+ {
+ client->errorValue = gs;
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ if (listsBase != listsLocal)
+ free (listsBase);
+ return RenderErrBase + BadGlyphSet;
+ }
+ }
+ buffer += 4;
+ }
+ else
+ {
+ lists->xOff = elt->deltax;
+ lists->yOff = elt->deltay;
+ lists->format = glyphSet->format;
+ lists->len = 0;
+ n = elt->len;
+ while (n--)
+ {
+ if (buffer + size <= end)
+ {
+ switch (size) {
+ case 1:
+ glyph = *((CARD8 *)buffer); break;
+ case 2:
+ glyph = *((CARD16 *)buffer); break;
+ case 4:
+ default:
+ glyph = *((CARD32 *)buffer); break;
+ }
+ if ((*glyphs = FindGlyph (glyphSet, glyph)))
+ {
+ lists->len++;
+ glyphs++;
+ }
+ }
+ buffer += size;
+ }
+ space = size * elt->len;
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ lists++;
+ }
+ }
+ if (buffer > end)
+ return BadLength;
+
+ CompositeGlyphs (stuff->op,
+ pSrc,
+ pDst,
+ pFormat,
+ stuff->xSrc,
+ stuff->ySrc,
+ nlist,
+ listsBase,
+ glyphsBase);
+
+ if (glyphsBase != glyphsLocal)
+ free (glyphsBase);
+ if (listsBase != listsLocal)
+ free (listsBase);
+
+ return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+ PicturePtr pDst;
+ int things;
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ if (!PictOpValid (stuff->op))
+ {
+ client->errorValue = stuff->op;
+ return BadValue;
+ }
+ VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pDst->pDrawable)
+ return BadDrawable;
+
+ things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ CompositeRects (stuff->op,
+ pDst,
+ &stuff->color,
+ things,
+ (xRectangle *) &stuff[1]);
+
+ return client->noClientException;
+}
+#endif /* NXAGENT_SERVER */
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (bit)
+ *line |= mask;
+ else
+ *line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+ { 1, 3, },
+ { 4, 2, },
+};
+
+#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ PicturePtr pSrc;
+ ScreenPtr pScreen;
+ unsigned short width, height;
+ CARD32 *argbbits, *argb;
+ unsigned char *srcbits, *srcline;
+ unsigned char *mskbits, *mskline;
+ int stride;
+ int x, y;
+ int nbytes_mono;
+ CursorMetricRec cm;
+ CursorPtr pCursor;
+ CARD32 twocolor[3];
+ int ncolor;
+
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ if (!pSrc->pDrawable)
+ return BadDrawable;
+ pScreen = pSrc->pDrawable->pScreen;
+ width = pSrc->pDrawable->width;
+ height = pSrc->pDrawable->height;
+ if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+ return BadAlloc;
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+ argbbits = malloc (width * height * sizeof (CARD32));
+ if (!argbbits)
+ return (BadAlloc);
+
+ stride = BitmapBytePad(width);
+ nbytes_mono = stride*height;
+ srcbits = (unsigned char *)malloc(nbytes_mono);
+ if (!srcbits)
+ {
+ free (argbbits);
+ return (BadAlloc);
+ }
+ mskbits = (unsigned char *)malloc(nbytes_mono);
+ if (!mskbits)
+ {
+ free(argbbits);
+ free(srcbits);
+ return (BadAlloc);
+ }
+ bzero ((char *) mskbits, nbytes_mono);
+ bzero ((char *) srcbits, nbytes_mono);
+
+ if (pSrc->format == PICT_a8r8g8b8)
+ {
+ (*pScreen->GetImage) (pSrc->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (void *) argbbits);
+ }
+ else
+ {
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ PictFormatPtr pFormat;
+ int error;
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return (BadImplementation);
+ }
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return (BadAlloc);
+ }
+ pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0,
+ client, &error);
+ if (!pPicture)
+ {
+ free (argbbits);
+ free (srcbits);
+ free (mskbits);
+ return error;
+ }
+ (*pScreen->DestroyPixmap) (pPixmap);
+ CompositePicture (PictOpSrc,
+ pSrc, 0, pPicture,
+ 0, 0, 0, 0, 0, 0, width, height);
+ (*pScreen->GetImage) (pPicture->pDrawable,
+ 0, 0, width, height, ZPixmap,
+ 0xffffffff, (void *) argbbits);
+ FreePicture (pPicture, 0);
+ }
+ /*
+ * Check whether the cursor can be directly supported by
+ * the core cursor code
+ */
+ ncolor = 0;
+ argb = argbbits;
+ for (y = 0; ncolor <= 2 && y < height; y++)
+ {
+ for (x = 0; ncolor <= 2 && x < width; x++)
+ {
+ CARD32 p = *argb++;
+ CARD32 a = (p >> 24);
+
+ if (a == 0) /* transparent */
+ continue;
+ if (a == 0xff) /* opaque */
+ {
+ int n;
+ for (n = 0; n < ncolor; n++)
+ if (p == twocolor[n])
+ break;
+ if (n == ncolor)
+ twocolor[ncolor++] = p;
+ }
+ else
+ ncolor = 3;
+ }
+ }
+
+ /*
+ * Convert argb image to two plane cursor
+ */
+ srcline = srcbits;
+ mskline = mskbits;
+ argb = argbbits;
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ CARD32 p = *argb++;
+
+ if (ncolor <= 2)
+ {
+ CARD32 a = ((p >> 24));
+
+ SetBit (mskline, x, a != 0);
+ SetBit (srcline, x, a != 0 && p == twocolor[0]);
+ }
+ else
+ {
+ CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+ CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+ CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+ /* Set mask from dithered alpha value */
+ SetBit(mskline, x, a > d);
+ /* Set src from dithered intensity value */
+ SetBit(srcline, x, a > d && i <= d);
+ }
+ }
+ srcline += stride;
+ mskline += stride;
+ }
+ /*
+ * Dither to white and black if the cursor has more than two colors
+ */
+ if (ncolor > 2)
+ {
+ twocolor[0] = 0xff000000;
+ twocolor[1] = 0xffffffff;
+ }
+ else
+ {
+ free (argbbits);
+ argbbits = 0;
+ }
+
+#define GetByte(p,s) (((p) >> (s)) & 0xff)
+#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8))
+
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ GetColor(twocolor[0], 16),
+ GetColor(twocolor[0], 8),
+ GetColor(twocolor[0], 0),
+ GetColor(twocolor[1], 16),
+ GetColor(twocolor[1], 8),
+ GetColor(twocolor[1], 0));
+ if (pCursor && AddResource(stuff->cid, RT_CURSOR, (void *)pCursor))
+ return (client->noClientException);
+ return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ PicturePtr pPicture;
+ int result;
+
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+ REQUEST (xRenderQueryFiltersReq);
+ DrawablePtr pDrawable;
+ xRenderQueryFiltersReply *reply;
+ int nbytesName;
+ int nnames;
+ ScreenPtr pScreen;
+ PictureScreenPtr ps;
+ int i, j;
+ int len;
+ int total_bytes;
+ INT16 *aliases;
+ char *names;
+
+ REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+ SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, DixReadAccess);
+
+ pScreen = pDrawable->pScreen;
+ nbytesName = 0;
+ nnames = 0;
+ ps = GetPictureScreenIfSet(pScreen);
+ if (ps)
+ {
+ for (i = 0; i < ps->nfilters; i++)
+ nbytesName += 1 + strlen (ps->filters[i].name);
+ for (i = 0; i < ps->nfilterAliases; i++)
+ nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+ nnames = ps->nfilters + ps->nfilterAliases;
+ }
+ len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+ total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+ reply = (xRenderQueryFiltersReply *) malloc (total_bytes);
+ if (!reply)
+ return BadAlloc;
+ aliases = (INT16 *) (reply + 1);
+ names = (char *) (aliases + ((nnames + 1) & ~1));
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = len;
+ reply->numAliases = nnames;
+ reply->numFilters = nnames;
+ if (ps)
+ {
+
+ /* fill in alias values */
+ for (i = 0; i < ps->nfilters; i++)
+ aliases[i] = FilterAliasNone;
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ for (j = 0; j < ps->nfilters; j++)
+ if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+ break;
+ if (j == ps->nfilters)
+ {
+ for (j = 0; j < ps->nfilterAliases; j++)
+ if (ps->filterAliases[i].filter_id ==
+ ps->filterAliases[j].alias_id)
+ {
+ break;
+ }
+ if (j == ps->nfilterAliases)
+ j = FilterAliasNone;
+ else
+ j = j + ps->nfilters;
+ }
+ aliases[i + ps->nfilters] = j;
+ }
+
+ /* fill in filter names */
+ for (i = 0; i < ps->nfilters; i++)
+ {
+ j = strlen (ps->filters[i].name);
+ *names++ = j;
+ strncpy (names, ps->filters[i].name, j);
+ names += j;
+ }
+
+ /* fill in filter alias names */
+ for (i = 0; i < ps->nfilterAliases; i++)
+ {
+ j = strlen (ps->filterAliases[i].alias);
+ *names++ = j;
+ strncpy (names, ps->filterAliases[i].alias, j);
+ names += j;
+ }
+ }
+
+ if (client->swapped)
+ {
+ for (i = 0; i < reply->numAliases; i++)
+ {
+ swaps (&aliases[i]);
+ }
+ swaps(&reply->sequenceNumber);
+ swapl(&reply->length);
+ swapl(&reply->numAliases);
+ swapl(&reply->numFilters);
+ }
+ WriteToClient(client, total_bytes, reply);
+ free (reply);
+
+ return(client->noClientException);
+}
+
+#ifndef NXAGENT_SERVER
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ PicturePtr pPicture;
+ int result;
+ xFixed *params;
+ int nparams;
+ char *name;
+
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ name = (char *) (stuff + 1);
+ params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+ nparams = ((xFixed *) stuff + client->req_len) - params;
+ result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+ return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateAnimCursorReq);
+ CursorPtr *cursors;
+ CARD32 *deltas;
+ CursorPtr pCursor;
+ int ncursor;
+ xAnimCursorElt *elt;
+ int i;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+ if (client->req_len & 1)
+ return BadLength;
+ ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+ cursors = malloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+ if (!cursors)
+ return BadAlloc;
+ deltas = (CARD32 *) (cursors + ncursor);
+ elt = (xAnimCursorElt *) (stuff + 1);
+ for (i = 0; i < ncursor; i++)
+ {
+ cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+ RT_CURSOR, DixReadAccess);
+ if (!cursors[i])
+ {
+ free (cursors);
+ client->errorValue = elt->cursor;
+ return BadCursor;
+ }
+ deltas[i] = elt->delay;
+ elt++;
+ }
+ ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+ free (cursors);
+ if (ret != Success)
+ return ret;
+
+ if (AddResource (stuff->cid, RT_CURSOR, (void *)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+ int ntraps;
+ PicturePtr pPicture;
+ REQUEST(xRenderAddTrapsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+ VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ if (!pPicture->pDrawable)
+ return BadDrawable;
+ ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (ntraps % sizeof (xTrap))
+ return BadLength;
+ ntraps /= sizeof (xTrap);
+ if (ntraps)
+ AddTraps (pPicture,
+ stuff->xOff, stuff->yOff,
+ ntraps, (xTrap *) &stuff[1]);
+ return client->noClientException;
+}
+
+#ifndef NXAGENT_SERVER
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+ PicturePtr pPicture;
+ int error = 0;
+ REQUEST(xRenderCreateSolidFillReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateLinearGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateRadialGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+ stuff->inner_radius, stuff->outer_radius,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+ PicturePtr pPicture;
+ int len;
+ int error = 0;
+ xFixed *stops;
+ xRenderColor *colors;
+ REQUEST(xRenderCreateConicalGradientReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ stops = (xFixed *)(stuff + 1);
+ colors = (xRenderColor *)(stops + stuff->nStops);
+
+ pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+ stuff->nStops, stops, colors, &error);
+ if (!pPicture)
+ return error;
+ if (!AddResource (stuff->pid, PictureType, (void *)pPicture))
+ return BadAlloc;
+ return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < RenderNumberRequests)
+ return (*ProcRenderVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+#endif /* NXAGENT_SERVER */
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+ REQUEST(xRenderQueryVersionReq);
+ REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->majorVersion);
+ swapl(&stuff->minorVersion);
+ return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+ REQUEST(xRenderQueryPictFormatsReq);
+ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+ swaps(&stuff->length);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+ REQUEST(xRenderQueryPictIndexValuesReq);
+ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->format);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+ REQUEST(xRenderCreatePictureReq);
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+ swaps(&stuff->length);
+ swapl(&stuff->pid);
+ swapl(&stuff->drawable);
+ swapl(&stuff->format);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+ REQUEST(xRenderChangePictureReq);
+ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ swapl(&stuff->mask);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+ REQUEST(xRenderFreePictureReq);
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+ REQUEST(xRenderCompositeReq);
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+ swaps(&stuff->length);
+ swapl(&stuff->src);
+ swapl(&stuff->mask);
+ swapl(&stuff->dst);
+ swaps(&stuff->xSrc);
+ swaps(&stuff->ySrc);
+ swaps(&stuff->xMask);
+ swaps(&stuff->yMask);
+ swaps(&stuff->xDst);
+ swaps(&stuff->yDst);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+ REQUEST(xRenderScaleReq);
+ REQUEST_SIZE_MATCH(xRenderScaleReq);
+ swaps(&stuff->length);
+ swapl(&stuff->src);
+ swapl(&stuff->dst);
+ swapl(&stuff->colorScale);
+ swapl(&stuff->alphaScale);
+ swaps(&stuff->xSrc);
+ swaps(&stuff->ySrc);
+ swaps(&stuff->xDst);
+ swaps(&stuff->yDst);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+ REQUEST(xRenderTrapezoidsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+ swaps (&stuff->length);
+ swapl (&stuff->src);
+ swapl (&stuff->dst);
+ swapl (&stuff->maskFormat);
+ swaps (&stuff->xSrc);
+ swaps (&stuff->ySrc);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+ REQUEST(xRenderTrianglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+ swaps (&stuff->length);
+ swapl (&stuff->src);
+ swapl (&stuff->dst);
+ swapl (&stuff->maskFormat);
+ swaps (&stuff->xSrc);
+ swaps (&stuff->ySrc);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+ REQUEST(xRenderTriStripReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+ swaps (&stuff->length);
+ swapl (&stuff->src);
+ swapl (&stuff->dst);
+ swapl (&stuff->maskFormat);
+ swaps (&stuff->xSrc);
+ swaps (&stuff->ySrc);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+ REQUEST(xRenderTriFanReq);
+
+ REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+ swaps (&stuff->length);
+ swapl (&stuff->src);
+ swapl (&stuff->dst);
+ swapl (&stuff->maskFormat);
+ swaps (&stuff->xSrc);
+ swaps (&stuff->ySrc);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+ REQUEST(xRenderCreateGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+ swaps(&stuff->length);
+ swapl(&stuff->gsid);
+ swapl(&stuff->format);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+ REQUEST(xRenderReferenceGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+ swaps(&stuff->length);
+ swapl(&stuff->gsid);
+ swapl(&stuff->existing);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphSetReq);
+ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+ swaps(&stuff->length);
+ swapl(&stuff->glyphset);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+ register int i;
+ CARD32 *gids;
+ void *end;
+ xGlyphInfo *gi;
+ REQUEST(xRenderAddGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->glyphset);
+ swapl(&stuff->nglyphs);
+ if (stuff->nglyphs & 0xe0000000)
+ return BadLength;
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ gids = (CARD32 *) (stuff + 1);
+ gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+ if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+ return BadLength;
+ if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+ return BadLength;
+ for (i = 0; i < stuff->nglyphs; i++)
+ {
+ swapl (&gids[i]);
+ swaps (&gi[i].width);
+ swaps (&gi[i].height);
+ swaps (&gi[i].x);
+ swaps (&gi[i].y);
+ swaps (&gi[i].xOff);
+ swaps (&gi[i].yOff);
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+ return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+ REQUEST(xRenderFreeGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+ swaps(&stuff->length);
+ swapl(&stuff->glyphset);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+ xGlyphElt *elt;
+ CARD8 *buffer;
+ CARD8 *end;
+ int space;
+ int i;
+ int size;
+
+ REQUEST(xRenderCompositeGlyphsReq);
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+ switch (stuff->renderReqType) {
+ default: size = 1; break;
+ case X_RenderCompositeGlyphs16: size = 2; break;
+ case X_RenderCompositeGlyphs32: size = 4; break;
+ }
+
+ swaps(&stuff->length);
+ swapl(&stuff->src);
+ swapl(&stuff->dst);
+ swapl(&stuff->maskFormat);
+ swapl(&stuff->glyphset);
+ swaps(&stuff->xSrc);
+ swaps(&stuff->ySrc);
+ buffer = (CARD8 *) (stuff + 1);
+ end = (CARD8 *) stuff + (client->req_len << 2);
+ while (buffer + sizeof (xGlyphElt) < end)
+ {
+ elt = (xGlyphElt *) buffer;
+ buffer += sizeof (xGlyphElt);
+
+ swaps (&elt->deltax);
+ swaps (&elt->deltay);
+
+ i = elt->len;
+ if (i == 0xff)
+ {
+ swapl ((int *) buffer);
+ buffer += 4;
+ }
+ else
+ {
+ space = size * i;
+ switch (size) {
+ case 1:
+ buffer += i;
+ break;
+ case 2:
+ while (i--)
+ {
+ swaps ((short *) buffer);
+ buffer += 2;
+ }
+ break;
+ case 4:
+ while (i--)
+ {
+ swapl ((int *) buffer);
+ buffer += 4;
+ }
+ break;
+ }
+ if (space & 3)
+ buffer += 4 - (space & 3);
+ }
+ }
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+ REQUEST(xRenderFillRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ swaps(&stuff->length);
+ swapl(&stuff->dst);
+ swaps(&stuff->color.red);
+ swaps(&stuff->color.green);
+ swaps(&stuff->color.blue);
+ swaps(&stuff->color.alpha);
+ SwapRestS(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+ REQUEST(xRenderCreateCursorReq);
+ REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->cid);
+ swapl(&stuff->src);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ swapl(&stuff->transform.matrix11);
+ swapl(&stuff->transform.matrix12);
+ swapl(&stuff->transform.matrix13);
+ swapl(&stuff->transform.matrix21);
+ swapl(&stuff->transform.matrix22);
+ swapl(&stuff->transform.matrix23);
+ swapl(&stuff->transform.matrix31);
+ swapl(&stuff->transform.matrix32);
+ swapl(&stuff->transform.matrix33);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+ REQUEST (xRenderQueryFiltersReq);
+ REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->drawable);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST (xRenderSetPictureFilterReq);
+ REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ swaps(&stuff->nbytes);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+ REQUEST (xRenderCreateAnimCursorReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->cid);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+ REQUEST (xRenderAddTrapsReq);
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->picture);
+ swaps(&stuff->xOff);
+ swaps(&stuff->yOff);
+ SwapRestL(stuff);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+ REQUEST (xRenderCreateSolidFillReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pid);
+ swaps(&stuff->color.alpha);
+ swaps(&stuff->color.red);
+ swaps(&stuff->color.green);
+ swaps(&stuff->color.blue);
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int num)
+{
+ int i;
+ CARD32 *stops;
+ CARD16 *colors;
+
+ stops = (CARD32 *)(stuff);
+ for (i = 0; i < num; ++i) {
+ swapl(stops);
+ ++stops;
+ }
+ colors = (CARD16 *) (stops);
+ for (i = 0; i < 4*num; ++i) {
+ swaps(colors);
+ ++colors;
+ }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+ int len;
+ REQUEST (xRenderCreateLinearGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pid);
+ swapl(&stuff->p1.x);
+ swapl(&stuff->p1.y);
+ swapl(&stuff->p2.x);
+ swapl(&stuff->p2.y);
+ swapl(&stuff->nStops);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+ if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+ int len;
+ REQUEST (xRenderCreateRadialGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pid);
+ swapl(&stuff->inner.x);
+ swapl(&stuff->inner.y);
+ swapl(&stuff->outer.x);
+ swapl(&stuff->outer.y);
+ swapl(&stuff->inner_radius);
+ swapl(&stuff->outer_radius);
+ swapl(&stuff->nStops);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+ if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+ int len;
+ REQUEST (xRenderCreateConicalGradientReq);
+ REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->pid);
+ swapl(&stuff->center.x);
+ swapl(&stuff->center.y);
+ swapl(&stuff->angle);
+ swapl(&stuff->nStops);
+
+ len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+ if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+ if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+ return BadLength;
+
+ swapStops(stuff+1, stuff->nStops);
+
+ return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+#ifndef NXAGENT_SERVER
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < RenderNumberRequests)
+ return (*SProcRenderVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+#endif /* NXAGENT_SERVER */
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+ pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+ if (!pPicture) { \
+ client->errorValue = pid; \
+ return err; \
+ } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+ if (pid == None) \
+ pPicture = 0; \
+ else { \
+ VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+ } \
+} \
+
+int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+ REQUEST(xRenderCreatePictureReq);
+ PanoramiXRes *refDraw, *newPict;
+ int result = Success, j;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+ if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+ client, stuff->drawable, XRC_DRAWABLE, DixWriteAccess)))
+ return BadDrawable;
+ if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+ newPict->type = XRT_PICTURE;
+ newPict->info[0].id = stuff->pid;
+
+ if (refDraw->type == XRT_WINDOW &&
+ stuff->drawable == screenInfo.screens[0]->root->drawable.id)
+ {
+ newPict->u.pict.root = TRUE;
+ }
+ else
+ newPict->u.pict.root = FALSE;
+
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPict->info[j].id = FakeClientID(client->index);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->pid = newPict->info[j].id;
+ stuff->drawable = refDraw->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+ if(result != Success) break;
+ }
+
+ if (result == Success)
+ AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+ else
+ free(newPict);
+
+ return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderChangePictureReq);
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureClipRectanglesReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureTransformReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+ REQUEST(xRenderSetPictureFilterReq);
+ int result = Success, j;
+ PanoramiXRes *pict;
+
+ REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+ if(result != Success) break;
+ }
+
+ return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+ PanoramiXRes *pict;
+ int result = Success, j;
+ REQUEST(xRenderFreePictureReq);
+
+ REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+ client->errorValue = stuff->picture;
+
+ VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess,
+ RenderErrBase + BadPicture);
+
+
+ FOR_NSCREENS_BACKWARD(j) {
+ stuff->picture = pict->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+ if(result != Success) break;
+ }
+
+ /* Since ProcRenderFreePicture is using FreeResource, it will free
+ our resource for us on the last pass through the loop above */
+
+ return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+ PanoramiXRes *src, *msk, *dst;
+ int result = Success, j;
+ xRenderCompositeReq orig;
+ REQUEST(xRenderCompositeReq);
+
+ REQUEST_SIZE_MATCH(xRenderCompositeReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ orig = *stuff;
+
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+ stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+ }
+ if (msk)
+ {
+ stuff->mask = msk->info[j].id;
+ if (msk->u.pict.root)
+ {
+ stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+ stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+ if(result != Success) break;
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderCompositeGlyphsReq);
+ xGlyphElt origElt, *elt;
+ INT16 xSrc, ySrc;
+
+ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+ sizeof (xGlyphElt)))
+ {
+ elt = (xGlyphElt *) (stuff + 1);
+ origElt = *elt;
+ xSrc = stuff->xSrc;
+ ySrc = stuff->ySrc;
+ FOR_NSCREENS_FORWARD(j) {
+ stuff->src = src->info[j].id;
+ if (src->u.pict.root)
+ {
+ stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+ stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+ }
+ stuff->dst = dst->info[j].id;
+ if (dst->u.pict.root)
+ {
+ elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+ elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+ if(result != Success) break;
+ }
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+ PanoramiXRes *dst;
+ int result = Success, j;
+ REQUEST(xRenderFillRectanglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root)
+ {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xRectangle *rects = (xRectangle *) (stuff + 1);
+ int i = extra_len / sizeof (xRectangle);
+
+ while (i--)
+ {
+ rects->x -= x_off;
+ rects->y -= y_off;
+ rects++;
+ }
+ }
+ }
+ stuff->dst = dst->info[j].id;
+ result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+ if(result != Success) break;
+ }
+ free(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTrapezoid *trap = (xTrapezoid *) (stuff + 1);
+ int i = extra_len / sizeof (xTrapezoid);
+
+ while (i--) {
+ trap->top -= y_off;
+ trap->bottom -= y_off;
+ trap->left.p1.x -= x_off;
+ trap->left.p1.y -= y_off;
+ trap->left.p2.x -= x_off;
+ trap->left.p2.y -= y_off;
+ trap->right.p1.x -= x_off;
+ trap->right.p1.y -= y_off;
+ trap->right.p2.x -= x_off;
+ trap->right.p2.y -= y_off;
+ trap++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xTriangle *tri = (xTriangle *) (stuff + 1);
+ int i = extra_len / sizeof (xTriangle);
+
+ while (i--) {
+ tri->p1.x -= x_off;
+ tri->p1.y -= y_off;
+ tri->p2.x -= x_off;
+ tri->p2.y -= y_off;
+ tri->p3.x -= x_off;
+ tri->p3.y -= y_off;
+ tri++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriStripReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderTriFanReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+
+ VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ xPointFixed *fixed = (xPointFixed *) (stuff + 1);
+ int i = extra_len / sizeof (xPointFixed);
+
+ while (i--) {
+ fixed->x -= x_off;
+ fixed->y -= y_off;
+ fixed++;
+ }
+ }
+ }
+
+ stuff->src = src->info[j].id;
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrapezoidsReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+ PanoramiXRes *src, *dst;
+ int result = Success, j;
+ REQUEST(xRenderColorTrianglesReq);
+ char *extra;
+ int extra_len;
+
+ REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+
+ VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+
+ extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len))) {
+ memcpy (extra, stuff + 1, extra_len);
+
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ if (dst->u.pict.root) {
+ int x_off = panoramiXdataPtr[j].x;
+ int y_off = panoramiXdataPtr[j].y;
+
+ if(x_off || y_off) {
+ ....;
+ }
+ }
+
+ stuff->dst = dst->info[j].id;
+ result =
+ (*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+ if(result != Success) break;
+ }
+
+ free(extra);
+ }
+
+ return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+ PanoramiXRes *picture;
+ int result = Success, j;
+ REQUEST(xRenderAddTrapsReq);
+ char *extra;
+ int extra_len;
+ INT16 x_off, y_off;
+
+ REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+ VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+ if (extra_len &&
+ (extra = (char *) malloc (extra_len)))
+ {
+ memcpy (extra, stuff + 1, extra_len);
+ x_off = stuff->xOff;
+ y_off = stuff->yOff;
+ FOR_NSCREENS_FORWARD(j) {
+ if (j) memcpy (stuff + 1, extra, extra_len);
+ stuff->picture = picture->info[j].id;
+
+ if (picture->u.pict.root)
+ {
+ stuff->xOff = x_off + panoramiXdataPtr[j].x;
+ stuff->yOff = y_off + panoramiXdataPtr[j].y;
+ }
+ result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+ if(result != Success) break;
+ }
+ free(extra);
+ }
+
+ return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+ int i;
+
+ XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+ for (i = 0; i < RenderNumberRequests; i++)
+ PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+ /*
+ * Stuff in Xinerama aware request processing hooks
+ */
+ ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+ ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+ ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+ ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+ ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+ ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+ ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+ ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+ ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+ ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+ ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+ ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+ ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+ ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+ int i;
+ for (i = 0; i < RenderNumberRequests; i++)
+ ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif /* PANORAMIX */
diff --git a/nx-X11/programs/Xserver/render/renderedge.c b/nx-X11/programs/Xserver/render/renderedge.c
new file mode 100644
index 000000000..f095038e5
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/renderedge.c
@@ -0,0 +1,202 @@
+/*
+ * $Id: renderedge.c,v 1.4 2005/07/03 07:02:08 daniels Exp $
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "renderedge.h"
+
+/*
+ * Compute the smallest value no less than y which is on a
+ * grid row
+ */
+
+xFixed
+RenderSampleCeilY (xFixed y, int n)
+{
+ xFixed f = xFixedFrac(y);
+ xFixed i = xFixedFloor(y);
+
+ f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
+ if (f > Y_FRAC_LAST(n))
+ {
+ f = Y_FRAC_FIRST(n);
+ i += xFixed1;
+ }
+ return (i | f);
+}
+
+#define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
+
+/*
+ * Compute the largest value no greater than y which is on a
+ * grid row
+ */
+xFixed
+RenderSampleFloorY (xFixed y, int n)
+{
+ xFixed f = xFixedFrac(y);
+ xFixed i = xFixedFloor (y);
+
+ f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
+ if (f < Y_FRAC_FIRST(n))
+ {
+ f = Y_FRAC_LAST(n);
+ i -= xFixed1;
+ }
+ return (i | f);
+}
+
+/*
+ * Step an edge by any amount (including negative values)
+ */
+void
+RenderEdgeStep (RenderEdge *e, int n)
+{
+ xFixed_48_16 ne;
+
+ e->x += n * e->stepx;
+
+ ne = e->e + n * (xFixed_48_16) e->dx;
+
+ if (n >= 0)
+ {
+ if (ne > 0)
+ {
+ int nx = (ne + e->dy - 1) / e->dy;
+ e->e = ne - nx * (xFixed_48_16) e->dy;
+ e->x += nx * e->signdx;
+ }
+ }
+ else
+ {
+ if (ne <= -e->dy)
+ {
+ int nx = (-ne) / e->dy;
+ e->e = ne + nx * (xFixed_48_16) e->dy;
+ e->x -= nx * e->signdx;
+ }
+ }
+}
+
+/*
+ * A private routine to initialize the multi-step
+ * elements of an edge structure
+ */
+static void
+_RenderEdgeMultiInit (RenderEdge *e, int n, xFixed *stepx_p, xFixed *dx_p)
+{
+ xFixed stepx;
+ xFixed_48_16 ne;
+
+ ne = n * (xFixed_48_16) e->dx;
+ stepx = n * e->stepx;
+ if (ne > 0)
+ {
+ int nx = ne / e->dy;
+ ne -= nx * e->dy;
+ stepx += nx * e->signdx;
+ }
+ *dx_p = ne;
+ *stepx_p = stepx;
+}
+
+/*
+ * Initialize one edge structure given the line endpoints and a
+ * starting y value
+ */
+void
+RenderEdgeInit (RenderEdge *e,
+ int n,
+ xFixed y_start,
+ xFixed x_top,
+ xFixed y_top,
+ xFixed x_bot,
+ xFixed y_bot)
+{
+ xFixed dx, dy;
+
+ e->x = x_top;
+ e->e = 0;
+ dx = x_bot - x_top;
+ dy = y_bot - y_top;
+ e->dy = dy;
+ e->dx = 0;
+ if (dy)
+ {
+ if (dx >= 0)
+ {
+ e->signdx = 1;
+ e->stepx = dx / dy;
+ e->dx = dx % dy;
+ e->e = -dy;
+ }
+ else
+ {
+ e->signdx = -1;
+ e->stepx = -(-dx / dy);
+ e->dx = -dx % dy;
+ e->e = 0;
+ }
+
+ _RenderEdgeMultiInit (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
+ _RenderEdgeMultiInit (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
+ }
+ RenderEdgeStep (e, y_start - y_top);
+}
+
+/*
+ * Initialize one edge structure given a line, starting y value
+ * and a pixel offset for the line
+ */
+void
+RenderLineFixedEdgeInit (RenderEdge *e,
+ int n,
+ xFixed y,
+ xLineFixed *line,
+ int x_off,
+ int y_off)
+{
+ xFixed x_off_fixed = IntToxFixed(x_off);
+ xFixed y_off_fixed = IntToxFixed(y_off);
+ xPointFixed *top, *bot;
+
+ if (line->p1.y <= line->p2.y)
+ {
+ top = &line->p1;
+ bot = &line->p2;
+ }
+ else
+ {
+ top = &line->p2;
+ bot = &line->p1;
+ }
+ RenderEdgeInit (e, n, y,
+ top->x + x_off_fixed,
+ top->y + y_off_fixed,
+ bot->x + x_off_fixed,
+ bot->y + y_off_fixed);
+}
+
diff --git a/nx-X11/programs/Xserver/render/renderedge.h b/nx-X11/programs/Xserver/render/renderedge.h
new file mode 100644
index 000000000..bfd19fa93
--- /dev/null
+++ b/nx-X11/programs/Xserver/render/renderedge.h
@@ -0,0 +1,120 @@
+/*
+ * $Id: renderedge.h,v 1.4 2005/08/24 11:18:33 daniels Exp $
+ *
+ * Copyright © 2004 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _RENDEREDGE_H_
+#define _RENDEREDGE_H_
+
+#include "picturestr.h"
+
+#define MAX_ALPHA(n) ((1 << (n)) - 1)
+#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1)
+#define N_X_FRAC(n) ((1 << ((n)/2)) + 1)
+
+#define STEP_Y_SMALL(n) (xFixed1 / N_Y_FRAC(n))
+#define STEP_Y_BIG(n) (xFixed1 - (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n))
+
+#define Y_FRAC_FIRST(n) (STEP_Y_SMALL(n) / 2)
+#define Y_FRAC_LAST(n) (Y_FRAC_FIRST(n) + (N_Y_FRAC(n) - 1) * STEP_Y_SMALL(n))
+
+#define STEP_X_SMALL(n) (xFixed1 / N_X_FRAC(n))
+#define STEP_X_BIG(n) (xFixed1 - (N_X_FRAC(n) - 1) * STEP_X_SMALL(n))
+
+#define X_FRAC_FIRST(n) (STEP_X_SMALL(n) / 2)
+#define X_FRAC_LAST(n) (X_FRAC_FIRST(n) + (N_X_FRAC(n) - 1) * STEP_X_SMALL(n))
+
+#define RenderSamplesX(x,n) ((n) == 1 ? 0 : (xFixedFrac (x) + X_FRAC_FIRST(n)) / STEP_X_SMALL(n))
+
+/*
+ * An edge structure. This represents a single polygon edge
+ * and can be quickly stepped across small or large gaps in the
+ * sample grid
+ */
+
+typedef struct {
+ xFixed x;
+ xFixed e;
+ xFixed stepx;
+ xFixed signdx;
+ xFixed dy;
+ xFixed dx;
+
+ xFixed stepx_small;
+ xFixed stepx_big;
+ xFixed dx_small;
+ xFixed dx_big;
+} RenderEdge;
+
+/*
+ * Step across a small sample grid gap
+ */
+#define RenderEdgeStepSmall(edge) { \
+ edge->x += edge->stepx_small; \
+ edge->e += edge->dx_small; \
+ if (edge->e > 0) \
+ { \
+ edge->e -= edge->dy; \
+ edge->x += edge->signdx; \
+ } \
+}
+
+/*
+ * Step across a large sample grid gap
+ */
+#define RenderEdgeStepBig(edge) { \
+ edge->x += edge->stepx_big; \
+ edge->e += edge->dx_big; \
+ if (edge->e > 0) \
+ { \
+ edge->e -= edge->dy; \
+ edge->x += edge->signdx; \
+ } \
+}
+
+xFixed
+RenderSampleCeilY (xFixed y, int bpp);
+
+xFixed
+RenderSampleFloorY (xFixed y, int bpp);
+
+void
+RenderEdgeStep (RenderEdge *e, int n);
+
+void
+RenderEdgeInit (RenderEdge *e,
+ int bpp,
+ xFixed y_start,
+ xFixed x_top,
+ xFixed y_top,
+ xFixed x_bot,
+ xFixed y_bot);
+
+void
+RenderLineFixedEdgeInit (RenderEdge *e,
+ int bpp,
+ xFixed y,
+ xLineFixed *line,
+ int x_off,
+ int y_off);
+
+#endif /* _RENDEREDGE_H_ */
diff --git a/nx-X11/programs/Xserver/xfixes/Imakefile b/nx-X11/programs/Xserver/xfixes/Imakefile
new file mode 100644
index 000000000..83e368488
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/Imakefile
@@ -0,0 +1,28 @@
+#include <Server.tmpl>
+
+ NULL =
+
+ SRCS = cursor.c region.c saveset.c select.c xfixes.c
+
+ OBJS = cursor.o region.o saveset.o select.o xfixes.o
+
+ INCLUDES = -I. -I../include -I../Xext -I../fixes -I../render \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ `pkg-config --cflags-only-I pixman-1`
+
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+ DEFINES = \
+ $(NX_DEFINES) \
+ $(NULL)
+
+NormalLibraryTarget(xfixes,$(OBJS))
+NormalLibraryObjectRule()
+LintLibraryTarget(xfixes,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/xfixes/cursor.c b/nx-X11/programs/Xserver/xfixes/cursor.c
new file mode 100644
index 000000000..00a912be3
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/cursor.c
@@ -0,0 +1,740 @@
+/*
+ * $Id: cursor.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xfixesint.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixevents.h"
+#include "servermd.h"
+#include "inputstr.h"
+#include "windowstr.h"
+
+static RESTYPE CursorClientType;
+static RESTYPE CursorWindowType;
+static int CursorScreenPrivateIndex = -1;
+static int CursorGeneration;
+static CursorPtr CursorCurrent;
+
+#define VERIFY_CURSOR(pCursor, cursor, client, access) { \
+ pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \
+ RT_CURSOR, (access)); \
+ if (!pCursor) { \
+ (client)->errorValue = (cursor); \
+ return BadCursor; \
+ } \
+}
+
+/*
+ * There is a global list of windows selecting for cursor events
+ */
+
+typedef struct _CursorEvent *CursorEventPtr;
+
+typedef struct _CursorEvent {
+ CursorEventPtr next;
+ CARD32 eventMask;
+ ClientPtr pClient;
+ WindowPtr pWindow;
+ XID clientResource;
+} CursorEventRec;
+
+static CursorEventPtr cursorEvents;
+
+/*
+ * Wrap DisplayCursor to catch cursor change events
+ */
+
+typedef struct _CursorScreen {
+ DisplayCursorProcPtr DisplayCursor;
+ CloseScreenProcPtr CloseScreen;
+} CursorScreenRec, *CursorScreenPtr;
+
+#define GetCursorScreen(s) ((CursorScreenPtr) ((s)->devPrivates[CursorScreenPrivateIndex].ptr))
+#define GetCursorScreenIfSet(s) ((CursorScreenPrivateIndex != -1) ? GetCursorScreen(s) : NULL)
+#define SetCursorScreen(s,p) ((s)->devPrivates[CursorScreenPrivateIndex].ptr = (void *) (p))
+#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
+
+static Bool
+CursorDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ Bool ret;
+
+ Unwrap (cs, pScreen, DisplayCursor);
+ ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
+ if (pCursor != CursorCurrent)
+ {
+ CursorEventPtr e;
+
+ CursorCurrent = pCursor;
+ for (e = cursorEvents; e; e = e->next)
+ {
+ if ((e->eventMask & XFixesDisplayCursorNotifyMask))
+ {
+ xXFixesCursorNotifyEvent ev;
+ ev.type = XFixesEventBase + XFixesCursorNotify;
+ ev.subtype = XFixesDisplayCursorNotify;
+ ev.window = e->pWindow->drawable.id;
+ ev.cursorSerial = pCursor->serialNumber;
+ ev.timestamp = currentTime.milliseconds;
+ ev.name = pCursor->name;
+ WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
+ }
+ }
+ }
+ Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
+ return ret;
+}
+
+static Bool
+CursorCloseScreen (ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen (pScreen);
+ Bool ret;
+
+ Unwrap (cs, pScreen, CloseScreen);
+ Unwrap (cs, pScreen, DisplayCursor);
+ ret = (*pScreen->CloseScreen) (pScreen);
+ free (cs);
+ if (screenInfo.numScreens <= 1)
+ CursorScreenPrivateIndex = -1;
+ return ret;
+}
+
+#define CursorAllEvents (XFixesDisplayCursorNotifyMask)
+
+static int
+XFixesSelectCursorInput (ClientPtr pClient,
+ WindowPtr pWindow,
+ CARD32 eventMask)
+{
+ CursorEventPtr *prev, e;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e->pClient == pClient &&
+ e->pWindow == pWindow)
+ {
+ break;
+ }
+ }
+ if (!eventMask)
+ {
+ if (e)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ return Success;
+ }
+ if (!e)
+ {
+ e = (CursorEventPtr) malloc (sizeof (CursorEventRec));
+ if (!e)
+ return BadAlloc;
+
+ e->next = 0;
+ e->pClient = pClient;
+ e->pWindow = pWindow;
+ e->clientResource = FakeClientID(pClient->index);
+
+ /*
+ * Add a resource hanging from the window to
+ * catch window destroy
+ */
+ if (!LookupIDByType(pWindow->drawable.id, CursorWindowType))
+ if (!AddResource (pWindow->drawable.id, CursorWindowType,
+ (void *) pWindow))
+ {
+ free (e);
+ return BadAlloc;
+ }
+
+ if (!AddResource (e->clientResource, CursorClientType, (void *) e))
+ return BadAlloc;
+
+ *prev = e;
+ }
+ e->eventMask = eventMask;
+ return Success;
+}
+
+int
+ProcXFixesSelectCursorInput (ClientPtr client)
+{
+ REQUEST (xXFixesSelectCursorInputReq);
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (stuff->eventMask & ~CursorAllEvents)
+ {
+ client->errorValue = stuff->eventMask;
+ return( BadValue );
+ }
+ return XFixesSelectCursorInput (client, pWin, stuff->eventMask);
+}
+
+static int
+GetBit (unsigned char *line, int x)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (*line & mask)
+ return 1;
+ return 0;
+}
+
+int
+SProcXFixesSelectCursorInput (ClientPtr client)
+{
+ REQUEST(xXFixesSelectCursorInputReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->eventMask);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+void
+SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
+ xXFixesCursorNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->cursorSerial, to->cursorSerial);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->name, to->name);
+}
+
+static void
+CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
+{
+ int width = pCursor->bits->width;
+ int height = pCursor->bits->height;
+ int npixels = width * height;
+
+#ifdef ARGB_CURSOR
+ if (pCursor->bits->argb)
+ memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
+ else
+#endif
+ {
+ unsigned char *srcLine = pCursor->bits->source;
+ unsigned char *mskLine = pCursor->bits->mask;
+ int stride = BitmapBytePad (width);
+ int x, y;
+ CARD32 fg, bg;
+
+ fg = (0xff000000 |
+ ((pCursor->foreRed & 0xff00) << 8) |
+ (pCursor->foreGreen & 0xff00) |
+ (pCursor->foreBlue >> 8));
+ bg = (0xff000000 |
+ ((pCursor->backRed & 0xff00) << 8) |
+ (pCursor->backGreen & 0xff00) |
+ (pCursor->backBlue >> 8));
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ if (GetBit (mskLine, x))
+ {
+ if (GetBit (srcLine, x))
+ *image++ = fg;
+ else
+ *image++ = bg;
+ }
+ else
+ *image++ = 0;
+ }
+ srcLine += stride;
+ mskLine += stride;
+ }
+ }
+}
+
+int
+ProcXFixesGetCursorImage (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageReq); */
+ xXFixesGetCursorImageReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels;
+ int width, height;
+ int x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
+ pCursor = CursorCurrent;
+ if (!pCursor)
+ return BadCursor;
+ GetSpritePosition (&x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ rep = malloc (sizeof (xXFixesGetCursorImageReply) +
+ npixels * sizeof (CARD32));
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels;
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage(pCursor, image);
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->x);
+ swaps(&rep->y);
+ swaps(&rep->width);
+ swaps(&rep->height);
+ swaps(&rep->xhot);
+ swaps(&rep->yhot);
+ swapl(&rep->cursorSerial);
+ SwapLongs(image, npixels);
+ }
+ WriteToClient(client, sizeof (xXFixesGetCursorImageReply) +
+ (npixels << 2), (char *) rep);
+ free (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImage (ClientPtr client)
+{
+ REQUEST(xXFixesGetCursorImageReq);
+ swaps(&stuff->length);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ char *tchar;
+ REQUEST(xXFixesSetCursorNameReq);
+ Atom atom;
+
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, DixWriteAccess);
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom (tchar, stuff->nbytes, TRUE);
+ if (atom == BAD_RESOURCE)
+ return BadAlloc;
+
+ pCursor->name = atom;
+ return(client->noClientException);
+}
+
+int
+SProcXFixesSetCursorName (ClientPtr client)
+{
+ REQUEST(xXFixesSetCursorNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ swapl(&stuff->cursor);
+ swaps(&stuff->nbytes);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ xXFixesGetCursorNameReply reply;
+ REQUEST(xXFixesGetCursorNameReq);
+ const char *str;
+ int len;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, DixReadAccess);
+ if (pCursor->name)
+ str = NameForAtom (pCursor->name);
+ else
+ str = "";
+ len = strlen (str);
+
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = pCursor->name;
+ reply.nbytes = len;
+ if (client->swapped) {
+ swaps(&reply.sequenceNumber);
+ swapl(&reply.length);
+ swapl(&reply.atom);
+ swaps(&reply.nbytes);
+ }
+ WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
+ WriteToClient(client, len, str);
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesGetCursorName (ClientPtr client)
+{
+ REQUEST(xXFixesSetCursorNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ swapl(&stuff->cursor);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageAndNameReq); */
+ xXFixesGetCursorImageAndNameReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels;
+ const char *name;
+ int nbytes, nbytesRound;
+ int width, height;
+ int x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
+ pCursor = CursorCurrent;
+ if (!pCursor)
+ return BadCursor;
+ GetSpritePosition (&x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ name = pCursor->name ? NameForAtom (pCursor->name) : "";
+ nbytes = strlen (name);
+ nbytesRound = (nbytes + 3) & ~3;
+ rep = malloc (sizeof (xXFixesGetCursorImageAndNameReply) +
+ npixels * sizeof (CARD32) + nbytesRound);
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels + (nbytesRound >> 2);
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+ rep->cursorName = pCursor->name;
+ rep->nbytes = nbytes;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage(pCursor, image);
+ memcpy((image + npixels), name, nbytes);
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->x);
+ swaps(&rep->y);
+ swaps(&rep->width);
+ swaps(&rep->height);
+ swaps(&rep->xhot);
+ swaps(&rep->yhot);
+ swapl(&rep->cursorSerial);
+ swapl(&rep->cursorName);
+ swaps(&rep->nbytes);
+ SwapLongs(image, npixels);
+ }
+ WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) +
+ (npixels << 2) + nbytesRound, (char *) rep);
+ free (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+ REQUEST(xXFixesGetCursorImageAndNameReq);
+ swaps(&stuff->length);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+/*
+ * Find every cursor reference in the system, ask testCursor
+ * whether it should be replaced with a reference to pCursor.
+ */
+
+typedef Bool (*TestCursorFunc) (CursorPtr pOld, void * closure);
+
+typedef struct {
+ RESTYPE type;
+ TestCursorFunc testCursor;
+ CursorPtr pNew;
+ void * closure;
+} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
+
+static const RESTYPE CursorRestypes[] = {
+ RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR
+};
+
+#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
+
+static Bool
+ReplaceCursorLookup (void * value, XID id, void * closure)
+{
+ ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure;
+ WindowPtr pWin;
+ GrabPtr pGrab;
+ CursorPtr pCursor = 0, *pCursorRef = 0;
+ XID cursor = 0;
+
+ switch (rcl->type) {
+ case RT_WINDOW:
+ pWin = (WindowPtr) value;
+ if (pWin->optional)
+ {
+ pCursorRef = &pWin->optional->cursor;
+ pCursor = *pCursorRef;
+ }
+ break;
+ case RT_PASSIVEGRAB:
+ pGrab = (GrabPtr) value;
+ pCursorRef = &pGrab->cursor;
+ pCursor = *pCursorRef;
+ break;
+ case RT_CURSOR:
+ pCursorRef = 0;
+ pCursor = (CursorPtr) value;
+ cursor = id;
+ break;
+ }
+ if (pCursor && pCursor != rcl->pNew)
+ {
+ if ((*rcl->testCursor) (pCursor, rcl->closure))
+ {
+ rcl->pNew->refcnt++;
+ /* either redirect reference or update resource database */
+ if (pCursorRef)
+ *pCursorRef = rcl->pNew;
+ else
+ ChangeResourceValue (id, RT_CURSOR, rcl->pNew);
+ FreeCursor (pCursor, cursor);
+ }
+ }
+ return FALSE; /* keep walking */
+}
+
+static void
+ReplaceCursor (CursorPtr pCursor,
+ TestCursorFunc testCursor,
+ void * closure)
+{
+ int clientIndex;
+ int resIndex;
+ ReplaceCursorLookupRec rcl;
+
+ /*
+ * Cursors exist only in the resource database, windows and grabs.
+ * All of these are always pointed at by the resource database. Walk
+ * the whole thing looking for cursors
+ */
+ rcl.testCursor = testCursor;
+ rcl.pNew = pCursor;
+ rcl.closure = closure;
+
+ /* for each client */
+ for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++)
+ {
+ if (!clients[clientIndex])
+ continue;
+ for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++)
+ {
+ rcl.type = CursorRestypes[resIndex];
+ /*
+ * This function walks the entire client resource database
+ */
+ LookupClientResourceComplex (clients[clientIndex],
+ rcl.type,
+ ReplaceCursorLookup,
+ (void *) &rcl);
+ }
+ }
+ /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
+ WindowHasNewCursor (screenInfo.screens[0]->root);
+}
+
+static Bool
+TestForCursor (CursorPtr pCursor, void * closure)
+{
+ return (pCursor == (CursorPtr) closure);
+}
+
+int
+ProcXFixesChangeCursor (ClientPtr client)
+{
+ CursorPtr pSource, pDestination;
+ REQUEST(xXFixesChangeCursorReq);
+
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ VERIFY_CURSOR (pSource, stuff->source, client, DixReadAccess);
+ VERIFY_CURSOR (pDestination, stuff->destination, client, DixWriteAccess);
+
+ ReplaceCursor (pSource, TestForCursor, (void *) pDestination);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursor (ClientPtr client)
+{
+ REQUEST(xXFixesChangeCursorReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ swapl(&stuff->source);
+ swapl(&stuff->destination);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static Bool
+TestForCursorName (CursorPtr pCursor, void * closure)
+{
+ Atom *pName = closure;
+ return (pCursor->name == *pName);
+}
+
+int
+ProcXFixesChangeCursorByName (ClientPtr client)
+{
+ CursorPtr pSource;
+ Atom name;
+ char *tchar;
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes);
+ VERIFY_CURSOR(pSource, stuff->source, client, DixReadAccess);
+ tchar = (char *) &stuff[1];
+ name = MakeAtom (tchar, stuff->nbytes, FALSE);
+ if (name)
+ ReplaceCursor (pSource, TestForCursorName, &name);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursorByName (ClientPtr client)
+{
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xXFixesChangeCursorByNameReq);
+ swapl(&stuff->source);
+ swaps(&stuff->nbytes);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static int
+CursorFreeClient (void * data, XID id)
+{
+ CursorEventPtr old = (CursorEventPtr) data;
+ CursorEventPtr *prev, e;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e == old)
+ {
+ *prev = e->next;
+ free (e);
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+CursorFreeWindow (void * data, XID id)
+{
+ WindowPtr pWindow = (WindowPtr) data;
+ CursorEventPtr e, next;
+
+ for (e = cursorEvents; e; e = next)
+ {
+ next = e->next;
+ if (e->pWindow == pWindow)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ }
+ return 1;
+}
+
+Bool
+XFixesCursorInit (void)
+{
+ int i;
+
+ if (CursorGeneration != serverGeneration)
+ {
+ CursorScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (CursorScreenPrivateIndex < 0)
+ return FALSE;
+ CursorGeneration = serverGeneration;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ CursorScreenPtr cs;
+
+ cs = (CursorScreenPtr) malloc (sizeof (CursorScreenRec));
+ if (!cs)
+ return FALSE;
+ Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
+ Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
+ SetCursorScreen (pScreen, cs);
+ }
+ CursorClientType = CreateNewResourceType(CursorFreeClient);
+ CursorWindowType = CreateNewResourceType(CursorFreeWindow);
+ return CursorClientType && CursorWindowType;
+}
+
diff --git a/nx-X11/programs/Xserver/xfixes/region.c b/nx-X11/programs/Xserver/xfixes/region.c
new file mode 100644
index 000000000..31d19b5ff
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/region.c
@@ -0,0 +1,840 @@
+/*
+ * $Id: region.c,v 1.7 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xfixesint.h"
+#include "scrnintstr.h"
+#ifdef RENDER
+#include <picturestr.h>
+extern int RenderErrBase;
+#endif
+#include <regionstr.h>
+#include <gcstruct.h>
+#include <window.h>
+
+RESTYPE RegionResType;
+
+static int
+RegionResFree (void * data, XID id)
+{
+ RegionPtr pRegion = (RegionPtr) data;
+
+ RegionDestroy(pRegion);
+ return Success;
+}
+
+RegionPtr
+XFixesRegionCopy (RegionPtr pRegion)
+{
+ RegionPtr pNew = RegionCreate(RegionExtents(pRegion),
+ RegionNumRects(pRegion));
+ if (!pNew)
+ return 0;
+ if (!RegionCopy(pNew, pRegion))
+ {
+ RegionDestroy(pNew);
+ return 0;
+ }
+ return pNew;
+}
+
+Bool
+XFixesRegionInit (void)
+{
+ RegionResType = CreateNewResourceType(RegionResFree);
+ return TRUE;
+}
+
+int
+ProcXFixesCreateRegion (ClientPtr client)
+{
+ int things;
+ RegionPtr pRegion;
+ REQUEST (xXFixesCreateRegionReq);
+
+ REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq);
+ if (things & 4)
+ return BadLength;
+ things >>= 3;
+
+ pRegion = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
+ if (!pRegion)
+ return BadAlloc;
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegion (ClientPtr client)
+{
+ REQUEST(xXFixesCreateRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
+ swapl(&stuff->region);
+ SwapRestS(stuff);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromBitmap (ClientPtr client)
+{
+ RegionPtr pRegion;
+ PixmapPtr pPixmap;
+ REQUEST (xXFixesCreateRegionFromBitmapReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ pPixmap = (PixmapPtr) SecurityLookupIDByType (client, stuff->bitmap,
+ RT_PIXMAP,
+ DixReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = stuff->bitmap;
+ return BadPixmap;
+ }
+ if (pPixmap->drawable.depth != 1)
+ return BadMatch;
+
+ pRegion = BitmapToRegion(pPixmap->drawable.pScreen, pPixmap);
+
+ if (!pRegion)
+ return BadAlloc;
+
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromBitmap (ClientPtr client)
+{
+ REQUEST(xXFixesCreateRegionFromBitmapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq);
+ swapl(&stuff->region);
+ swapl(&stuff->bitmap);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromWindow (ClientPtr client)
+{
+ RegionPtr pRegion;
+ Bool copy = TRUE;
+ WindowPtr pWin;
+ REQUEST (xXFixesCreateRegionFromWindowReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+ switch (stuff->kind) {
+ case WindowRegionBounding:
+#ifdef SHAPE
+ pRegion = wBoundingShape(pWin);
+ if (!pRegion)
+#endif
+ {
+ pRegion = CreateBoundingShape (pWin);
+ copy = FALSE;
+ }
+ break;
+ case WindowRegionClip:
+#ifdef SHAPE
+ pRegion = wClipShape(pWin);
+ if (!pRegion)
+#endif
+ {
+ pRegion = CreateClipShape (pWin);
+ copy = FALSE;
+ }
+ break;
+ default:
+ client->errorValue = stuff->kind;
+ return BadValue;
+ }
+ if (copy && pRegion)
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromWindow (ClientPtr client)
+{
+ REQUEST(xXFixesCreateRegionFromWindowReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq);
+ swapl(&stuff->region);
+ swapl(&stuff->window);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromGC (ClientPtr client)
+{
+ RegionPtr pRegion, pClip;
+ GCPtr pGC;
+ REQUEST (xXFixesCreateRegionFromGCReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, DixReadAccess);
+
+ switch (pGC->clientClipType) {
+ case CT_PIXMAP:
+ pRegion = BitmapToRegion(pGC->pScreen, (PixmapPtr) pGC->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ case CT_REGION:
+ pClip = (RegionPtr) pGC->clientClip;
+ pRegion = XFixesRegionCopy (pClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ default:
+ return BadImplementation; /* assume sane server bits */
+ }
+
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromGC (ClientPtr client)
+{
+ REQUEST(xXFixesCreateRegionFromGCReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq);
+ swapl(&stuff->region);
+ swapl(&stuff->gc);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromPicture (ClientPtr client)
+{
+#ifdef RENDER
+ RegionPtr pRegion;
+ PicturePtr pPicture;
+ REQUEST (xXFixesCreateRegionFromPictureReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ VERIFY_PICTURE(pPicture, stuff->picture, client, DixReadAccess,
+ RenderErrBase + BadPicture);
+
+ switch (pPicture->clientClipType) {
+ case CT_PIXMAP:
+ pRegion = BitmapToRegion(pPicture->pDrawable->pScreen,
+ (PixmapPtr) pPicture->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ case CT_REGION:
+ pRegion = XFixesRegionCopy ((RegionPtr) pPicture->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ default:
+ return BadImplementation; /* assume sane server bits */
+ }
+
+ if (!AddResource (stuff->region, RegionResType, (void *) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesCreateRegionFromPicture (ClientPtr client)
+{
+ REQUEST(xXFixesCreateRegionFromPictureReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq);
+ swapl(&stuff->region);
+ swapl(&stuff->picture);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesDestroyRegion (ClientPtr client)
+{
+ REQUEST (xXFixesDestroyRegionReq);
+ RegionPtr pRegion;
+
+ REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
+ FreeResource (stuff->region, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+SProcXFixesDestroyRegion (ClientPtr client)
+{
+ REQUEST(xXFixesDestroyRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
+ swapl(&stuff->region);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetRegion (ClientPtr client)
+{
+ int things;
+ RegionPtr pRegion, pNew;
+ REQUEST (xXFixesSetRegionReq);
+
+ REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
+
+ things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq);
+ if (things & 4)
+ return BadLength;
+ things >>= 3;
+
+ pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED);
+ if (!pNew)
+ return BadAlloc;
+ if (!RegionCopy(pRegion, pNew))
+ {
+ RegionDestroy(pNew);
+ return BadAlloc;
+ }
+ RegionDestroy(pNew);
+ return(client->noClientException);
+}
+
+int
+SProcXFixesSetRegion (ClientPtr client)
+{
+ REQUEST(xXFixesSetRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
+ swapl(&stuff->region);
+ SwapRestS(stuff);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCopyRegion (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ REQUEST (xXFixesCopyRegionReq);
+
+ VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
+
+ if (!RegionCopy(pDestination, pSource))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCopyRegion (ClientPtr client)
+{
+ REQUEST(xXFixesCopyRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq);
+ swapl(&stuff->source);
+ swapl(&stuff->destination);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCombineRegion (ClientPtr client)
+{
+ RegionPtr pSource1, pSource2, pDestination;
+ int ret = Success;
+ REQUEST (xXFixesCombineRegionReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCombineRegionReq);
+ VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess);
+ VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
+
+ switch (stuff->xfixesReqType) {
+ case X_XFixesUnionRegion:
+ if (!RegionUnion(pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ case X_XFixesIntersectRegion:
+ if (!RegionIntersect(pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ case X_XFixesSubtractRegion:
+ if (!RegionSubtract(pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ }
+
+ if (ret == Success)
+ ret = client->noClientException;
+ return ret;
+}
+
+int
+SProcXFixesCombineRegion (ClientPtr client)
+{
+ REQUEST(xXFixesCombineRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesCombineRegionReq);
+ swapl(&stuff->source1);
+ swapl(&stuff->source2);
+ swapl(&stuff->destination);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesInvertRegion (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ BoxRec bounds;
+ int ret = Success;
+ REQUEST(xXFixesInvertRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
+ VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
+
+ /* Compute bounds, limit to 16 bits */
+ bounds.x1 = stuff->x;
+ bounds.y1 = stuff->y;
+ if ((int) stuff->x + (int) stuff->width > MAXSHORT)
+ bounds.x2 = MAXSHORT;
+ else
+ bounds.x2 = stuff->x + stuff->width;
+
+ if ((int) stuff->y + (int) stuff->height > MAXSHORT)
+ bounds.y2 = MAXSHORT;
+ else
+ bounds.y2 = stuff->y + stuff->height;
+
+ if (!RegionInverse(pDestination, pSource, &bounds))
+ ret = BadAlloc;
+
+ if (ret == Success)
+ ret = client->noClientException;
+ return ret;
+}
+
+int
+SProcXFixesInvertRegion (ClientPtr client)
+{
+ REQUEST(xXFixesInvertRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
+ swapl(&stuff->source);
+ swaps(&stuff->x);
+ swaps(&stuff->y);
+ swaps(&stuff->width);
+ swaps(&stuff->height);
+ swapl(&stuff->destination);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesTranslateRegion (ClientPtr client)
+{
+ RegionPtr pRegion;
+ REQUEST(xXFixesTranslateRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
+
+ RegionTranslate(pRegion, stuff->dx, stuff->dy);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesTranslateRegion (ClientPtr client)
+{
+ REQUEST(xXFixesTranslateRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
+ swapl(&stuff->region);
+ swaps(&stuff->dx);
+ swaps(&stuff->dy);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesRegionExtents (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ REQUEST(xXFixesRegionExtentsReq);
+
+ REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
+ VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
+
+ RegionReset(pDestination, RegionExtents(pSource));
+
+ return (client->noClientException);
+}
+
+int
+SProcXFixesRegionExtents (ClientPtr client)
+{
+ REQUEST(xXFixesRegionExtentsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
+ swapl(&stuff->source);
+ swapl(&stuff->destination);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesFetchRegion (ClientPtr client)
+{
+ RegionPtr pRegion;
+ xXFixesFetchRegionReply *reply;
+ xRectangle *pRect;
+ BoxPtr pExtent;
+ BoxPtr pBox;
+ int i, nBox;
+ REQUEST(xXFixesFetchRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess);
+
+ pExtent = RegionExtents(pRegion);
+ pBox = RegionRects (pRegion);
+ nBox = RegionNumRects (pRegion);
+
+ reply = malloc (sizeof (xXFixesFetchRegionReply) +
+ nBox * sizeof (xRectangle));
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = nBox << 1;
+ reply->x = pExtent->x1;
+ reply->y = pExtent->y1;
+ reply->width = pExtent->x2 - pExtent->x1;
+ reply->height = pExtent->y2 - pExtent->y1;
+
+ pRect = (xRectangle *) (reply + 1);
+ for (i = 0; i < nBox; i++)
+ {
+ pRect[i].x = pBox[i].x1;
+ pRect[i].y = pBox[i].y1;
+ pRect[i].width = pBox[i].x2 - pBox[i].x1;
+ pRect[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+ if (client->swapped) {
+ swaps(&reply->sequenceNumber);
+ swapl(&reply->length);
+ swaps(&reply->x);
+ swaps(&reply->y);
+ swaps(&reply->width);
+ swaps(&reply->height);
+ SwapShorts((INT16 *) pRect, nBox * 4);
+ }
+ WriteToClient(client, sizeof (xXFixesFetchRegionReply) +
+ nBox * sizeof (xRectangle), reply);
+ free (reply);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesFetchRegion (ClientPtr client)
+{
+ REQUEST(xXFixesFetchRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
+ swapl(&stuff->region);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetGCClipRegion (ClientPtr client)
+{
+ GCPtr pGC;
+ RegionPtr pRegion;
+ XID vals[2];
+ REQUEST(xXFixesSetGCClipRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, DixWriteAccess);
+ VERIFY_REGION_OR_NONE (pRegion, stuff->region, client, DixReadAccess);
+
+ if (pRegion)
+ {
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ }
+
+ vals[0] = stuff->xOrigin;
+ vals[1] = stuff->yOrigin;
+ DoChangeGC (pGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (*pGC->funcs->ChangeClip)(pGC, pRegion ? CT_REGION : CT_NONE, (void *)pRegion, 0);
+
+ return (client->noClientException);
+}
+
+int
+SProcXFixesSetGCClipRegion (ClientPtr client)
+{
+ REQUEST(xXFixesSetGCClipRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
+ swapl(&stuff->gc);
+ swapl(&stuff->region);
+ swaps(&stuff->xOrigin);
+ swaps(&stuff->yOrigin);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+typedef RegionPtr (*CreateDftPtr)(WindowPtr pWin);
+
+int
+ProcXFixesSetWindowShapeRegion (ClientPtr client)
+{
+#ifdef SHAPE
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ RegionPtr pRegion;
+ RegionPtr *pDestRegion;
+ REQUEST(xXFixesSetWindowShapeRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
+ pWin = (WindowPtr) LookupIDByType (stuff->dest, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->dest;
+ return BadWindow;
+ }
+ VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess);
+ pScreen = pWin->drawable.pScreen;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ case ShapeClip:
+ case ShapeInput:
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ if (pRegion)
+ {
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ switch (stuff->destKind) {
+ default:
+ case ShapeBounding:
+ pDestRegion = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ pDestRegion = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ pDestRegion = &pWin->optional->inputShape;
+ break;
+ }
+ if (stuff->xOff || stuff->yOff)
+ RegionTranslate(pRegion, stuff->xOff, stuff->yOff);
+ }
+ else
+ {
+ if (pWin->optional)
+ {
+ switch (stuff->destKind) {
+ default:
+ case ShapeBounding:
+ pDestRegion = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ pDestRegion = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ pDestRegion = &pWin->optional->inputShape;
+ break;
+ }
+ }
+ else
+ pDestRegion = &pRegion; /* a NULL region pointer */
+ }
+ if (*pDestRegion)
+ RegionDestroy(*pDestRegion);
+ *pDestRegion = pRegion;
+ (*pScreen->SetShape) (pWin);
+ SendShapeNotify (pWin, stuff->destKind);
+ return (client->noClientException);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesSetWindowShapeRegion (ClientPtr client)
+{
+ REQUEST(xXFixesSetWindowShapeRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
+ swapl(&stuff->dest);
+ swaps(&stuff->xOff);
+ swaps(&stuff->yOff);
+ swapl(&stuff->region);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetPictureClipRegion (ClientPtr client)
+{
+#ifdef RENDER
+ PicturePtr pPicture;
+ RegionPtr pRegion;
+ REQUEST(xXFixesSetPictureClipRegionReq);
+
+ REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq);
+ VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess,
+ RenderErrBase + BadPicture);
+ VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess);
+
+ return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin,
+ pRegion);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesSetPictureClipRegion (ClientPtr client)
+{
+ REQUEST(xXFixesSetPictureClipRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq);
+ swapl(&stuff->picture);
+ swapl(&stuff->region);
+ swaps(&stuff->xOrigin);
+ swaps(&stuff->yOrigin);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesExpandRegion (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ int ret = Success;
+ REQUEST (xXFixesExpandRegionReq);
+ BoxPtr pTmp;
+ BoxPtr pSrc;
+ int nBoxes;
+ int i;
+
+ REQUEST_SIZE_MATCH (xXFixesExpandRegionReq);
+ VERIFY_REGION(pSource, stuff->source, client, DixReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess);
+
+ nBoxes = RegionNumRects(pSource);
+ pSrc = RegionRects(pSource);
+ if (nBoxes)
+ {
+ pTmp = malloc (nBoxes * sizeof (BoxRec));
+ if (!pTmp)
+ return BadAlloc;
+ for (i = 0; i < nBoxes; i++)
+ {
+ pTmp[i].x1 = pSrc[i].x1 - stuff->left;
+ pTmp[i].x2 = pSrc[i].x2 + stuff->right;
+ pTmp[i].y1 = pSrc[i].y1 - stuff->top;
+ pTmp[i].y2 = pSrc[i].y2 + stuff->bottom;
+ }
+ RegionEmpty(pDestination);
+ for (i = 0; i < nBoxes; i++)
+ {
+ RegionRec r;
+ RegionInit(&r, &pTmp[i], 0);
+ RegionUnion(pDestination, pDestination, &r);
+ }
+ }
+ if (ret == Success)
+ ret = client->noClientException;
+ return ret;
+}
+
+int
+SProcXFixesExpandRegion (ClientPtr client)
+{
+ REQUEST(xXFixesExpandRegionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xXFixesExpandRegionReq);
+ swapl(&stuff->source);
+ swapl(&stuff->destination);
+ swaps(&stuff->left);
+ swaps(&stuff->right);
+ swaps(&stuff->top);
+ swaps(&stuff->bottom);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
diff --git a/nx-X11/programs/Xserver/xfixes/saveset.c b/nx-X11/programs/Xserver/xfixes/saveset.c
new file mode 100644
index 000000000..0a5b2b8da
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/saveset.c
@@ -0,0 +1,78 @@
+/*
+ * $Id: saveset.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xfixesint.h"
+
+int
+ProcXFixesChangeSaveSet(ClientPtr client)
+{
+ Bool toRoot, remap;
+ int result;
+ WindowPtr pWin;
+ REQUEST(xXFixesChangeSaveSetReq);
+
+ REQUEST_SIZE_MATCH(xXFixesChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode != SetModeInsert) && (stuff->mode != SetModeDelete))
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+ if ((stuff->target != SaveSetNearest) && (stuff->target != SaveSetRoot))
+ {
+ client->errorValue = stuff->target;
+ return( BadValue );
+ }
+ if ((stuff->map != SaveSetMap) && (stuff->map != SaveSetUnmap))
+ {
+ client->errorValue = stuff->map;
+ return( BadValue );
+ }
+ toRoot = (stuff->target == SaveSetRoot);
+ remap = (stuff->map == SaveSetMap);
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, toRoot, remap);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+SProcXFixesChangeSaveSet(ClientPtr client)
+{
+ REQUEST(xXFixesChangeSaveSetReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ return ProcXFixesChangeSaveSet(client);
+}
diff --git a/nx-X11/programs/Xserver/xfixes/select.c b/nx-X11/programs/Xserver/xfixes/select.c
new file mode 100644
index 000000000..b21301d1c
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/select.c
@@ -0,0 +1,281 @@
+/*
+ * $Id: select.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xfixesint.h"
+
+static RESTYPE SelectionClientType, SelectionWindowType;
+static Bool SelectionCallbackRegistered = FALSE;
+
+/*
+ * There is a global list of windows selecting for selection events
+ * on every selection. This should be plenty efficient for the
+ * expected usage, if it does become a problem, it should be easily
+ * replaced with a hash table of some kind keyed off the selection atom
+ */
+
+typedef struct _SelectionEvent *SelectionEventPtr;
+
+typedef struct _SelectionEvent {
+ SelectionEventPtr next;
+ Atom selection;
+ CARD32 eventMask;
+ ClientPtr pClient;
+ WindowPtr pWindow;
+ XID clientResource;
+} SelectionEventRec;
+
+static SelectionEventPtr selectionEvents;
+
+static void
+XFixesSelectionCallback (CallbackListPtr *callbacks, void * data, void * args)
+{
+ SelectionEventPtr e;
+ SelectionInfoRec *info = (SelectionInfoRec *) args;
+ Selection *selection = info->selection;
+ int subtype;
+ CARD32 eventMask;
+
+ switch (info->kind) {
+ case SelectionSetOwner:
+ subtype = XFixesSetSelectionOwnerNotify;
+ eventMask = XFixesSetSelectionOwnerNotifyMask;
+ break;
+ case SelectionWindowDestroy:
+ subtype = XFixesSelectionWindowDestroyNotify;
+ eventMask = XFixesSelectionWindowDestroyNotifyMask;
+ break;
+ case SelectionClientClose:
+ subtype = XFixesSelectionClientCloseNotify;
+ eventMask = XFixesSelectionClientCloseNotifyMask;
+ break;
+ default:
+ return;
+ }
+ for (e = selectionEvents; e; e = e->next)
+ {
+ if (e->selection == selection->selection &&
+ (e->eventMask & eventMask))
+ {
+ xXFixesSelectionNotifyEvent ev;
+
+ memset(&ev, 0, sizeof(xXFixesSelectionNotifyEvent));
+
+ ev.type = XFixesEventBase + XFixesSelectionNotify;
+ ev.subtype = subtype;
+ ev.window = e->pWindow->drawable.id;
+ if (subtype == XFixesSetSelectionOwnerNotify)
+ ev.owner = selection->window;
+ else
+ ev.owner = 0;
+ ev.selection = e->selection;
+ ev.timestamp = currentTime.milliseconds;
+ ev.selectionTimestamp = selection->lastTimeChanged.milliseconds;
+ WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
+ }
+ }
+}
+
+static Bool
+CheckSelectionCallback (void)
+{
+ if (selectionEvents)
+ {
+ if (!SelectionCallbackRegistered)
+ {
+ if (!AddCallback (&SelectionCallback, XFixesSelectionCallback, NULL))
+ return FALSE;
+ SelectionCallbackRegistered = TRUE;
+ }
+ }
+ else
+ {
+ if (SelectionCallbackRegistered)
+ {
+ DeleteCallback (&SelectionCallback, XFixesSelectionCallback, NULL);
+ SelectionCallbackRegistered = FALSE;
+ }
+ }
+ return TRUE;
+}
+
+#define SelectionAllEvents (XFixesSetSelectionOwnerNotifyMask |\
+ XFixesSelectionWindowDestroyNotifyMask |\
+ XFixesSelectionClientCloseNotifyMask)
+
+static int
+XFixesSelectSelectionInput (ClientPtr pClient,
+ Atom selection,
+ WindowPtr pWindow,
+ CARD32 eventMask)
+{
+ SelectionEventPtr *prev, e;
+
+ for (prev = &selectionEvents; (e = *prev); prev = &e->next)
+ {
+ if (e->selection == selection &&
+ e->pClient == pClient &&
+ e->pWindow == pWindow)
+ {
+ break;
+ }
+ }
+ if (!eventMask)
+ {
+ if (e)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ return Success;
+ }
+ if (!e)
+ {
+ e = (SelectionEventPtr) malloc (sizeof (SelectionEventRec));
+ if (!e)
+ return BadAlloc;
+
+ e->next = 0;
+ e->selection = selection;
+ e->pClient = pClient;
+ e->pWindow = pWindow;
+ e->clientResource = FakeClientID(pClient->index);
+
+ /*
+ * Add a resource hanging from the window to
+ * catch window destroy
+ */
+ if (!LookupIDByType(pWindow->drawable.id, SelectionWindowType))
+ if (!AddResource (pWindow->drawable.id, SelectionWindowType,
+ (void *) pWindow))
+ {
+ free (e);
+ return BadAlloc;
+ }
+
+ if (!AddResource (e->clientResource, SelectionClientType, (void *) e))
+ return BadAlloc;
+
+ *prev = e;
+ if (!CheckSelectionCallback ())
+ {
+ FreeResource (e->clientResource, 0);
+ return BadAlloc;
+ }
+ }
+ e->eventMask = eventMask;
+ return Success;
+}
+
+int
+ProcXFixesSelectSelectionInput (ClientPtr client)
+{
+ REQUEST (xXFixesSelectSelectionInputReq);
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH (xXFixesSelectSelectionInputReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ DixReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (stuff->eventMask & ~SelectionAllEvents)
+ {
+ client->errorValue = stuff->eventMask;
+ return( BadValue );
+ }
+ return XFixesSelectSelectionInput (client, stuff->selection,
+ pWin, stuff->eventMask);
+}
+
+int
+SProcXFixesSelectSelectionInput (ClientPtr client)
+{
+ REQUEST(xXFixesSelectSelectionInputReq);
+
+ REQUEST_SIZE_MATCH(xXFixesSelectSelectionInputReq);
+ swaps(&stuff->length);
+ swapl(&stuff->window);
+ swapl(&stuff->selection);
+ swapl(&stuff->eventMask);
+ return ProcXFixesSelectSelectionInput(client);
+}
+
+void
+SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
+ xXFixesSelectionNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->owner, to->owner);
+ cpswapl (from->selection, to->selection);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->selectionTimestamp, to->selectionTimestamp);
+}
+
+static int
+SelectionFreeClient (void * data, XID id)
+{
+ SelectionEventPtr old = (SelectionEventPtr) data;
+ SelectionEventPtr *prev, e;
+
+ for (prev = &selectionEvents; (e = *prev); prev = &e->next)
+ {
+ if (e == old)
+ {
+ *prev = e->next;
+ free (e);
+ CheckSelectionCallback ();
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+SelectionFreeWindow (void * data, XID id)
+{
+ WindowPtr pWindow = (WindowPtr) data;
+ SelectionEventPtr e, next;
+
+ for (e = selectionEvents; e; e = next)
+ {
+ next = e->next;
+ if (e->pWindow == pWindow)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ }
+ return 1;
+}
+
+Bool
+XFixesSelectionInit (void)
+{
+ SelectionClientType = CreateNewResourceType(SelectionFreeClient);
+ SelectionWindowType = CreateNewResourceType(SelectionFreeWindow);
+ return SelectionClientType && SelectionWindowType;
+}
diff --git a/nx-X11/programs/Xserver/xfixes/xfixes.c b/nx-X11/programs/Xserver/xfixes/xfixes.c
new file mode 100644
index 000000000..add8d1b0e
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/xfixes.c
@@ -0,0 +1,231 @@
+/*
+ * $Id: xfixes.c,v 1.7 2005/07/03 07:37:35 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xfixesint.h"
+#include "protocol-versions.h"
+
+unsigned char XFixesReqCode;
+int XFixesEventBase;
+int XFixesErrorBase;
+int XFixesClientPrivateIndex;
+
+static int
+ProcXFixesQueryVersion(ClientPtr client)
+{
+ XFixesClientPtr pXFixesClient = GetXFixesClient (client);
+ xXFixesQueryVersionReply rep;
+ REQUEST(xXFixesQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
+ memset(&rep, 0, sizeof(xXFixesQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ } else {
+ rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION;
+ if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION &&
+ stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION)
+ rep.minorVersion = stuff->minorVersion;
+ else
+ rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
+ }
+ pXFixesClient->major_version = rep.majorVersion;
+ pXFixesClient->minor_version = rep.minorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.majorVersion);
+ swapl(&rep.minorVersion);
+ }
+ WriteToClient(client, sizeof(xXFixesQueryVersionReply), &rep);
+ return(client->noClientException);
+}
+
+/* Major version controls available requests */
+static const int version_requests[] = {
+ X_XFixesQueryVersion, /* before client sends QueryVersion */
+ X_XFixesGetCursorImage, /* Version 1 */
+ X_XFixesChangeCursorByName, /* Version 2 */
+ X_XFixesExpandRegion, /* Version 3 */
+};
+
+#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
+
+int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ ProcXFixesQueryVersion,
+ ProcXFixesChangeSaveSet,
+ ProcXFixesSelectSelectionInput,
+ ProcXFixesSelectCursorInput,
+ ProcXFixesGetCursorImage,
+/*************** Version 2 ******************/
+ ProcXFixesCreateRegion,
+ ProcXFixesCreateRegionFromBitmap,
+ ProcXFixesCreateRegionFromWindow,
+ ProcXFixesCreateRegionFromGC,
+ ProcXFixesCreateRegionFromPicture,
+ ProcXFixesDestroyRegion,
+ ProcXFixesSetRegion,
+ ProcXFixesCopyRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesInvertRegion,
+ ProcXFixesTranslateRegion,
+ ProcXFixesRegionExtents,
+ ProcXFixesFetchRegion,
+ ProcXFixesSetGCClipRegion,
+ ProcXFixesSetWindowShapeRegion,
+ ProcXFixesSetPictureClipRegion,
+ ProcXFixesSetCursorName,
+ ProcXFixesGetCursorName,
+ ProcXFixesGetCursorImageAndName,
+ ProcXFixesChangeCursor,
+ ProcXFixesChangeCursorByName,
+/*************** Version 3 ******************/
+ ProcXFixesExpandRegion,
+};
+
+static int
+ProcXFixesDispatch (ClientPtr client)
+{
+ REQUEST(xXFixesReq);
+ XFixesClientPtr pXFixesClient = GetXFixesClient (client);
+
+ if (pXFixesClient->major_version > NUM_VERSION_REQUESTS)
+ return BadRequest;
+ if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
+ return BadRequest;
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static int
+SProcXFixesQueryVersion(ClientPtr client)
+{
+ REQUEST(xXFixesQueryVersionReq);
+
+ swaps(&stuff->length);
+ swapl(&stuff->majorVersion);
+ swapl(&stuff->minorVersion);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ SProcXFixesQueryVersion,
+ SProcXFixesChangeSaveSet,
+ SProcXFixesSelectSelectionInput,
+ SProcXFixesSelectCursorInput,
+ SProcXFixesGetCursorImage,
+/*************** Version 2 ******************/
+ SProcXFixesCreateRegion,
+ SProcXFixesCreateRegionFromBitmap,
+ SProcXFixesCreateRegionFromWindow,
+ SProcXFixesCreateRegionFromGC,
+ SProcXFixesCreateRegionFromPicture,
+ SProcXFixesDestroyRegion,
+ SProcXFixesSetRegion,
+ SProcXFixesCopyRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesInvertRegion,
+ SProcXFixesTranslateRegion,
+ SProcXFixesRegionExtents,
+ SProcXFixesFetchRegion,
+ SProcXFixesSetGCClipRegion,
+ SProcXFixesSetWindowShapeRegion,
+ SProcXFixesSetPictureClipRegion,
+ SProcXFixesSetCursorName,
+ SProcXFixesGetCursorName,
+ SProcXFixesGetCursorImageAndName,
+ SProcXFixesChangeCursor,
+ SProcXFixesChangeCursorByName,
+/*************** Version 3 ******************/
+ SProcXFixesExpandRegion,
+};
+
+static int
+SProcXFixesDispatch (ClientPtr client)
+{
+ REQUEST(xXFixesReq);
+ if (stuff->xfixesReqType >= XFixesNumberRequests)
+ return BadRequest;
+ return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static void
+XFixesClientCallback (CallbackListPtr *list,
+ void *closure,
+ void *data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ XFixesClientPtr pXFixesClient = GetXFixesClient (pClient);
+
+ pXFixesClient->major_version = 0;
+ pXFixesClient->minor_version = 0;
+}
+
+/*ARGSUSED*/
+static void
+XFixesResetProc (ExtensionEntry *extEntry)
+{
+ DeleteCallback (&ClientStateCallback, XFixesClientCallback, 0);
+}
+
+void
+XFixesExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ XFixesClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (XFixesClientPrivateIndex,
+ sizeof (XFixesClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, XFixesClientCallback, 0))
+ return;
+
+ if (XFixesSelectionInit() && XFixesCursorInit () && XFixesRegionInit () &&
+ (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents,
+ XFixesNumberErrors,
+ ProcXFixesDispatch, SProcXFixesDispatch,
+ XFixesResetProc, StandardMinorOpcode)) != 0)
+ {
+ XFixesReqCode = (unsigned char)extEntry->base;
+ XFixesEventBase = extEntry->eventBase;
+ XFixesErrorBase = extEntry->errorBase;
+ EventSwapVector[XFixesEventBase + XFixesSelectionNotify] =
+ (EventSwapPtr) SXFixesSelectionNotifyEvent;
+ EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
+ (EventSwapPtr) SXFixesCursorNotifyEvent;
+ }
+}
diff --git a/nx-X11/programs/Xserver/xfixes/xfixes.h b/nx-X11/programs/Xserver/xfixes/xfixes.h
new file mode 100644
index 000000000..fcd941778
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/xfixes.h
@@ -0,0 +1,54 @@
+/*
+ * $Id: xfixes.h,v 1.6 2005/07/03 07:02:08 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XFIXES_H_
+#define _XFIXES_H_
+
+#include "resource.h"
+
+extern RESTYPE RegionResType;
+extern int XFixesErrorBase;
+
+#define VERIFY_REGION(pRegion, rid, client, mode) { \
+ pRegion = SecurityLookupIDByType (client, rid, RegionResType, mode); \
+ if (!pRegion) { \
+ client->errorValue = rid; \
+ return XFixesErrorBase + BadRegion; \
+ } \
+}
+
+#define VERIFY_REGION_OR_NONE(pRegion, rid, client, mode) { \
+ pRegion = 0; \
+ if (rid) VERIFY_REGION(pRegion, rid, client, mode); \
+}
+
+RegionPtr
+XFixesRegionCopy (RegionPtr pRegion);
+
+
+#endif /* _XFIXES_H_ */
diff --git a/nx-X11/programs/Xserver/xfixes/xfixesint.h b/nx-X11/programs/Xserver/xfixes/xfixesint.h
new file mode 100644
index 000000000..70550f5f1
--- /dev/null
+++ b/nx-X11/programs/Xserver/xfixes/xfixesint.h
@@ -0,0 +1,242 @@
+/*
+ * $Id: xfixesint.h,v 1.7 2005/07/03 08:53:54 daniels Exp $
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XFIXESINT_H_
+#define _XFIXESINT_H_
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <nx-X11/extensions/xfixesproto.h>
+#include "windowstr.h"
+#include "selection.h"
+#include "xfixes.h"
+
+extern unsigned char XFixesReqCode;
+extern int XFixesEventBase;
+extern int XFixesClientPrivateIndex;
+
+typedef struct _XFixesClient {
+ CARD32 major_version;
+ CARD32 minor_version;
+} XFixesClientRec, *XFixesClientPtr;
+
+#define GetXFixesClient(pClient) ((XFixesClientPtr) (pClient)->devPrivates[XFixesClientPrivateIndex].ptr)
+
+extern int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr);
+extern int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr);
+
+/* Initialize extension at server startup time */
+
+void
+XFixesExtensionInit(void);
+
+/* Save set */
+int
+ProcXFixesChangeSaveSet(ClientPtr client);
+
+int
+SProcXFixesChangeSaveSet(ClientPtr client);
+
+/* Selection events */
+int
+ProcXFixesSelectSelectionInput (ClientPtr client);
+
+int
+SProcXFixesSelectSelectionInput (ClientPtr client);
+
+void
+SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
+ xXFixesSelectionNotifyEvent *to);
+Bool
+XFixesSelectionInit (void);
+
+/* Cursor notification */
+Bool
+XFixesCursorInit (void);
+
+int
+ProcXFixesSelectCursorInput (ClientPtr client);
+
+int
+SProcXFixesSelectCursorInput (ClientPtr client);
+
+void
+SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
+ xXFixesCursorNotifyEvent *to);
+
+int
+ProcXFixesGetCursorImage (ClientPtr client);
+
+int
+SProcXFixesGetCursorImage (ClientPtr client);
+
+/* Cursor names (Version 2) */
+
+int
+ProcXFixesSetCursorName (ClientPtr client);
+
+int
+SProcXFixesSetCursorName (ClientPtr client);
+
+int
+ProcXFixesGetCursorName (ClientPtr client);
+
+int
+SProcXFixesGetCursorName (ClientPtr client);
+
+int
+ProcXFixesGetCursorImageAndName (ClientPtr client);
+
+int
+SProcXFixesGetCursorImageAndName (ClientPtr client);
+
+/* Cursor replacement (Version 2) */
+
+int
+ProcXFixesChangeCursor (ClientPtr client);
+
+int
+SProcXFixesChangeCursor (ClientPtr client);
+
+int
+ProcXFixesChangeCursorByName (ClientPtr client);
+
+int
+SProcXFixesChangeCursorByName (ClientPtr client);
+
+/* Region objects (Version 2* */
+Bool
+XFixesRegionInit (void);
+
+int
+ProcXFixesCreateRegion (ClientPtr client);
+
+int
+SProcXFixesCreateRegion (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromBitmap (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromBitmap (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromWindow (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromWindow (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromGC (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromGC (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromPicture (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromPicture (ClientPtr client);
+
+int
+ProcXFixesDestroyRegion (ClientPtr client);
+
+int
+SProcXFixesDestroyRegion (ClientPtr client);
+
+int
+ProcXFixesSetRegion (ClientPtr client);
+
+int
+SProcXFixesSetRegion (ClientPtr client);
+
+int
+ProcXFixesCopyRegion (ClientPtr client);
+
+int
+SProcXFixesCopyRegion (ClientPtr client);
+
+int
+ProcXFixesCombineRegion (ClientPtr client);
+
+int
+SProcXFixesCombineRegion (ClientPtr client);
+
+int
+ProcXFixesInvertRegion (ClientPtr client);
+
+int
+SProcXFixesInvertRegion (ClientPtr client);
+
+int
+ProcXFixesTranslateRegion (ClientPtr client);
+
+int
+SProcXFixesTranslateRegion (ClientPtr client);
+
+int
+ProcXFixesRegionExtents (ClientPtr client);
+
+int
+SProcXFixesRegionExtents (ClientPtr client);
+
+int
+ProcXFixesFetchRegion (ClientPtr client);
+
+int
+SProcXFixesFetchRegion (ClientPtr client);
+
+int
+ProcXFixesSetGCClipRegion (ClientPtr client);
+
+int
+SProcXFixesSetGCClipRegion (ClientPtr client);
+
+int
+ProcXFixesSetWindowShapeRegion (ClientPtr client);
+
+int
+SProcXFixesSetWindowShapeRegion (ClientPtr client);
+
+int
+ProcXFixesSetPictureClipRegion (ClientPtr client);
+
+int
+SProcXFixesSetPictureClipRegion (ClientPtr client);
+
+int
+ProcXFixesExpandRegion (ClientPtr client);
+
+int
+SProcXFixesExpandRegion (ClientPtr client);
+
+#endif /* _XFIXESINT_H_ */
diff --git a/nx-X11/programs/Xserver/xkb/Imakefile b/nx-X11/programs/Xserver/xkb/Imakefile
new file mode 100644
index 000000000..89e042212
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/Imakefile
@@ -0,0 +1,81 @@
+#define SGIHyperOpt
+#include <Server.tmpl>
+
+#if BuildXInputExt
+XKBXI_SRCS = xkbPrOtherEv.c
+XKBXI_OBJS = xkbPrOtherEv.o
+#endif
+
+#ifdef DfltDisableXKB
+XKB_DISABLE = -DXKB_DFLT_DISABLED=1
+#else
+XKB_DISABLE = -DXKB_DFLT_DISABLED=0
+#endif
+
+XKB_DDXDEFS = XkbServerDefines
+
+#if defined(NXAgentServer) && NXAgentServer
+ NX_DEFINES = -DNXAGENT_SERVER
+#endif
+
+#if (defined(XorgServer) && XorgServer)
+XF86INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC)
+ XF86_OBJS = xf86KillSrv.o xf86VT.o xf86Private.o
+#endif
+
+ DDX_SRCS = ddxBeep.c ddxCtrls.c ddxFakeBtn.c ddxFakeMtn.c ddxInit.c \
+ ddxKeyClick.c ddxKillSrv.c ddxLEDs.c ddxVT.c ddxLoad.c \
+ ddxList.c ddxConfig.c ddxDevBtn.c ddxPrivate.c xkbconfig.c
+ DDX_OBJS = ddxBeep.o ddxCtrls.o ddxFakeBtn.o ddxFakeMtn.o ddxInit.o \
+ ddxKeyClick.o ddxKillSrv.o ddxLEDs.o ddxVT.o ddxLoad.o \
+ ddxList.o ddxConfig.o ddxDevBtn.o ddxPrivate.o xkbconfig.o
+ SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \
+ xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \
+ xkmread.c xkbtext.c xkbfmisc.c xkberrs.c xkbout.c maprules.c \
+ XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \
+ $(XKBXI_SRCS) $(DDX_SRCS)
+ OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \
+ xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \
+ xkmread.o xkbtext.o xkbfmisc.o xkberrs.o xkbout.o maprules.o \
+ XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \
+ $(XKBXI_OBJS) $(DDX_OBJS)
+ INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mi $(XF86INCLUDES) \
+ `pkg-config --cflags-only-I pixman-1`
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+DEFINES = $(XKB_DDXDEFS) $(NX_DEFINES)
+XKB_DEFINES = -DXKB_BASE_DIRECTORY=\"$(LIBDIR)/xkb\" $(XKB_DISABLE)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(xkb,$(OBJS))
+LintLibraryTarget(xkb,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#if (defined(XorgServer) && XorgServer)
+ObjectFromSpecialSource(xf86KillSrv,ddxKillSrv,-DXF86DDXACTIONS)
+ObjectFromSpecialSource(xf86VT,ddxVT,-DXF86DDXACTIONS)
+ObjectFromSpecialSource(xf86Private,ddxPrivate,-DXF86DDXACTIONS)
+AllTarget($(XF86_OBJS))
+#endif
+
+SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES))
+
+#if BuildLibraries
+#if UseConfDirForXkb
+LinkConfDirectory(xkb,.,xkb,.)
+ODIR = $(CONFDIR)
+#else
+ODIR = $(LIBDIR)
+#endif
+#ifdef VarDbDirectory
+NDIR = $(VARDBDIR)
+#else
+NDIR = $(CONFDIR)
+#endif
+#if !UseConfDirForXkb || defined(VarDbDirectory)
+LinkConfDirectoryLong(xkb,xkb,compiled,compiled,$(ODIR),$(NDIR))
+#endif
+#endif
+
+DependTarget()
diff --git a/nx-X11/programs/Xserver/xkb/XKBAlloc.c b/nx-X11/programs/Xserver/xkb/XKBAlloc.c
new file mode 100644
index 000000000..bc0206f8e
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/XKBAlloc.c
@@ -0,0 +1,487 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocCompatMap(XkbDescPtr xkb,unsigned which,unsigned nSI)
+{
+XkbCompatMapPtr compat;
+XkbSymInterpretRec *prev_interpret;
+
+ if (!xkb)
+ return BadMatch;
+ if (xkb->compat) {
+ if (xkb->compat->size_si>=nSI)
+ return Success;
+ compat= xkb->compat;
+ compat->size_si= nSI;
+ if (compat->sym_interpret==NULL)
+ compat->num_si= 0;
+ prev_interpret = compat->sym_interpret;
+ compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
+ nSI,XkbSymInterpretRec);
+ if (compat->sym_interpret==NULL) {
+ _XkbFree(prev_interpret);
+ compat->size_si= compat->num_si= 0;
+ return BadAlloc;
+ }
+ if (compat->num_si!=0) {
+ _XkbClearElems(compat->sym_interpret,compat->num_si,
+ compat->size_si-1,XkbSymInterpretRec);
+ }
+ return Success;
+ }
+ compat= _XkbTypedCalloc(1,XkbCompatMapRec);
+ if (compat==NULL)
+ return BadAlloc;
+ if (nSI>0) {
+ compat->sym_interpret= _XkbTypedCalloc(nSI,XkbSymInterpretRec);
+ if (!compat->sym_interpret) {
+ _XkbFree(compat);
+ return BadAlloc;
+ }
+ }
+ compat->size_si= nSI;
+ compat->num_si= 0;
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ xkb->compat= compat;
+ return Success;
+}
+
+
+void
+XkbFreeCompatMap(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+register XkbCompatMapPtr compat;
+
+ if ((xkb==NULL)||(xkb->compat==NULL))
+ return;
+ compat= xkb->compat;
+ if (freeMap)
+ which= XkbAllCompatMask;
+ if (which&XkbGroupCompatMask)
+ bzero((char *)&compat->groups[0],XkbNumKbdGroups*sizeof(XkbModsRec));
+ if (which&XkbSymInterpMask) {
+ if ((compat->sym_interpret)&&(compat->size_si>0))
+ _XkbFree(compat->sym_interpret);
+ compat->size_si= compat->num_si= 0;
+ compat->sym_interpret= NULL;
+ }
+ if (freeMap) {
+ _XkbFree(compat);
+ xkb->compat= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocNames(XkbDescPtr xkb,unsigned which,int nTotalRG,int nTotalAliases)
+{
+XkbNamesPtr names;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->names==NULL) {
+ xkb->names = _XkbTypedCalloc(1,XkbNamesRec);
+ if (xkb->names==NULL)
+ return BadAlloc;
+ }
+ names= xkb->names;
+ if ((which&XkbKTLevelNamesMask)&&(xkb->map!=NULL)&&(xkb->map->types!=NULL)){
+ register int i;
+ XkbKeyTypePtr type;
+
+ type= xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ if (type->level_names==NULL) {
+ type->level_names= _XkbTypedCalloc(type->num_levels,Atom);
+ if (type->level_names==NULL)
+ return BadAlloc;
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys==NULL)) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadValue;
+ names->keys= _XkbTypedCalloc((xkb->max_key_code+1),XkbKeyNameRec);
+ if (names->keys==NULL)
+ return BadAlloc;
+ }
+ if ((which&XkbKeyAliasesMask)&&(nTotalAliases>0)) {
+ if (names->key_aliases==NULL) {
+ names->key_aliases= _XkbTypedCalloc(nTotalAliases,XkbKeyAliasRec);
+ }
+ else if (nTotalAliases>names->num_key_aliases) {
+ XkbKeyAliasRec *prev_aliases = names->key_aliases;
+
+ names->key_aliases= _XkbTypedRealloc(names->key_aliases,
+ nTotalAliases,XkbKeyAliasRec);
+ if (names->key_aliases!=NULL) {
+ _XkbClearElems(names->key_aliases,names->num_key_aliases,
+ nTotalAliases-1,XkbKeyAliasRec);
+ } else {
+ _XkbFree(prev_aliases);
+ }
+ }
+ if (names->key_aliases==NULL) {
+ names->num_key_aliases= 0;
+ return BadAlloc;
+ }
+ names->num_key_aliases= nTotalAliases;
+ }
+ if ((which&XkbRGNamesMask)&&(nTotalRG>0)) {
+ if (names->radio_groups==NULL) {
+ names->radio_groups= _XkbTypedCalloc(nTotalRG,Atom);
+ }
+ else if (nTotalRG>names->num_rg) {
+ Atom *prev_radio_groups = names->radio_groups;
+
+ names->radio_groups= _XkbTypedRealloc(names->radio_groups,nTotalRG,
+ Atom);
+ if (names->radio_groups!=NULL) {
+ _XkbClearElems(names->radio_groups,names->num_rg,nTotalRG-1,
+ Atom);
+ } else {
+ _XkbFree(prev_radio_groups);
+ }
+ }
+ if (names->radio_groups==NULL)
+ return BadAlloc;
+ names->num_rg= nTotalRG;
+ }
+ return Success;
+}
+
+void
+XkbFreeNames(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+XkbNamesPtr names;
+
+ if ((xkb==NULL)||(xkb->names==NULL))
+ return;
+ names= xkb->names;
+ if (freeMap)
+ which= XkbAllNamesMask;
+ if (which&XkbKTLevelNamesMask) {
+ XkbClientMapPtr map= xkb->map;
+ if ((map!=NULL)&&(map->types!=NULL)) {
+ register int i;
+ register XkbKeyTypePtr type;
+ type= map->types;
+ for (i=0;i<map->num_types;i++,type++) {
+ if (type->level_names!=NULL) {
+ _XkbFree(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ }
+ if ((which&XkbKeyNamesMask)&&(names->keys!=NULL)) {
+ _XkbFree(names->keys);
+ names->keys= NULL;
+ names->num_keys= 0;
+ }
+ if ((which&XkbKeyAliasesMask)&&(names->key_aliases)){
+ _XkbFree(names->key_aliases);
+ names->key_aliases=NULL;
+ names->num_key_aliases=0;
+ }
+ if ((which&XkbRGNamesMask)&&(names->radio_groups)) {
+ _XkbFree(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ if (freeMap) {
+ _XkbFree(names);
+ xkb->names= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbAllocControls(XkbDescPtr xkb,unsigned which)
+{
+ if (xkb==NULL)
+ return BadMatch;
+
+ if (xkb->ctrls==NULL) {
+ xkb->ctrls= _XkbTypedCalloc(1,XkbControlsRec);
+ if (!xkb->ctrls)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+/*ARGSUSED*/
+void
+XkbFreeControls(XkbDescPtr xkb,unsigned which,Bool freeMap)
+{
+ if (freeMap && (xkb!=NULL) && (xkb->ctrls!=NULL)) {
+ _XkbFree(xkb->ctrls);
+ xkb->ctrls= NULL;
+ }
+ return;
+}
+
+/***===================================================================***/
+
+Status
+XkbAllocIndicatorMaps(XkbDescPtr xkb)
+{
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->indicators==NULL) {
+ xkb->indicators= _XkbTypedCalloc(1,XkbIndicatorRec);
+ if (!xkb->indicators)
+ return BadAlloc;
+ }
+ return Success;
+}
+
+void
+XkbFreeIndicatorMaps(XkbDescPtr xkb)
+{
+ if ((xkb!=NULL)&&(xkb->indicators!=NULL)) {
+ _XkbFree(xkb->indicators);
+ xkb->indicators= NULL;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+XkbDescRec *
+XkbAllocKeyboard(void)
+{
+XkbDescRec *xkb;
+
+ xkb = _XkbTypedCalloc(1,XkbDescRec);
+ if (xkb)
+ xkb->device_spec= XkbUseCoreKbd;
+ return xkb;
+}
+
+void
+XkbFreeKeyboard(XkbDescPtr xkb,unsigned which,Bool freeAll)
+{
+ if (xkb==NULL)
+ return;
+ if (freeAll)
+ which= XkbAllComponentsMask;
+ if (which&XkbClientMapMask)
+ XkbFreeClientMap(xkb,XkbAllClientInfoMask,True);
+ if (which&XkbServerMapMask)
+ XkbFreeServerMap(xkb,XkbAllServerInfoMask,True);
+ if (which&XkbCompatMapMask)
+ XkbFreeCompatMap(xkb,XkbAllCompatMask,True);
+ if (which&XkbIndicatorMapMask)
+ XkbFreeIndicatorMaps(xkb);
+ if (which&XkbNamesMask)
+ XkbFreeNames(xkb,XkbAllNamesMask,True);
+ if ((which&XkbGeometryMask) && (xkb->geom!=NULL))
+ XkbFreeGeometry(xkb->geom,XkbGeomAllMask,True);
+ if (which&XkbControlsMask)
+ XkbFreeControls(xkb,XkbAllControlsMask,True);
+ if (freeAll)
+ _XkbFree(xkb);
+ return;
+}
+
+/***====================================================================***/
+
+XkbDeviceLedInfoPtr
+XkbAddDeviceLedInfo(XkbDeviceInfoPtr devi,unsigned ledClass,unsigned ledId)
+{
+XkbDeviceLedInfoPtr devli;
+register int i;
+
+ if ((!devi)||(!XkbSingleXIClass(ledClass))||(!XkbSingleXIId(ledId)))
+ return NULL;
+ for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
+ if ((devli->led_class==ledClass)&&(devli->led_id==ledId))
+ return devli;
+ }
+ if (devi->num_leds>=devi->sz_leds) {
+ XkbDeviceLedInfoRec *prev_leds = devi->leds;
+
+ if (devi->sz_leds>0) devi->sz_leds*= 2;
+ else devi->sz_leds= 1;
+ devi->leds= _XkbTypedRealloc(devi->leds,devi->sz_leds,
+ XkbDeviceLedInfoRec);
+ if (!devi->leds) {
+ _XkbFree(prev_leds);
+ devi->sz_leds= devi->num_leds= 0;
+ return NULL;
+ }
+ i= devi->num_leds;
+ for (devli=&devi->leds[i];i<devi->sz_leds;i++,devli++) {
+ bzero(devli,sizeof(XkbDeviceLedInfoRec));
+ devli->led_class= XkbXINone;
+ devli->led_id= XkbXINone;
+ }
+ }
+ devli= &devi->leds[devi->num_leds++];
+ bzero(devli,sizeof(XkbDeviceLedInfoRec));
+ devli->led_class= ledClass;
+ devli->led_id= ledId;
+ return devli;
+}
+
+Status
+XkbResizeDeviceButtonActions(XkbDeviceInfoPtr devi,unsigned newTotal)
+{
+ XkbAction *prev_btn_acts;
+
+ if ((!devi)||(newTotal>255))
+ return BadValue;
+ if ((devi->btn_acts!=NULL)&&(newTotal==devi->num_btns))
+ return Success;
+ if (newTotal==0) {
+ if (devi->btn_acts!=NULL) {
+ _XkbFree(devi->btn_acts);
+ devi->btn_acts= NULL;
+ }
+ devi->num_btns= 0;
+ return Success;
+ }
+ prev_btn_acts = devi->btn_acts;
+ devi->btn_acts= _XkbTypedRealloc(devi->btn_acts,newTotal,XkbAction);
+ if (devi->btn_acts==NULL) {
+ _XkbFree(prev_btn_acts);
+ devi->num_btns= 0;
+ return BadAlloc;
+ }
+ if (newTotal>devi->num_btns) {
+ XkbAction *act;
+ act= &devi->btn_acts[devi->num_btns];
+ bzero((char *)act,(newTotal-devi->num_btns)*sizeof(XkbAction));
+ }
+ devi->num_btns= newTotal;
+ return Success;
+}
+
+/*ARGSUSED*/
+XkbDeviceInfoPtr
+XkbAllocDeviceInfo(unsigned deviceSpec,unsigned nButtons,unsigned szLeds)
+{
+XkbDeviceInfoPtr devi;
+
+ devi= _XkbTypedCalloc(1,XkbDeviceInfoRec);
+ if (devi!=NULL) {
+ devi->device_spec= deviceSpec;
+ devi->has_own_state= False;
+ devi->num_btns= 0;
+ devi->btn_acts= NULL;
+ if (nButtons>0) {
+ devi->num_btns= nButtons;
+ devi->btn_acts= _XkbTypedCalloc(nButtons,XkbAction);
+ if (!devi->btn_acts) {
+ _XkbFree(devi);
+ return NULL;
+ }
+ }
+ devi->dflt_kbd_fb= XkbXINone;
+ devi->dflt_led_fb= XkbXINone;
+ devi->num_leds= 0;
+ devi->sz_leds= 0;
+ devi->leds= NULL;
+ if (szLeds>0) {
+ devi->sz_leds= szLeds;
+ devi->leds= _XkbTypedCalloc(szLeds,XkbDeviceLedInfoRec);
+ if (!devi->leds) {
+ if (devi->btn_acts)
+ _XkbFree(devi->btn_acts);
+ _XkbFree(devi);
+ return NULL;
+ }
+ }
+ }
+ return devi;
+}
+
+
+void
+XkbFreeDeviceInfo(XkbDeviceInfoPtr devi,unsigned which,Bool freeDevI)
+{
+ if (devi) {
+ if (freeDevI) {
+ which= XkbXI_AllDeviceFeaturesMask;
+ if (devi->name) {
+ _XkbFree(devi->name);
+ devi->name= NULL;
+ }
+ }
+ if ((which&XkbXI_ButtonActionsMask)&&(devi->btn_acts)) {
+ _XkbFree(devi->btn_acts);
+ devi->num_btns= 0;
+ devi->btn_acts= NULL;
+ }
+ if ((which&XkbXI_IndicatorsMask)&&(devi->leds)) {
+ register int i;
+ if ((which&XkbXI_IndicatorsMask)==XkbXI_IndicatorsMask) {
+ _XkbFree(devi->leds);
+ devi->sz_leds= devi->num_leds= 0;
+ devi->leds= NULL;
+ }
+ else {
+ XkbDeviceLedInfoPtr devli;
+ for (i=0,devli=devi->leds;i<devi->num_leds;i++,devli++) {
+ if (which&XkbXI_IndicatorMapsMask)
+ bzero((char *)&devli->maps[0],sizeof(devli->maps));
+ else bzero((char *)&devli->names[0],sizeof(devli->names));
+ }
+ }
+ }
+ if (freeDevI)
+ _XkbFree(devi);
+ }
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/XKBGAlloc.c b/nx-X11/programs/Xserver/xkb/XKBGAlloc.c
new file mode 100644
index 000000000..50e598280
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/XKBGAlloc.c
@@ -0,0 +1,1006 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+
+#ifdef X_NOT_POSIX
+#define Size_t unsigned int
+#else
+#define Size_t size_t
+#endif
+
+/***====================================================================***/
+
+static void
+_XkbFreeGeomLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz)
+{
+ if ((freeAll)||(*elems==NULL)) {
+ *num_inout= *sz_inout= 0;
+ if (*elems!=NULL) {
+ _XkbFree(*elems);
+ *elems= NULL;
+ }
+ return;
+ }
+
+ if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+
+ if (first+count>=(*num_inout)) {
+ /* truncating the array is easy */
+ (*num_inout)= first;
+ }
+ else {
+ char * ptr;
+ int extra;
+ ptr= *elems;
+ extra= ((*num_inout)-(first+count))*elem_sz;
+ if (extra>0)
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],extra);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+typedef void (*ContentsClearFunc)(
+ char * /* priv */
+);
+
+static void
+_XkbFreeGeomNonLeafElems( Bool freeAll,
+ int first,
+ int count,
+ unsigned short * num_inout,
+ unsigned short * sz_inout,
+ char ** elems,
+ unsigned int elem_sz,
+ ContentsClearFunc freeFunc)
+{
+register int i;
+register char *ptr;
+
+ if (freeAll) {
+ first= 0;
+ count= (*num_inout);
+ }
+ else if ((first>=(*num_inout))||(first<0)||(count<1))
+ return;
+ else if (first+count>(*num_inout))
+ count= (*num_inout)-first;
+ if (*elems==NULL)
+ return;
+
+ if (freeFunc) {
+ ptr= *elems;
+ ptr+= first*elem_sz;
+ for (i=0;i<count;i++) {
+ (*freeFunc)(ptr);
+ ptr+= elem_sz;
+ }
+ }
+ if (freeAll) {
+ (*num_inout)= (*sz_inout)= 0;
+ if (*elems) {
+ _XkbFree(*elems);
+ *elems= NULL;
+ }
+ }
+ else if (first+count>=(*num_inout))
+ *num_inout= first;
+ else {
+ i= ((*num_inout)-(first+count))*elem_sz;
+ ptr= *elems;
+ memmove(&ptr[first*elem_sz],&ptr[(first+count)*elem_sz],i);
+ (*num_inout)-= count;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearProperty(char *prop_in)
+{
+XkbPropertyPtr prop= (XkbPropertyPtr)prop_in;
+
+ if (prop->name) {
+ _XkbFree(prop->name);
+ prop->name= NULL;
+ }
+ if (prop->value) {
+ _XkbFree(prop->value);
+ prop->value= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomProperties( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_properties,&geom->sz_properties,
+ (char **)&geom->properties,
+ sizeof(XkbPropertyRec),_XkbClearProperty);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeyAliases( XkbGeometryPtr geom,
+ int first,
+ int count,
+ Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &geom->num_key_aliases,&geom->sz_key_aliases,
+ (char **)&geom->key_aliases,
+ sizeof(XkbKeyAliasRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearColor(char *color_in)
+{
+XkbColorPtr color= (XkbColorPtr)color_in;
+
+ if (color->spec)
+ _XkbFree(color->spec);
+ return;
+}
+
+void
+XkbFreeGeomColors(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_colors,&geom->sz_colors,
+ (char **)&geom->colors,
+ sizeof(XkbColorRec),_XkbClearColor);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomPoints(XkbOutlinePtr outline,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &outline->num_points,&outline->sz_points,
+ (char **)&outline->points,
+ sizeof(XkbPointRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOutline(char *outline_in)
+{
+XkbOutlinePtr outline= (XkbOutlinePtr)outline_in;
+
+ if (outline->points!=NULL)
+ XkbFreeGeomPoints(outline,0,outline->num_points,True);
+ return;
+}
+
+void
+XkbFreeGeomOutlines(XkbShapePtr shape,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &shape->num_outlines,&shape->sz_outlines,
+ (char **)&shape->outlines,
+ sizeof(XkbOutlineRec),_XkbClearOutline);
+
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearShape(char *shape_in)
+{
+XkbShapePtr shape= (XkbShapePtr)shape_in;
+
+ if (shape->outlines)
+ XkbFreeGeomOutlines(shape,0,shape->num_outlines,True);
+ return;
+}
+
+void
+XkbFreeGeomShapes(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_shapes,&geom->sz_shapes,
+ (char **)&geom->shapes,
+ sizeof(XkbShapeRec),_XkbClearShape);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomOverlayKeys(XkbOverlayRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbOverlayKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlayRow(char *row_in)
+{
+XkbOverlayRowPtr row= (XkbOverlayRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomOverlayKeys(row,0,row->num_keys,True);
+ return;
+}
+
+void
+XkbFreeGeomOverlayRows(XkbOverlayPtr overlay,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &overlay->num_rows,&overlay->sz_rows,
+ (char **)&overlay->rows,
+ sizeof(XkbOverlayRowRec),_XkbClearOverlayRow);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearOverlay(char *overlay_in)
+{
+XkbOverlayPtr overlay= (XkbOverlayPtr)overlay_in;
+
+ if (overlay->rows!=NULL)
+ XkbFreeGeomOverlayRows(overlay,0,overlay->num_rows,True);
+ return;
+}
+
+void
+XkbFreeGeomOverlays(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_overlays,&section->sz_overlays,
+ (char **)&section->overlays,
+ sizeof(XkbOverlayRec),_XkbClearOverlay);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbFreeGeomKeys(XkbRowPtr row,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomLeafElems(freeAll,first,count,
+ &row->num_keys,&row->sz_keys,
+ (char **)&row->keys,
+ sizeof(XkbKeyRec));
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearRow(char *row_in)
+{
+XkbRowPtr row= (XkbRowPtr)row_in;
+
+ if (row->keys!=NULL)
+ XkbFreeGeomKeys(row,0,row->num_keys,True);
+ return;
+}
+
+void
+XkbFreeGeomRows(XkbSectionPtr section,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &section->num_rows,&section->sz_rows,
+ (char **)&section->rows,
+ sizeof(XkbRowRec),_XkbClearRow);
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearSection(char *section_in)
+{
+XkbSectionPtr section= (XkbSectionPtr)section_in;
+
+ if (section->rows!=NULL)
+ XkbFreeGeomRows(section,0,section->num_rows,True);
+ if (section->doodads!=NULL) {
+ XkbFreeGeomDoodads(section->doodads,section->num_doodads,True);
+ section->doodads= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeGeomSections(XkbGeometryPtr geom,int first,int count,Bool freeAll)
+{
+ _XkbFreeGeomNonLeafElems(freeAll,first,count,
+ &geom->num_sections,&geom->sz_sections,
+ (char **)&geom->sections,
+ sizeof(XkbSectionRec),_XkbClearSection);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_XkbClearDoodad(char *doodad_in)
+{
+XkbDoodadPtr doodad= (XkbDoodadPtr)doodad_in;
+
+ switch (doodad->any.type) {
+ case XkbTextDoodad:
+ {
+ if (doodad->text.text!=NULL) {
+ _XkbFree(doodad->text.text);
+ doodad->text.text= NULL;
+ }
+ if (doodad->text.font!=NULL) {
+ _XkbFree(doodad->text.font);
+ doodad->text.font= NULL;
+ }
+ }
+ break;
+ case XkbLogoDoodad:
+ {
+ if (doodad->logo.logo_name!=NULL) {
+ _XkbFree(doodad->logo.logo_name);
+ doodad->logo.logo_name= NULL;
+ }
+ }
+ break;
+ }
+ return;
+}
+
+void
+XkbFreeGeomDoodads(XkbDoodadPtr doodads,int nDoodads,Bool freeAll)
+{
+register int i;
+register XkbDoodadPtr doodad;
+
+ if (doodads) {
+ for (i=0,doodad= doodads;i<nDoodads;i++,doodad++) {
+ _XkbClearDoodad((char *)doodad);
+ }
+ if (freeAll)
+ _XkbFree(doodads);
+ }
+ return;
+}
+
+void
+XkbFreeGeometry(XkbGeometryPtr geom,unsigned which,Bool freeMap)
+{
+ if (geom==NULL)
+ return;
+ if (freeMap)
+ which= XkbGeomAllMask;
+ if ((which&XkbGeomPropertiesMask)&&(geom->properties!=NULL))
+ XkbFreeGeomProperties(geom,0,geom->num_properties,True);
+ if ((which&XkbGeomColorsMask)&&(geom->colors!=NULL))
+ XkbFreeGeomColors(geom,0,geom->num_colors,True);
+ if ((which&XkbGeomShapesMask)&&(geom->shapes!=NULL))
+ XkbFreeGeomShapes(geom,0,geom->num_shapes,True);
+ if ((which&XkbGeomSectionsMask)&&(geom->sections!=NULL))
+ XkbFreeGeomSections(geom,0,geom->num_sections,True);
+ if ((which&XkbGeomDoodadsMask)&&(geom->doodads!= NULL)) {
+ XkbFreeGeomDoodads(geom->doodads,geom->num_doodads,True);
+ geom->doodads= NULL;
+ geom->num_doodads= geom->sz_doodads= 0;
+ }
+ if ((which&XkbGeomKeyAliasesMask)&&(geom->key_aliases!=NULL))
+ XkbFreeGeomKeyAliases(geom,0,geom->num_key_aliases,True);
+ if (freeMap) {
+ if (geom->label_font!=NULL) {
+ _XkbFree(geom->label_font);
+ geom->label_font= NULL;
+ }
+ _XkbFree(geom);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+_XkbGeomAlloc( XPointer * old,
+ unsigned short * num,
+ unsigned short * total,
+ int num_new,
+ Size_t sz_elem)
+{
+ if (num_new<1)
+ return Success;
+ if ((*old)==NULL)
+ *num= *total= 0;
+
+ if ((*num)+num_new<=(*total))
+ return Success;
+
+ *total= (*num)+num_new;
+ if ((*old)!=NULL)
+ (*old)= (XPointer)_XkbRealloc((*old),(*total)*sz_elem);
+ else (*old)= (XPointer)_XkbCalloc((*total),sz_elem);
+ if ((*old)==NULL) {
+ *total= *num= 0;
+ return BadAlloc;
+ }
+
+ if (*num>0) {
+ char *tmp= (char *)(*old);
+ bzero(&tmp[sz_elem*(*num)],(num_new*sz_elem));
+ }
+ return Success;
+}
+
+#define _XkbAllocProps(g,n) _XkbGeomAlloc((XPointer *)&(g)->properties,\
+ &(g)->num_properties,&(g)->sz_properties,\
+ (n),sizeof(XkbPropertyRec))
+#define _XkbAllocColors(g,n) _XkbGeomAlloc((XPointer *)&(g)->colors,\
+ &(g)->num_colors,&(g)->sz_colors,\
+ (n),sizeof(XkbColorRec))
+#define _XkbAllocShapes(g,n) _XkbGeomAlloc((XPointer *)&(g)->shapes,\
+ &(g)->num_shapes,&(g)->sz_shapes,\
+ (n),sizeof(XkbShapeRec))
+#define _XkbAllocSections(g,n) _XkbGeomAlloc((XPointer *)&(g)->sections,\
+ &(g)->num_sections,&(g)->sz_sections,\
+ (n),sizeof(XkbSectionRec))
+#define _XkbAllocDoodads(g,n) _XkbGeomAlloc((XPointer *)&(g)->doodads,\
+ &(g)->num_doodads,&(g)->sz_doodads,\
+ (n),sizeof(XkbDoodadRec))
+#define _XkbAllocKeyAliases(g,n) _XkbGeomAlloc((XPointer *)&(g)->key_aliases,\
+ &(g)->num_key_aliases,&(g)->sz_key_aliases,\
+ (n),sizeof(XkbKeyAliasRec))
+
+#define _XkbAllocOutlines(s,n) _XkbGeomAlloc((XPointer *)&(s)->outlines,\
+ &(s)->num_outlines,&(s)->sz_outlines,\
+ (n),sizeof(XkbOutlineRec))
+#define _XkbAllocRows(s,n) _XkbGeomAlloc((XPointer *)&(s)->rows,\
+ &(s)->num_rows,&(s)->sz_rows,\
+ (n),sizeof(XkbRowRec))
+#define _XkbAllocPoints(o,n) _XkbGeomAlloc((XPointer *)&(o)->points,\
+ &(o)->num_points,&(o)->sz_points,\
+ (n),sizeof(XkbPointRec))
+#define _XkbAllocKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbKeyRec))
+#define _XkbAllocOverlays(s,n) _XkbGeomAlloc((XPointer *)&(s)->overlays,\
+ &(s)->num_overlays,&(s)->sz_overlays,\
+ (n),sizeof(XkbOverlayRec))
+#define _XkbAllocOverlayRows(o,n) _XkbGeomAlloc((XPointer *)&(o)->rows,\
+ &(o)->num_rows,&(o)->sz_rows,\
+ (n),sizeof(XkbOverlayRowRec))
+#define _XkbAllocOverlayKeys(r,n) _XkbGeomAlloc((XPointer *)&(r)->keys,\
+ &(r)->num_keys,&(r)->sz_keys,\
+ (n),sizeof(XkbOverlayKeyRec))
+
+Status
+XkbAllocGeomProps(XkbGeometryPtr geom,int nProps)
+{
+ return _XkbAllocProps(geom,nProps);
+}
+
+Status
+XkbAllocGeomColors(XkbGeometryPtr geom,int nColors)
+{
+ return _XkbAllocColors(geom,nColors);
+}
+
+Status
+XkbAllocGeomKeyAliases(XkbGeometryPtr geom,int nKeyAliases)
+{
+ return _XkbAllocKeyAliases(geom,nKeyAliases);
+}
+
+Status
+XkbAllocGeomShapes(XkbGeometryPtr geom,int nShapes)
+{
+ return _XkbAllocShapes(geom,nShapes);
+}
+
+Status
+XkbAllocGeomSections(XkbGeometryPtr geom,int nSections)
+{
+ return _XkbAllocSections(geom,nSections);
+}
+
+Status
+XkbAllocGeomOverlays(XkbSectionPtr section,int nOverlays)
+{
+ return _XkbAllocOverlays(section,nOverlays);
+}
+
+Status
+XkbAllocGeomOverlayRows(XkbOverlayPtr overlay,int nRows)
+{
+ return _XkbAllocOverlayRows(overlay,nRows);
+}
+
+Status
+XkbAllocGeomOverlayKeys(XkbOverlayRowPtr row,int nKeys)
+{
+ return _XkbAllocOverlayKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeomDoodads(XkbGeometryPtr geom,int nDoodads)
+{
+ return _XkbAllocDoodads(geom,nDoodads);
+}
+
+Status
+XkbAllocGeomSectionDoodads(XkbSectionPtr section,int nDoodads)
+{
+ return _XkbAllocDoodads(section,nDoodads);
+}
+
+Status
+XkbAllocGeomOutlines(XkbShapePtr shape,int nOL)
+{
+ return _XkbAllocOutlines(shape,nOL);
+}
+
+Status
+XkbAllocGeomRows(XkbSectionPtr section,int nRows)
+{
+ return _XkbAllocRows(section,nRows);
+}
+
+Status
+XkbAllocGeomPoints(XkbOutlinePtr ol,int nPts)
+{
+ return _XkbAllocPoints(ol,nPts);
+}
+
+Status
+XkbAllocGeomKeys(XkbRowPtr row,int nKeys)
+{
+ return _XkbAllocKeys(row,nKeys);
+}
+
+Status
+XkbAllocGeometry(XkbDescPtr xkb,XkbGeometrySizesPtr sizes)
+{
+XkbGeometryPtr geom;
+Status rtrn;
+
+ if (xkb->geom==NULL) {
+ xkb->geom= _XkbTypedCalloc(1,XkbGeometryRec);
+ if (!xkb->geom)
+ return BadAlloc;
+ }
+ geom= xkb->geom;
+ if ((sizes->which&XkbGeomPropertiesMask)&&
+ ((rtrn=_XkbAllocProps(geom,sizes->num_properties))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomColorsMask)&&
+ ((rtrn=_XkbAllocColors(geom,sizes->num_colors))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomShapesMask)&&
+ ((rtrn=_XkbAllocShapes(geom,sizes->num_shapes))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomSectionsMask)&&
+ ((rtrn=_XkbAllocSections(geom,sizes->num_sections))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomDoodadsMask)&&
+ ((rtrn=_XkbAllocDoodads(geom,sizes->num_doodads))!=Success)) {
+ goto BAIL;
+ }
+ if ((sizes->which&XkbGeomKeyAliasesMask)&&
+ ((rtrn=_XkbAllocKeyAliases(geom,sizes->num_key_aliases))!=Success)) {
+ goto BAIL;
+ }
+ return Success;
+BAIL:
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= NULL;
+ return rtrn;
+}
+
+/***====================================================================***/
+
+XkbPropertyPtr
+XkbAddGeomProperty(XkbGeometryPtr geom,char *name,char *value)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ if ((!geom)||(!name)||(!value))
+ return NULL;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ if ((prop->name)&&(strcmp(name,prop->name)==0)) {
+ if (prop->value)
+ _XkbFree(prop->value);
+ prop->value= (char *)_XkbAlloc(strlen(value)+1);
+ if (prop->value)
+ strcpy(prop->value,value);
+ return prop;
+ }
+ }
+ if ((geom->num_properties>=geom->sz_properties)&&
+ (_XkbAllocProps(geom,1)!=Success)) {
+ return NULL;
+ }
+ prop= &geom->properties[geom->num_properties];
+ prop->name= (char *)_XkbAlloc(strlen(name)+1);
+ if (!name)
+ return NULL;
+ strcpy(prop->name,name);
+ prop->value= (char *)_XkbAlloc(strlen(value)+1);
+ if (!value) {
+ _XkbFree(prop->name);
+ prop->name= NULL;
+ return NULL;
+ }
+ strcpy(prop->value,value);
+ geom->num_properties++;
+ return prop;
+}
+
+XkbKeyAliasPtr
+XkbAddGeomKeyAlias(XkbGeometryPtr geom,char *aliasStr,char *realStr)
+{
+register int i;
+register XkbKeyAliasPtr alias;
+
+ if ((!geom)||(!aliasStr)||(!realStr)||(!aliasStr[0])||(!realStr[0]))
+ return NULL;
+ for (i=0,alias=geom->key_aliases;i<geom->num_key_aliases;i++,alias++) {
+ if (strncmp(alias->alias,aliasStr,XkbKeyNameLength)==0) {
+ bzero(alias->real,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ return alias;
+ }
+ }
+ if ((geom->num_key_aliases>=geom->sz_key_aliases)&&
+ (_XkbAllocKeyAliases(geom,1)!=Success)) {
+ return NULL;
+ }
+ alias= &geom->key_aliases[geom->num_key_aliases];
+ bzero(alias,sizeof(XkbKeyAliasRec));
+ strncpy(alias->alias,aliasStr,XkbKeyNameLength);
+ strncpy(alias->real,realStr,XkbKeyNameLength);
+ geom->num_key_aliases++;
+ return alias;
+}
+
+XkbColorPtr
+XkbAddGeomColor(XkbGeometryPtr geom,char *spec,unsigned int pixel)
+{
+register int i;
+register XkbColorPtr color;
+
+ if ((!geom)||(!spec))
+ return NULL;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ if ((color->spec)&&(strcmp(color->spec,spec)==0)) {
+ color->pixel= pixel;
+ return color;
+ }
+ }
+ if ((geom->num_colors>=geom->sz_colors)&&
+ (_XkbAllocColors(geom,1)!=Success)) {
+ return NULL;
+ }
+ color= &geom->colors[geom->num_colors];
+ color->pixel= pixel;
+ color->spec= (char *)_XkbAlloc(strlen(spec)+1);
+ if (!color->spec)
+ return NULL;
+ strcpy(color->spec,spec);
+ geom->num_colors++;
+ return color;
+}
+
+XkbOutlinePtr
+XkbAddGeomOutline(XkbShapePtr shape,int sz_points)
+{
+XkbOutlinePtr outline;
+
+ if ((!shape)||(sz_points<0))
+ return NULL;
+ if ((shape->num_outlines>=shape->sz_outlines)&&
+ (_XkbAllocOutlines(shape,1)!=Success)) {
+ return NULL;
+ }
+ outline= &shape->outlines[shape->num_outlines];
+ bzero(outline,sizeof(XkbOutlineRec));
+ if ((sz_points>0)&&(_XkbAllocPoints(outline,sz_points)!=Success))
+ return NULL;
+ shape->num_outlines++;
+ return outline;
+}
+
+XkbShapePtr
+XkbAddGeomShape(XkbGeometryPtr geom,Atom name,int sz_outlines)
+{
+XkbShapePtr shape;
+register int i;
+
+ if ((!geom)||(!name)||(sz_outlines<0))
+ return NULL;
+ if (geom->num_shapes>0) {
+ for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+ if (name==shape->name)
+ return shape;
+ }
+ }
+ if ((geom->num_shapes>=geom->sz_shapes)&&
+ (_XkbAllocShapes(geom,1)!=Success))
+ return NULL;
+ shape= &geom->shapes[geom->num_shapes];
+ bzero(shape,sizeof(XkbShapeRec));
+ if ((sz_outlines>0)&&(_XkbAllocOutlines(shape,sz_outlines)!=Success))
+ return NULL;
+ shape->name= name;
+ shape->primary= shape->approx= NULL;
+ geom->num_shapes++;
+ return shape;
+}
+
+XkbKeyPtr
+XkbAddGeomKey(XkbRowPtr row)
+{
+XkbKeyPtr key;
+ if (!row)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys++];
+ bzero(key,sizeof(XkbKeyRec));
+ return key;
+}
+
+XkbRowPtr
+XkbAddGeomRow(XkbSectionPtr section,int sz_keys)
+{
+XkbRowPtr row;
+
+ if ((!section)||(sz_keys<0))
+ return NULL;
+ if ((section->num_rows>=section->sz_rows)&&
+ (_XkbAllocRows(section,1)!=Success))
+ return NULL;
+ row= &section->rows[section->num_rows];
+ bzero(row,sizeof(XkbRowRec));
+ if ((sz_keys>0)&&(_XkbAllocKeys(row,sz_keys)!=Success))
+ return NULL;
+ section->num_rows++;
+ return row;
+}
+
+XkbSectionPtr
+XkbAddGeomSection( XkbGeometryPtr geom,
+ Atom name,
+ int sz_rows,
+ int sz_doodads,
+ int sz_over)
+{
+register int i;
+XkbSectionPtr section;
+
+ if ((!geom)||(name==None)||(sz_rows<0))
+ return NULL;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ if (section->name!=name)
+ continue;
+ if (((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))||
+ ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success))||
+ ((sz_over>0)&&(_XkbAllocOverlays(section,sz_over)!=Success)))
+ return NULL;
+ return section;
+ }
+ if ((geom->num_sections>=geom->sz_sections)&&
+ (_XkbAllocSections(geom,1)!=Success))
+ return NULL;
+ section= &geom->sections[geom->num_sections];
+ if ((sz_rows>0)&&(_XkbAllocRows(section,sz_rows)!=Success))
+ return NULL;
+ if ((sz_doodads>0)&&(_XkbAllocDoodads(section,sz_doodads)!=Success)) {
+ if (section->rows) {
+ _XkbFree(section->rows);
+ section->rows= NULL;
+ section->sz_rows= section->num_rows= 0;
+ }
+ return NULL;
+ }
+ section->name= name;
+ geom->num_sections++;
+ return section;
+}
+
+XkbDoodadPtr
+XkbAddGeomDoodad(XkbGeometryPtr geom,XkbSectionPtr section,Atom name)
+{
+XkbDoodadPtr old,doodad;
+register int i,nDoodads;
+
+ if ((!geom)||(name==None))
+ return NULL;
+ if ((section!=NULL)&&(section->num_doodads>0)) {
+ old= section->doodads;
+ nDoodads= section->num_doodads;
+ }
+ else {
+ old= geom->doodads;
+ nDoodads= geom->num_doodads;
+ }
+ for (i=0,doodad=old;i<nDoodads;i++,doodad++) {
+ if (doodad->any.name==name)
+ return doodad;
+ }
+ if (section) {
+ if ((section->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(section,1)!=Success)) {
+ return NULL;
+ }
+ doodad= &section->doodads[section->num_doodads++];
+ }
+ else {
+ if ((geom->num_doodads>=geom->sz_doodads)&&
+ (_XkbAllocDoodads(geom,1)!=Success))
+ return NULL;
+ doodad= &geom->doodads[geom->num_doodads++];
+ }
+ bzero(doodad,sizeof(XkbDoodadRec));
+ doodad->any.name= name;
+ return doodad;
+}
+
+XkbOverlayKeyPtr
+XkbAddGeomOverlayKey( XkbOverlayPtr overlay,
+ XkbOverlayRowPtr row,
+ char * over,
+ char * under)
+{
+register int i;
+XkbOverlayKeyPtr key;
+XkbSectionPtr section;
+XkbRowPtr row_under;
+Bool found;
+
+ if ((!overlay)||(!row)||(!over)||(!under))
+ return NULL;
+ section= overlay->section_under;
+ if (row->row_under>=section->num_rows)
+ return NULL;
+ row_under= &section->rows[row->row_under];
+ for (i=0,found=False;i<row_under->num_keys;i++) {
+ if (strncmp(under,row_under->keys[i].name.name,XkbKeyNameLength)==0) {
+ found= True;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ if ((row->num_keys>=row->sz_keys)&&(_XkbAllocOverlayKeys(row,1)!=Success))
+ return NULL;
+ key= &row->keys[row->num_keys];
+ strncpy(key->under.name,under,XkbKeyNameLength);
+ strncpy(key->over.name,over,XkbKeyNameLength);
+ row->num_keys++;
+ return key;
+}
+
+XkbOverlayRowPtr
+XkbAddGeomOverlayRow(XkbOverlayPtr overlay,int row_under,int sz_keys)
+{
+register int i;
+XkbOverlayRowPtr row;
+
+ if ((!overlay)||(sz_keys<0))
+ return NULL;
+ if (row_under>=overlay->section_under->num_rows)
+ return NULL;
+ for (i=0;i<overlay->num_rows;i++) {
+ if (overlay->rows[i].row_under==row_under) {
+ row= &overlay->rows[i];
+ if ((row->sz_keys<sz_keys)&&
+ (_XkbAllocOverlayKeys(row,sz_keys)!=Success)) {
+ return NULL;
+ }
+ return &overlay->rows[i];
+ }
+ }
+ if ((overlay->num_rows>=overlay->sz_rows)&&
+ (_XkbAllocOverlayRows(overlay,1)!=Success))
+ return NULL;
+ row= &overlay->rows[overlay->num_rows];
+ bzero(row,sizeof(XkbOverlayRowRec));
+ if ((sz_keys>0)&&(_XkbAllocOverlayKeys(row,sz_keys)!=Success))
+ return NULL;
+ row->row_under= row_under;
+ overlay->num_rows++;
+ return row;
+}
+
+XkbOverlayPtr
+XkbAddGeomOverlay(XkbSectionPtr section,Atom name,int sz_rows)
+{
+register int i;
+XkbOverlayPtr overlay;
+
+ if ((!section)||(name==None)||(sz_rows==0))
+ return NULL;
+
+ for (i=0,overlay=section->overlays;i<section->num_overlays;i++,overlay++) {
+ if (overlay->name==name) {
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ return overlay;
+ }
+ }
+ if ((section->num_overlays>=section->sz_overlays)&&
+ (_XkbAllocOverlays(section,1)!=Success))
+ return NULL;
+ overlay= &section->overlays[section->num_overlays];
+ if ((sz_rows>0)&&(_XkbAllocOverlayRows(overlay,sz_rows)!=Success))
+ return NULL;
+ overlay->name= name;
+ overlay->section_under= section;
+ section->num_overlays++;
+ return overlay;
+}
diff --git a/nx-X11/programs/Xserver/xkb/XKBMAlloc.c b/nx-X11/programs/Xserver/xkb/XKBMAlloc.c
new file mode 100644
index 000000000..66b20b89e
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/XKBMAlloc.c
@@ -0,0 +1,1006 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <nx-X11/keysym.h>
+#include <xkbsrv.h>
+
+
+/***====================================================================***/
+
+Status
+XkbAllocClientMap(XkbDescPtr xkb,unsigned which,unsigned nTotalTypes)
+{
+register int i;
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||((nTotalTypes>0)&&(nTotalTypes<XkbNumRequiredTypes)))
+ return BadValue;
+ if ((which&XkbKeySymsMask)&&
+ ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))) {
+#ifdef DEBUG
+fprintf(stderr,"bad keycode (%d,%d) in XkbAllocClientMap\n",
+ xkb->min_key_code,xkb->max_key_code);
+#endif
+ return BadValue;
+ }
+
+ if (xkb->map==NULL) {
+ map= _XkbTypedCalloc(1,XkbClientMapRec);
+ if (map==NULL)
+ return BadAlloc;
+ xkb->map= map;
+ }
+ else map= xkb->map;
+
+ if ((which&XkbKeyTypesMask)&&(nTotalTypes>0)) {
+ if (map->types==NULL) {
+ map->types= _XkbTypedCalloc(nTotalTypes,XkbKeyTypeRec);
+ if (map->types==NULL)
+ return BadAlloc;
+ map->num_types= 0;
+ map->size_types= nTotalTypes;
+ }
+ else if (map->size_types<nTotalTypes) {
+ XkbKeyTypeRec *prev_types = map->types;
+
+ map->types= _XkbTypedRealloc(map->types,nTotalTypes,XkbKeyTypeRec);
+ if (map->types==NULL) {
+ _XkbFree(prev_types);
+ map->num_types= map->size_types= 0;
+ return BadAlloc;
+ }
+ map->size_types= nTotalTypes;
+ bzero(&map->types[map->num_types],
+ ((map->size_types-map->num_types)*sizeof(XkbKeyTypeRec)));
+ }
+ }
+ if (which&XkbKeySymsMask) {
+ int nKeys= XkbNumKeys(xkb);
+ if (map->syms==NULL) {
+ map->size_syms= (nKeys*15)/10;
+ map->syms= _XkbTypedCalloc(map->size_syms,KeySym);
+ if (!map->syms) {
+ map->size_syms= 0;
+ return BadAlloc;
+ }
+ map->num_syms= 1;
+ map->syms[0]= NoSymbol;
+ }
+ if (map->key_sym_map==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_sym_map= _XkbTypedCalloc(i,XkbSymMapRec);
+ if (map->key_sym_map==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbModifierMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->modmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->modmap= _XkbTypedCalloc(i,unsigned char);
+ if (map->modmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+Status
+XkbAllocServerMap(XkbDescPtr xkb,unsigned which,unsigned nNewActions)
+{
+register int i;
+XkbServerMapPtr map;
+
+ if (xkb==NULL)
+ return BadMatch;
+ if (xkb->server==NULL) {
+ map= _XkbTypedCalloc(1,XkbServerMapRec);
+ if (map==NULL)
+ return BadAlloc;
+ for (i=0;i<XkbNumVirtualMods;i++) {
+ map->vmods[i]= XkbNoModifierMask;
+ }
+ xkb->server= map;
+ }
+ else map= xkb->server;
+ if (which&XkbExplicitComponentsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->explicit==NULL) {
+ i= xkb->max_key_code+1;
+ map->explicit= _XkbTypedCalloc(i,unsigned char);
+ if (map->explicit==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyActionsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (nNewActions<1)
+ nNewActions= 1;
+ if (map->acts==NULL) {
+ map->acts= _XkbTypedCalloc((nNewActions+1),XkbAction);
+ if (map->acts==NULL)
+ return BadAlloc;
+ map->num_acts= 1;
+ map->size_acts= nNewActions+1;
+ }
+ else if ((map->size_acts-map->num_acts)<nNewActions) {
+ unsigned need;
+ XkbAction *prev_acts = map->acts;
+ need= map->num_acts+nNewActions;
+ map->acts= _XkbTypedRealloc(map->acts,need,XkbAction);
+ if (map->acts==NULL) {
+ _XkbFree(prev_acts);
+ map->num_acts= map->size_acts= 0;
+ return BadAlloc;
+ }
+ map->size_acts= need;
+ bzero(&map->acts[map->num_acts],
+ ((map->size_acts-map->num_acts)*sizeof(XkbAction)));
+ }
+ if (map->key_acts==NULL) {
+ i= xkb->max_key_code+1;
+ map->key_acts= _XkbTypedCalloc(i,unsigned short);
+ if (map->key_acts==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbKeyBehaviorsMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->behaviors==NULL) {
+ i= xkb->max_key_code+1;
+ map->behaviors= _XkbTypedCalloc(i,XkbBehavior);
+ if (map->behaviors==NULL)
+ return BadAlloc;
+ }
+ }
+ if (which&XkbVirtualModMapMask) {
+ if ((!XkbIsLegalKeycode(xkb->min_key_code))||
+ (!XkbIsLegalKeycode(xkb->max_key_code))||
+ (xkb->max_key_code<xkb->min_key_code))
+ return BadMatch;
+ if (map->vmodmap==NULL) {
+ i= xkb->max_key_code+1;
+ map->vmodmap= _XkbTypedCalloc(i,unsigned short);
+ if (map->vmodmap==NULL)
+ return BadAlloc;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+Status
+XkbCopyKeyType(XkbKeyTypePtr from,XkbKeyTypePtr into)
+{
+ if ((!from)||(!into))
+ return BadMatch;
+ if (into->map) {
+ _XkbFree(into->map);
+ into->map= NULL;
+ }
+ if (into->preserve) {
+ _XkbFree(into->preserve);
+ into->preserve= NULL;
+ }
+ if (into->level_names) {
+ _XkbFree(into->level_names);
+ into->level_names= NULL;
+ }
+ *into= *from;
+ if ((from->map)&&(into->map_count>0)) {
+ into->map= _XkbTypedCalloc(into->map_count,XkbKTMapEntryRec);
+ if (!into->map)
+ return BadAlloc;
+ memcpy(into->map,from->map,into->map_count*sizeof(XkbKTMapEntryRec));
+ }
+ if ((from->preserve)&&(into->map_count>0)) {
+ into->preserve= _XkbTypedCalloc(into->map_count,XkbModsRec);
+ if (!into->preserve)
+ return BadAlloc;
+ memcpy(into->preserve,from->preserve,
+ into->map_count*sizeof(XkbModsRec));
+ }
+ if ((from->level_names)&&(into->num_levels>0)) {
+ into->level_names= _XkbTypedCalloc(into->num_levels,Atom);
+ if (!into->level_names)
+ return BadAlloc;
+ memcpy(into->level_names,from->level_names,
+ into->num_levels*sizeof(Atom));
+ }
+ return Success;
+}
+
+Status
+XkbCopyKeyTypes(XkbKeyTypePtr from,XkbKeyTypePtr into,int num_types)
+{
+register int i,rtrn;
+
+ if ((!from)||(!into)||(num_types<0))
+ return BadMatch;
+ for (i=0;i<num_types;i++) {
+ if ((rtrn= XkbCopyKeyType(from++,into++))!=Success)
+ return rtrn;
+ }
+ return Success;
+}
+
+XkbKeyTypePtr
+XkbAddKeyType( XkbDescPtr xkb,
+ Atom name,
+ int map_count,
+ Bool want_preserve,
+ int num_lvls)
+{
+register int i;
+unsigned tmp;
+XkbKeyTypePtr type;
+XkbClientMapPtr map;
+
+ if ((!xkb)||(num_lvls<1))
+ return NULL;
+ map= xkb->map;
+ if ((map)&&(map->types)) {
+ for (i=0;i<map->num_types;i++) {
+ if (map->types[i].name==name) {
+ Status status;
+ status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
+ return (status==Success?&map->types[i]:NULL);
+ }
+ }
+ }
+ if ((!map)||(!map->types)||(!map->num_types<XkbNumRequiredTypes)) {
+ tmp= XkbNumRequiredTypes+1;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,tmp)!=Success)
+ return NULL;
+ tmp= 0;
+ if (map->num_types<=XkbKeypadIndex)
+ tmp|= XkbKeypadMask;
+ if (map->num_types<=XkbAlphabeticIndex)
+ tmp|= XkbAlphabeticMask;
+ if (map->num_types<=XkbTwoLevelIndex)
+ tmp|= XkbTwoLevelMask;
+ if (map->num_types<=XkbOneLevelIndex)
+ tmp|= XkbOneLevelMask;
+ if (XkbInitCanonicalKeyTypes(xkb,tmp,XkbNoModifier)==Success) {
+ for (i=0;i<map->num_types;i++) {
+ Status status;
+ if (map->types[i].name!=name)
+ continue;
+ status=XkbResizeKeyType(xkb,i,map_count,want_preserve,num_lvls);
+ return (status==Success?&map->types[i]:NULL);
+ }
+ }
+ }
+ if ((map->num_types<=map->size_types)&&
+ (XkbAllocClientMap(xkb,XkbKeyTypesMask,map->num_types+1)!=Success)) {
+ return NULL;
+ }
+ type= &map->types[map->num_types];
+ map->num_types++;
+ bzero((char *)type,sizeof(XkbKeyTypeRec));
+ type->num_levels= num_lvls;
+ type->map_count= map_count;
+ type->name= name;
+ if (map_count>0) {
+ type->map= _XkbTypedCalloc(map_count,XkbKTMapEntryRec);
+ if (!type->map) {
+ map->num_types--;
+ return NULL;
+ }
+ if (want_preserve) {
+ type->preserve= _XkbTypedCalloc(map_count,XkbModsRec);
+ if (!type->preserve) {
+ _XkbFree(type->map);
+ map->num_types--;
+ return NULL;
+ }
+ }
+ }
+ return type;
+}
+
+Status
+XkbResizeKeyType( XkbDescPtr xkb,
+ int type_ndx,
+ int map_count,
+ Bool want_preserve,
+ int new_num_lvls)
+{
+XkbKeyTypePtr type;
+KeyCode matchingKeys[XkbMaxKeyCount],nMatchingKeys;
+
+ if ((type_ndx<0)||(type_ndx>=xkb->map->num_types)||(map_count<0)||
+ (new_num_lvls<1))
+ return BadValue;
+ switch (type_ndx) {
+ case XkbOneLevelIndex:
+ if (new_num_lvls!=1)
+ return BadMatch;
+ break;
+ case XkbTwoLevelIndex:
+ case XkbAlphabeticIndex:
+ case XkbKeypadIndex:
+ if (new_num_lvls!=2)
+ return BadMatch;
+ break;
+ }
+ type= &xkb->map->types[type_ndx];
+ if (map_count==0) {
+ if (type->map!=NULL)
+ _XkbFree(type->map);
+ type->map= NULL;
+ if (type->preserve!=NULL)
+ _XkbFree(type->preserve);
+ type->preserve= NULL;
+ type->map_count= 0;
+ }
+ else {
+ XkbKTMapEntryRec *prev_map = type->map;
+
+ if ((map_count>type->map_count)||(type->map==NULL))
+ type->map=_XkbTypedRealloc(type->map,map_count,XkbKTMapEntryRec);
+ if (!type->map) {
+ if (prev_map)
+ _XkbFree(prev_map);
+ return BadAlloc;
+ }
+ if (want_preserve) {
+ XkbModsRec *prev_preserve = type->preserve;
+
+ if ((map_count>type->map_count)||(type->preserve==NULL)) {
+ type->preserve= _XkbTypedRealloc(type->preserve,map_count,
+ XkbModsRec);
+ }
+ if (!type->preserve) {
+ if (prev_preserve)
+ _XkbFree(prev_preserve);
+ return BadAlloc;
+ }
+ }
+ else if (type->preserve!=NULL) {
+ _XkbFree(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= map_count;
+ }
+
+ if ((new_num_lvls>type->num_levels)||(type->level_names==NULL)) {
+ Atom * prev_level_names = type->level_names;
+
+ type->level_names=_XkbTypedRealloc(type->level_names,new_num_lvls,Atom);
+ if (!type->level_names) {
+ if (prev_level_names)
+ _XkbFree(prev_level_names);
+ return BadAlloc;
+ }
+ }
+ /*
+ * Here's the theory:
+ * If the width of the type changed, we might have to resize the symbol
+ * maps for any keys that use the type for one or more groups. This is
+ * expensive, so we'll try to cull out any keys that are obviously okay:
+ * In any case:
+ * - keys that have a group width <= the old width are okay (because
+ * they could not possibly have been associated with the old type)
+ * If the key type increased in size:
+ * - keys that already have a group width >= to the new width are okay
+ * + keys that have a group width >= the old width but < the new width
+ * might have to be enlarged.
+ * If the key type decreased in size:
+ * - keys that have a group width > the old width don't have to be
+ * resized (because they must have some other wider type associated
+ * with some group).
+ * + keys that have a group width == the old width might have to be
+ * shrunk.
+ * The possibilities marked with '+' require us to examine the key types
+ * associated with each group for the key.
+ */
+ bzero(matchingKeys,XkbMaxKeyCount*sizeof(KeyCode));
+ nMatchingKeys= 0;
+ if (new_num_lvls>type->num_levels) {
+ int nTotal;
+ KeySym * newSyms;
+ int width,match,nResize;
+ register int i,g,nSyms;
+
+ nResize= 0;
+ for (nTotal=1,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ if ((!match)||(width>=new_num_lvls))
+ nTotal+= XkbKeyNumSyms(xkb,i);
+ else {
+ nTotal+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ nResize++;
+ }
+ }
+ if (nResize>0) {
+ int nextMatch;
+ xkb->map->size_syms= (nTotal*12)/10;
+ newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
+ if (newSyms==NULL)
+ return BadAlloc;
+ nextMatch= 0;
+ nSyms= 1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (matchingKeys[nextMatch]==i) {
+ KeySym *pOld;
+ nextMatch++;
+ width= XkbKeyGroupsWidth(xkb,i);
+ pOld= XkbKeySymsPtr(xkb,i);
+ for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
+ memcpy(&newSyms[nSyms+(new_num_lvls*g)],&pOld[width*g],
+ width*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumGroups(xkb,i)*new_num_lvls;
+ }
+ else {
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),
+ XkbKeyNumSyms(xkb,i)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset= nSyms;
+ nSyms+= XkbKeyNumSyms(xkb,i);
+ }
+ }
+ type->num_levels= new_num_lvls;
+ _XkbFree(xkb->map->syms);
+ xkb->map->syms= newSyms;
+ xkb->map->num_syms= nSyms;
+ return Success;
+ }
+ }
+ else if (new_num_lvls<type->num_levels) {
+ int width,match;
+ register int g,i;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ width= XkbKeyGroupsWidth(xkb,i);
+ if (width<type->num_levels)
+ continue;
+ for (match=0,g=XkbKeyNumGroups(xkb,i)-1;(g>=0)&&(!match);g--) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)==type_ndx) {
+ matchingKeys[nMatchingKeys++]= i;
+ match= 1;
+ }
+ }
+ }
+ }
+ if (nMatchingKeys>0) {
+ int key,firstClear;
+ register int i,g;
+ if (new_num_lvls>type->num_levels)
+ firstClear= type->num_levels;
+ else firstClear= new_num_lvls;
+ for (i=0;i<nMatchingKeys;i++) {
+ KeySym * pSyms;
+ int width,nClear;
+
+ key= matchingKeys[i];
+ width= XkbKeyGroupsWidth(xkb,key);
+ nClear= width-firstClear;
+ pSyms= XkbKeySymsPtr(xkb,key);
+ for (g=XkbKeyNumGroups(xkb,key)-1;g>=0;g--) {
+ if (XkbKeyKeyTypeIndex(xkb,key,g)==type_ndx) {
+ if (nClear>0)
+ bzero(&pSyms[g*width+firstClear],nClear*sizeof(KeySym));
+ }
+ }
+ }
+ }
+ type->num_levels= new_num_lvls;
+ return Success;
+}
+
+KeySym *
+XkbResizeKeySyms(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nSyms,nKeySyms;
+unsigned nOldSyms;
+KeySym *newSyms;
+
+ if (needed==0) {
+ xkb->map->key_sym_map[key].offset= 0;
+ return xkb->map->syms;
+ }
+ nOldSyms= XkbKeyNumSyms(xkb,key);
+ if (nOldSyms>=(unsigned)needed) {
+ return XkbKeySymsPtr(xkb,key);
+ }
+ if (xkb->map->size_syms-xkb->map->num_syms>=(unsigned)needed) {
+ if (nOldSyms>0) {
+ memcpy(&xkb->map->syms[xkb->map->num_syms],XkbKeySymsPtr(xkb,key),
+ nOldSyms*sizeof(KeySym));
+ }
+ if ((needed-nOldSyms)>0) {
+ bzero(&xkb->map->syms[xkb->map->num_syms+XkbKeyNumSyms(xkb,key)],
+ (needed-nOldSyms)*sizeof(KeySym));
+ }
+ xkb->map->key_sym_map[key].offset = xkb->map->num_syms;
+ xkb->map->num_syms+= needed;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+ }
+ xkb->map->size_syms+= (needed>32?needed:32);
+ newSyms = _XkbTypedCalloc(xkb->map->size_syms,KeySym);
+ if (newSyms==NULL)
+ return NULL;
+ newSyms[0]= NoSymbol;
+ nSyms = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nCopy;
+
+ nCopy= nKeySyms= XkbKeyNumSyms(xkb,i);
+ if ((nKeySyms==0)&&(i!=key))
+ continue;
+ if (i==key)
+ nKeySyms= needed;
+ if (nCopy!=0)
+ memcpy(&newSyms[nSyms],XkbKeySymsPtr(xkb,i),nCopy*sizeof(KeySym));
+ if (nKeySyms>nCopy)
+ bzero(&newSyms[nSyms+nCopy],(nKeySyms-nCopy)*sizeof(KeySym));
+ xkb->map->key_sym_map[i].offset = nSyms;
+ nSyms+= nKeySyms;
+ }
+ _XkbFree(xkb->map->syms);
+ xkb->map->syms = newSyms;
+ xkb->map->num_syms = nSyms;
+ return &xkb->map->syms[xkb->map->key_sym_map[key].offset];
+}
+
+static unsigned
+_ExtendRange( unsigned int old_flags,
+ unsigned int flag,
+ KeyCode newKC,
+ KeyCode * old_min,
+ unsigned char * old_num)
+{
+ if ((old_flags&flag)==0) {
+ old_flags|= flag;
+ *old_min= newKC;
+ *old_num= 1;
+ }
+ else {
+ int last= (*old_min)+(*old_num)-1;
+ if (newKC<*old_min) {
+ *old_min= newKC;
+ *old_num= (last-newKC)+1;
+ }
+ else if (newKC>last) {
+ *old_num= (newKC-(*old_min))+1;
+ }
+ }
+ return old_flags;
+}
+
+Status
+XkbChangeKeycodeRange( XkbDescPtr xkb,
+ int minKC,
+ int maxKC,
+ XkbChangesPtr changes)
+{
+int tmp;
+
+ if ((!xkb)||(minKC<XkbMinLegalKeyCode)||(maxKC>XkbMaxLegalKeyCode))
+ return BadValue;
+ if (minKC>maxKC)
+ return BadMatch;
+ if (minKC<xkb->min_key_code) {
+ if (changes)
+ changes->map.min_key_code= minKC;
+ tmp= xkb->min_key_code-minKC;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ bzero((char *)&xkb->map->key_sym_map[minKC],
+ tmp*sizeof(XkbSymMapRec));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,minKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ bzero((char *)&xkb->map->modmap[minKC],tmp);
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ bzero((char *)&xkb->server->behaviors[minKC],
+ tmp*sizeof(XkbBehavior));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,minKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ bzero((char *)&xkb->server->key_acts[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,minKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ bzero((char *)&xkb->server->vmodmap[minKC],
+ tmp*sizeof(unsigned short));
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,minKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ bzero((char *)&xkb->names->keys[minKC],tmp*sizeof(XkbKeyNameRec));
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,minKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->min_key_code= minKC;
+ }
+ if (maxKC>xkb->max_key_code) {
+ if (changes)
+ changes->map.max_key_code= maxKC;
+ tmp= maxKC-xkb->max_key_code;
+ if (xkb->map) {
+ if (xkb->map->key_sym_map) {
+ XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map;
+
+ xkb->map->key_sym_map= _XkbTypedRealloc(xkb->map->key_sym_map,
+ (maxKC+1),XkbSymMapRec);
+ if (!xkb->map->key_sym_map) {
+ _XkbFree(prev_key_sym_map);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code+1],
+ tmp*sizeof(XkbSymMapRec));
+#else
+ bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
+ tmp*sizeof(XkbSymMapRec));
+#endif
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeySymsMask,maxKC,
+ &changes->map.first_key_sym,
+ &changes->map.num_key_syms);
+ }
+ }
+ if (xkb->map->modmap) {
+ unsigned char *prev_modmap = xkb->map->modmap;
+
+ xkb->map->modmap= _XkbTypedRealloc(xkb->map->modmap,
+ (maxKC+1),unsigned char);
+ if (!xkb->map->modmap) {
+ _XkbFree(prev_modmap);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->map->modmap[xkb->max_key_code+1],tmp);
+#else
+ bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
+#endif
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbModifierMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_modmap_keys);
+ }
+ }
+ }
+ if (xkb->server) {
+ if (xkb->server->behaviors) {
+ XkbBehavior *prev_behaviors = xkb->server->behaviors;
+
+ xkb->server->behaviors=_XkbTypedRealloc(xkb->server->behaviors,
+ (maxKC+1),XkbBehavior);
+ if (!xkb->server->behaviors) {
+ _XkbFree(prev_behaviors);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->server->behaviors[xkb->max_key_code+1],
+ tmp*sizeof(XkbBehavior));
+#else
+ bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
+ tmp*sizeof(XkbBehavior));
+#endif
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyBehaviorsMask,maxKC,
+ &changes->map.first_key_behavior,
+ &changes->map.num_key_behaviors);
+ }
+ }
+ if (xkb->server->key_acts) {
+ unsigned short *prev_key_acts = xkb->server->key_acts;
+
+ xkb->server->key_acts= _XkbTypedRealloc(xkb->server->key_acts,
+ (maxKC+1),unsigned short);
+ if (!xkb->server->key_acts) {
+ _XkbFree(prev_key_acts);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->server->key_acts[xkb->max_key_code+1],
+ tmp*sizeof(unsigned short));
+#else
+ bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+#endif
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbKeyActionsMask,maxKC,
+ &changes->map.first_key_act,
+ &changes->map.num_key_acts);
+ }
+ }
+ if (xkb->server->vmodmap) {
+ unsigned short *prev_vmodmap = xkb->server->vmodmap;
+
+ xkb->server->vmodmap= _XkbTypedRealloc(xkb->server->vmodmap,
+ (maxKC+1),unsigned short);
+ if (!xkb->server->vmodmap) {
+ _XkbFree(prev_vmodmap);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->server->vmodmap[xkb->max_key_code+1],
+ tmp*sizeof(unsigned short));
+#else
+ bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
+ tmp*sizeof(unsigned short));
+#endif
+ if (changes) {
+ changes->map.changed= _ExtendRange(changes->map.changed,
+ XkbVirtualModMapMask,maxKC,
+ &changes->map.first_modmap_key,
+ &changes->map.num_vmodmap_keys);
+ }
+ }
+ }
+ if ((xkb->names)&&(xkb->names->keys)) {
+ XkbKeyNameRec *prev_keys = xkb->names->keys;
+
+ xkb->names->keys= _XkbTypedRealloc(xkb->names->keys,
+ (maxKC+1),XkbKeyNameRec);
+ if (!xkb->names->keys) {
+ _XkbFree(prev_keys);
+ return BadAlloc;
+ }
+#ifdef NXAGENT_SERVER
+ bzero((char *)&xkb->names->keys[xkb->max_key_code+1],
+ tmp*sizeof(XkbKeyNameRec));
+#else
+ bzero((char *)&xkb->names->keys[xkb->max_key_code],
+ tmp*sizeof(XkbKeyNameRec));
+#endif
+ if (changes) {
+ changes->names.changed= _ExtendRange(changes->names.changed,
+ XkbKeyNamesMask,maxKC,
+ &changes->names.first_key,
+ &changes->names.num_keys);
+ }
+ }
+ xkb->max_key_code= maxKC;
+ }
+ return Success;
+}
+
+XkbAction *
+XkbResizeKeyActions(XkbDescPtr xkb,int key,int needed)
+{
+register int i,nActs;
+XkbAction *newActs;
+
+ if (needed==0) {
+ xkb->server->key_acts[key]= 0;
+ return NULL;
+ }
+ if (XkbKeyHasActions(xkb,key)&&(XkbKeyNumSyms(xkb,key)>=(unsigned)needed))
+ return XkbKeyActionsPtr(xkb,key);
+ if (xkb->server->size_acts-xkb->server->num_acts>=(unsigned)needed) {
+ xkb->server->key_acts[key]= xkb->server->num_acts;
+ xkb->server->num_acts+= needed;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+ }
+ xkb->server->size_acts= xkb->server->num_acts+needed+8;
+ newActs = _XkbTypedCalloc(xkb->server->size_acts,XkbAction);
+ if (newActs==NULL)
+ return NULL;
+ newActs[0].type = XkbSA_NoAction;
+ nActs = 1;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ int nKeyActs,nCopy;
+
+ if ((xkb->server->key_acts[i]==0)&&(i!=key))
+ continue;
+
+ nCopy= nKeyActs= XkbKeyNumActions(xkb,i);
+ if (i==key) {
+ nKeyActs= needed;
+ if (needed<nCopy)
+ nCopy= needed;
+ }
+
+ if (nCopy>0)
+ memcpy(&newActs[nActs],XkbKeyActionsPtr(xkb,i),
+ nCopy*sizeof(XkbAction));
+ if (nCopy<nKeyActs)
+ bzero(&newActs[nActs+nCopy],(nKeyActs-nCopy)*sizeof(XkbAction));
+ xkb->server->key_acts[i]= nActs;
+ nActs+= nKeyActs;
+ }
+ _XkbFree(xkb->server->acts);
+ xkb->server->acts = newActs;
+ xkb->server->num_acts= nActs;
+ return &xkb->server->acts[xkb->server->key_acts[key]];
+}
+
+void
+XkbFreeClientMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbClientMapPtr map;
+
+ if ((xkb==NULL)||(xkb->map==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllClientInfoMask;
+ map= xkb->map;
+ if (what&XkbKeyTypesMask) {
+ if (map->types!=NULL) {
+ if (map->num_types>0) {
+ register int i;
+ XkbKeyTypePtr type;
+ for (i=0,type=map->types;i<map->num_types;i++,type++) {
+ if (type->map!=NULL) {
+ _XkbFree(type->map);
+ type->map= NULL;
+ }
+ if (type->preserve!=NULL) {
+ _XkbFree(type->preserve);
+ type->preserve= NULL;
+ }
+ type->map_count= 0;
+ if (type->level_names!=NULL) {
+ _XkbFree(type->level_names);
+ type->level_names= NULL;
+ }
+ }
+ }
+ _XkbFree(map->types);
+ map->num_types= map->size_types= 0;
+ map->types= NULL;
+ }
+ }
+ if (what&XkbKeySymsMask) {
+ if (map->key_sym_map!=NULL) {
+ _XkbFree(map->key_sym_map);
+ map->key_sym_map= NULL;
+ }
+ if (map->syms!=NULL) {
+ _XkbFree(map->syms);
+ map->size_syms= map->num_syms= 0;
+ map->syms= NULL;
+ }
+ }
+ if ((what&XkbModifierMapMask)&&(map->modmap!=NULL)) {
+ _XkbFree(map->modmap);
+ map->modmap= NULL;
+ }
+ if (freeMap) {
+ _XkbFree(xkb->map);
+ xkb->map= NULL;
+ }
+ return;
+}
+
+void
+XkbFreeServerMap(XkbDescPtr xkb,unsigned what,Bool freeMap)
+{
+XkbServerMapPtr map;
+
+ if ((xkb==NULL)||(xkb->server==NULL))
+ return;
+ if (freeMap)
+ what= XkbAllServerInfoMask;
+ map= xkb->server;
+ if ((what&XkbExplicitComponentsMask)&&(map->explicit!=NULL)) {
+ _XkbFree(map->explicit);
+ map->explicit= NULL;
+ }
+ if (what&XkbKeyActionsMask) {
+ if (map->key_acts!=NULL) {
+ _XkbFree(map->key_acts);
+ map->key_acts= NULL;
+ }
+ if (map->acts!=NULL) {
+ _XkbFree(map->acts);
+ map->num_acts= map->size_acts= 0;
+ map->acts= NULL;
+ }
+ }
+ if ((what&XkbKeyBehaviorsMask)&&(map->behaviors!=NULL)) {
+ _XkbFree(map->behaviors);
+ map->behaviors= NULL;
+ }
+ if ((what&XkbVirtualModMapMask)&&(map->vmodmap!=NULL)) {
+ _XkbFree(map->vmodmap);
+ map->vmodmap= NULL;
+ }
+
+ if (freeMap) {
+ _XkbFree(xkb->server);
+ xkb->server= NULL;
+ }
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/XKBMisc.c b/nx-X11/programs/Xserver/xkb/XKBMisc.c
new file mode 100644
index 000000000..68edfde74
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/XKBMisc.c
@@ -0,0 +1,964 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <nx-X11/keysym.h>
+#include <xkbsrv.h>
+
+
+/***====================================================================***/
+
+#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec))
+static XkbKTMapEntryRec map2Level[]= {
+ { True, ShiftMask, {1, ShiftMask, 0} }
+};
+
+static XkbKTMapEntryRec mapAlpha[]= {
+ { True, ShiftMask, { 1, ShiftMask, 0 } },
+ { True, LockMask, { 0, LockMask, 0 } }
+};
+
+static XkbModsRec preAlpha[]= {
+ { 0, 0, 0 },
+ { LockMask, LockMask, 0 }
+};
+
+#define NL_VMOD_MASK 0
+static XkbKTMapEntryRec mapKeypad[]= {
+ { True, ShiftMask, { 1, ShiftMask, 0 } },
+ { False, 0, { 1, 0, NL_VMOD_MASK } }
+};
+
+static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = {
+ { { 0, 0, 0 },
+ 1, /* num_levels */
+ 0, /* map_count */
+ NULL, NULL,
+ None, NULL
+ },
+ { { ShiftMask, ShiftMask, 0 },
+ 2, /* num_levels */
+ mapSize(map2Level), /* map_count */
+ map2Level, NULL,
+ None, NULL
+ },
+ { { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
+ 2, /* num_levels */
+ mapSize(mapAlpha), /* map_count */
+ mapAlpha, preAlpha,
+ None, NULL
+ },
+ { { ShiftMask, ShiftMask, NL_VMOD_MASK },
+ 2, /* num_levels */
+ mapSize(mapKeypad), /* map_count */
+ mapKeypad, NULL,
+ None, NULL
+ }
+};
+
+Status
+XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod)
+{
+XkbClientMapPtr map;
+XkbKeyTypePtr from,to;
+Status rtrn;
+
+ if (!xkb)
+ return BadMatch;
+ rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes);
+ if (rtrn!=Success)
+ return rtrn;
+ map= xkb->map;
+ if ((which&XkbAllRequiredTypes)==0)
+ return Success;
+ rtrn= Success;
+ from= canonicalTypes;
+ to= map->types;
+ if (which&XkbOneLevelMask)
+ rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]);
+ if ((which&XkbTwoLevelMask)&&(rtrn==Success))
+ rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]);
+ if ((which&XkbAlphabeticMask)&&(rtrn==Success))
+ rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]);
+ if ((which&XkbKeypadMask)&&(rtrn==Success)) {
+ XkbKeyTypePtr type;
+ rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]);
+ type= &to[XkbKeypadIndex];
+ if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) {
+ type->mods.vmods= (1<<keypadVMod);
+ type->map[0].active= True;
+ type->map[0].mods.mask= ShiftMask;
+ type->map[0].mods.real_mods= ShiftMask;
+ type->map[0].mods.vmods= 0;
+ type->map[0].level= 1;
+ type->map[1].active= False;
+ type->map[1].mods.mask= 0;
+ type->map[1].mods.real_mods= 0;
+ type->map[1].mods.vmods= (1<<keypadVMod);
+ type->map[1].level= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol)
+#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l))
+
+int
+XkbKeyTypesForCoreSymbols( XkbDescPtr xkb,
+ int map_width,
+ KeySym * core_syms,
+ unsigned int protected,
+ int * types_inout,
+ KeySym * xkb_syms_rtrn)
+{
+register int i;
+unsigned int empty;
+int nSyms[XkbNumKbdGroups];
+int nGroups,tmp,groupsWidth;
+
+ /* Section 12.2 of the protocol describes this process in more detail */
+ /* Step 1: find the # of symbols in the core mapping per group */
+ groupsWidth= 2;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) {
+ nSyms[i]= xkb->map->types[types_inout[i]].num_levels;
+ if (nSyms[i]>groupsWidth)
+ groupsWidth= nSyms[i];
+ }
+ else {
+ types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */
+ nSyms[i]= 2;
+ }
+ }
+ if (nSyms[XkbGroup1Index]<2)
+ nSyms[XkbGroup1Index]= 2;
+ if (nSyms[XkbGroup2Index]<2)
+ nSyms[XkbGroup2Index]= 2;
+ /* Step 2: Copy the symbols from the core ordering to XKB ordering */
+ /* symbols in the core are in the order: */
+ /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1);
+ for (i=2;i<nSyms[XkbGroup1Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i);
+ }
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2);
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3);
+ tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */
+ for (i=2;i<nSyms[XkbGroup2Index];i++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i);
+ }
+ tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index];
+ if ((tmp>=map_width)&&
+ ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) {
+ nSyms[XkbGroup3Index]= 0;
+ nSyms[XkbGroup4Index]= 0;
+ nGroups= 2;
+ }
+ else {
+ nGroups= 3;
+ for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp);
+ }
+ if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) {
+ nGroups= 4;
+ for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) {
+ xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp);
+ }
+ }
+ else {
+ nSyms[XkbGroup4Index]= 0;
+ }
+ }
+ /* steps 3&4: alphanumeric expansion, assign canonical types */
+ empty= 0;
+ for (i=0;i<nGroups;i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) {
+ KeySym upper,lower;
+ XConvertCase(syms[0],&lower,&upper);
+ if (upper!=lower) {
+ xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower;
+ xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper;
+ if ((protected&(1<<i))==0)
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ else if ((protected&(1<<i))==0) {
+ types_inout[i]= XkbOneLevelIndex;
+ /* nSyms[i]= 1;*/
+ }
+ }
+ if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) {
+ if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1]))
+ types_inout[i]= XkbKeypadIndex;
+ else {
+ KeySym upper,lower;
+ XConvertCase(syms[0],&lower,&upper);
+ if ((syms[0]==lower)&&(syms[1]==upper))
+ types_inout[i]= XkbAlphabeticIndex;
+ }
+ }
+ if (syms[0]==NoSymbol) {
+ register int n;
+ Bool found;
+ for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) {
+ found= (syms[n]!=NoSymbol);
+ }
+ if (!found)
+ empty|= (1<<i);
+ }
+ }
+ /* step 5: squoosh out empty groups */
+ if (empty) {
+ for (i=nGroups-1;i>=0;i--) {
+ if (((empty&(1<<i))==0)||(protected&(1<<i)))
+ break;
+ nGroups--;
+ }
+ }
+ if (nGroups<1)
+ return 0;
+
+ /* step 6: replicate group 1 into group two, if necessary */
+ if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) {
+ if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) {
+ nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index];
+ types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index];
+ memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn,
+ 2*sizeof(KeySym));
+ }
+ else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) {
+ memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]],
+ (char *)xkb_syms_rtrn,
+ nSyms[XkbGroup1Index]*sizeof(KeySym));
+ }
+ }
+
+ /* step 7: check for all groups identical or all width 1 */
+ if (nGroups>1) {
+ Bool sameType,allOneLevel;
+ allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1);
+ for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) {
+ sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index]));
+ if (allOneLevel)
+ allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1);
+ }
+ if ((sameType)&&
+ (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){
+ register int s;
+ Bool identical;
+ for (i=1,identical=True;identical&&(i<nGroups);i++) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)];
+ for (s=0;identical&&(s<nSyms[i]);s++) {
+ if (syms[s]!=xkb_syms_rtrn[s])
+ identical= False;
+ }
+ }
+ if (identical)
+ nGroups= 1;
+ }
+ if (allOneLevel && (nGroups>1)) {
+ KeySym *syms;
+ syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]];
+ nSyms[XkbGroup1Index]= 1;
+ for (i=1;i<nGroups;i++) {
+ xkb_syms_rtrn[i]= syms[0];
+ syms+= nSyms[i];
+ nSyms[i]= 1;
+ }
+ }
+ }
+ return nGroups;
+}
+
+static XkbSymInterpretPtr
+_XkbFindMatchingInterp( XkbDescPtr xkb,
+ KeySym sym,
+ unsigned int real_mods,
+ unsigned int level)
+{
+register unsigned i;
+XkbSymInterpretPtr interp,rtrn;
+CARD8 mods;
+
+ rtrn= NULL;
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ if ((interp->sym==NoSymbol)||(sym==interp->sym)) {
+ int match;
+ if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0))
+ mods= real_mods;
+ else mods= 0;
+ switch (interp->match&XkbSI_OpMask) {
+ case XkbSI_NoneOf:
+ match= ((interp->mods&mods)==0);
+ break;
+ case XkbSI_AnyOfOrNone:
+ match= ((mods==0)||((interp->mods&mods)!=0));
+ break;
+ case XkbSI_AnyOf:
+ match= ((interp->mods&mods)!=0);
+ break;
+ case XkbSI_AllOf:
+ match= ((interp->mods&mods)==interp->mods);
+ break;
+ case XkbSI_Exactly:
+ match= (interp->mods==mods);
+ break;
+ default:
+ match= 0;
+ break;
+ }
+ if (match) {
+ if (interp->sym!=NoSymbol) {
+ return interp;
+ }
+ else if (rtrn==NULL) {
+ rtrn= interp;
+ }
+ }
+ }
+ }
+ return rtrn;
+}
+
+static void
+_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey)
+{
+KeyCode last;
+
+ last= (*pFirst)+(*pNum);
+ if (newKey<*pFirst) {
+ *pFirst= newKey;
+ *pNum= (last-newKey)+1;
+ }
+ else if (newKey>last) {
+ *pNum= (last-*pFirst)+1;
+ }
+ return;
+}
+
+static void
+_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask|= tmp;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask|= tmp;
+ }
+ break;
+ }
+ return;
+}
+
+#define IBUF_SIZE 8
+
+Bool
+XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes)
+{
+KeySym * syms;
+unsigned char explicit,mods;
+XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE];
+int n,nSyms,found;
+unsigned changed,tmp;
+
+ if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)||
+ (!xkb->compat)||(!xkb->compat->sym_interpret)||
+ (key<xkb->min_key_code)||(key>xkb->max_key_code)) {
+ return False;
+ }
+ if (((!xkb->server)||(!xkb->server->key_acts))&&
+ (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) {
+ return False;
+ }
+ changed= 0; /* keeps track of what has changed in _this_ call */
+ explicit= xkb->server->explicit[key];
+ if (explicit&XkbExplicitInterpretMask) /* nothing to do */
+ return True;
+ mods= (xkb->map->modmap?xkb->map->modmap[key]:0);
+ nSyms= XkbKeyNumSyms(xkb,key);
+ syms= XkbKeySymsPtr(xkb,key);
+ if (nSyms>IBUF_SIZE) {
+ interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr);
+ if (interps==NULL) {
+ interps= ibuf;
+ nSyms= IBUF_SIZE;
+ }
+ }
+ else {
+ interps= ibuf;
+ }
+ found= 0;
+ for (n=0;n<nSyms;n++) {
+ unsigned level= (n%XkbKeyGroupsWidth(xkb,key));
+ interps[n]= NULL;
+ if (syms[n]!=NoSymbol) {
+ interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level);
+ if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction)
+ found++;
+ else interps[n]= NULL;
+ }
+ }
+ /* 1/28/96 (ef) -- XXX! WORKING HERE */
+ if (!found) {
+ if (xkb->server->key_acts[key]!=0) {
+ xkb->server->key_acts[key]= 0;
+ changed|= XkbKeyActionsMask;
+ }
+ }
+ else {
+ XkbAction *pActs;
+ unsigned int new_vmodmask;
+ changed|= XkbKeyActionsMask;
+ pActs= XkbResizeKeyActions(xkb,key,nSyms);
+ if (!pActs)
+ return False;
+ new_vmodmask= 0;
+ for (n=0;n<nSyms;n++) {
+ if (interps[n]) {
+ unsigned effMods;
+
+ pActs[n]= *((XkbAction *)&interps[n]->act);
+ if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) {
+ effMods= mods;
+ if (interps[n]->virtual_mod!=XkbNoModifier)
+ new_vmodmask|= (1<<interps[n]->virtual_mod);
+ }
+ else effMods= 0;
+ _XkbSetActionKeyMods(xkb,&pActs[n],effMods);
+ }
+ else pActs[n].type= XkbSA_NoAction;
+ }
+ if (((explicit&XkbExplicitVModMapMask)==0)&&
+ (xkb->server->vmodmap[key]!=new_vmodmask)) {
+ changed|= XkbVirtualModMapMask;
+ xkb->server->vmodmap[key]= new_vmodmask;
+ }
+ if (interps[0]) {
+ if ((interps[0]->flags&XkbSI_LockingKey)&&
+ ((explicit&XkbExplicitBehaviorMask)==0)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+ if (interps[0]->flags&XkbSI_AutoRepeat)
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ }
+ }
+ if ((!found)||(interps[0]==NULL)) {
+ if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) {
+ CARD8 old;
+ old= xkb->ctrls->per_key_repeat[key/8];
+#ifdef RETURN_SHOULD_REPEAT
+ if (*XkbKeySymsPtr(xkb,key) != XK_Return)
+#endif
+ xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8));
+ if (changes && (old!=xkb->ctrls->per_key_repeat[key/8]))
+ changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask;
+ }
+ if (((explicit&XkbExplicitBehaviorMask)==0)&&
+ (xkb->server->behaviors[key].type==XkbKB_Lock)) {
+ xkb->server->behaviors[key].type= XkbKB_Default;
+ changed|= XkbKeyBehaviorsMask;
+ }
+ }
+ if (changes) {
+ XkbMapChangesPtr mc;
+ mc= &changes->map;
+ tmp= (changed&mc->changed);
+ if (tmp&XkbKeyActionsMask)
+ _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key);
+ else if (changed&XkbKeyActionsMask) {
+ mc->changed|= XkbKeyActionsMask;
+ mc->first_key_act= key;
+ mc->num_key_acts= 1;
+ }
+ if (tmp&XkbKeyBehaviorsMask) {
+ _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors,
+ key);
+ }
+ else if (changed&XkbKeyBehaviorsMask) {
+ mc->changed|= XkbKeyBehaviorsMask;
+ mc->first_key_behavior= key;
+ mc->num_key_behaviors= 1;
+ }
+ if (tmp&XkbVirtualModMapMask)
+ _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key);
+ else if (changed&XkbVirtualModMapMask) {
+ mc->changed|= XkbVirtualModMapMask;
+ mc->first_vmodmap_key= key;
+ mc->num_vmodmap_keys= 1;
+ }
+ mc->changed|= changed;
+ }
+ if (interps!=ibuf)
+ _XkbFree(interps);
+ return True;
+}
+
+Bool
+XkbUpdateMapFromCore( XkbDescPtr xkb,
+ KeyCode first_key,
+ int num_keys,
+ int map_width,
+ KeySym * core_keysyms,
+ XkbChangesPtr changes)
+{
+register int key,last_key;
+KeySym * syms;
+
+ syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width];
+ if (changes) {
+ if (changes->map.changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->map.first_key_sym,
+ &changes->map.num_key_syms,first_key);
+ if (num_keys>1) {
+ _XkbAddKeyChange(&changes->map.first_key_sym,
+ &changes->map.num_key_syms,
+ first_key+num_keys-1);
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym= first_key;
+ changes->map.num_key_syms= num_keys;
+ }
+ }
+ last_key= first_key+num_keys-1;
+ for (key=first_key;key<=last_key;key++,syms+= map_width) {
+ XkbMapChangesPtr mc;
+ unsigned explicit;
+ KeySym tsyms[XkbMaxSymsPerKey];
+ int types[XkbNumKbdGroups];
+ int nG;
+
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms);
+ if (changes)
+ mc= &changes->map;
+ else mc= NULL;
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&&
+ (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes && (changes->map.changed&XkbVirtualModsMask))
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+ return True;
+}
+
+Status
+XkbChangeTypesOfKey( XkbDescPtr xkb,
+ int key,
+ int nGroups,
+ unsigned groups,
+ int * newTypesIn,
+ XkbMapChangesPtr changes)
+{
+XkbKeyTypePtr pOldType,pNewType;
+register int i;
+int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
+
+ if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
+ (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)||
+ (nGroups>XkbNumKbdGroups)) {
+ return BadMatch;
+ }
+ if (nGroups==0) {
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex;
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,0);
+ xkb->map->key_sym_map[key].group_info= i;
+ XkbResizeKeySyms(xkb,key,0);
+ return Success;
+ }
+
+ nOldGroups= XkbKeyNumGroups(xkb,key);
+ oldWidth= XkbKeyGroupsWidth(xkb,key);
+ for (width=i=0;i<nGroups;i++) {
+ if (groups&(1<<i))
+ newTypes[i]= newTypesIn[i];
+ else if (i<nOldGroups)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i);
+ else if (nOldGroups>0)
+ newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ else newTypes[i]= XkbTwoLevelIndex;
+ if (newTypes[i]>xkb->map->num_types)
+ return BadMatch;
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>width)
+ width= pNewType->num_levels;
+ }
+ if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups))
+ xkb->ctrls->num_groups= nGroups;
+ if ((width!=oldWidth)||(nGroups!=nOldGroups)) {
+ KeySym oldSyms[XkbMaxSymsPerKey],*pSyms;
+ int nCopy;
+
+ if (nOldGroups==0) {
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms!=NULL) {
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ }
+ return Success;
+ }
+ return BadAlloc;
+ }
+ pSyms= XkbKeySymsPtr(xkb,key);
+ memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ pSyms= XkbResizeKeySyms(xkb,key,width*nGroups);
+ if (pSyms==NULL)
+ return BadAlloc;
+ bzero(pSyms,width*nGroups*sizeof(KeySym));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym));
+ }
+ if (XkbKeyHasActions(xkb,key)) {
+ XkbAction oldActs[XkbMaxSymsPerKey],*pActs;
+ pActs= XkbKeyActionsPtr(xkb,key);
+ memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction));
+ pActs= XkbResizeKeyActions(xkb,key,width*nGroups);
+ if (pActs==NULL)
+ return BadAlloc;
+ bzero(pActs,width*nGroups*sizeof(XkbAction));
+ for (i=0;(i<nGroups)&&(i<nOldGroups);i++) {
+ pOldType= XkbKeyKeyType(xkb,key,i);
+ pNewType= &xkb->map->types[newTypes[i]];
+ if (pNewType->num_levels>pOldType->num_levels)
+ nCopy= pOldType->num_levels;
+ else nCopy= pNewType->num_levels;
+ memcpy(&pActs[i*width],&oldActs[i*oldWidth],
+ nCopy*sizeof(XkbAction));
+ }
+ }
+ i= xkb->map->key_sym_map[key].group_info;
+ i= XkbSetNumGroups(i,nGroups);
+ xkb->map->key_sym_map[key].group_info= i;
+ xkb->map->key_sym_map[key].width= width;
+ }
+ width= 0;
+ for (i=0;i<nGroups;i++) {
+ xkb->map->key_sym_map[key].kt_index[i]= newTypes[i];
+ if (xkb->map->types[newTypes[i]].num_levels>width)
+ width= xkb->map->types[newTypes[i]].num_levels;
+ }
+ xkb->map->key_sym_map[key].width= width;
+ if (changes!=NULL) {
+ if (changes->changed&XkbKeySymsMask) {
+ _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms,
+ key);
+ }
+ else {
+ changes->changed|= XkbKeySymsMask;
+ changes->first_key_sym= key;
+ changes->num_key_syms= 1;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+Bool
+XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn)
+{
+register int i,bit;
+register unsigned mask;
+
+ if (xkb==NULL)
+ return False;
+ if (virtual_mask==0) {
+ *mask_rtrn= 0;
+ return True;
+ }
+ if (xkb->server==NULL)
+ return False;
+ for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (virtual_mask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ *mask_rtrn= mask;
+ return True;
+}
+
+/***====================================================================***/
+
+Bool
+XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed)
+{
+unsigned int tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->mods.mask= act->mods.real_mods;
+ act->mods.mask|= tmp;
+ return True;
+ }
+ break;
+ case XkbSA_ISOLock:
+ if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) {
+ XkbVirtualModsToReal(xkb,tmp,&tmp);
+ act->iso.mask= act->iso.real_mods;
+ act->iso.mask|= tmp;
+ return True;
+ }
+ break;
+ }
+ return False;
+}
+
+void
+XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb,
+ XkbKeyTypePtr type,
+ unsigned int changed,
+ XkbChangesPtr changes)
+{
+register unsigned int i;
+unsigned int mask = 0;
+
+ XkbVirtualModsToReal(xkb,type->mods.vmods,&mask);
+ type->mods.mask= type->mods.real_mods|mask;
+ if ((type->map_count>0)&&(type->mods.vmods!=0)) {
+ XkbKTMapEntryPtr entry;
+ for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+ if (entry->mods.vmods!=0) {
+ XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask);
+ entry->mods.mask=entry->mods.real_mods|mask;
+ /* entry is active if vmods are bound*/
+ entry->active= (mask!=0);
+ }
+ else entry->active= 1;
+ }
+ }
+ if (changes) {
+ int type_ndx;
+ type_ndx= type-xkb->map->types;
+ if ((type_ndx<0)||(type_ndx>xkb->map->num_types))
+ return;
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int last;
+ last= changes->map.first_type+changes->map.num_types-1;
+ if (type_ndx<changes->map.first_type) {
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= (last-type_ndx)+1;
+ }
+ else if (type_ndx>last) {
+ changes->map.num_types= (type_ndx-changes->map.first_type)+1;
+ }
+ }
+ else {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= type_ndx;
+ changes->map.num_types= 1;
+ }
+ }
+ return;
+}
+
+Bool
+XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes)
+{
+register int i;
+unsigned int checkState = 0;
+
+ if ((!xkb) || (!xkb->map) || (changed==0))
+ return False;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].mods.vmods & changed)
+ XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes);
+ }
+ if (changed&xkb->ctrls->internal.vmods) {
+ unsigned int newMask = 0;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask);
+ newMask|= xkb->ctrls->internal.real_mods;
+ if (xkb->ctrls->internal.mask!=newMask) {
+ xkb->ctrls->internal.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbInternalModsMask;
+ checkState= True;
+ }
+ }
+ }
+ if (changed&xkb->ctrls->ignore_lock.vmods) {
+ unsigned int newMask = 0;
+ XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask);
+ newMask|= xkb->ctrls->ignore_lock.real_mods;
+ if (xkb->ctrls->ignore_lock.mask!=newMask) {
+ xkb->ctrls->ignore_lock.mask= newMask;
+ if (changes) {
+ changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask;
+ checkState= True;
+ }
+ }
+ }
+ if (xkb->indicators!=NULL) {
+ XkbIndicatorMapPtr map;
+ map= &xkb->indicators->maps[0];
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed) {
+ unsigned int newMask = 0;
+ XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask);
+ newMask|= map->mods.real_mods;
+ if (newMask!=map->mods.mask) {
+ map->mods.mask= newMask;
+ if (changes) {
+ changes->indicators.map_changes|= (1<<i);
+ checkState= True;
+ }
+ }
+ }
+ }
+ }
+ if (xkb->compat!=NULL) {
+ XkbCompatMapPtr compat;
+ compat= xkb->compat;
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ unsigned int newMask = 0;
+ XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask);
+ newMask|= compat->groups[i].real_mods;
+ if (compat->groups[i].mask!=newMask) {
+ compat->groups[i].mask= newMask;
+ if (changes) {
+ changes->compat.changed_groups|= (1<<i);
+ checkState= True;
+ }
+ }
+ }
+ }
+ if (xkb->map && xkb->server) {
+ int highChange = 0, lowChange = -1;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyHasActions(xkb,i)) {
+ register XkbAction *pAct;
+ register int n;
+
+ pAct= XkbKeyActionsPtr(xkb,i);
+ for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) {
+ if ((pAct->type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,pAct,changed)) {
+ if (lowChange<0)
+ lowChange= i;
+ highChange= i;
+ }
+ }
+ }
+ }
+ if (changes && (lowChange>0)) { /* something changed */
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int last;
+ if (changes->map.first_key_act<lowChange)
+ lowChange= changes->map.first_key_act;
+ last= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (last>highChange)
+ highChange= last;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= lowChange;
+ changes->map.num_key_acts= (highChange-lowChange)+1;
+ }
+ }
+ return checkState;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxBeep.c b/nx-X11/programs/Xserver/xkb/ddxBeep.c
new file mode 100644
index 000000000..fa4af7456
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxBeep.c
@@ -0,0 +1,338 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+/*#define FALLING_TONE 1*/
+/*#define RISING_TONE 1*/
+#define FALLING_TONE 10
+#define RISING_TONE 10
+#define SHORT_TONE 50
+#define SHORT_DELAY 60
+#define LONG_TONE 75
+#define VERY_LONG_TONE 100
+#define LONG_DELAY 85
+#define CLICK_DURATION 1
+
+#define DEEP_PITCH 250
+#define LOW_PITCH 500
+#define MID_PITCH 1000
+#define HIGH_PITCH 2000
+#define CLICK_PITCH 1500
+
+static unsigned long atomGeneration= 0;
+static Atom featureOn;
+static Atom featureOff;
+static Atom featureChange;
+static Atom ledOn;
+static Atom ledOff;
+static Atom ledChange;
+static Atom slowWarn;
+static Atom slowPress;
+static Atom slowReject;
+static Atom slowAccept;
+static Atom slowRelease;
+static Atom stickyLatch;
+static Atom stickyLock;
+static Atom stickyUnlock;
+static Atom bounceReject;
+static char doesPitch = 1;
+
+#define FEATURE_ON "AX_FeatureOn"
+#define FEATURE_OFF "AX_FeatureOff"
+#define FEATURE_CHANGE "AX_FeatureChange"
+#define LED_ON "AX_IndicatorOn"
+#define LED_OFF "AX_IndicatorOff"
+#define LED_CHANGE "AX_IndicatorChange"
+#define SLOW_WARN "AX_SlowKeysWarning"
+#define SLOW_PRESS "AX_SlowKeyPress"
+#define SLOW_REJECT "AX_SlowKeyReject"
+#define SLOW_ACCEPT "AX_SlowKeyAccept"
+#define SLOW_RELEASE "AX_SlowKeyRelease"
+#define STICKY_LATCH "AX_StickyLatch"
+#define STICKY_LOCK "AX_StickyLock"
+#define STICKY_UNLOCK "AX_StickyUnlock"
+#define BOUNCE_REJECT "AX_BounceKeyReject"
+
+#define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,True)
+
+static void
+_XkbDDXBeepInitAtoms(void)
+{
+ featureOn= MAKE_ATOM(FEATURE_ON);
+ featureOff= MAKE_ATOM(FEATURE_OFF);
+ featureChange= MAKE_ATOM(FEATURE_CHANGE);
+ ledOn= MAKE_ATOM(LED_ON);
+ ledOff= MAKE_ATOM(LED_OFF);
+ ledChange= MAKE_ATOM(LED_CHANGE);
+ slowWarn= MAKE_ATOM(SLOW_WARN);
+ slowPress= MAKE_ATOM(SLOW_PRESS);
+ slowReject= MAKE_ATOM(SLOW_REJECT);
+ slowAccept= MAKE_ATOM(SLOW_ACCEPT);
+ slowRelease= MAKE_ATOM(SLOW_RELEASE);
+ stickyLatch= MAKE_ATOM(STICKY_LATCH);
+ stickyLock= MAKE_ATOM(STICKY_LOCK);
+ stickyUnlock= MAKE_ATOM(STICKY_UNLOCK);
+ bounceReject= MAKE_ATOM(BOUNCE_REJECT);
+#if defined(sun)
+ doesPitch = 0;
+#endif
+ return;
+}
+
+static CARD32
+_XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+DeviceIntPtr dev= (DeviceIntPtr)arg;
+KbdFeedbackPtr feed;
+KeybdCtrl * ctrl;
+XkbSrvInfoPtr xkbInfo;
+CARD32 next;
+int pitch,duration;
+int oldPitch,oldDuration;
+Atom name;
+
+ if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)||
+ (dev->kbdfeed==NULL))
+ return 0;
+ if (atomGeneration!=serverGeneration) {
+ _XkbDDXBeepInitAtoms();
+ atomGeneration= serverGeneration;
+ }
+
+ feed= dev->kbdfeed;
+ ctrl= &feed->ctrl;
+ xkbInfo= dev->key->xkbInfo;
+ next= 0;
+ pitch= oldPitch= ctrl->bell_pitch;
+ duration= oldDuration= ctrl->bell_duration;
+#ifdef DEBUG
+ if (xkbDebugFlags>1)
+ ErrorF("beep: %d (count= %d)\n",xkbInfo->beepType,xkbInfo->beepCount);
+#endif
+ name= None;
+ switch (xkbInfo->beepType) {
+ default:
+ ErrorF("Unknown beep type %d\n",xkbInfo->beepType);
+ case _BEEP_NONE:
+ duration= 0;
+ break;
+
+ /* When an LED is turned on, we want a high-pitched beep.
+ * When the LED it turned off, we want a low-pitched beep.
+ * If we cannot do pitch, we want a single beep for on and two
+ * beeps for off.
+ */
+ case _BEEP_LED_ON:
+ if (name==None) name= ledOn;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ break;
+ case _BEEP_LED_OFF:
+ if (name==None) name= ledOff;
+ duration= SHORT_TONE;
+ pitch= LOW_PITCH;
+ if (!doesPitch && xkbInfo->beepCount<1)
+ next = SHORT_DELAY;
+ break;
+
+ /* When a Feature is turned on, we want an up-siren.
+ * When a Feature is turned off, we want a down-siren.
+ * If we cannot do pitch, we want a single beep for on and two
+ * beeps for off.
+ */
+ case _BEEP_FEATURE_ON:
+ if (name==None) name= featureOn;
+ if (xkbInfo->beepCount<1) {
+ pitch= LOW_PITCH;
+ duration= VERY_LONG_TONE;
+ if (doesPitch)
+ next= SHORT_DELAY;
+ }
+ else {
+ pitch= MID_PITCH;
+ duration= SHORT_TONE;
+ }
+ break;
+
+ case _BEEP_FEATURE_OFF:
+ if (name==None) name= featureOff;
+ if (xkbInfo->beepCount<1) {
+ pitch= MID_PITCH;
+ if (doesPitch)
+ duration= VERY_LONG_TONE;
+ else duration= SHORT_TONE;
+ next= SHORT_DELAY;
+ }
+ else {
+ pitch= LOW_PITCH;
+ duration= SHORT_TONE;
+ }
+ break;
+
+ /* Two high beeps indicate an LED or Feature changed
+ * state, but that another LED or Feature is also on.
+ * [[[WDW - This is not in AccessDOS ]]]
+ */
+ case _BEEP_LED_CHANGE:
+ if (name==None) name= ledChange;
+ case _BEEP_FEATURE_CHANGE:
+ if (name==None) name= featureChange;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ if (xkbInfo->beepCount<1) {
+ next= SHORT_DELAY;
+ }
+ break;
+
+ /* Three high-pitched beeps are the warning that SlowKeys
+ * is going to be turned on or off.
+ */
+ case _BEEP_SLOW_WARN:
+ if (name==None) name= slowWarn;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ if (xkbInfo->beepCount<2)
+ next= SHORT_DELAY;
+ break;
+
+ /* Click on SlowKeys press and accept.
+ * Deep pitch when a SlowKey or BounceKey is rejected.
+ * [[[WDW - Rejects are not in AccessDOS ]]]
+ * If we cannot do pitch, we want single beeps.
+ */
+ case _BEEP_SLOW_PRESS:
+ if (name==None) name= slowPress;
+ case _BEEP_SLOW_ACCEPT:
+ if (name==None) name= slowAccept;
+ case _BEEP_SLOW_RELEASE:
+ if (name==None) name= slowRelease;
+ duration= CLICK_DURATION;
+ pitch= CLICK_PITCH;
+ break;
+ case _BEEP_BOUNCE_REJECT:
+ if (name==None) name= bounceReject;
+ case _BEEP_SLOW_REJECT:
+ if (name==None) name= slowReject;
+ duration= SHORT_TONE;
+ pitch= DEEP_PITCH;
+ break;
+
+ /* Low followed by high pitch when a StickyKey is latched.
+ * High pitch when a StickyKey is locked.
+ * Low pitch when unlocked.
+ * If we cannot do pitch, two beeps for latch, nothing for
+ * lock, and two for unlock.
+ */
+ case _BEEP_STICKY_LATCH:
+ if (name==None) name= stickyLatch;
+ duration= SHORT_TONE;
+ if (xkbInfo->beepCount<1) {
+ next= SHORT_DELAY;
+ pitch= LOW_PITCH;
+ }
+ else pitch= HIGH_PITCH;
+ break;
+ case _BEEP_STICKY_LOCK:
+ if (name==None) name= stickyLock;
+ if (doesPitch) {
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ }
+ break;
+ case _BEEP_STICKY_UNLOCK:
+ if (name==None) name= stickyUnlock;
+ duration= SHORT_TONE;
+ pitch= LOW_PITCH;
+ if (!doesPitch && xkbInfo->beepCount<1)
+ next = SHORT_DELAY;
+ break;
+ }
+ if (timer == NULL && duration>0) {
+ CARD32 starttime = GetTimeInMillis();
+ CARD32 elapsedtime;
+
+ ctrl->bell_duration= duration;
+ ctrl->bell_pitch= pitch;
+ if (xkbInfo->beepCount==0) {
+ XkbHandleBell(0,0,dev,ctrl->bell,(void *)ctrl,KbdFeedbackClass,name,None,
+ NULL);
+ }
+ else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
+ (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(void *)ctrl,KbdFeedbackClass);
+ }
+ ctrl->bell_duration= oldDuration;
+ ctrl->bell_pitch= oldPitch;
+ xkbInfo->beepCount++;
+
+ /* Some DDX schedule the beep and return immediately, others don't
+ return until the beep is completed. We measure the time and if
+ it's less than the beep duration, make sure not to schedule the
+ next beep until after the current one finishes. */
+
+ elapsedtime = GetTimeInMillis();
+ if (elapsedtime > starttime) { /* watch out for millisecond counter
+ overflow! */
+ elapsedtime -= starttime;
+ } else {
+ elapsedtime = 0;
+ }
+ if (elapsedtime < duration) {
+ next += duration - elapsedtime;
+ }
+
+ }
+ return next;
+}
+
+int
+XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which)
+{
+XkbSrvInfoRec *xkbInfo= dev->key->xkbInfo;
+CARD32 next;
+
+ xkbInfo->beepType= what;
+ xkbInfo->beepCount= 0;
+ next= _XkbDDXBeepExpire(NULL,0,(void *)dev);
+ if (next>0) {
+ xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
+ 0, next,
+ _XkbDDXBeepExpire, (void *)dev);
+ }
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxConfig.c b/nx-X11/programs/Xserver/xkb/ddxConfig.c
new file mode 100644
index 000000000..0046b853e
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxConfig.c
@@ -0,0 +1,208 @@
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "os.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XKBconfig.h>
+
+Bool
+XkbDDXApplyConfig(XPointer cfg_in,XkbSrvInfoPtr info)
+{
+XkbConfigRtrnPtr rtrn;
+XkbDescPtr xkb;
+Bool ok;
+XkbEventCauseRec cause;
+
+ xkb= info->desc;
+ rtrn= (XkbConfigRtrnPtr)cfg_in;
+ if (rtrn==NULL)
+ return True;
+ ok= XkbCFApplyRtrnValues(rtrn,XkbCFDflts,xkb);
+ if (rtrn->initial_mods.replace) {
+ info->state.locked_mods= rtrn->initial_mods.mods;
+ }
+ else {
+ info->state.locked_mods|= rtrn->initial_mods.mods;
+ if (rtrn->initial_mods.mods_clear)
+ info->state.locked_mods&= ~rtrn->initial_mods.mods_clear;
+ }
+ XkbComputeDerivedState(info);
+ XkbSetCauseUnknown(&cause);
+ XkbUpdateIndicators(info->device,XkbAllIndicatorsMask,False,NULL,&cause);
+ if (info->device && info->device->kbdfeed) {
+ DeviceIntPtr dev;
+ KeybdCtrl newCtrl;
+ dev= info->device;
+ newCtrl= dev->kbdfeed->ctrl;
+ if (rtrn->click_volume>=0)
+ newCtrl.click= rtrn->click_volume;
+ if (rtrn->bell_volume>=0)
+ newCtrl.bell= rtrn->bell_volume;
+ if (rtrn->bell_pitch>0)
+ newCtrl.bell_pitch= rtrn->bell_pitch;
+ if (rtrn->bell_duration>0)
+ newCtrl.bell_duration= rtrn->bell_duration;
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&newCtrl);
+ }
+ XkbCFFreeRtrn(rtrn,XkbCFDflts,xkb);
+ return ok;
+}
+
+XPointer
+XkbDDXPreloadConfig( char ** rulesRtrn,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names,
+ DeviceIntPtr dev)
+{
+char buf[PATH_MAX];
+char * dName;
+FILE * file;
+XkbConfigRtrnPtr rtrn;
+
+#if defined(MetroLink)
+ if (dev && dev->name)
+ dName= dev->name;
+ else dName= "";
+ /* It doesn't appear that XkbBaseDirectory could ever get set to NULL */
+ sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display,
+ (dName[0]?".":""),dName);
+#else
+ if (dev && dev->name)
+ dName= dev->name;
+ else dName= "";
+ if (XkbBaseDirectory!=NULL) {
+ if (strlen(XkbBaseDirectory)+strlen(display)
+ +strlen(dName)+10+(dName[0]?1:0) > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("path exceeds max length\n");
+#endif
+ return NULL;
+ }
+ sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display,
+ (dName[0]?".":""),dName);
+ }
+ else {
+ if (strlen(display)+strlen(dName)+10+(dName[0]?1:0) > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("path exceeds max length\n");
+#endif
+ return NULL;
+ }
+ sprintf(buf,"X%s-config%s%s",display,(dName[0]?".":""),dName);
+ }
+#endif
+#ifdef DEBUG
+ ErrorF("Looking for keyboard configuration in %s...",buf);
+#endif
+ file= fopen(buf,"r");
+ if (file==NULL) {
+#ifdef DEBUG
+ ErrorF("file not found\n");
+#endif
+ return NULL;
+ }
+ rtrn= _XkbTypedCalloc(1,XkbConfigRtrnRec);
+ if (rtrn!=NULL) {
+ if (!XkbCFParse(file,XkbCFDflts,NULL,rtrn)) {
+#ifdef DEBUG
+ ErrorF("error\n");
+#endif
+ ErrorF("Error parsing config file: ");
+ XkbCFReportError(stderr,buf,rtrn->error,rtrn->line);
+ _XkbFree(rtrn);
+ fclose(file);
+ return NULL;
+ }
+#ifdef DEBUG
+ ErrorF("found it\n");
+#endif
+ if (rtrn->rules_file) {
+ *rulesRtrn= rtrn->rules_file;
+ rtrn->rules_file= NULL;
+ }
+ if (rtrn->model) {
+ defs->model= rtrn->model;
+ rtrn->model= NULL;
+ }
+ if (rtrn->layout) {
+ defs->layout= rtrn->layout;
+ rtrn->layout= NULL;
+ }
+ if (rtrn->variant) {
+ defs->variant= rtrn->variant;
+ rtrn->variant= NULL;
+ }
+ if (rtrn->options) {
+ defs->options= rtrn->options;
+ rtrn->options= NULL;
+ }
+ XkbSetRulesUsed(defs);
+
+ if (rtrn->keycodes!=NULL) {
+ if (names->keycodes) _XkbFree(names->keycodes);
+ names->keycodes= rtrn->keycodes;
+ rtrn->keycodes= NULL;
+ }
+ if (rtrn->geometry!=NULL) {
+ if (names->geometry) _XkbFree(names->geometry);
+ names->geometry= rtrn->geometry;
+ rtrn->geometry= NULL;
+ }
+ if (rtrn->symbols!=NULL) {
+ if (rtrn->phys_symbols==NULL)
+ rtrn->phys_symbols= Xstrdup(names->symbols);
+ if (names->symbols) _XkbFree(names->symbols);
+ names->symbols= rtrn->symbols;
+ rtrn->symbols= NULL;
+ }
+ if (rtrn->types!=NULL) {
+ if (names->types) _XkbFree(names->types);
+ names->types= rtrn->types;
+ rtrn->types= NULL;
+ }
+ if (rtrn->compat!=NULL) {
+ if (names->compat) _XkbFree(names->compat);
+ names->compat= rtrn->compat;
+ rtrn->compat= NULL;
+ }
+ }
+ fclose(file);
+ return (XPointer)rtrn;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxCtrls.c b/nx-X11/programs/Xserver/xkb/ddxCtrls.c
new file mode 100644
index 000000000..783576a5a
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxCtrls.c
@@ -0,0 +1,128 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+void
+XkbDDXKeybdCtrlProc(DeviceIntPtr dev,KeybdCtrl *ctrl)
+{
+int realRepeat;
+
+ realRepeat= ctrl->autoRepeat;
+ if ((dev->kbdfeed)&&(XkbDDXUsesSoftRepeat(dev)))
+ ctrl->autoRepeat= 0;
+#ifdef DEBUG
+if (xkbDebugFlags&0x4) {
+ ErrorF("XkbDDXKeybdCtrlProc: setting repeat to %d (real repeat is %d)\n",
+ ctrl->autoRepeat,realRepeat);
+}
+#endif
+ if (dev->key && dev->key->xkbInfo && dev->key->xkbInfo->kbdProc)
+ (*dev->key->xkbInfo->kbdProc)(dev,ctrl);
+ ctrl->autoRepeat= realRepeat;
+ return;
+}
+
+
+int
+XkbDDXUsesSoftRepeat(DeviceIntPtr pXDev)
+{
+#ifndef XKB_ALWAYS_USES_SOFT_REPEAT
+ if (pXDev && pXDev->kbdfeed ) {
+ if (pXDev->kbdfeed->ctrl.autoRepeat) {
+ if (pXDev->key && pXDev->key->xkbInfo) {
+ XkbDescPtr xkb;
+ xkb= pXDev->key->xkbInfo->desc;
+ if ((xkb->ctrls->repeat_delay == 660) &&
+ (xkb->ctrls->repeat_interval == 40) &&
+ ((xkb->ctrls->enabled_ctrls&(XkbSlowKeysMask|
+ XkbBounceKeysMask|
+ XkbMouseKeysMask))==0)) {
+ return 0;
+ }
+ return ((xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0);
+ }
+ }
+ }
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+void
+XkbDDXChangeControls(DeviceIntPtr dev,XkbControlsPtr old,XkbControlsPtr new)
+{
+unsigned changed, i;
+unsigned char *rep_old, *rep_new, *rep_fb;
+
+ changed= new->enabled_ctrls^old->enabled_ctrls;
+#ifdef NOTDEF
+ if (changed&XkbRepeatKeysMask) {
+ if (dev->kbdfeed) {
+ int realRepeat;
+
+ if (new->enabled_ctrls&XkbRepeatKeysMask)
+ dev->kbdfeed->ctrl.autoRepeat= realRepeat= 1;
+ else dev->kbdfeed->ctrl.autoRepeat= realRepeat= 0;
+
+ if (XkbDDXUsesSoftRepeat(dev))
+ dev->kbdfeed->ctrl.autoRepeat= FALSE;
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ dev->kbdfeed->ctrl.autoRepeat= realRepeat;
+ }
+ }
+#endif
+ for (rep_old = old->per_key_repeat,
+ rep_new = new->per_key_repeat,
+ rep_fb = dev->kbdfeed->ctrl.autoRepeats,
+ i = 0; i < XkbPerKeyBitArraySize; i++) {
+ if (rep_old[i] != rep_new[i]) {
+ rep_fb[i] = rep_new[i];
+ changed &= XkbPerKeyRepeatMask;
+ }
+ }
+
+ if (changed&XkbPerKeyRepeatMask) {
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ }
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/ddxDevBtn.c b/nx-X11/programs/Xserver/xkb/ddxDevBtn.c
new file mode 100644
index 000000000..5d3190ba6
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxDevBtn.c
@@ -0,0 +1,99 @@
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+
+extern int DeviceValuator;
+
+void
+XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
+{
+int * devVal;
+INT32 * evVal;
+xEvent events[2];
+deviceKeyButtonPointer *btn;
+deviceValuator * val;
+int x,y;
+int nAxes, i, count;
+
+ if ((dev==(DeviceIntPtr)LookupPointerDevice())||(!dev->public.on))
+ return;
+
+ nAxes = (dev->valuator?dev->valuator->numAxes:0);
+ if (nAxes > 6)
+ nAxes = 6;
+
+ GetSpritePosition(&x,&y);
+ btn= (deviceKeyButtonPointer *) &events[0];
+ val= (deviceValuator *) &events[1];
+ if (press) btn->type= DeviceButtonPress;
+ else btn->type= DeviceButtonRelease;
+ btn->detail= button;
+ btn->time= GetTimeInMillis();
+ btn->root_x= x;
+ btn->root_y= y;
+ btn->deviceid= dev->id;
+ count= 1;
+ if (nAxes>0) {
+ btn->deviceid|= 0x80;
+ val->type = DeviceValuator;
+ val->deviceid = dev->id;
+ val->first_valuator = 0;
+
+ evVal= &val->valuator0;
+ devVal= dev->valuator->axisVal;
+ for (i=nAxes;i>0;i--) {
+ *evVal++ = *devVal++;
+ if (evVal > &val->valuator5) {
+ int tmp = val->first_valuator+6;
+ val->num_valuators = 6;
+ val++;
+ evVal= &val->valuator0;
+ val->first_valuator= tmp;
+ }
+ }
+ if ((nAxes % 6) != 0) {
+ val->num_valuators = (nAxes % 6);
+ }
+ count= 1+((nAxes+5)/6);
+ }
+
+ (*dev->public.processInputProc)((xEventPtr)btn, dev, count);
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c b/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c
new file mode 100644
index 000000000..db7de5595
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxFakeBtn.c
@@ -0,0 +1,58 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+void
+XkbDDXFakePointerButton(int event,int button)
+{
+xEvent ev;
+int x,y;
+DevicePtr ptr;
+
+ if ((ptr = LookupPointerDevice())==NULL)
+ return;
+ GetSpritePosition(&x,&y);
+ ev.u.u.type = event;
+ ev.u.u.detail = button;
+ ev.u.keyButtonPointer.time = GetTimeInMillis();
+ ev.u.keyButtonPointer.rootX = x;
+ ev.u.keyButtonPointer.rootY = y;
+ (*ptr->processInputProc)( &ev, (DeviceIntPtr)ptr, 1 );
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c b/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c
new file mode 100644
index 000000000..854a7b72f
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxFakeMtn.c
@@ -0,0 +1,118 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "mipointer.h"
+#include "mipointrst.h"
+
+void
+XkbDDXFakePointerMotion(unsigned flags,int x,int y)
+{
+int oldX,oldY;
+ScreenPtr pScreen, oldScreen;
+
+ GetSpritePosition(&oldX, &oldY);
+ pScreen = oldScreen = GetSpriteWindow()->drawable.pScreen;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ BoxRec box;
+ int i;
+
+ if(!RegionContainsPoint(&XineramaScreenRegions[pScreen->myNum],
+ oldX, oldY, &box)) {
+ FOR_NSCREENS(i) {
+ if(i == pScreen->myNum)
+ continue;
+ if(RegionContainsPoint(&XineramaScreenRegions[i],
+ oldX, oldY, &box)) {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+ oldScreen = pScreen;
+
+ if (flags&XkbSA_MoveAbsoluteX)
+ oldX= x;
+ else oldX+= x;
+ if (flags&XkbSA_MoveAbsoluteY)
+ oldY= y;
+ else oldY+= y;
+
+ if(!RegionContainsPoint(&XineramaScreenRegions[pScreen->myNum],
+ oldX, oldY, &box)) {
+ FOR_NSCREENS(i) {
+ if(i == pScreen->myNum)
+ continue;
+ if(RegionContainsPoint(&XineramaScreenRegions[i],
+ oldX, oldY, &box)) {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+ oldX -= panoramiXdataPtr[pScreen->myNum].x;
+ oldY -= panoramiXdataPtr[pScreen->myNum].y;
+ }
+ else
+#endif
+ {
+ if (flags&XkbSA_MoveAbsoluteX)
+ oldX= x;
+ else oldX+= x;
+ if (flags&XkbSA_MoveAbsoluteY)
+ oldY= y;
+ else oldY+= y;
+
+#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
+ (*(GetScreenPrivate(oldScreen))->screenFuncs->CursorOffScreen)
+ (&pScreen, &oldX, &oldY);
+ }
+
+ if (pScreen != oldScreen)
+ NewCurrentScreen(pScreen, oldX, oldY);
+ if (pScreen->SetCursorPosition)
+ (*pScreen->SetCursorPosition)(pScreen, oldX, oldY, TRUE);
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxInit.c b/nx-X11/programs/Xserver/xkb/ddxInit.c
new file mode 100644
index 000000000..18e5e6a45
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxInit.c
@@ -0,0 +1,45 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+int
+XkbDDXInitDevice(DeviceIntPtr dev)
+{
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxKeyClick.c b/nx-X11/programs/Xserver/xkb/ddxKeyClick.c
new file mode 100644
index 000000000..ddc34b0fd
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxKeyClick.c
@@ -0,0 +1,49 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+void
+XkbDDXKeyClick(DeviceIntPtr pXDev,int keycode,int synthetic)
+{
+#ifdef DEBUG
+ if (xkbDebugFlags)
+ ErrorF("Click.\n");
+#endif
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxKillSrv.c b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c
new file mode 100644
index 000000000..b61c4529b
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c
@@ -0,0 +1,66 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+#ifdef XF86DDXACTIONS
+#include "xf86.h"
+#endif
+
+int
+XkbDDXTerminateServer(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+{
+#ifdef NXAGENT_SERVER
+
+ return 0;
+
+#else
+
+#ifdef XF86DDXACTIONS
+ xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
+#else
+ GiveUp(1);
+#endif
+ return 0;
+
+#endif /* NXAGENT_SERVER */
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxLEDs.c b/nx-X11/programs/Xserver/xkb/ddxLEDs.c
new file mode 100644
index 000000000..4fe74bbd6
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxLEDs.c
@@ -0,0 +1,71 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+void
+XkbDDXUpdateIndicators(DeviceIntPtr dev,CARD32 new)
+{
+ dev->kbdfeed->ctrl.leds= new;
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ return;
+}
+
+void
+XkbDDXUpdateDeviceIndicators( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ CARD32 new)
+{
+ if (sli->fb.kf==dev->kbdfeed)
+ XkbDDXUpdateIndicators(dev,new);
+ else if (sli->class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ kf= sli->fb.kf;
+ if (kf && kf->CtrlProc) {
+ (*kf->CtrlProc)(dev,&kf->ctrl);
+ }
+ }
+ else if (sli->class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ lf= sli->fb.lf;
+ if (lf && lf->CtrlProc) {
+ (*lf->CtrlProc)(dev,&lf->ctrl);
+ }
+ }
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxList.c b/nx-X11/programs/Xserver/xkb/ddxList.c
new file mode 100644
index 000000000..6023366da
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxList.c
@@ -0,0 +1,299 @@
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xos.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+#ifdef WIN32
+/* from ddxLoad.c */
+extern const char* Win32TempDir();
+extern int Win32System(const char *cmdline);
+#undef System
+#define System Win32System
+
+#define W32_tmparg " '%s'"
+#define W32_tmpfile ,tmpname
+#define W32_tmplen strlen(tmpname)+3
+#else
+#define W32_tmparg
+#define W32_tmpfile
+#define W32_tmplen 0
+#endif
+
+/***====================================================================***/
+
+static char *componentDirs[_XkbListNumComponents] = {
+ "keymap", "keycodes", "types", "compat", "symbols", "geometry"
+};
+
+/***====================================================================***/
+
+static Status
+_AddListComponent( XkbSrvListInfoPtr list,
+ int what,
+ unsigned flags,
+ char * str,
+ ClientPtr client)
+{
+int slen,wlen;
+unsigned char * wire8;
+unsigned short *wire16;
+char * tmp;
+
+ if (list->nTotal>=list->maxRtrn) {
+ list->nTotal++;
+ return Success;
+ }
+ tmp= strchr(str,')');
+ if ((tmp==NULL)&&((tmp=strchr(str,'('))==NULL)) {
+ slen= strlen(str);
+ while ((slen>0) && isspace(str[slen-1])) {
+ slen--;
+ }
+ }
+ else {
+ slen= (tmp-str+1);
+ }
+ wlen= (((slen+1)/2)*2)+4; /* four bytes for flags and length, pad to */
+ /* 2-byte boundary */
+ if ((list->szPool-list->nPool)<wlen) {
+ if (wlen>1024) list->szPool+= XkbPaddedSize(wlen*2);
+ else list->szPool+= 1024;
+ list->pool= _XkbTypedRealloc(list->pool,list->szPool,char);
+ if (!list->pool)
+ return BadAlloc;
+ }
+ wire16= (unsigned short *)&list->pool[list->nPool];
+ wire8= (unsigned char *)&wire16[2];
+ wire16[0]= flags;
+ wire16[1]= slen;
+ memcpy(wire8,str,slen);
+ if (client->swapped) {
+ swaps(&wire16[0]);
+ swaps(&wire16[1]);
+ }
+ list->nPool+= wlen;
+ list->nFound[what]++;
+ list->nTotal++;
+ return Success;
+}
+
+/***====================================================================***/
+static Status
+XkbDDXListComponent( DeviceIntPtr dev,
+ int what,
+ XkbSrvListInfoPtr list,
+ ClientPtr client)
+{
+char *file,*map,*tmp,*buf=NULL;
+FILE *in;
+Status status;
+int rval;
+Bool haveDir;
+#ifdef WIN32
+char tmpname[PATH_MAX];
+#endif
+
+ if ((list->pattern[what]==NULL)||(list->pattern[what][0]=='\0'))
+ return Success;
+ file= list->pattern[what];
+ map= strrchr(file,'(');
+ if (map!=NULL) {
+ char *tmp;
+ map++;
+ tmp= strrchr(map,')');
+ if ((tmp==NULL)||(tmp[1]!='\0')) {
+ /* illegal pattern. No error, but no match */
+ return Success;
+ }
+ }
+
+ in= NULL;
+ haveDir= True;
+#ifdef WIN32
+ strcpy(tmpname, Win32TempDir());
+ strcat(tmpname, "\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+ if (XkbBaseDirectory!=NULL) {
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ buf = Xprintf("%s/%s.dir",XkbBaseDirectory,componentDirs[what]);
+ in= fopen(buf,"r");
+ free (buf);
+ buf = NULL;
+ }
+ if (!in) {
+ haveDir= False;
+ buf = Xprintf(
+ "'%s/xkbcomp' '-R%s/%s' -w %ld -l -vlfhpR '%s'" W32_tmparg,
+ XkbBinDirectory,XkbBaseDirectory,componentDirs[what],(long)
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file W32_tmpfile
+ );
+ }
+ }
+ else {
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ buf = Xprintf("%s.dir",componentDirs[what]);
+ in= fopen(buf,"r");
+ free (buf);
+ buf = NULL;
+ }
+ if (!in) {
+ haveDir= False;
+ buf = Xprintf(
+ "xkbcomp -R%s -w %ld -l -vlfhpR '%s'" W32_tmparg,
+ componentDirs[what],(long)
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file W32_tmpfile
+ );
+ }
+ }
+ status= Success;
+ if (!haveDir)
+ {
+#ifndef WIN32
+ in= Popen(buf,"r");
+#else
+#ifdef DEBUG_CMD
+ ErrorF("xkb executes: %s\n",buf);
+#endif
+ if (System(buf) < 0)
+ ErrorF("Could not invoke keymap compiler\n");
+ else
+ in= fopen(tmpname, "r");
+#endif
+ }
+ if (!in)
+ {
+ if (buf != NULL)
+ free (buf);
+#ifdef WIN32
+ unlink(tmpname);
+#endif
+ return BadImplementation;
+ }
+ list->nFound[what]= 0;
+ while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) {
+ unsigned flags;
+ register unsigned int i;
+ if (*tmp=='#') /* comment, skip it */
+ continue;
+ if (!strncmp(tmp, "Warning:", 8) || !strncmp(tmp, " ", 8))
+ /* skip warnings too */
+ continue;
+ flags= 0;
+ /* each line in the listing is supposed to start with two */
+ /* groups of eight characters, which specify the general */
+ /* flags and the flags that are specific to the component */
+ /* if they're missing, fail with BadImplementation */
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the general flags */
+ if (isalpha(*tmp)) flags|= (1L<<i);
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (!isspace(*tmp)) {
+ status= BadImplementation;
+ break;
+ }
+ else tmp++;
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the component flags */
+ if (isalpha(*tmp)) flags|= (1L<<(i+8));
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (isspace(*tmp)) {
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+ }
+ else {
+ status= BadImplementation;
+ break;
+ }
+ status= _AddListComponent(list,what,flags,tmp,client);
+ }
+#ifndef WIN32
+ if (haveDir)
+ fclose(in);
+ else if ((rval=pclose(in))!=0) {
+ if (xkbDebugFlags)
+ ErrorF("xkbcomp returned exit code %d\n",rval);
+ }
+#else
+ fclose(in);
+ unlink(tmpname);
+#endif
+ if (buf != NULL)
+ free (buf);
+ return status;
+}
+
+/***====================================================================***/
+
+/* ARGSUSED */
+Status
+XkbDDXList(DeviceIntPtr dev,XkbSrvListInfoPtr list,ClientPtr client)
+{
+Status status;
+
+ status= XkbDDXListComponent(dev,_XkbListKeymaps,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListKeycodes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListTypes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListCompat,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListSymbols,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListGeometry,list,client);
+ return status;
+}
diff --git a/nx-X11/programs/Xserver/xkb/ddxLoad.c b/nx-X11/programs/Xserver/xkb/ddxLoad.c
new file mode 100644
index 000000000..5f24e9ccc
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxLoad.c
@@ -0,0 +1,908 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XKB_CONFIG_H
+#include <xkb-config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/* stat() */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xos.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+#include "xkb.h"
+
+#if defined(CSRG_BASED) || defined(linux) || defined(__GNU__)
+#include <paths.h>
+#endif
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+ /*
+ * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
+ * relative to the top-level XKB configuration directory.
+ * Making the server write to a subdirectory of that directory
+ * requires some work in the general case (install procedure
+ * has to create links to /var or somesuch on many machines),
+ * so we just compile into /usr/tmp for now.
+ */
+#ifndef XKM_OUTPUT_DIR
+#define XKM_OUTPUT_DIR "compiled/"
+#endif
+
+#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
+#define ERROR_PREFIX "\"> \""
+#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
+#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\""
+
+#if defined(WIN32)
+#define PATHSEPARATOR "\\"
+#else
+#define PATHSEPARATOR "/"
+#endif
+
+#ifdef WIN32
+
+#include <nx-X11/Xwindows.h>
+const char*
+Win32TempDir()
+{
+ static char buffer[PATH_MAX];
+ if (GetTempPath(sizeof(buffer), buffer))
+ {
+ int len;
+ buffer[sizeof(buffer)-1] = 0;
+ len = strlen(buffer);
+ if (len > 0)
+ if (buffer[len-1] == '\\')
+ buffer[len-1] = 0;
+ return buffer;
+ }
+ if (getenv("TEMP") != NULL)
+ return getenv("TEMP");
+ else if (getenv("TMP") != NULL)
+ return getenv("TEMP");
+ else
+ return "/tmp";
+}
+
+int
+Win32System(const char *cmdline)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ DWORD dwExitCode;
+ char *cmd = xstrdup(cmdline);
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( &pi, sizeof(pi) );
+
+ if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ LPVOID buffer;
+ if (!FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buffer,
+ 0,
+ NULL ))
+ {
+ ErrorF("Starting '%s' failed!\n", cmdline);
+ }
+ else
+ {
+ ErrorF("Starting '%s' failed: %s", cmdline, (char *)buffer);
+ LocalFree(buffer);
+ }
+
+ free(cmd);
+ return -1;
+ }
+ /* Wait until child process exits. */
+ WaitForSingleObject( pi.hProcess, INFINITE );
+
+ GetExitCodeProcess( pi.hProcess, &dwExitCode);
+
+ /* Close process and thread handles. */
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ free(cmd);
+
+ return dwExitCode;
+}
+#undef System
+#define System(x) Win32System(x)
+#endif
+
+#ifdef MAKE_XKM_OUTPUT_DIR
+/* Borrow trans_mkdir from Xtransutil.c to more safely make directories */
+# undef X11_t
+# define TRANS_SERVER
+# define PRMSG(lvl,x,a,b,c) \
+ if (lvl <= 1) { LogMessage(X_ERROR,x,a,b,c); } else ((void)0)
+# include <nx-X11/Xtrans/Xtransutil.c>
+# ifndef XKM_OUTPUT_DIR_MODE
+# define XKM_OUTPUT_DIR_MODE 0755
+# endif
+#endif
+
+#ifdef NXAGENT_SERVER
+
+#define NX_XKB_BASE_DIRECTORY "/usr/lib/X11/xkb"
+#define NX_XKB_ALTERNATE_BASE_DIRECTORY "/usr/share/X11/xkb"
+#define NX_XKB_RULES_BASE_FILE "rules/base"
+#define NX_ALT_XKBCOMP_PATH "/usr/bin"
+
+static char _NXXkbBasePath[PATH_MAX];
+static char _NXXkbCompPath[PATH_MAX];
+
+static int NXVerifyXkbBaseDirectory(const char *dirPath)
+{
+ int size;
+ char *rulesBaseFilePath;
+ struct stat rulesBaseFileStat;
+
+ /*
+ * If rules/base file
+ * is not present inside
+ * the Xkb Base Directory,
+ * we suppose that the
+ * path is not valid.
+ */
+
+ size = strlen(dirPath) + strlen("/") +
+ strlen(NX_XKB_RULES_BASE_FILE) + 1;
+
+ if ((rulesBaseFilePath = malloc((size + 1) * sizeof(char))) == NULL)
+ {
+ FatalError("NXVerifyXkbBaseDirectory: malloc failed.\n");
+ }
+
+ strcpy(rulesBaseFilePath, dirPath);
+ strcat(rulesBaseFilePath, "/");
+ strcat(rulesBaseFilePath, NX_XKB_RULES_BASE_FILE);
+
+ #ifdef TEST
+ fprintf(stderr, "NXVerifyXkbBaseDirectory: Looking for [%s] file.\n",
+ rulesBaseFilePath);
+ #endif
+
+ if (stat(rulesBaseFilePath, &rulesBaseFileStat) != 0)
+ {
+
+ #ifdef TEST
+ fprintf(stderr, "NXVerifyXkbBaseDirectory: Xkb Base Directory [%s] is not valid (can't find file [%s]).\n",
+ dirPath, rulesBaseFilePath);
+ #endif
+
+ free(rulesBaseFilePath);
+
+ return 0;
+ }
+
+ #ifdef TEST
+ fprintf(stderr, "NXVerifyXkbBaseDirectory: Xkb Base Directory [%s] is valid.\n",
+ dirPath);
+ #endif
+
+ free(rulesBaseFilePath);
+
+ return 1;
+}
+
+/*
+ * This function returns the directory
+ * containing the configuration files.
+ * This directory is referred by Xkb-
+ * BaseDirectory variable (generally
+ * it contains the hardcoded path at
+ * compile time). If the directory
+ * does not exist, the function will
+ * try a set of well known directories.
+ */
+
+char *_NXGetXkbBasePath(const char *path)
+{
+ /*
+ * Check the xkb base directory only once.
+ */
+
+ if (*_NXXkbBasePath != '\0')
+ {
+ return _NXXkbBasePath;
+ }
+
+ if (NXVerifyXkbBaseDirectory(XkbBaseDirectory) == 1)
+ {
+ if (strlen(XkbBaseDirectory) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
+ #endif
+
+ goto _NXGetXkbBasePathError;
+ }
+
+ strcpy(_NXXkbBasePath, XkbBaseDirectory);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
+ _NXXkbBasePath);
+ #endif
+
+ return _NXXkbBasePath;
+ }
+
+ if (NXVerifyXkbBaseDirectory(NX_XKB_BASE_DIRECTORY) == 1)
+ {
+ if (strlen(NX_XKB_BASE_DIRECTORY) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
+ #endif
+
+ goto _NXGetXkbBasePathError;
+ }
+
+ strcpy(_NXXkbBasePath, NX_XKB_BASE_DIRECTORY);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
+ _NXXkbBasePath);
+ #endif
+
+ return _NXXkbBasePath;
+ }
+
+ if (NXVerifyXkbBaseDirectory(NX_XKB_ALTERNATE_BASE_DIRECTORY) == 1)
+ {
+ if (strlen(NX_XKB_ALTERNATE_BASE_DIRECTORY) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
+ #endif
+
+ goto _NXGetXkbBasePathError;
+ }
+
+ strcpy(_NXXkbBasePath, NX_XKB_ALTERNATE_BASE_DIRECTORY);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
+ _NXXkbBasePath);
+ #endif
+
+ return _NXXkbBasePath;
+ }
+
+_NXGetXkbBasePathError:
+
+ if (strlen(path) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
+ #endif
+ }
+
+ strcpy(_NXXkbBasePath, path);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbBasePath: Using default xkb base path [%s].\n",
+ _NXXkbBasePath);
+ #endif
+
+ return _NXXkbBasePath;
+}
+
+static int NXVerifyXkbCompPath(char *path)
+{
+ char *xkbCompPath;
+ int xkbCompPathSize;
+ struct stat xkbCompPathStat;
+
+ if (path == NULL)
+ {
+ return 0;
+ }
+
+ xkbCompPathSize = strlen(path) + strlen("/") +
+ strlen("xkbcomp") + 1;
+
+ if ((xkbCompPath = malloc((xkbCompPathSize + 1) * sizeof(char))) == NULL)
+ {
+ FatalError("NXVerifyXkbCompPath: WARNING! malloc failed.\n");
+
+ return 0;
+ }
+
+ strcpy(xkbCompPath, path);
+ strcat(xkbCompPath, "/");
+ strcat(xkbCompPath, "xkbcomp");
+
+ if (stat(xkbCompPath, &xkbCompPathStat) != 0)
+ {
+ #ifdef NX_TRANS_TEST
+ fprintf(stderr, "NXVerifyXkbCompPath: WARNING! Failed to stat xkbcomp path [%s].\n",
+ xkbCompPath);
+ #endif
+
+ free(xkbCompPath);
+
+ return 0;
+ }
+
+ free(xkbCompPath);
+
+ return 1;
+}
+
+/*
+ * This function returns the directory
+ * containing the xkbcomp executable.
+ * The function will first try to locate
+ * the executable in the hardcoded path
+ * (the same path as the "base" xkb one)
+ * and, if the xkbcomp file couldn't be
+ * found, the function will not include
+ * an explicit path and will rely on the
+ * PATH environment to list the directory.
+ */
+
+char *_NXGetXkbCompPath(const char *path)
+{
+
+ char * xkbCompPath;
+
+ /*
+ * Check the xkbcomp executable
+ * directory only once.
+ */
+
+ if (*_NXXkbCompPath != '\0')
+ {
+ return _NXXkbCompPath;
+ }
+
+ xkbCompPath = _NXGetXkbBasePath(path);
+
+ if (NXVerifyXkbCompPath(xkbCompPath) == 1)
+ {
+ if (strlen(xkbCompPath) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
+ #endif
+
+ goto _NXGetXkbCompPathError;
+ }
+
+ strcpy(_NXXkbCompPath, xkbCompPath);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: Using xkbcomp path [%s].\n",
+ _NXXkbCompPath);
+ #endif
+
+ return _NXXkbCompPath;
+ }
+
+ xkbCompPath = NX_ALT_XKBCOMP_PATH;
+
+ if (NXVerifyXkbCompPath(xkbCompPath) == 1)
+ {
+ if (strlen(xkbCompPath) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
+ #endif
+
+ goto _NXGetXkbCompPathError;
+ }
+
+ strcpy(_NXXkbCompPath, xkbCompPath);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: Using NX xkbcomp path [%s].\n",
+ _NXXkbCompPath);
+ #endif
+
+ return _NXXkbCompPath;
+ }
+
+_NXGetXkbCompPathError:
+
+ if (strlen(path) + 1 > PATH_MAX)
+ {
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
+ #endif
+ }
+
+ strcpy(_NXXkbCompPath, path);
+
+ #ifdef TEST
+ fprintf(stderr, "_NXGetXkbCompPath: Using default xkbcomp path [%s].\n",
+ _NXXkbCompPath);
+ #endif
+
+ return _NXXkbCompPath;
+}
+
+#endif
+
+static void
+OutputDirectory(
+ char* outdir,
+ size_t size)
+{
+#ifndef WIN32
+ if (getuid() == 0 && (strlen(XKM_OUTPUT_DIR) < size)
+#ifdef MAKE_XKM_OUTPUT_DIR
+ && (trans_mkdir(XKM_OUTPUT_DIR, XKM_OUTPUT_DIR_MODE) == 0)
+#endif
+ )
+ {
+ /* if server running as root it *may* be able to write */
+ /* FIXME: check whether directory is writable at all */
+ (void) strcpy (outdir, XKM_OUTPUT_DIR);
+ } else
+#endif
+#ifdef _PATH_VARTMP
+ if ((strlen(_PATH_VARTMP) + 1) < size)
+ {
+ (void) strcpy (outdir, _PATH_VARTMP);
+ if (outdir[strlen(outdir) - 1] != '/') /* Hi IBM, Digital */
+ (void) strcat (outdir, "/");
+ } else
+#endif
+#ifdef WIN32
+ if (strlen(Win32TempDir()) + 1 < size)
+ {
+ (void) strcpy(outdir, Win32TempDir());
+ (void) strcat(outdir, "\\");
+ } else
+#endif
+ if (strlen("/tmp/") < size)
+ {
+ (void) strcpy (outdir, "/tmp/");
+ }
+}
+
+Bool
+XkbDDXCompileNamedKeymap( XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ char * nameRtrn,
+ int nameRtrnLen)
+{
+char *cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile;
+
+ if (names->keymap==NULL)
+ return False;
+ strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0';
+ if ((map= strrchr(file,'('))!=NULL) {
+ char *tmp;
+ if ((tmp= strrchr(map,')'))!=NULL) {
+ *map++= '\0';
+ *tmp= '\0';
+ }
+ else {
+ map= NULL;
+ }
+ }
+ if ((outFile= strrchr(file,'/'))!=NULL)
+ outFile= Xstrdup(&outFile[1]);
+ else outFile= Xstrdup(file);
+ XkbEnsureSafeMapName(outFile);
+ OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+
+#ifdef NXAGENT_SERVER
+
+ if (_NXGetXkbCompPath(XkbBaseDirectory) != NULL)
+ {
+
+#else
+
+ if (XkbBaseDirectory!=NULL) {
+
+#endif
+
+#ifdef NXAGENT_SERVER
+ char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
+ char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
+#else
+ char *xkbbasedir = XkbBaseDirectory;
+ char *xkbbindir = XkbBinDirectory;
+#endif
+
+ cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"",
+ xkbbindir,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ xkbbasedir,(map?"-m ":""),(map?map:""),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
+ xkm_output_dir,outFile);
+ }
+ else {
+ cmd = Xprintf("xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"",
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ (map?"-m ":""),(map?map:""),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
+ xkm_output_dir,outFile);
+ }
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n");
+ ErrorF(" \"cmd\"\n");
+ }
+#endif
+#ifdef DEBUG_CMD
+ ErrorF("xkb executes: %s\n",cmd);
+#endif
+ if (System(cmd)==0) {
+ if (nameRtrn) {
+ strncpy(nameRtrn,outFile,nameRtrnLen);
+ nameRtrn[nameRtrnLen-1]= '\0';
+ }
+ if (outFile!=NULL)
+ _XkbFree(outFile);
+ if (cmd!=NULL)
+ free(cmd);
+ return True;
+ }
+#ifdef DEBUG
+ ErrorF("Error compiling keymap (%s)\n",names->keymap);
+#endif
+ if (outFile!=NULL)
+ _XkbFree(outFile);
+ if (cmd!=NULL)
+ free(cmd);
+ return False;
+}
+
+Bool
+XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ char * nameRtrn,
+ int nameRtrnLen)
+{
+FILE * out;
+char *buf = NULL, keymap[PATH_MAX],xkm_output_dir[PATH_MAX];
+
+#ifdef WIN32
+char tmpname[PATH_MAX];
+#endif
+ if ((names->keymap==NULL)||(names->keymap[0]=='\0')) {
+ sprintf(keymap,"server-%s",display);
+ }
+ else {
+ if (strlen(names->keymap) > PATH_MAX - 1) {
+ ErrorF("name of keymap (%s) exceeds max length\n", names->keymap);
+ return False;
+ }
+ strcpy(keymap,names->keymap);
+ }
+
+ XkbEnsureSafeMapName(keymap);
+ OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+#ifdef WIN32
+ strcpy(tmpname, Win32TempDir());
+ strcat(tmpname, "\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+
+#ifdef NXAGENT_SERVER
+ if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) {
+#else
+ if (XkbBaseDirectory!=NULL) {
+#endif
+
+#ifndef WIN32
+ char *xkmfile = "-";
+#else
+ /* WIN32 has no popen. The input must be stored in a file which is used as input
+ for xkbcomp. xkbcomp does not read from stdin. */
+ char *xkmfile = tmpname;
+#endif
+#ifdef NXAGENT_SERVER
+ char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
+ char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
+#else
+ char *xkbbasedir = XkbBaseDirectory;
+ char *xkbbindir = XkbBinDirectory;
+#endif
+
+ buf = Xprintf(
+ "\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ xkbbindir,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ xkbbasedir, xkmfile,
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap);
+ }
+ else {
+#ifndef WIN32
+ char *xkmfile = "-";
+#else
+ char *xkmfile = tmpname;
+#endif
+ buf = Xprintf(
+ "xkbcomp -w %d -xkm \"%s\" -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ xkmfile,
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap);
+ }
+
+ #ifdef TEST
+ if (buf != NULL)
+ fprintf(stderr, "XkbDDXCompileKeymapByNames: "
+ "Executing command [%s].\n", buf);
+ else
+ fprintf(stderr, "XkbDDXCompileKeymapByNames: "
+ "Callin Popen() with null command.\n");
+ #endif
+
+#ifndef WIN32
+ out= Popen(buf,"w");
+#else
+ out= fopen(tmpname, "w");
+#endif
+
+ if (out!=NULL) {
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n");
+ XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need);
+ }
+#endif
+ XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need);
+#ifndef WIN32
+#ifdef __sun
+ if (Pclose(out) != 0)
+ {
+ ErrorF("Warning: Spurious failure reported in Pclose() runnning 'xkbcomp'.\n");
+ }
+ if (1)
+#else
+ if (Pclose(out)==0)
+#endif
+#else
+ if (fclose(out)==0 && System(buf) >= 0)
+#endif
+ {
+#ifdef DEBUG_CMD
+ ErrorF("xkb executes: %s\n",buf);
+ ErrorF("xkbcomp input:\n");
+ XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need);
+ ErrorF("end xkbcomp input\n");
+#endif
+ if (nameRtrn) {
+ strncpy(nameRtrn,keymap,nameRtrnLen);
+ nameRtrn[nameRtrnLen-1]= '\0';
+ }
+ if (buf != NULL)
+ free (buf);
+ return True;
+ }
+#ifdef DEBUG
+ else
+ ErrorF("Error compiling keymap (%s)\n",keymap);
+#endif
+#ifdef WIN32
+ /* remove the temporary file */
+ unlink(tmpname);
+#endif
+ }
+#ifdef DEBUG
+ else {
+#ifndef WIN32
+ ErrorF("Could not invoke keymap compiler\n");
+#else
+ ErrorF("Could not open file %s\n", tmpname);
+#endif
+ }
+#endif
+ if (nameRtrn)
+ nameRtrn[0]= '\0';
+ if (buf != NULL)
+ free (buf);
+ return False;
+}
+
+FILE *
+XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
+{
+char buf[PATH_MAX],xkm_output_dir[PATH_MAX];
+FILE * file;
+
+ buf[0]= '\0';
+ if (mapName!=NULL) {
+ OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+ if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')
+#ifdef WIN32
+ &&(!isalpha(xkm_output_dir[0]) || xkm_output_dir[1]!=':')
+#endif
+ ) {
+ if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
+ +strlen(mapName)+6 <= PATH_MAX)
+ {
+ sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
+ xkm_output_dir,mapName);
+ }
+ }
+ else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
+ sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
+ if (buf[0] != '\0')
+ file= fopen(buf,"rb");
+ else file= NULL;
+ }
+ else file= NULL;
+ if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
+ strncpy(fileNameRtrn,buf,fileNameRtrnLen);
+ buf[fileNameRtrnLen-1]= '\0';
+ }
+ return file;
+}
+
+unsigned
+XkbDDXLoadKeymapByNames( DeviceIntPtr keybd,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ XkbFileInfo * finfoRtrn,
+ char * nameRtrn,
+ int nameRtrnLen)
+{
+XkbDescPtr xkb;
+FILE * file;
+char fileName[PATH_MAX];
+unsigned missing;
+
+ bzero(finfoRtrn,sizeof(XkbFileInfo));
+ if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL))
+ xkb= NULL;
+ else xkb= keybd->key->xkbInfo->desc;
+ if ((names->keycodes==NULL)&&(names->types==NULL)&&
+ (names->compat==NULL)&&(names->symbols==NULL)&&
+ (names->geometry==NULL)) {
+ if (names->keymap==NULL) {
+ bzero(finfoRtrn,sizeof(XkbFileInfo));
+ if (xkb && XkbDetermineFileType(finfoRtrn,XkbXKMFile,NULL) &&
+ ((finfoRtrn->defined&need)==need) ) {
+ finfoRtrn->xkb= xkb;
+ nameRtrn[0]= '\0';
+ return finfoRtrn->defined;
+ }
+ return 0;
+ }
+ else if (!XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)) {
+#ifdef NOISY
+ ErrorF("Couldn't compile keymap file\n");
+#endif
+ return 0;
+ }
+ }
+ else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
+ nameRtrn,nameRtrnLen)){
+#ifdef NOISY
+ ErrorF("Couldn't compile keymap file\n");
+#endif
+ return 0;
+ }
+ file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
+ if (file==NULL) {
+ LogMessage(X_ERROR, "Couldn't open compiled keymap file %s\n",fileName);
+ return 0;
+ }
+ missing= XkmReadFile(file,need,want,finfoRtrn);
+ if (finfoRtrn->xkb==NULL) {
+ LogMessage(X_ERROR, "Error loading keymap %s\n",fileName);
+ fclose(file);
+ (void) unlink (fileName);
+ return 0;
+ }
+#ifdef DEBUG
+ else if (xkbDebugFlags) {
+ ErrorF("Loaded %s, defined=0x%x\n",fileName,finfoRtrn->defined);
+ }
+#endif
+ fclose(file);
+ (void) unlink (fileName);
+ return (need|want)&(~missing);
+}
+
+Bool
+XkbDDXNamesFromRules( DeviceIntPtr keybd,
+ char * rules_name,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names)
+{
+char buf[PATH_MAX];
+FILE * file;
+Bool complete;
+XkbRF_RulesPtr rules;
+
+ if (!rules_name)
+ return False;
+ if (XkbBaseDirectory==NULL) {
+ if (strlen(rules_name)+7 > PATH_MAX)
+ return False;
+ sprintf(buf,"rules/%s",rules_name);
+ }
+ else {
+ if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX)
+ return False;
+ sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name);
+ }
+ if ((file= fopen(buf,"r"))==NULL)
+ return False;
+ if ((rules= XkbRF_Create(0,0))==NULL) {
+ fclose(file);
+ return False;
+ }
+ if (!XkbRF_LoadRules(file,rules)) {
+ fclose(file);
+ XkbRF_Free(rules,True);
+ return False;
+ }
+ bzero((char *)names,sizeof(XkbComponentNamesRec));
+ complete= XkbRF_GetComponents(rules,defs,names);
+ fclose(file);
+ XkbRF_Free(rules,True);
+ return complete;
+}
+
+
diff --git a/nx-X11/programs/Xserver/xkb/ddxPrivate.c b/nx-X11/programs/Xserver/xkb/ddxPrivate.c
new file mode 100644
index 000000000..8fdc8c91f
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxPrivate.c
@@ -0,0 +1,43 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include "windowstr.h"
+#include <xkbsrv.h>
+
+#ifdef XF86DDXACTIONS
+#include "xf86.h"
+#endif
+
+int
+XkbDDXPrivate(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+{
+#ifdef XF86DDXACTIONS
+ XkbAnyAction *xf86act = &(act->any);
+ char msgbuf[XkbAnyActionDataSize+1];
+
+ if (xf86act->type == XkbSA_XFree86Private) {
+ memcpy(msgbuf, xf86act->data, XkbAnyActionDataSize);
+ msgbuf[XkbAnyActionDataSize]= '\0';
+ if (_XkbStrCaseCmp(msgbuf, "-vmode")==0)
+ xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
+ else if (_XkbStrCaseCmp(msgbuf, "+vmode")==0)
+ xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
+ else if (_XkbStrCaseCmp(msgbuf, "ungrab")==0)
+ xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
+ else if (_XkbStrCaseCmp(msgbuf, "clsgrb")==0)
+ xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
+ else
+ xf86ProcessActionEvent(ACTION_MESSAGE, (void *) msgbuf);
+ }
+#endif
+ return 0;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/ddxVT.c b/nx-X11/programs/Xserver/xkb/ddxVT.c
new file mode 100644
index 000000000..d01c6532d
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/ddxVT.c
@@ -0,0 +1,69 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include <nx-X11/extensions/XI.h>
+
+#ifdef XF86DDXACTIONS
+#include "xf86.h"
+#endif
+
+int
+XkbDDXSwitchScreen(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+{
+#ifdef XF86DDXACTIONS
+ {
+ int scrnnum = XkbSAScreen(&act->screen);
+
+ if (act->screen.flags & XkbSA_SwitchApplication) {
+ if (act->screen.flags & XkbSA_SwitchAbsolute)
+ xf86ProcessActionEvent(ACTION_SWITCHSCREEN,(void *) &scrnnum);
+ else {
+ if (scrnnum < 0)
+ xf86ProcessActionEvent(ACTION_SWITCHSCREEN_PREV,NULL);
+ else
+ xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT,NULL);
+ }
+ }
+ }
+#endif
+ return 1;
+}
diff --git a/nx-X11/programs/Xserver/xkb/maprules.c b/nx-X11/programs/Xserver/xkb/maprules.c
new file mode 100644
index 000000000..337c8634b
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/maprules.c
@@ -0,0 +1,1334 @@
+/************************************************************
+ Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define X_INCLUDE_STRING_H
+#define XOS_USE_NO_LOCKING
+#include <nx-X11/Xos_r.h>
+
+
+#include <nx-X11/Xproto.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xos.h>
+#include <nx-X11/Xfuncs.h>
+#include <nx-X11/Xatom.h>
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+
+
+#ifdef DEBUG
+#define PR_DEBUG(s) fprintf(stderr,s)
+#define PR_DEBUG1(s,a) fprintf(stderr,s,a)
+#define PR_DEBUG2(s,a,b) fprintf(stderr,s,a,b)
+#else
+#define PR_DEBUG(s)
+#define PR_DEBUG1(s,a)
+#define PR_DEBUG2(s,a,b)
+#endif
+
+/***====================================================================***/
+
+#define DFLT_LINE_SIZE 128
+
+typedef struct {
+ int line_num;
+ int sz_line;
+ int num_line;
+ char buf[DFLT_LINE_SIZE];
+ char * line;
+} InputLine;
+
+static void
+InitInputLine(InputLine *line)
+{
+ line->line_num= 1;
+ line->num_line= 0;
+ line->sz_line= DFLT_LINE_SIZE;
+ line->line= line->buf;
+ return;
+}
+
+static void
+FreeInputLine(InputLine *line)
+{
+ if (line->line!=line->buf)
+ _XkbFree(line->line);
+ line->line_num= 1;
+ line->num_line= 0;
+ line->sz_line= DFLT_LINE_SIZE;
+ line->line= line->buf;
+ return;
+}
+
+static int
+InputLineAddChar(InputLine *line,int ch)
+{
+ if (line->num_line>=line->sz_line) {
+ if (line->line==line->buf) {
+ line->line= (char *)_XkbAlloc(line->sz_line*2);
+ memcpy(line->line,line->buf,line->sz_line);
+ }
+ else {
+ line->line=(char *)_XkbRealloc((char *)line->line,line->sz_line*2);
+ }
+ line->sz_line*= 2;
+ }
+ line->line[line->num_line++]= ch;
+ return ch;
+}
+
+#define ADD_CHAR(l,c) ((l)->num_line<(l)->sz_line?\
+ (int)((l)->line[(l)->num_line++]= (c)):\
+ InputLineAddChar(l,c))
+
+static Bool
+GetInputLine(FILE *file,InputLine *line,Bool checkbang)
+{
+int ch;
+Bool endOfFile,spacePending,slashPending,inComment;
+
+ endOfFile= False;
+ while ((!endOfFile)&&(line->num_line==0)) {
+ spacePending= slashPending= inComment= False;
+ while (((ch=getc(file))!='\n')&&(ch!=EOF)) {
+ if (ch=='\\') {
+ if ((ch=getc(file))==EOF)
+ break;
+ if (ch=='\n') {
+ inComment= False;
+ ch= ' ';
+ line->line_num++;
+ }
+ }
+ if (inComment)
+ continue;
+ if (ch=='/') {
+ if (slashPending) {
+ inComment= True;
+ slashPending= False;
+ }
+ else {
+ slashPending= True;
+ }
+ continue;
+ }
+ else if (slashPending) {
+ if (spacePending) {
+ ADD_CHAR(line,' ');
+ spacePending= False;
+ }
+ ADD_CHAR(line,'/');
+ slashPending= False;
+ }
+ if (isspace(ch)) {
+ while (isspace(ch)&&(ch!='\n')&&(ch!=EOF)) {
+ ch= getc(file);
+ }
+ if (ch==EOF)
+ break;
+ if ((ch!='\n')&&(line->num_line>0))
+ spacePending= True;
+ ungetc(ch,file);
+ }
+ else {
+ if (spacePending) {
+ ADD_CHAR(line,' ');
+ spacePending= False;
+ }
+ if (checkbang && ch=='!') {
+ if (line->num_line!=0) {
+ PR_DEBUG("The '!' legal only at start of line\n");
+ PR_DEBUG("Line containing '!' ignored\n");
+ line->num_line= 0;
+ inComment= 0;
+ break;
+ }
+
+ }
+ ADD_CHAR(line,ch);
+ }
+ }
+ if (ch==EOF)
+ endOfFile= True;
+/* else line->num_line++;*/
+ }
+ if ((line->num_line==0)&&(endOfFile))
+ return False;
+ ADD_CHAR(line,'\0');
+ return True;
+}
+
+/***====================================================================***/
+
+#define MODEL 0
+#define LAYOUT 1
+#define VARIANT 2
+#define OPTION 3
+#define KEYCODES 4
+#define SYMBOLS 5
+#define TYPES 6
+#define COMPAT 7
+#define GEOMETRY 8
+#define KEYMAP 9
+#define MAX_WORDS 10
+
+#define PART_MASK 0x000F
+#define COMPONENT_MASK 0x03F0
+
+static char * cname[MAX_WORDS] = {
+ "model", "layout", "variant", "option",
+ "keycodes", "symbols", "types", "compat", "geometry", "keymap"
+};
+
+typedef struct _RemapSpec {
+ int number;
+ int num_remap;
+ struct {
+ int word;
+ int index;
+ } remap[MAX_WORDS];
+} RemapSpec;
+
+typedef struct _FileSpec {
+ char * name[MAX_WORDS];
+ struct _FileSpec * pending;
+} FileSpec;
+
+typedef struct {
+ char * model;
+ char * layout[XkbNumKbdGroups+1];
+ char * variant[XkbNumKbdGroups+1];
+ char * options;
+} XkbRF_MultiDefsRec, *XkbRF_MultiDefsPtr;
+
+#define NDX_BUFF_SIZE 4
+
+/***====================================================================***/
+
+static char*
+get_index(char *str, int *ndx)
+{
+ char ndx_buf[NDX_BUFF_SIZE];
+ char *end;
+
+ if (*str != '[') {
+ *ndx = 0;
+ return str;
+ }
+ str++;
+ end = strchr(str, ']');
+ if (end == NULL) {
+ *ndx = -1;
+ return str - 1;
+ }
+ if ( (end - str) >= NDX_BUFF_SIZE) {
+ *ndx = -1;
+ return end + 1;
+ }
+ strncpy(ndx_buf, str, end - str);
+ ndx_buf[end - str] = '\0';
+ *ndx = atoi(ndx_buf);
+ return end + 1;
+}
+
+static void
+SetUpRemap(InputLine *line,RemapSpec *remap)
+{
+char * tok,*str;
+unsigned present, l_ndx_present, v_ndx_present;
+register int i;
+int len, ndx;
+_Xstrtokparams strtok_buf;
+#ifdef DEBUG
+Bool found;
+#endif
+
+
+ l_ndx_present = v_ndx_present = present= 0;
+ str= &line->line[1];
+ len = remap->number;
+ bzero((char *)remap,sizeof(RemapSpec));
+ remap->number = len;
+ while ((tok=_XStrtok(str," ",strtok_buf))!=NULL) {
+#ifdef DEBUG
+ found= False;
+#endif
+ str= NULL;
+ if (strcmp(tok,"=")==0)
+ continue;
+ for (i=0;i<MAX_WORDS;i++) {
+ len = strlen(cname[i]);
+ if (strncmp(cname[i],tok,len)==0) {
+ if(strlen(tok) > len) {
+ char *end = get_index(tok+len, &ndx);
+ if ((i != LAYOUT && i != VARIANT) ||
+ *end != '\0' || ndx == -1)
+ break;
+ if (ndx < 1 || ndx > XkbNumKbdGroups) {
+ PR_DEBUG2("Illegal %s index: %d\n", cname[i], ndx);
+ PR_DEBUG1("Index must be in range 1..%d\n",
+ XkbNumKbdGroups);
+ break;
+ }
+ } else {
+ ndx = 0;
+ }
+#ifdef DEBUG
+ found= True;
+#endif
+ if (present&(1<<i)) {
+ if ((i == LAYOUT && l_ndx_present&(1<<ndx)) ||
+ (i == VARIANT && v_ndx_present&(1<<ndx)) ) {
+ PR_DEBUG1("Component \"%s\" listed twice\n",tok);
+ PR_DEBUG("Second definition ignored\n");
+ break;
+ }
+ }
+ present |= (1<<i);
+ if (i == LAYOUT)
+ l_ndx_present |= 1 << ndx;
+ if (i == VARIANT)
+ v_ndx_present |= 1 << ndx;
+ remap->remap[remap->num_remap].word= i;
+ remap->remap[remap->num_remap++].index= ndx;
+ break;
+ }
+ }
+#ifdef DEBUG
+ if (!found) {
+ fprintf(stderr,"Unknown component \"%s\" ignored\n",tok);
+ }
+#endif
+ }
+ if ((present&PART_MASK)==0) {
+#ifdef DEBUG
+ unsigned mask= PART_MASK;
+ fprintf(stderr,"Mapping needs at least one of ");
+ for (i=0; (i<MAX_WORDS); i++) {
+ if ((1L<<i)&mask) {
+ mask&= ~(1L<<i);
+ if (mask) fprintf(stderr,"\"%s,\" ",cname[i]);
+ else fprintf(stderr,"or \"%s\"\n",cname[i]);
+ }
+ }
+ fprintf(stderr,"Illegal mapping ignored\n");
+#endif
+ remap->num_remap= 0;
+ return;
+ }
+ if ((present&COMPONENT_MASK)==0) {
+ PR_DEBUG("Mapping needs at least one component\n");
+ PR_DEBUG("Illegal mapping ignored\n");
+ remap->num_remap= 0;
+ return;
+ }
+ if (((present&PART_MASK)&(1<<OPTION))&&
+ ((present&PART_MASK)!=(1<<OPTION))) {
+ PR_DEBUG("Options cannot appear with other parts\n");
+ PR_DEBUG("Illegal mapping ignored\n");
+ remap->num_remap= 0;
+ return;
+ }
+ if (((present&COMPONENT_MASK)&(1<<KEYMAP))&&
+ ((present&COMPONENT_MASK)!=(1<<KEYMAP))) {
+ PR_DEBUG("Keymap cannot appear with other components\n");
+ PR_DEBUG("Illegal mapping ignored\n");
+ remap->num_remap= 0;
+ return;
+ }
+ remap->number++;
+ return;
+}
+
+static Bool
+MatchOneOf(char *wanted,char *vals_defined)
+{
+char *str,*next;
+int want_len= strlen(wanted);
+
+ for (str=vals_defined,next=NULL;str!=NULL;str=next) {
+ int len;
+ next= strchr(str,',');
+ if (next) {
+ len= next-str;
+ next++;
+ }
+ else {
+ len= strlen(str);
+ }
+ if ((len==want_len)&&(strncmp(wanted,str,len)==0))
+ return True;
+ }
+ return False;
+}
+
+/***====================================================================***/
+
+static Bool
+CheckLine( InputLine * line,
+ RemapSpec * remap,
+ XkbRF_RulePtr rule,
+ XkbRF_GroupPtr group)
+{
+char * str,*tok;
+register int nread, i;
+FileSpec tmp;
+_Xstrtokparams strtok_buf;
+Bool append = False;
+
+ if (line->line[0]=='!') {
+ if (line->line[1] == '$' ||
+ (line->line[1] == ' ' && line->line[2] == '$')) {
+ char *gname = strchr(line->line, '$');
+ char *words = strchr(gname, ' ');
+ if(!words)
+ return False;
+ *words++ = '\0';
+ for (; *words; words++) {
+ if (*words != '=' && *words != ' ')
+ break;
+ }
+ if (*words == '\0')
+ return False;
+ group->name = Xstrdup(gname);
+ group->words = Xstrdup(words);
+ for (i = 1, words = group->words; *words; words++) {
+ if ( *words == ' ') {
+ *words++ = '\0';
+ i++;
+ }
+ }
+ group->number = i;
+ return True;
+ } else {
+ SetUpRemap(line,remap);
+ return False;
+ }
+ }
+
+ if (remap->num_remap==0) {
+ PR_DEBUG("Must have a mapping before first line of data\n");
+ PR_DEBUG("Illegal line of data ignored\n");
+ return False;
+ }
+ bzero((char *)&tmp,sizeof(FileSpec));
+ str= line->line;
+ for (nread= 0;(tok=_XStrtok(str," ",strtok_buf))!=NULL;nread++) {
+ str= NULL;
+ if (strcmp(tok,"=")==0) {
+ nread--;
+ continue;
+ }
+ if (nread>remap->num_remap) {
+ PR_DEBUG("Too many words on a line\n");
+ PR_DEBUG1("Extra word \"%s\" ignored\n",tok);
+ continue;
+ }
+ tmp.name[remap->remap[nread].word]= tok;
+ if (*tok == '+' || *tok == '|')
+ append = True;
+ }
+ if (nread<remap->num_remap) {
+ PR_DEBUG1("Too few words on a line: %s\n", line->line);
+ PR_DEBUG("line ignored\n");
+ return False;
+ }
+
+ rule->flags= 0;
+ rule->number = remap->number;
+ if (tmp.name[OPTION])
+ rule->flags|= XkbRF_Option;
+ else if (append)
+ rule->flags|= XkbRF_Append;
+ else
+ rule->flags|= XkbRF_Normal;
+ rule->model= Xstrdup(tmp.name[MODEL]);
+ rule->layout= Xstrdup(tmp.name[LAYOUT]);
+ rule->variant= Xstrdup(tmp.name[VARIANT]);
+ rule->option= Xstrdup(tmp.name[OPTION]);
+
+ rule->keycodes= Xstrdup(tmp.name[KEYCODES]);
+ rule->symbols= Xstrdup(tmp.name[SYMBOLS]);
+ rule->types= Xstrdup(tmp.name[TYPES]);
+ rule->compat= Xstrdup(tmp.name[COMPAT]);
+ rule->geometry= Xstrdup(tmp.name[GEOMETRY]);
+ rule->keymap= Xstrdup(tmp.name[KEYMAP]);
+
+ rule->layout_num = rule->variant_num = 0;
+ for (i = 0; i < nread; i++) {
+ if (remap->remap[i].index) {
+ if (remap->remap[i].word == LAYOUT)
+ rule->layout_num = remap->remap[i].index;
+ if (remap->remap[i].word == VARIANT)
+ rule->variant_num = remap->remap[i].index;
+ }
+ }
+ return True;
+}
+
+static char *
+_Concat(char *str1,char *str2)
+{
+int len;
+
+ if ((!str1)||(!str2))
+ return str1;
+ len= strlen(str1)+strlen(str2)+1;
+ str1= _XkbTypedRealloc(str1,len,char);
+ if (str1)
+ strcat(str1,str2);
+ return str1;
+}
+
+static void
+squeeze_spaces(char *p1)
+{
+ char *p2;
+ for (p2 = p1; *p2; p2++) {
+ *p1 = *p2;
+ if (*p1 != ' ') p1++;
+ }
+ *p1 = '\0';
+}
+
+static Bool
+MakeMultiDefs(XkbRF_MultiDefsPtr mdefs, XkbRF_VarDefsPtr defs)
+{
+
+ bzero((char *)mdefs,sizeof(XkbRF_MultiDefsRec));
+ mdefs->model = defs->model;
+ mdefs->options = Xstrdup(defs->options);
+ if (mdefs->options) squeeze_spaces(mdefs->options);
+
+ if (defs->layout) {
+ if (!strchr(defs->layout, ',')) {
+ mdefs->layout[0] = defs->layout;
+ } else {
+ char *p;
+ int i;
+ mdefs->layout[1] = Xstrdup(defs->layout);
+ if (mdefs->layout[1] == NULL)
+ return False;
+ squeeze_spaces(mdefs->layout[1]);
+ p = mdefs->layout[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->layout[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+
+ if (defs->variant) {
+ if (!strchr(defs->variant, ',')) {
+ mdefs->variant[0] = defs->variant;
+ } else {
+ char *p;
+ int i;
+ mdefs->variant[1] = Xstrdup(defs->variant);
+ if (mdefs->variant[1] == NULL)
+ return False;
+ squeeze_spaces(mdefs->variant[1]);
+ p = mdefs->variant[1];
+ for (i = 2; i <= XkbNumKbdGroups; i++) {
+ if ((p = strchr(p, ','))) {
+ *p++ = '\0';
+ mdefs->variant[i] = p;
+ } else {
+ break;
+ }
+ }
+ if (p && (p = strchr(p, ',')))
+ *p = '\0';
+ }
+ }
+ return True;
+}
+
+static void
+FreeMultiDefs(XkbRF_MultiDefsPtr defs)
+{
+ if (defs->options) _XkbFree(defs->options);
+ if (defs->layout[1]) _XkbFree(defs->layout[1]);
+ if (defs->variant[1]) _XkbFree(defs->variant[1]);
+}
+
+static void
+Apply(char *src, char **dst)
+{
+ if (src) {
+ if (*src == '+' || *src == '!') {
+ *dst= _Concat(*dst, src);
+ } else {
+ if (*dst == NULL)
+ *dst= Xstrdup(src);
+ }
+ }
+}
+
+static void
+XkbRF_ApplyRule( XkbRF_RulePtr rule,
+ XkbComponentNamesPtr names)
+{
+ rule->flags&= ~XkbRF_PendingMatch; /* clear the flag because it's applied */
+
+ Apply(rule->keycodes, &names->keycodes);
+ Apply(rule->symbols, &names->symbols);
+ Apply(rule->types, &names->types);
+ Apply(rule->compat, &names->compat);
+ Apply(rule->geometry, &names->geometry);
+ Apply(rule->keymap, &names->keymap);
+}
+
+static Bool
+CheckGroup( XkbRF_RulesPtr rules,
+ char * group_name,
+ char * name)
+{
+ int i;
+ char *p;
+ XkbRF_GroupPtr group;
+
+ for (i = 0, group = rules->groups; i < rules->num_groups; i++, group++) {
+ if (! strcmp(group->name, group_name)) {
+ break;
+ }
+ }
+ if (i == rules->num_groups)
+ return False;
+ for (i = 0, p = group->words; i < group->number; i++, p += strlen(p)+1) {
+ if (! strcmp(p, name)) {
+ return True;
+ }
+ }
+ return False;
+}
+
+static int
+XkbRF_CheckApplyRule( XkbRF_RulePtr rule,
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ XkbRF_RulesPtr rules)
+{
+ Bool pending = False;
+
+ if (rule->model != NULL) {
+ if(mdefs->model == NULL)
+ return 0;
+ if (strcmp(rule->model, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->model[0] == '$') {
+ if (!CheckGroup(rules, rule->model, mdefs->model))
+ return 0;
+ } else {
+ if (strcmp(rule->model, mdefs->model) != 0)
+ return 0;
+ }
+ }
+ }
+ if (rule->option != NULL) {
+ if (mdefs->options == NULL)
+ return 0;
+ if ((!MatchOneOf(rule->option,mdefs->options)))
+ return 0;
+ }
+
+ if (rule->layout != NULL) {
+ if(mdefs->layout[rule->layout_num] == NULL ||
+ *mdefs->layout[rule->layout_num] == '\0')
+ return 0;
+ if (strcmp(rule->layout, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->layout[0] == '$') {
+ if (!CheckGroup(rules, rule->layout,
+ mdefs->layout[rule->layout_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->layout, mdefs->layout[rule->layout_num]) != 0)
+ return 0;
+ }
+ }
+ }
+ if (rule->variant != NULL) {
+ if (mdefs->variant[rule->variant_num] == NULL ||
+ *mdefs->variant[rule->variant_num] == '\0')
+ return 0;
+ if (strcmp(rule->variant, "*") == 0) {
+ pending = True;
+ } else {
+ if (rule->variant[0] == '$') {
+ if (!CheckGroup(rules, rule->variant,
+ mdefs->variant[rule->variant_num]))
+ return 0;
+ } else {
+ if (strcmp(rule->variant,
+ mdefs->variant[rule->variant_num]) != 0)
+ return 0;
+ }
+ }
+ }
+ if (pending) {
+ rule->flags|= XkbRF_PendingMatch;
+ return rule->number;
+ }
+ /* exact match, apply it now */
+ XkbRF_ApplyRule(rule,names);
+ return rule->number;
+}
+
+static void
+XkbRF_ClearPartialMatches(XkbRF_RulesPtr rules)
+{
+register int i;
+XkbRF_RulePtr rule;
+
+ for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
+ rule->flags&= ~XkbRF_PendingMatch;
+ }
+}
+
+static void
+XkbRF_ApplyPartialMatches(XkbRF_RulesPtr rules,XkbComponentNamesPtr names)
+{
+int i;
+XkbRF_RulePtr rule;
+
+ for (rule = rules->rules, i = 0; i < rules->num_rules; i++, rule++) {
+ if ((rule->flags&XkbRF_PendingMatch)==0)
+ continue;
+ XkbRF_ApplyRule(rule,names);
+ }
+}
+
+static void
+XkbRF_CheckApplyRules( XkbRF_RulesPtr rules,
+ XkbRF_MultiDefsPtr mdefs,
+ XkbComponentNamesPtr names,
+ int flags)
+{
+int i;
+XkbRF_RulePtr rule;
+int skip;
+
+ for (rule = rules->rules, i=0; i < rules->num_rules; rule++, i++) {
+ if ((rule->flags & flags) != flags)
+ continue;
+ skip = XkbRF_CheckApplyRule(rule, mdefs, names, rules);
+ if (skip && !(flags & XkbRF_Option)) {
+ for ( ;(i < rules->num_rules) && (rule->number == skip);
+ rule++, i++);
+ rule--; i--;
+ }
+ }
+}
+
+/***====================================================================***/
+
+static char *
+XkbRF_SubstituteVars(char *name, XkbRF_MultiDefsPtr mdefs)
+{
+char *str, *outstr, *orig, *var;
+int len, ndx;
+
+ orig= name;
+ str= index(name,'%');
+ if (str==NULL)
+ return name;
+ len= strlen(name);
+ while (str!=NULL) {
+ char pfx= str[1];
+ int extra_len= 0;
+ if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
+ extra_len= 1;
+ str++;
+ }
+ else if (pfx=='(') {
+ extra_len= 2;
+ str++;
+ }
+ var = str + 1;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ str = index(str,'%');
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx])
+ len+= strlen(mdefs->layout[ndx])+extra_len;
+ else if ((*var=='m')&&mdefs->model)
+ len+= strlen(mdefs->model)+extra_len;
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx])
+ len+= strlen(mdefs->variant[ndx])+extra_len;
+ if ((pfx=='(')&&(*str==')')) {
+ str++;
+ }
+ str= index(&str[0],'%');
+ }
+ name= (char *)_XkbAlloc(len+1);
+ str= orig;
+ outstr= name;
+ while (*str!='\0') {
+ if (str[0]=='%') {
+ char pfx,sfx;
+ str++;
+ pfx= str[0];
+ sfx= '\0';
+ if ((pfx=='+')||(pfx=='|')||(pfx=='_')||(pfx=='-')) {
+ str++;
+ }
+ else if (pfx=='(') {
+ sfx= ')';
+ str++;
+ }
+ else pfx= '\0';
+
+ var = str;
+ str = get_index(var + 1, &ndx);
+ if (ndx == -1) {
+ continue;
+ }
+ if ((*var=='l') && mdefs->layout[ndx] && *mdefs->layout[ndx]) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->layout[ndx]);
+ outstr+= strlen(mdefs->layout[ndx]);
+ if (sfx) *outstr++= sfx;
+ }
+ else if ((*var=='m')&&(mdefs->model)) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->model);
+ outstr+= strlen(mdefs->model);
+ if (sfx) *outstr++= sfx;
+ }
+ else if ((*var=='v') && mdefs->variant[ndx] && *mdefs->variant[ndx]) {
+ if (pfx) *outstr++= pfx;
+ strcpy(outstr,mdefs->variant[ndx]);
+ outstr+= strlen(mdefs->variant[ndx]);
+ if (sfx) *outstr++= sfx;
+ }
+ if ((pfx=='(')&&(*str==')'))
+ str++;
+ }
+ else {
+ *outstr++= *str++;
+ }
+ }
+ *outstr++= '\0';
+ if (orig!=name)
+ _XkbFree(orig);
+ return name;
+}
+
+/***====================================================================***/
+
+Bool
+XkbRF_GetComponents( XkbRF_RulesPtr rules,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names)
+{
+ XkbRF_MultiDefsRec mdefs;
+
+ MakeMultiDefs(&mdefs, defs);
+
+ bzero((char *)names,sizeof(XkbComponentNamesRec));
+ XkbRF_ClearPartialMatches(rules);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Normal);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Append);
+ XkbRF_ApplyPartialMatches(rules, names);
+ XkbRF_CheckApplyRules(rules, &mdefs, names, XkbRF_Option);
+
+ if (names->keycodes)
+ names->keycodes= XkbRF_SubstituteVars(names->keycodes, &mdefs);
+ if (names->symbols)
+ names->symbols= XkbRF_SubstituteVars(names->symbols, &mdefs);
+ if (names->types)
+ names->types= XkbRF_SubstituteVars(names->types, &mdefs);
+ if (names->compat)
+ names->compat= XkbRF_SubstituteVars(names->compat, &mdefs);
+ if (names->geometry)
+ names->geometry= XkbRF_SubstituteVars(names->geometry, &mdefs);
+ if (names->keymap)
+ names->keymap= XkbRF_SubstituteVars(names->keymap, &mdefs);
+
+ FreeMultiDefs(&mdefs);
+ return (names->keycodes && names->symbols && names->types &&
+ names->compat && names->geometry ) || names->keymap;
+}
+
+XkbRF_RulePtr
+XkbRF_AddRule(XkbRF_RulesPtr rules)
+{
+ if (rules->sz_rules<1) {
+ rules->sz_rules= 16;
+ rules->num_rules= 0;
+ rules->rules= _XkbTypedCalloc(rules->sz_rules,XkbRF_RuleRec);
+ }
+ else if (rules->num_rules>=rules->sz_rules) {
+ rules->sz_rules*= 2;
+ rules->rules= _XkbTypedRealloc(rules->rules,rules->sz_rules,
+ XkbRF_RuleRec);
+ }
+ if (!rules->rules) {
+ rules->sz_rules= rules->num_rules= 0;
+#ifdef DEBUG
+ fprintf(stderr,"Allocation failure in XkbRF_AddRule\n");
+#endif
+ return NULL;
+ }
+ bzero((char *)&rules->rules[rules->num_rules],sizeof(XkbRF_RuleRec));
+ return &rules->rules[rules->num_rules++];
+}
+
+XkbRF_GroupPtr
+XkbRF_AddGroup(XkbRF_RulesPtr rules)
+{
+ if (rules->sz_groups<1) {
+ rules->sz_groups= 16;
+ rules->num_groups= 0;
+ rules->groups= _XkbTypedCalloc(rules->sz_groups,XkbRF_GroupRec);
+ }
+ else if (rules->num_groups >= rules->sz_groups) {
+ rules->sz_groups *= 2;
+ rules->groups= _XkbTypedRealloc(rules->groups,rules->sz_groups,
+ XkbRF_GroupRec);
+ }
+ if (!rules->groups) {
+ rules->sz_groups= rules->num_groups= 0;
+ return NULL;
+ }
+
+ bzero((char *)&rules->groups[rules->num_groups],sizeof(XkbRF_GroupRec));
+ return &rules->groups[rules->num_groups++];
+}
+
+Bool
+XkbRF_LoadRules(FILE *file, XkbRF_RulesPtr rules)
+{
+InputLine line;
+RemapSpec remap;
+XkbRF_RuleRec trule,*rule;
+XkbRF_GroupRec tgroup,*group;
+
+ if (!(rules && file))
+ return False;
+ bzero((char *)&remap,sizeof(RemapSpec));
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ InitInputLine(&line);
+ while (GetInputLine(file,&line,True)) {
+ if (CheckLine(&line,&remap,&trule,&tgroup)) {
+ if (tgroup.number) {
+ if ((group= XkbRF_AddGroup(rules))!=NULL) {
+ *group= tgroup;
+ bzero((char *)&tgroup,sizeof(XkbRF_GroupRec));
+ }
+ } else {
+ if ((rule= XkbRF_AddRule(rules))!=NULL) {
+ *rule= trule;
+ bzero((char *)&trule,sizeof(XkbRF_RuleRec));
+ }
+ }
+ }
+ line.num_line= 0;
+ }
+ FreeInputLine(&line);
+ return True;
+}
+
+Bool
+XkbRF_LoadRulesByName(char *base,char *locale,XkbRF_RulesPtr rules)
+{
+FILE * file;
+char buf[PATH_MAX];
+Bool ok;
+
+ if ((!base)||(!rules))
+ return False;
+ if (locale) {
+ if (strlen(base)+strlen(locale)+2 > PATH_MAX)
+ return False;
+ sprintf(buf,"%s-%s", base, locale);
+ }
+ else {
+ if (strlen(base)+1 > PATH_MAX)
+ return False;
+ strcpy(buf,base);
+ }
+
+ file= fopen(buf, "r");
+ if ((!file)&&(locale)) { /* fallback if locale was specified */
+ strcpy(buf,base);
+ file= fopen(buf, "r");
+ }
+ if (!file)
+ return False;
+ ok= XkbRF_LoadRules(file,rules);
+ fclose(file);
+ return ok;
+}
+
+/***====================================================================***/
+
+#define HEAD_NONE 0
+#define HEAD_MODEL 1
+#define HEAD_LAYOUT 2
+#define HEAD_VARIANT 3
+#define HEAD_OPTION 4
+#define HEAD_EXTRA 5
+
+XkbRF_VarDescPtr
+XkbRF_AddVarDesc(XkbRF_DescribeVarsPtr vars)
+{
+ if (vars->sz_desc<1) {
+ vars->sz_desc= 16;
+ vars->num_desc= 0;
+ vars->desc= _XkbTypedCalloc(vars->sz_desc,XkbRF_VarDescRec);
+ }
+ else if (vars->num_desc>=vars->sz_desc) {
+ vars->sz_desc*= 2;
+ vars->desc= _XkbTypedRealloc(vars->desc,vars->sz_desc,XkbRF_VarDescRec);
+ }
+ if (!vars->desc) {
+ vars->sz_desc= vars->num_desc= 0;
+ PR_DEBUG("Allocation failure in XkbRF_AddVarDesc\n");
+ return NULL;
+ }
+ vars->desc[vars->num_desc].name= NULL;
+ vars->desc[vars->num_desc].desc= NULL;
+ return &vars->desc[vars->num_desc++];
+}
+
+XkbRF_VarDescPtr
+XkbRF_AddVarDescCopy(XkbRF_DescribeVarsPtr vars,XkbRF_VarDescPtr from)
+{
+XkbRF_VarDescPtr nd;
+
+ if ((nd=XkbRF_AddVarDesc(vars))!=NULL) {
+ nd->name= Xstrdup(from->name);
+ nd->desc= Xstrdup(from->desc);
+ }
+ return nd;
+}
+
+XkbRF_DescribeVarsPtr
+XkbRF_AddVarToDescribe(XkbRF_RulesPtr rules,char *name)
+{
+ if (rules->sz_extra<1) {
+ rules->num_extra= 0;
+ rules->sz_extra= 1;
+ rules->extra_names= _XkbTypedCalloc(rules->sz_extra,char *);
+ rules->extra= _XkbTypedCalloc(rules->sz_extra, XkbRF_DescribeVarsRec);
+ }
+ else if (rules->num_extra>=rules->sz_extra) {
+ rules->sz_extra*= 2;
+ rules->extra_names= _XkbTypedRealloc(rules->extra_names,rules->sz_extra,
+ char *);
+ rules->extra=_XkbTypedRealloc(rules->extra, rules->sz_extra,
+ XkbRF_DescribeVarsRec);
+ }
+ if ((!rules->extra_names)||(!rules->extra)) {
+ PR_DEBUG("allocation error in extra parts\n");
+ rules->sz_extra= rules->num_extra= 0;
+ rules->extra_names= NULL;
+ rules->extra= NULL;
+ return NULL;
+ }
+ rules->extra_names[rules->num_extra]= Xstrdup(name);
+ bzero(&rules->extra[rules->num_extra],sizeof(XkbRF_DescribeVarsRec));
+ return &rules->extra[rules->num_extra++];
+}
+
+Bool
+XkbRF_LoadDescriptions(FILE *file,XkbRF_RulesPtr rules)
+{
+InputLine line;
+XkbRF_VarDescRec tmp;
+char *tok;
+int len,headingtype,extra_ndx = 0;
+
+ bzero((char *)&tmp, sizeof(XkbRF_VarDescRec));
+ headingtype = HEAD_NONE;
+ InitInputLine(&line);
+ for ( ; GetInputLine(file,&line,False); line.num_line= 0) {
+ if (line.line[0]=='!') {
+ tok = strtok(&(line.line[1]), " \t");
+ if (!_XkbStrCaseCmp(tok,"model"))
+ headingtype = HEAD_MODEL;
+ else if (!_XkbStrCaseCmp(tok,"layout"))
+ headingtype = HEAD_LAYOUT;
+ else if (!_XkbStrCaseCmp(tok,"variant"))
+ headingtype = HEAD_VARIANT;
+ else if (!_XkbStrCaseCmp(tok,"option"))
+ headingtype = HEAD_OPTION;
+ else {
+ int i;
+ headingtype = HEAD_EXTRA;
+ extra_ndx= -1;
+ for (i=0;(i<rules->num_extra)&&(extra_ndx<0);i++) {
+ if (!_XkbStrCaseCmp(tok,rules->extra_names[i]))
+ extra_ndx= i;
+ }
+ if (extra_ndx<0) {
+ XkbRF_DescribeVarsPtr var;
+ PR_DEBUG1("Extra heading \"%s\" encountered\n",tok);
+ var= XkbRF_AddVarToDescribe(rules,tok);
+ if (var)
+ extra_ndx= var-rules->extra;
+ else headingtype= HEAD_NONE;
+ }
+ }
+ continue;
+ }
+
+ if (headingtype == HEAD_NONE) {
+ PR_DEBUG("Must have a heading before first line of data\n");
+ PR_DEBUG("Illegal line of data ignored\n");
+ continue;
+ }
+
+ len = strlen(line.line);
+ if ((tmp.name= strtok(line.line, " \t")) == NULL) {
+ PR_DEBUG("Huh? No token on line\n");
+ PR_DEBUG("Illegal line of data ignored\n");
+ continue;
+ }
+ if (strlen(tmp.name) == len) {
+ PR_DEBUG("No description found\n");
+ PR_DEBUG("Illegal line of data ignored\n");
+ continue;
+ }
+
+ tok = line.line + strlen(tmp.name) + 1;
+ while ((*tok!='\n')&&isspace(*tok))
+ tok++;
+ if (*tok == '\0') {
+ PR_DEBUG("No description found\n");
+ PR_DEBUG("Illegal line of data ignored\n");
+ continue;
+ }
+ tmp.desc= tok;
+ switch (headingtype) {
+ case HEAD_MODEL:
+ XkbRF_AddVarDescCopy(&rules->models,&tmp);
+ break;
+ case HEAD_LAYOUT:
+ XkbRF_AddVarDescCopy(&rules->layouts,&tmp);
+ break;
+ case HEAD_VARIANT:
+ XkbRF_AddVarDescCopy(&rules->variants,&tmp);
+ break;
+ case HEAD_OPTION:
+ XkbRF_AddVarDescCopy(&rules->options,&tmp);
+ break;
+ case HEAD_EXTRA:
+ XkbRF_AddVarDescCopy(&rules->extra[extra_ndx],&tmp);
+ break;
+ }
+ }
+ FreeInputLine(&line);
+ if ((rules->models.num_desc==0) && (rules->layouts.num_desc==0) &&
+ (rules->variants.num_desc==0) && (rules->options.num_desc==0) &&
+ (rules->num_extra==0)) {
+ return False;
+ }
+ return True;
+}
+
+Bool
+XkbRF_LoadDescriptionsByName(char *base,char *locale,XkbRF_RulesPtr rules)
+{
+FILE * file;
+char buf[PATH_MAX];
+Bool ok;
+
+ if ((!base)||(!rules))
+ return False;
+ if (locale) {
+ if (strlen(base)+strlen(locale)+6 > PATH_MAX)
+ return False;
+ sprintf(buf,"%s-%s.lst", base, locale);
+ }
+ else {
+ if (strlen(base)+5 > PATH_MAX)
+ return False;
+ sprintf(buf,"%s.lst", base);
+ }
+
+ file= fopen(buf, "r");
+ if ((!file)&&(locale)) { /* fallback if locale was specified */
+ sprintf(buf,"%s.lst", base);
+
+ file= fopen(buf, "r");
+ }
+ if (!file)
+ return False;
+ ok= XkbRF_LoadDescriptions(file,rules);
+ fclose(file);
+ return ok;
+}
+
+/***====================================================================***/
+
+XkbRF_RulesPtr
+XkbRF_Load(char *base,char *locale,Bool wantDesc,Bool wantRules)
+{
+XkbRF_RulesPtr rules;
+
+ if ((!base)||((!wantDesc)&&(!wantRules)))
+ return NULL;
+ if ((rules=_XkbTypedCalloc(1,XkbRF_RulesRec))==NULL)
+ return NULL;
+ if (wantDesc&&(!XkbRF_LoadDescriptionsByName(base,locale,rules))) {
+ XkbRF_Free(rules,True);
+ return NULL;
+ }
+ if (wantRules&&(!XkbRF_LoadRulesByName(base,locale,rules))) {
+ XkbRF_Free(rules,True);
+ return NULL;
+ }
+ return rules;
+}
+
+XkbRF_RulesPtr
+XkbRF_Create(int szRules,int szExtra)
+{
+XkbRF_RulesPtr rules;
+
+ if ((rules=_XkbTypedCalloc(1,XkbRF_RulesRec))==NULL)
+ return NULL;
+ if (szRules>0) {
+ rules->sz_rules= szRules;
+ rules->rules= _XkbTypedCalloc(rules->sz_rules,XkbRF_RuleRec);
+ if (!rules->rules) {
+ _XkbFree(rules);
+ return NULL;
+ }
+ }
+ if (szExtra>0) {
+ rules->sz_extra= szExtra;
+ rules->extra= _XkbTypedCalloc(rules->sz_extra,XkbRF_DescribeVarsRec);
+ if (!rules->extra) {
+ if (rules->rules)
+ _XkbFree(rules->rules);
+ _XkbFree(rules);
+ return NULL;
+ }
+ }
+ return rules;
+}
+
+/***====================================================================***/
+
+static void
+XkbRF_ClearVarDescriptions(XkbRF_DescribeVarsPtr var)
+{
+register int i;
+
+ for (i=0;i<var->num_desc;i++) {
+ if (var->desc[i].name)
+ _XkbFree(var->desc[i].name);
+ if (var->desc[i].desc)
+ _XkbFree(var->desc[i].desc);
+ var->desc[i].name= var->desc[i].desc= NULL;
+ }
+ if (var->desc)
+ _XkbFree(var->desc);
+ var->desc= NULL;
+ return;
+}
+
+void
+XkbRF_Free(XkbRF_RulesPtr rules,Bool freeRules)
+{
+int i;
+XkbRF_RulePtr rule;
+XkbRF_GroupPtr group;
+
+ if (!rules)
+ return;
+ XkbRF_ClearVarDescriptions(&rules->models);
+ XkbRF_ClearVarDescriptions(&rules->layouts);
+ XkbRF_ClearVarDescriptions(&rules->variants);
+ XkbRF_ClearVarDescriptions(&rules->options);
+ if (rules->extra) {
+ for (i = 0; i < rules->num_extra; i++) {
+ XkbRF_ClearVarDescriptions(&rules->extra[i]);
+ }
+ _XkbFree(rules->extra);
+ rules->num_extra= rules->sz_extra= 0;
+ rules->extra= NULL;
+ }
+ if (rules->rules) {
+ for (i=0,rule=rules->rules;i<rules->num_rules;i++,rule++) {
+ if (rule->model) _XkbFree(rule->model);
+ if (rule->layout) _XkbFree(rule->layout);
+ if (rule->variant) _XkbFree(rule->variant);
+ if (rule->option) _XkbFree(rule->option);
+ if (rule->keycodes) _XkbFree(rule->keycodes);
+ if (rule->symbols) _XkbFree(rule->symbols);
+ if (rule->types) _XkbFree(rule->types);
+ if (rule->compat) _XkbFree(rule->compat);
+ if (rule->geometry) _XkbFree(rule->geometry);
+ if (rule->keymap) _XkbFree(rule->keymap);
+ bzero((char *)rule,sizeof(XkbRF_RuleRec));
+ }
+ _XkbFree(rules->rules);
+ rules->num_rules= rules->sz_rules= 0;
+ rules->rules= NULL;
+ }
+
+ if (rules->groups) {
+ for (i=0, group=rules->groups;i<rules->num_groups;i++,group++) {
+ if (group->name) _XkbFree(group->name);
+ if (group->words) _XkbFree(group->words);
+ }
+ _XkbFree(rules->groups);
+ rules->num_groups= 0;
+ rules->groups= NULL;
+ }
+ if (freeRules)
+ _XkbFree(rules);
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/xkb.c b/nx-X11/programs/Xserver/xkb/xkb.c
new file mode 100644
index 000000000..6798f2dda
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkb.c
@@ -0,0 +1,6214 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "extnsionst.h"
+#include "xkb.h"
+#include "protocol-versions.h"
+
+#include <nx-X11/extensions/XI.h>
+
+ int XkbEventBase;
+ int XkbErrorBase;
+ int XkbReqCode;
+ int XkbKeyboardErrorCode;
+Atom xkbONE_LEVEL;
+Atom xkbTWO_LEVEL;
+Atom xkbKEYPAD;
+CARD32 xkbDebugFlags = 0;
+CARD32 xkbDebugCtrls = 0;
+
+#ifndef XKB_SRV_UNSUPPORTED_XI_FEATURES
+#define XKB_SRV_UNSUPPORTED_XI_FEATURES XkbXI_KeyboardsMask
+#endif
+
+unsigned XkbXIUnsupported= XKB_SRV_UNSUPPORTED_XI_FEATURES;
+
+RESTYPE RT_XKBCLIENT;
+
+/***====================================================================***/
+
+#define CHK_DEVICE(d,sp,lf) {\
+ int why;\
+ d = (DeviceIntPtr)lf((sp),&why);\
+ if (!dev) {\
+ client->errorValue = _XkbErrCode2(why,(sp));\
+ return XkbKeyboardErrorCode;\
+ }\
+}
+
+#define CHK_KBD_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupKeyboard)
+#define CHK_LED_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupLedDevice)
+#define CHK_BELL_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupBellDevice)
+#define CHK_ANY_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupAnyDevice)
+
+#define CHK_ATOM_ONLY2(a,ev,er) {\
+ if (((a)==None)||(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_ONLY(a) \
+ CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
+
+#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ (er)= BadAtom;\
+ return ret;\
+ }\
+}
+#define CHK_ATOM_OR_NONE2(a,ev,er) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_OR_NONE(a) \
+ CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
+
+#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ (er)= BadValue;\
+ return ret;\
+ }\
+}
+#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ return er;\
+ }\
+}
+#define CHK_MASK_LEGAL(err,mask,legal) \
+ CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
+
+#define CHK_MASK_MATCH(err,affect,value) {\
+ if ((value)&(~(affect))) { \
+ client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
+ return BadMatch;\
+ }\
+}
+#define CHK_MASK_OVERLAP(err,m1,m2) {\
+ if ((m1)&(m2)) { \
+ client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
+ return BadMatch;\
+ }\
+}
+#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
+ return er;\
+ }\
+ else if ( (first)<(x)->min_key_code ) {\
+ (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
+ return er;\
+ }\
+}
+#define CHK_KEY_RANGE(err,first,num,x) \
+ CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
+
+#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
+ return er;\
+ }\
+ else if ( (first)<(r)->minKeyCode ) {\
+ (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
+ return er;\
+ }\
+}
+#define CHK_REQ_KEY_RANGE(err,first,num,r) \
+ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
+
+/***====================================================================***/
+
+int
+ProcXkbUseExtension(ClientPtr client)
+{
+ REQUEST(xkbUseExtensionReq);
+ xkbUseExtensionReply rep;
+ int supported;
+
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
+ /* pre-release version 0.65 is compatible with 1.00 */
+ supported= ((SERVER_XKB_MAJOR_VERSION==1)&&
+ (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
+ }
+ else supported = 1;
+
+#ifdef XKB_SWAPPING_BUSTED
+ if (client->swapped)
+ supported= 0;
+#endif
+
+ if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
+ client->xkbClientFlags= _XkbClientInitialized;
+ client->vMajor= stuff->wantedMajor;
+ client->vMinor= stuff->wantedMinor;
+ }
+ else if (xkbDebugFlags&0x1) {
+ ErrorF("Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
+ client->index,
+ (long)client->clientAsMask,
+ stuff->wantedMajor,stuff->wantedMinor,
+ SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION);
+ }
+ memset(&rep, 0, sizeof(xkbUseExtensionReply));
+ rep.type = X_Reply;
+ rep.supported = supported;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.serverMajor = SERVER_XKB_MAJOR_VERSION;
+ rep.serverMinor = SERVER_XKB_MINOR_VERSION;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.serverMajor);
+ swaps(&rep.serverMinor);
+ }
+ WriteToClient(client,SIZEOF(xkbUseExtensionReply), &rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSelectEvents(ClientPtr client)
+{
+ unsigned legal;
+ DeviceIntPtr dev;
+ XkbInterestPtr masks;
+ REQUEST(xkbSelectEventsReq);
+
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+
+ if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
+ client->mapNotifyMask&= ~stuff->affectMap;
+ client->mapNotifyMask|= (stuff->affectMap&stuff->map);
+ }
+ if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
+ return client->noClientException;
+
+ masks = XkbFindClientResource((DevicePtr)dev,client);
+ if (!masks){
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ masks= XkbAddClientResource((DevicePtr)dev,client,id);
+ }
+ if (masks) {
+ union {
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from,to;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if ((bit&maskLeft)==0)
+ continue;
+ maskLeft&= ~bit;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ to.c16= &client->newKeyboardNotifyMask;
+ legal= XkbAllNewKeyboardEventsMask;
+ size= 2;
+ break;
+ case XkbStateNotify:
+ to.c16= &masks->stateNotifyMask;
+ legal= XkbAllStateEventsMask;
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ to.c32= &masks->ctrlsNotifyMask;
+ legal= XkbAllControlEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorStateNotify:
+ to.c32= &masks->iStateNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorMapNotify:
+ to.c32= &masks->iMapNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbNamesNotify:
+ to.c16= &masks->namesNotifyMask;
+ legal= XkbAllNameEventsMask;
+ size= 2;
+ break;
+ case XkbCompatMapNotify:
+ to.c8= &masks->compatNotifyMask;
+ legal= XkbAllCompatMapEventsMask;
+ size= 1;
+ break;
+ case XkbBellNotify:
+ to.c8= &masks->bellNotifyMask;
+ legal= XkbAllBellEventsMask;
+ size= 1;
+ break;
+ case XkbActionMessage:
+ to.c8= &masks->actionMessageMask;
+ legal= XkbAllActionMessagesMask;
+ size= 1;
+ break;
+ case XkbAccessXNotify:
+ to.c16= &masks->accessXNotifyMask;
+ legal= XkbAllAccessXEventsMask;
+ size= 2;
+ break;
+ case XkbExtensionDeviceNotify:
+ to.c16= &masks->extDevNotifyMask;
+ legal= XkbAllExtensionDeviceEventsMask;
+ size= 2;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(33,bit);
+ return BadValue;
+ }
+
+ if (stuff->clear&bit) {
+ if (size==2) to.c16[0]= 0;
+ else if (size==4) to.c32[0]= 0;
+ else to.c8[0]= 0;
+ }
+ else if (stuff->selectAll&bit) {
+ if (size==2) to.c16[0]= ~0;
+ else if (size==4) to.c32[0]= ~0;
+ else to.c8[0]= ~0;
+ }
+ else {
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
+ CHK_MASK_LEGAL(ndx,from.c16[0],legal);
+ to.c16[0]&= ~from.c16[0];
+ to.c16[0]|= (from.c16[0]&from.c16[1]);
+ }
+ else if (size==4) {
+ CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
+ CHK_MASK_LEGAL(ndx,from.c32[0],legal);
+ to.c32[0]&= ~from.c32[0];
+ to.c32[0]|= (from.c32[0]&from.c32[1]);
+ }
+ else {
+ CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
+ CHK_MASK_LEGAL(ndx,from.c8[0],legal);
+ to.c8[0]&= ~from.c8[0];
+ to.c8[0]|= (from.c8[0]&from.c8[1]);
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ }
+ if (dataLeft>2) {
+ ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ return client->noClientException;
+ }
+ return BadAlloc;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbBell(ClientPtr client)
+{
+ REQUEST(xkbBellReq);
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ int base;
+ int newPercent,oldPitch,oldDuration;
+ void * ctrl;
+
+ REQUEST_SIZE_MATCH(xkbBellReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_BELL_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ if ((stuff->forceSound)&&(stuff->eventOnly)) {
+ client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
+ return BadMatch;
+ }
+ if (stuff->percent < -100 || stuff->percent > 100) {
+ client->errorValue = _XkbErrCode2(0x2,stuff->percent);
+ return BadValue;
+ }
+ if (stuff->duration<-1) {
+ client->errorValue = _XkbErrCode2(0x3,stuff->duration);
+ return BadValue;
+ }
+ if (stuff->pitch<-1) {
+ client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
+ return BadValue;
+ }
+
+ if (stuff->bellClass == XkbDfltXIClass) {
+ if (dev->kbdfeed!=NULL)
+ stuff->bellClass= KbdFeedbackClass;
+ else stuff->bellClass= BellFeedbackClass;
+ }
+ if (stuff->bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ if (stuff->bellID==XkbDfltXIId)
+ k= dev->kbdfeed;
+ else {
+ for (k=dev->kbdfeed; k; k=k->next) {
+ if (k->ctrl.id == stuff->bellID)
+ break;
+ }
+ }
+ if (!k) {
+ client->errorValue= _XkbErrCode2(0x5,stuff->bellID);
+ return BadValue;
+ }
+ base = k->ctrl.bell;
+ ctrl = (void *) &(k->ctrl);
+ oldPitch= k->ctrl.bell_pitch;
+ oldDuration= k->ctrl.bell_duration;
+ if (stuff->pitch!=0) {
+ if (stuff->pitch==-1)
+ k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
+ else k->ctrl.bell_pitch= stuff->pitch;
+ }
+ if (stuff->duration!=0) {
+ if (stuff->duration==-1)
+ k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
+ else k->ctrl.bell_duration= stuff->duration;
+ }
+ }
+ else if (stuff->bellClass == BellFeedbackClass) {
+ BellFeedbackPtr b;
+ if (stuff->bellID==XkbDfltXIId)
+ b= dev->bell;
+ else {
+ for (b=dev->bell; b; b=b->next) {
+ if (b->ctrl.id == stuff->bellID)
+ break;
+ }
+ }
+ if (!b) {
+ client->errorValue = _XkbErrCode2(0x6,stuff->bellID);
+ return BadValue;
+ }
+ base = b->ctrl.percent;
+ ctrl = (void *) &(b->ctrl);
+ oldPitch= b->ctrl.pitch;
+ oldDuration= b->ctrl.duration;
+ if (stuff->pitch!=0) {
+ if (stuff->pitch==-1)
+ b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
+ else b->ctrl.pitch= stuff->pitch;
+ }
+ if (stuff->duration!=0) {
+ if (stuff->duration==-1)
+ b->ctrl.duration= defaultKeyboardControl.bell_duration;
+ else b->ctrl.duration= stuff->duration;
+ }
+ }
+ else {
+ client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);;
+ return BadValue;
+ }
+ if (stuff->window!=None) {
+ pWin= (WindowPtr)LookupIDByType(stuff->window,RT_WINDOW);
+ if (pWin==NULL) {
+ client->errorValue= stuff->window;
+ return BadValue;
+ }
+ }
+ else pWin= NULL;
+
+ newPercent= (base*stuff->percent)/100;
+ if (stuff->percent < 0)
+ newPercent= base+newPercent;
+ else newPercent= base-newPercent+stuff->percent;
+ XkbHandleBell(stuff->forceSound, stuff->eventOnly,
+ dev, newPercent, ctrl, stuff->bellClass,
+ stuff->name, pWin, client);
+ if ((stuff->pitch!=0)||(stuff->duration!=0)) {
+ if (stuff->bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ k= (KbdFeedbackPtr)ctrl;
+ if (stuff->pitch!=0)
+ k->ctrl.bell_pitch= oldPitch;
+ if (stuff->duration!=0)
+ k->ctrl.bell_duration= oldDuration;
+ }
+ else {
+ BellFeedbackPtr b;
+ b= (BellFeedbackPtr)ctrl;
+ if (stuff->pitch!=0)
+ b->ctrl.pitch= oldPitch;
+ if (stuff->duration!=0)
+ b->ctrl.duration= oldDuration;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetState(ClientPtr client)
+{
+ REQUEST(xkbGetStateReq);
+ DeviceIntPtr dev;
+ xkbGetStateReply rep;
+ XkbStateRec *xkb;
+
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb= &dev->key->xkbInfo->state;
+ bzero(&rep,sizeof(xkbGetStateReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.mods = dev->key->state&0xff;
+ rep.baseMods = xkb->base_mods;
+ rep.lockedMods = xkb->locked_mods;
+ rep.latchedMods = xkb->latched_mods;
+ rep.group = xkb->group;
+ rep.baseGroup = xkb->base_group;
+ rep.latchedGroup = xkb->latched_group;
+ rep.lockedGroup = xkb->locked_group;
+ rep.compatState = xkb->compat_state;
+ rep.ptrBtnState = xkb->ptr_buttons;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swaps(&rep.ptrBtnState);
+ }
+ WriteToClient(client, SIZEOF(xkbGetStateReply), &rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbLatchLockState(ClientPtr client)
+{
+ int status;
+ DeviceIntPtr dev;
+ XkbStateRec oldState,*newState;
+ CARD16 changed;
+
+ REQUEST(xkbLatchLockStateReq);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_MATCH(0x01,stuff->affectModLocks,stuff->modLocks);
+ CHK_MASK_MATCH(0x01,stuff->affectModLatches,stuff->modLatches);
+
+ status = Success;
+ oldState= dev->key->xkbInfo->state;
+ newState= &dev->key->xkbInfo->state;
+ if ( stuff->affectModLocks ) {
+ newState->locked_mods&= ~stuff->affectModLocks;
+ newState->locked_mods|= (stuff->affectModLocks&stuff->modLocks);
+ }
+ if (( status == Success ) && stuff->lockGroup )
+ newState->locked_group = stuff->groupLock;
+ if (( status == Success ) && stuff->affectModLatches )
+ status=XkbLatchModifiers(dev,stuff->affectModLatches,stuff->modLatches);
+ if (( status == Success ) && stuff->latchGroup )
+ status=XkbLatchGroup(dev,stuff->groupLatch);
+
+ if ( status != Success )
+ return status;
+
+ XkbComputeDerivedState(dev->key->xkbInfo);
+ dev->key->state= XkbStateFieldFromRec(newState);
+
+ changed = XkbStateChangedFlags(&oldState,newState);
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= 0;
+ sn.eventType= 0;
+ sn.requestMajor = XkbReqCode;
+ sn.requestMinor = X_kbLatchLockState;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseXkbReq(&cause,X_kbLatchLockState,client);
+ XkbUpdateIndicators(dev,changed,True,NULL,&cause);
+ }
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetControls(ClientPtr client)
+{
+ xkbGetControlsReply rep;
+ XkbControlsPtr xkb;
+ DeviceIntPtr dev;
+
+ REQUEST(xkbGetControlsReq);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc->ctrls;
+ rep.type = X_Reply;
+ rep.length = (SIZEOF(xkbGetControlsReply)-
+ SIZEOF(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = ((DeviceIntPtr)dev)->id;
+ rep.numGroups = xkb->num_groups;
+ rep.groupsWrap = xkb->groups_wrap;
+ rep.internalMods = xkb->internal.mask;
+ rep.ignoreLockMods = xkb->ignore_lock.mask;
+ rep.internalRealMods = xkb->internal.real_mods;
+ rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
+ rep.internalVMods = xkb->internal.vmods;
+ rep.ignoreLockVMods = xkb->ignore_lock.vmods;
+ rep.enabledCtrls = xkb->enabled_ctrls;
+ rep.repeatDelay = xkb->repeat_delay;
+ rep.repeatInterval = xkb->repeat_interval;
+ rep.slowKeysDelay = xkb->slow_keys_delay;
+ rep.debounceDelay = xkb->debounce_delay;
+ rep.mkDelay = xkb->mk_delay;
+ rep.mkInterval = xkb->mk_interval;
+ rep.mkTimeToMax = xkb->mk_time_to_max;
+ rep.mkMaxSpeed = xkb->mk_max_speed;
+ rep.mkCurve = xkb->mk_curve;
+ rep.mkDfltBtn = xkb->mk_dflt_btn;
+ rep.axTimeout = xkb->ax_timeout;
+ rep.axtCtrlsMask = xkb->axt_ctrls_mask;
+ rep.axtCtrlsValues = xkb->axt_ctrls_values;
+ rep.axtOptsMask = xkb->axt_opts_mask;
+ rep.axtOptsValues = xkb->axt_opts_values;
+ rep.axOptions = xkb->ax_options;
+ memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.internalVMods);
+ swaps(&rep.ignoreLockVMods);
+ swapl(&rep.enabledCtrls);
+ swaps(&rep.repeatDelay);
+ swaps(&rep.repeatInterval);
+ swaps(&rep.slowKeysDelay);
+ swaps(&rep.debounceDelay);
+ swaps(&rep.mkDelay);
+ swaps(&rep.mkInterval);
+ swaps(&rep.mkTimeToMax);
+ swaps(&rep.mkMaxSpeed);
+ swaps(&rep.mkCurve);
+ swaps(&rep.axTimeout);
+ swapl(&rep.axtCtrlsMask);
+ swapl(&rep.axtCtrlsValues);
+ swaps(&rep.axtOptsMask);
+ swaps(&rep.axtOptsValues);
+ swaps(&rep.axOptions);
+ }
+ WriteToClient(client, SIZEOF(xkbGetControlsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcXkbSetControls(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+ XkbControlsRec new,old;
+ xkbControlsNotify cn;
+ XkbEventCauseRec cause;
+ XkbSrvLedInfoPtr sli;
+
+ REQUEST(xkbSetControlsReq);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->changeCtrls,XkbAllControlsMask);
+
+ xkbi = dev->key->xkbInfo;
+ ctrl = xkbi->desc->ctrls;
+ new = *ctrl;
+ XkbSetCauseXkbReq(&cause,X_kbSetControls,client);
+ if (stuff->changeCtrls&XkbInternalModsMask) {
+ CHK_MASK_MATCH(0x02,stuff->affectInternalMods,stuff->internalMods);
+ CHK_MASK_MATCH(0x03,stuff->affectInternalVMods,stuff->internalVMods);
+ new.internal.real_mods&=~stuff->affectInternalMods;
+ new.internal.real_mods|=(stuff->affectInternalMods&stuff->internalMods);
+ new.internal.vmods&=~stuff->affectInternalVMods;
+ new.internal.vmods|= (stuff->affectInternalVMods&stuff->internalVMods);
+ new.internal.mask= new.internal.real_mods|
+ XkbMaskForVMask(xkbi->desc,new.internal.vmods);
+ }
+ if (stuff->changeCtrls&XkbIgnoreLockModsMask) {
+ CHK_MASK_MATCH(0x4,stuff->affectIgnoreLockMods,stuff->ignoreLockMods);
+ CHK_MASK_MATCH(0x5,stuff->affectIgnoreLockVMods,stuff->ignoreLockVMods);
+ new.ignore_lock.real_mods&=~stuff->affectIgnoreLockMods;
+ new.ignore_lock.real_mods|=
+ (stuff->affectIgnoreLockMods&stuff->ignoreLockMods);
+ new.ignore_lock.vmods&= ~stuff->affectIgnoreLockVMods;
+ new.ignore_lock.vmods|=
+ (stuff->affectIgnoreLockVMods&stuff->ignoreLockVMods);
+ new.ignore_lock.mask= new.ignore_lock.real_mods|
+ XkbMaskForVMask(xkbi->desc,new.ignore_lock.vmods);
+ }
+ CHK_MASK_MATCH(0x06,stuff->affectEnabledCtrls,stuff->enabledCtrls);
+ if (stuff->affectEnabledCtrls) {
+ CHK_MASK_LEGAL(0x07,stuff->affectEnabledCtrls,XkbAllBooleanCtrlsMask);
+ new.enabled_ctrls&= ~stuff->affectEnabledCtrls;
+ new.enabled_ctrls|= (stuff->affectEnabledCtrls&stuff->enabledCtrls);
+ }
+ if (stuff->changeCtrls&XkbRepeatKeysMask) {
+ if ((stuff->repeatDelay<1)||(stuff->repeatInterval<1)) {
+ client->errorValue = _XkbErrCode3(0x08,stuff->repeatDelay,
+ stuff->repeatInterval);
+ return BadValue;
+ }
+ new.repeat_delay = stuff->repeatDelay;
+ new.repeat_interval = stuff->repeatInterval;
+ }
+ if (stuff->changeCtrls&XkbSlowKeysMask) {
+ if (stuff->slowKeysDelay<1) {
+ client->errorValue = _XkbErrCode2(0x09,stuff->slowKeysDelay);
+ return BadValue;
+ }
+ new.slow_keys_delay = stuff->slowKeysDelay;
+ }
+ if (stuff->changeCtrls&XkbBounceKeysMask) {
+ if (stuff->debounceDelay<1) {
+ client->errorValue = _XkbErrCode2(0x0A,stuff->debounceDelay);
+ return BadValue;
+ }
+ new.debounce_delay = stuff->debounceDelay;
+ }
+ if (stuff->changeCtrls&XkbMouseKeysMask) {
+ if (stuff->mkDfltBtn>XkbMaxMouseKeysBtn) {
+ client->errorValue = _XkbErrCode2(0x0B,stuff->mkDfltBtn);
+ return BadValue;
+ }
+ new.mk_dflt_btn = stuff->mkDfltBtn;
+ }
+ if (stuff->changeCtrls&XkbMouseKeysAccelMask) {
+ if ((stuff->mkDelay<1) || (stuff->mkInterval<1) ||
+ (stuff->mkTimeToMax<1) || (stuff->mkMaxSpeed<1)||
+ (stuff->mkCurve<-1000)) {
+ client->errorValue = _XkbErrCode2(0x0C,0);
+ return BadValue;
+ }
+ new.mk_delay = stuff->mkDelay;
+ new.mk_interval = stuff->mkInterval;
+ new.mk_time_to_max = stuff->mkTimeToMax;
+ new.mk_max_speed = stuff->mkMaxSpeed;
+ new.mk_curve = stuff->mkCurve;
+ AccessXComputeCurveFactor(xkbi,&new);
+ }
+ if (stuff->changeCtrls&XkbGroupsWrapMask) {
+ unsigned act,num;
+ act= XkbOutOfRangeGroupAction(stuff->groupsWrap);
+ switch (act) {
+ case XkbRedirectIntoRange:
+ num= XkbOutOfRangeGroupNumber(stuff->groupsWrap);
+ if (num>=new.num_groups) {
+ client->errorValue= _XkbErrCode3(0x0D,new.num_groups,num);
+ return BadValue;
+ }
+ case XkbWrapIntoRange:
+ case XkbClampIntoRange:
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x0E,act);
+ return BadValue;
+ }
+ new.groups_wrap= stuff->groupsWrap;
+ }
+ CHK_MASK_LEGAL(0x0F,stuff->axOptions,XkbAX_AllOptionsMask);
+ if (stuff->changeCtrls&XkbAccessXKeysMask)
+ new.ax_options = stuff->axOptions&XkbAX_AllOptionsMask;
+ else {
+ if (stuff->changeCtrls&XkbStickyKeysMask) {
+ new.ax_options&= ~XkbAX_SKOptionsMask;
+ new.ax_options|= stuff->axOptions&XkbAX_SKOptionsMask;
+ }
+ if (stuff->changeCtrls&XkbAccessXFeedbackMask) {
+ new.ax_options&= ~XkbAX_FBOptionsMask;
+ new.ax_options|= stuff->axOptions&XkbAX_FBOptionsMask;
+ }
+ }
+
+ if (stuff->changeCtrls&XkbAccessXTimeoutMask) {
+ if (stuff->axTimeout<1) {
+ client->errorValue = _XkbErrCode2(0x10,stuff->axTimeout);
+ return BadValue;
+ }
+ CHK_MASK_MATCH(0x11,stuff->axtCtrlsMask,stuff->axtCtrlsValues);
+ CHK_MASK_LEGAL(0x12,stuff->axtCtrlsMask,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x13,stuff->axtOptsMask,stuff->axtOptsValues);
+ CHK_MASK_LEGAL(0x14,stuff->axtOptsMask,XkbAX_AllOptionsMask);
+ new.ax_timeout = stuff->axTimeout;
+ new.axt_ctrls_mask = stuff->axtCtrlsMask;
+ new.axt_ctrls_values = (stuff->axtCtrlsValues&stuff->axtCtrlsMask);
+ new.axt_opts_mask = stuff->axtOptsMask;
+ new.axt_opts_values= (stuff->axtOptsValues&stuff->axtOptsMask);
+ }
+ if (stuff->changeCtrls&XkbPerKeyRepeatMask) {
+ memcpy(new.per_key_repeat,stuff->perKeyRepeat,XkbPerKeyBitArraySize);
+ }
+ old= *ctrl;
+ *ctrl= new;
+ XkbDDXChangeControls(dev,&old,ctrl);
+ if (XkbComputeControlsNotify(dev,&old,ctrl,&cn,False)) {
+ cn.keycode= 0;
+ cn.eventType = 0;
+ cn.requestMajor = XkbReqCode;
+ cn.requestMinor = X_kbSetControls;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ if ((sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0))!=NULL)
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrl->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(dev,xkbi,True,&cause);
+ }
+#endif
+ return client->noClientException;
+}
+
+int
+XkbSetRepeatRate(DeviceIntPtr dev,int timeout,int interval,int major,int minor)
+{
+int changed= 0;
+XkbControlsRec old,*xkb;
+
+ if ((!dev)||(!dev->key)||(!dev->key->xkbInfo))
+ return 0;
+ xkb= dev->key->xkbInfo->desc->ctrls;
+ old= *xkb;
+ if ((timeout!=0) && (xkb->repeat_delay!=timeout)) {
+ xkb->repeat_delay= timeout;
+ changed++;
+ }
+ if ((interval!=0) && (xkb->repeat_interval!=interval)) {
+ xkb->repeat_interval= interval;
+ changed++;
+ }
+ if (changed) {
+ xkbControlsNotify cn;
+ XkbDDXChangeControls(dev,&old,xkb);
+ if (XkbComputeControlsNotify(dev,&old,xkb,&cn,False)) {
+ cn.keycode= 0;
+ cn.eventType = 0;
+ cn.requestMajor = major;
+ cn.requestMinor = minor;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ }
+ return 1;
+}
+
+int
+XkbGetRepeatRate(DeviceIntPtr dev,int *timeout,int *interval)
+{
+XkbControlsPtr xkb;
+
+ if ((!dev)||(!dev->key)||(!dev->key->xkbInfo))
+ return 0;
+ xkb= dev->key->xkbInfo->desc->ctrls;
+ if (timeout) *timeout= xkb->repeat_delay;
+ if (interval) *interval= xkb->repeat_interval;
+ return 1;
+}
+
+/***====================================================================***/
+
+static int
+XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbKeyTypeRec *type;
+ unsigned i,len;
+
+ len= 0;
+ if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ rep->present&= ~XkbKeyTypesMask;
+ rep->firstType= rep->nTypes= 0;
+ return 0;
+ }
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++){
+ len+= SIZEOF(xkbKeyTypeWireDesc);
+ if (type->map_count>0) {
+ len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
+ if (type->preserve)
+ len+= (type->map_count*SIZEOF(xkbModsWireDesc));
+ }
+ }
+ return len;
+}
+
+static char *
+XkbWriteKeyTypes( XkbDescPtr xkb,
+ xkbGetMapReply * rep,
+ char * buf,
+ ClientPtr client)
+{
+ XkbKeyTypePtr type;
+ unsigned i;
+ xkbKeyTypeWireDesc *wire;
+
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++) {
+ register unsigned n;
+ wire= (xkbKeyTypeWireDesc *)buf;
+ wire->mask = type->mods.mask;
+ wire->realMods = type->mods.real_mods;
+ wire->virtualMods = type->mods.vmods;
+ wire->numLevels = type->num_levels;
+ wire->nMapEntries = type->map_count;
+ wire->preserve = (type->preserve!=NULL);
+ if (client->swapped) {
+ swaps(&wire->virtualMods);
+ }
+
+ buf= (char *)&wire[1];
+ if (wire->nMapEntries>0) {
+ xkbKTMapEntryWireDesc * wire;
+ XkbKTMapEntryPtr entry;
+ wire= (xkbKTMapEntryWireDesc *)buf;
+ entry= type->map;
+ for (n=0;n<type->map_count;n++,wire++,entry++) {
+ wire->active= entry->active;
+ wire->mask= entry->mods.mask;
+ wire->level= entry->level;
+ wire->realMods= entry->mods.real_mods;
+ wire->virtualMods= entry->mods.vmods;
+ if (client->swapped) {
+ swaps(&wire->virtualMods);
+ }
+ }
+ buf= (char *)wire;
+ if (type->preserve!=NULL) {
+ xkbModsWireDesc * pwire;
+ XkbModsPtr preserve;
+ pwire= (xkbModsWireDesc *)buf;
+ preserve= type->preserve;
+ for (n=0;n<type->map_count;n++,pwire++,preserve++) {
+ pwire->mask= preserve->mask;
+ pwire->realMods= preserve->real_mods;
+ pwire->virtualMods= preserve->vmods;
+ if (client->swapped) {
+ swaps(&pwire->virtualMods);
+ }
+ }
+ buf= (char *)pwire;
+ }
+ }
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbSymMapPtr symMap;
+ unsigned i,len;
+ unsigned nSyms,nSymsThisKey;
+
+ if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
+ rep->present&= ~XkbKeySymsMask;
+ rep->firstKeySym= rep->nKeySyms= 0;
+ rep->totalSyms= 0;
+ return 0;
+ }
+ len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
+ if (symMap->offset!=0) {
+ nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
+ nSyms+= nSymsThisKey;
+ }
+ }
+ len+= nSyms*4;
+ rep->totalSyms= nSyms;
+ return len;
+}
+
+static int
+XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+register unsigned i,nMods,bit;
+
+ if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
+ (!xkb)||(!xkb->server)) {
+ rep->present&= ~XkbVirtualModsMask;
+ rep->virtualMods= 0;
+ return 0;
+ }
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit)
+ nMods++;
+ }
+ return XkbPaddedSize(nMods);
+}
+
+static char *
+XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+register KeySym * pSym;
+XkbSymMapPtr symMap;
+xkbSymMapWireDesc * outMap;
+register unsigned i;
+
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=0;i<rep->nKeySyms;i++,symMap++) {
+ outMap = (xkbSymMapWireDesc *)buf;
+ outMap->ktIndex[0] = symMap->kt_index[0];
+ outMap->ktIndex[1] = symMap->kt_index[1];
+ outMap->ktIndex[2] = symMap->kt_index[2];
+ outMap->ktIndex[3] = symMap->kt_index[3];
+ outMap->groupInfo = symMap->group_info;
+ outMap->width= symMap->width;
+ outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
+ buf= (char *)&outMap[1];
+ if (outMap->nSyms==0)
+ continue;
+
+ pSym = &xkb->map->syms[symMap->offset];
+ memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
+ if (client->swapped) {
+ register int nSyms= outMap->nSyms;
+ swaps(&outMap->nSyms);
+ while (nSyms-->0) {
+ swapl((int *)buf);
+ buf+= 4;
+ }
+ }
+ else buf+= outMap->nSyms*4;
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nActs;
+ register KeyCode firstKey;
+
+ if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
+ rep->present&= ~XkbKeyActionsMask;
+ rep->firstKeyAct= rep->nKeyActs= 0;
+ rep->totalActs= 0;
+ return 0;
+ }
+ firstKey= rep->firstKeyAct;
+ for (nActs=i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+firstKey]!=0)
+ nActs+= XkbKeyNumActions(xkb,i+firstKey);
+ }
+ len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
+ rep->totalActs= nActs;
+ return len;
+}
+
+static char *
+XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ CARD8 * numDesc;
+ XkbAnyAction * actDesc;
+
+ numDesc = (CARD8 *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
+ numDesc[i] = 0;
+ else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ }
+ buf+= XkbPaddedSize(rep->nKeyActs);
+
+ actDesc = (XkbAnyAction *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
+ unsigned int num;
+ num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ memcpy((char *)actDesc,
+ (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
+ num*SIZEOF(xkbActionWireDesc));
+ actDesc+= num;
+ }
+ }
+ buf = (char *)actDesc;
+ return buf;
+}
+
+static int
+XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nBhvr;
+ XkbBehavior * bhv;
+
+ if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
+ rep->present&= ~XkbKeyBehaviorsMask;
+ rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
+ rep->totalKeyBehaviors= 0;
+ return 0;
+ }
+ bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
+ if (bhv->type!=XkbKB_Default)
+ nBhvr++;
+ }
+ len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
+ rep->totalKeyBehaviors= nBhvr;
+ return len;
+}
+
+static char *
+XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ xkbBehaviorWireDesc *wire;
+ XkbBehavior *pBhvr;
+
+ wire = (xkbBehaviorWireDesc *)buf;
+ pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
+ if (pBhvr->type!=XkbKB_Default) {
+ wire->key= i+rep->firstKeyBehavior;
+ wire->type= pBhvr->type;
+ wire->data= pBhvr->data;
+ wire++;
+ }
+ }
+ buf = (char *)wire;
+ return buf;
+}
+
+static int
+XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
+ rep->present&= ~XkbExplicitComponentsMask;
+ rep->firstKeyExplicit= rep->nKeyExplicit= 0;
+ rep->totalKeyExplicit= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
+ if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
+ nRtrn++;
+ }
+ rep->totalKeyExplicit= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
+ return len;
+}
+
+static char *
+XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pExp;
+
+ start= buf;
+ pExp= &xkb->server->explicit[rep->firstKeyExplicit];
+ for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
+ if (*pExp!=0) {
+ *buf++= i+rep->firstKeyExplicit;
+ *buf++= *pExp;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
+ rep->present&= ~XkbModifierMapMask;
+ rep->firstModMapKey= rep->nModMapKeys= 0;
+ rep->totalModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
+ if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalModMapKeys= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
+ return len;
+}
+
+static char *
+XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pMap;
+
+ start= buf;
+ pMap= &xkb->map->modmap[rep->firstModMapKey];
+ for (i=0;i<rep->nModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ *buf++= i+rep->firstModMapKey;
+ *buf++= *pMap;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
+ rep->present&= ~XkbVirtualModMapMask;
+ rep->firstVModMapKey= rep->nVModMapKeys= 0;
+ rep->totalVModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
+ if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalVModMapKeys= nRtrn;
+ len= nRtrn*SIZEOF(xkbVModMapWireDesc);
+ return len;
+}
+
+static char *
+XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+xkbVModMapWireDesc * wire;
+unsigned short * pMap;
+
+ wire= (xkbVModMapWireDesc *)buf;
+ pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
+ for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ wire->key= i+rep->firstVModMapKey;
+ wire->vmods= *pMap;
+ wire++;
+ }
+ }
+ return (char *)wire;
+}
+
+static Status
+XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+int len;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ len= XkbSizeKeyTypes(xkb,rep);
+ len+= XkbSizeKeySyms(xkb,rep);
+ len+= XkbSizeKeyActions(xkb,rep);
+ len+= XkbSizeKeyBehaviors(xkb,rep);
+ len+= XkbSizeVirtualMods(xkb,rep);
+ len+= XkbSizeExplicit(xkb,rep);
+ len+= XkbSizeModifierMap(xkb,rep);
+ len+= XkbSizeVirtualModMap(xkb,rep);
+ rep->length+= (len/4);
+ return Success;
+}
+
+static int
+XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+unsigned i,len;
+char *desc,*start;
+
+ len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
+ start= desc= (char *)malloc(len);
+ if (!start)
+ return BadAlloc;
+ memset(start, 0, len);
+
+ if ( rep->nTypes>0 )
+ desc = XkbWriteKeyTypes(xkb,rep,desc,client);
+ if ( rep->nKeySyms>0 )
+ desc = XkbWriteKeySyms(xkb,rep,desc,client);
+ if ( rep->nKeyActs>0 )
+ desc = XkbWriteKeyActions(xkb,rep,desc,client);
+ if ( rep->totalKeyBehaviors>0 )
+ desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
+ if ( rep->virtualMods ) {
+ register int sz,bit;
+ for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit) {
+ desc[sz++]= xkb->server->vmods[i];
+ }
+ }
+ desc+= XkbPaddedSize(sz);
+ }
+ if ( rep->totalKeyExplicit>0 )
+ desc= XkbWriteExplicit(xkb,rep,desc,client);
+ if ( rep->totalModMapKeys>0 )
+ desc= XkbWriteModifierMap(xkb,rep,desc,client);
+ if ( rep->totalVModMapKeys>0 )
+ desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
+ if ((desc-start)!=(len)) {
+ ErrorF("BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->present);
+ swaps(&rep->totalSyms);
+ swaps(&rep->totalActs);
+ }
+ WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), rep);
+ WriteToClient(client, len, start);
+ free((char *)start);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetMapReply rep;
+ XkbDescRec *xkb;
+ int n,status;
+
+ REQUEST(xkbGetMapReq);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
+ CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
+ CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
+
+ xkb= dev->key->xkbInfo->desc;
+ bzero(&rep,sizeof(xkbGetMapReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
+ rep.deviceID = dev->id;
+ rep.present = stuff->partial|stuff->full;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ if ( stuff->full&XkbKeyTypesMask ) {
+ rep.firstType = 0;
+ rep.nTypes = xkb->map->num_types;
+ }
+ else if (stuff->partial&XkbKeyTypesMask) {
+ if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
+ stuff->firstType,stuff->nTypes);
+ return BadValue;
+ }
+ rep.firstType = stuff->firstType;
+ rep.nTypes = stuff->nTypes;
+ }
+ else rep.nTypes = 0;
+ rep.totalTypes = xkb->map->num_types;
+
+ n= XkbNumKeys(xkb);
+ if ( stuff->full&XkbKeySymsMask ) {
+ rep.firstKeySym = xkb->min_key_code;
+ rep.nKeySyms = n;
+ }
+ else if (stuff->partial&XkbKeySymsMask) {
+ CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
+ rep.firstKeySym = stuff->firstKeySym;
+ rep.nKeySyms = stuff->nKeySyms;
+ }
+ else rep.nKeySyms = 0;
+ rep.totalSyms= 0;
+
+ if ( stuff->full&XkbKeyActionsMask ) {
+ rep.firstKeyAct= xkb->min_key_code;
+ rep.nKeyActs= n;
+ }
+ else if (stuff->partial&XkbKeyActionsMask) {
+ CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
+ rep.firstKeyAct= stuff->firstKeyAct;
+ rep.nKeyActs= stuff->nKeyActs;
+ }
+ else rep.nKeyActs= 0;
+ rep.totalActs= 0;
+
+ if ( stuff->full&XkbKeyBehaviorsMask ) {
+ rep.firstKeyBehavior = xkb->min_key_code;
+ rep.nKeyBehaviors = n;
+ }
+ else if (stuff->partial&XkbKeyBehaviorsMask) {
+ CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
+ rep.firstKeyBehavior= stuff->firstKeyBehavior;
+ rep.nKeyBehaviors= stuff->nKeyBehaviors;
+ }
+ else rep.nKeyBehaviors = 0;
+ rep.totalKeyBehaviors= 0;
+
+ if (stuff->full&XkbVirtualModsMask)
+ rep.virtualMods= ~0;
+ else if (stuff->partial&XkbVirtualModsMask)
+ rep.virtualMods= stuff->virtualMods;
+
+ if (stuff->full&XkbExplicitComponentsMask) {
+ rep.firstKeyExplicit= xkb->min_key_code;
+ rep.nKeyExplicit= n;
+ }
+ else if (stuff->partial&XkbExplicitComponentsMask) {
+ CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
+ rep.firstKeyExplicit= stuff->firstKeyExplicit;
+ rep.nKeyExplicit= stuff->nKeyExplicit;
+ }
+ else rep.nKeyExplicit = 0;
+ rep.totalKeyExplicit= 0;
+
+ if (stuff->full&XkbModifierMapMask) {
+ rep.firstModMapKey= xkb->min_key_code;
+ rep.nModMapKeys= n;
+ }
+ else if (stuff->partial&XkbModifierMapMask) {
+ CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
+ rep.firstModMapKey= stuff->firstModMapKey;
+ rep.nModMapKeys= stuff->nModMapKeys;
+ }
+ else rep.nModMapKeys = 0;
+ rep.totalModMapKeys= 0;
+
+ if (stuff->full&XkbVirtualModMapMask) {
+ rep.firstVModMapKey= xkb->min_key_code;
+ rep.nVModMapKeys= n;
+ }
+ else if (stuff->partial&XkbVirtualModMapMask) {
+ CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
+ rep.firstVModMapKey= stuff->firstVModMapKey;
+ rep.nVModMapKeys= stuff->nVModMapKeys;
+ }
+ else rep.nVModMapKeys = 0;
+ rep.totalVModMapKeys= 0;
+
+ if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
+ return status;
+ return XkbSendMap(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static int
+CheckKeyTypes( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc **wireRtrn,
+ int * nMapsRtrn,
+ CARD8 * mapWidthRtrn)
+{
+unsigned nMaps;
+register unsigned i,n;
+register CARD8 * map;
+register xkbKeyTypeWireDesc *wire = *wireRtrn;
+
+ if (req->firstType>((unsigned)xkb->map->num_types)) {
+ *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
+ return 0;
+ }
+ if (req->flags&XkbSetMapResizeTypes) {
+ nMaps = req->firstType+req->nTypes;
+ if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
+ *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
+ return 0;
+ }
+ }
+ else if (req->present&XkbKeyTypesMask) {
+ nMaps = xkb->map->num_types;
+ if ((req->firstType+req->nTypes)>nMaps) {
+ *nMapsRtrn = req->firstType+req->nTypes;
+ return 0;
+ }
+ }
+ else {
+ *nMapsRtrn = xkb->map->num_types;
+ for (i=0;i<xkb->map->num_types;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ return 1;
+ }
+
+ for (i=0;i<req->firstType;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ for (i=0;i<req->nTypes;i++) {
+ unsigned width;
+ if (client->swapped) {
+ swaps(&wire->virtualMods);
+ }
+ n= i+req->firstType;
+ width= wire->numLevels;
+ if (width<1) {
+ *nMapsRtrn= _XkbErrCode3(0x04,n,width);
+ return 0;
+ }
+ else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ else if ((width!=2)&&
+ ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
+ (n==XkbAlphabeticIndex))) {
+ /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ if (wire->nMapEntries>0) {
+ xkbKTSetMapEntryWireDesc * mapWire;
+ xkbModsWireDesc * preWire;
+ mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ if (client->swapped) {
+ swaps(&mapWire[n].virtualMods);
+ }
+ if (mapWire[n].realMods&(~wire->realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
+ wire->realMods);
+ return 0;
+ }
+ if (mapWire[n].virtualMods&(~wire->virtualMods)) {
+ *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
+ return 0;
+ }
+ if (mapWire[n].level>=wire->numLevels) {
+ *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
+ mapWire[n].level);
+ return 0;
+ }
+ if (wire->preserve) {
+ if (client->swapped) {
+ swaps(&preWire[n].virtualMods);
+ }
+ if (preWire[n].realMods&(~mapWire[n].realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
+ mapWire[n].realMods);
+ return 0;
+ }
+ if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
+ *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
+ return 0;
+ }
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ mapWidthRtrn[i+req->firstType] = wire->numLevels;
+ wire= (xkbKeyTypeWireDesc *)map;
+ }
+ for (i=req->firstType+req->nTypes;i<nMaps;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ *nMapsRtrn = nMaps;
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ xkbSymMapWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register unsigned i;
+XkbSymMapPtr map;
+xkbSymMapWireDesc* wire = *wireRtrn;
+
+ if (!(XkbKeySymsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
+ map = &xkb->map->key_sym_map[xkb->min_key_code];
+ for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
+ register int g,ng,w;
+ ng= XkbNumGroups(map->group_info);
+ for (w=g=0;g<ng;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*ng;
+ }
+ for (i=0;i<req->nKeySyms;i++) {
+ KeySym *pSyms;
+ register unsigned nG;
+ if (client->swapped) {
+ swaps(&wire->nSyms);
+ }
+ nG = XkbNumGroups(wire->groupInfo);
+ if (nG>XkbNumKbdGroups) {
+ *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
+ return 0;
+ }
+ if (nG>0) {
+ register int g,w;
+ for (g=w=0;g<nG;g++) {
+ if (wire->ktIndex[g]>=(unsigned)nTypes) {
+ *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
+ wire->ktIndex[g]);
+ return 0;
+ }
+ if (mapWidths[wire->ktIndex[g]]>w)
+ w= mapWidths[wire->ktIndex[g]];
+ }
+ if (wire->width!=w) {
+ *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
+ return 0;
+ }
+ w*= nG;
+ symsPerKey[i+req->firstKeySym] = w;
+ if (w!=wire->nSyms) {
+ *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
+ return 0;
+ }
+ }
+ else if (wire->nSyms!=0) {
+ *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
+ return 0;
+ }
+ pSyms = (KeySym *)&wire[1];
+ wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+
+ map = &xkb->map->key_sym_map[i];
+ for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
+ register int g,nG,w;
+ nG= XkbKeyNumGroups(xkb,i);
+ for (w=g=0;g<nG;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*nG;
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ CARD8 ** wireRtrn,
+ int * nActsRtrn)
+{
+int nActs;
+CARD8 * wire = *wireRtrn;
+register unsigned i;
+
+ if (!(XkbKeyActionsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
+ for (nActs=i=0;i<req->nKeyActs;i++) {
+ if (wire[0]!=0) {
+ if (wire[0]==symsPerKey[i+req->firstKeyAct])
+ nActs+= wire[0];
+ else {
+ *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
+ return 0;
+ }
+ }
+ wire++;
+ }
+ if (req->nKeyActs%4)
+ wire+= 4-(req->nKeyActs%4);
+ *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
+ *nActsRtrn = nActs;
+ return 1;
+}
+
+static int
+CheckKeyBehaviors( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbBehaviorWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register xkbBehaviorWireDesc * wire = *wireRtrn;
+register XkbServerMapPtr server = xkb->server;
+register unsigned i;
+unsigned first,last;
+
+ if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
+ req->present&= ~XkbKeyBehaviorsMask;
+ req->nKeyBehaviors= 0;
+ return 1;
+ }
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
+ return 0;
+ }
+
+ for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
+ return 0;
+ }
+ if ((wire->type&XkbKB_Permanent)&&
+ ((server->behaviors[wire->key].type!=wire->type)||
+ (server->behaviors[wire->key].data!=wire->data))) {
+ *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
+ return 0;
+ }
+ if ((wire->type==XkbKB_RadioGroup)&&
+ ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
+ *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
+ XkbMaxRadioGroups);
+ return 0;
+ }
+ if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
+ CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
+ }
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckVirtualMods( XkbDescRec * xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 *wire = *wireRtrn;
+register unsigned i,nMods,bit;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return 1;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit)
+ nMods++;
+ }
+ *wireRtrn= (wire+XkbPaddedSize(nMods));
+ return 1;
+}
+
+static int
+CheckKeyExplicit( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
+ req->present&= ~XkbExplicitComponentsMask;
+ req->nKeyExplicit= 0;
+ return 1;
+ }
+ first= req->firstKeyExplicit;
+ last= first+req->nKeyExplicit-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
+ return 0;
+ }
+ if (wire[1]&(~XkbAllExplicitMask)) {
+ *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
+ req->present&= ~XkbModifierMapMask;
+ req->nModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstModMapKey;
+ last= first+req->nModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckVirtualModMap( XkbDescPtr xkb,
+ xkbSetMapReq *req,
+ xkbVModMapWireDesc **wireRtrn,
+ int *errRtrn)
+{
+register xkbVModMapWireDesc * wire = *wireRtrn;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
+ req->present&= ~XkbVirtualModMapMask;
+ req->nVModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstVModMapKey;
+ last= first+req->nVModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
+ return 0;
+ }
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
+ return 0;
+ }
+ }
+ *wireRtrn= wire;
+ return 1;
+}
+
+static char *
+SetKeyTypes( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+unsigned first,last;
+CARD8 *map;
+
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
+ i= req->firstType+req->nTypes;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
+ return NULL;
+ }
+ }
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
+ xkb->map->num_types= req->firstType+req->nTypes;
+
+ for (i=0;i<req->nTypes;i++) {
+ XkbKeyTypePtr pOld;
+ register unsigned n;
+
+ if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
+ wire->preserve,wire->numLevels)!=Success) {
+ return NULL;
+ }
+ pOld = &xkb->map->types[i+req->firstType];
+ map = (CARD8 *)&wire[1];
+
+ pOld->mods.real_mods = wire->realMods;
+ pOld->mods.vmods= wire->virtualMods;
+ pOld->num_levels = wire->numLevels;
+ pOld->map_count= wire->nMapEntries;
+
+ pOld->mods.mask= pOld->mods.real_mods|
+ XkbMaskForVMask(xkb,pOld->mods.vmods);
+
+ if (wire->nMapEntries) {
+ xkbKTSetMapEntryWireDesc *mapWire;
+ xkbModsWireDesc *preWire;
+ unsigned tmp;
+ mapWire= (xkbKTSetMapEntryWireDesc *)map;
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ pOld->map[n].active= 1;
+ pOld->map[n].mods.mask= mapWire[n].realMods;
+ pOld->map[n].mods.real_mods= mapWire[n].realMods;
+ pOld->map[n].mods.vmods= mapWire[n].virtualMods;
+ pOld->map[n].level= mapWire[n].level;
+ if (mapWire[n].virtualMods!=0) {
+ tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
+ pOld->map[n].active= (tmp!=0);
+ pOld->map[n].mods.mask|= tmp;
+ }
+ if (wire->preserve) {
+ pOld->preserve[n].real_mods= preWire[n].realMods;
+ pOld->preserve[n].vmods= preWire[n].virtualMods;
+ tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
+ pOld->preserve[n].mask= preWire[n].realMods|tmp;
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ wire = (xkbKeyTypeWireDesc *)map;
+ }
+ first= req->firstType;
+ last= first+req->nTypes-1; /* last changed type */
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int oldLast;
+ oldLast= changes->map.first_type+changes->map.num_types-1;
+ if (changes->map.first_type<first)
+ first= changes->map.first_type;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type = first;
+ changes->map.num_types = (last-first)+1;
+ return (char *)wire;
+}
+
+static char *
+SetKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbSymMapWireDesc * wire,
+ XkbChangesPtr changes,
+ DeviceIntPtr dev)
+{
+register unsigned i,s;
+XkbSymMapPtr oldMap;
+KeySym * newSyms;
+KeySym * pSyms;
+unsigned first,last;
+
+ oldMap = &xkb->map->key_sym_map[req->firstKeySym];
+ for (i=0;i<req->nKeySyms;i++,oldMap++) {
+ pSyms = (KeySym *)&wire[1];
+ if (wire->nSyms>0) {
+ newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
+ for (s=0;s<wire->nSyms;s++) {
+ newSyms[s]= pSyms[s];
+ }
+ if (client->swapped) {
+ for (s=0;s<wire->nSyms;s++) {
+ swapl(&newSyms[s]);
+ }
+ }
+ }
+ oldMap->kt_index[0] = wire->ktIndex[0];
+ oldMap->kt_index[1] = wire->ktIndex[1];
+ oldMap->kt_index[2] = wire->ktIndex[2];
+ oldMap->kt_index[3] = wire->ktIndex[3];
+ oldMap->group_info = wire->groupInfo;
+ oldMap->width = wire->width;
+ wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+ first= req->firstKeySym;
+ last= first+req->nKeySyms-1;
+ if (changes->map.changed&XkbKeySymsMask) {
+ int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
+ if (changes->map.first_key_sym<first)
+ first= changes->map.first_key_sym;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = (last-first+1);
+
+ s= 0;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyNumGroups(xkb,i)>s)
+ s= XkbKeyNumGroups(xkb,i);
+ }
+ if (s!=xkb->ctrls->num_groups) {
+ xkbControlsNotify cn;
+ XkbControlsRec old;
+ cn.keycode= 0;
+ cn.eventType= 0;
+ cn.requestMajor= XkbReqCode;
+ cn.requestMinor= X_kbSetMap;
+ old= *xkb->ctrls;
+ xkb->ctrls->num_groups= s;
+ if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,False))
+ XkbSendControlsNotify(dev,&cn);
+ }
+ return (char *)wire;
+}
+
+static char *
+SetKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+CARD8 * nActs = wire;
+XkbAction * newActs;
+
+ wire+= XkbPaddedSize(req->nKeyActs);
+ for (i=0;i<req->nKeyActs;i++) {
+ if (nActs[i]==0)
+ xkb->server->key_acts[i+req->firstKeyAct]= 0;
+ else {
+ newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
+ memcpy((char *)newActs,(char *)wire,
+ nActs[i]*SIZEOF(xkbActionWireDesc));
+ wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
+ }
+ }
+ first= req->firstKeyAct;
+ last= (first+req->nKeyActs-1);
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (changes->map.first_key_act<first)
+ first= changes->map.first_key_act;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= first;
+ changes->map.num_key_acts= (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetKeyBehaviors( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq *req,
+ xkbBehaviorWireDesc *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+int maxRG = -1;
+XkbDescPtr xkb = xkbi->desc;
+XkbServerMapPtr server = xkb->server;
+unsigned first,last;
+
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
+ for (i=0;i<req->totalKeyBehaviors;i++) {
+ if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
+ server->behaviors[wire->key].type= wire->type;
+ server->behaviors[wire->key].data= wire->data;
+ if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
+ maxRG= wire->data + 1;
+ }
+ wire++;
+ }
+
+ if (maxRG>(int)xkbi->nRadioGroups) {
+ int sz = maxRG*sizeof(XkbRadioGroupRec);
+ if (xkbi->radioGroups)
+ xkbi->radioGroups=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz);
+ else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(1, sz);
+ if (xkbi->radioGroups) {
+ if (xkbi->nRadioGroups)
+ bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
+ (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
+ xkbi->nRadioGroups= maxRG;
+ }
+ else xkbi->nRadioGroups= 0;
+ /* should compute members here */
+ }
+ if (changes->map.changed&XkbKeyBehaviorsMask) {
+ unsigned oldLast;
+ oldLast= changes->map.first_key_behavior+
+ changes->map.num_key_behaviors-1;
+ if (changes->map.first_key_behavior<req->firstKeyBehavior)
+ first= changes->map.first_key_behavior;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyBehaviorsMask;
+ changes->map.first_key_behavior = first;
+ changes->map.num_key_behaviors = (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register int i,bit,nMods;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return (char *)wire;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit) {
+ if (srv->vmods[i]!=wire[nMods]) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ srv->vmods[i]= wire[nMods];
+ }
+ nMods++;
+ }
+ }
+ return (char *)(wire+XkbPaddedSize(nMods));
+}
+
+static char *
+SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr xkb = xkbi->desc->server;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstKeyExplicit;
+ last= req->firstKeyExplicit+req->nKeyExplicit-1;
+ bzero(&xkb->explicit[first],req->nKeyExplicit);
+ for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
+ xkb->explicit[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbExplicitComponentsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_explicit+
+ changes->map.num_key_explicit-1;
+ if (changes->map.first_key_explicit<first)
+ first= changes->map.first_key_explicit;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_key_explicit= first;
+ changes->map.num_key_explicit= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetModifierMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbClientMapPtr xkb = xkbi->desc->map;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstModMapKey;
+ last= req->firstModMapKey+req->nModMapKeys-1;
+ bzero(&xkb->modmap[first],req->nModMapKeys);
+ for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
+ xkb->modmap[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbModifierMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_modmap_key+
+ changes->map.num_modmap_keys-1;
+ if (changes->map.first_modmap_key<first)
+ first= changes->map.first_modmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_modmap_key= first;
+ changes->map.num_modmap_keys= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualModMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ xkbVModMapWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ first= req->firstVModMapKey;
+ last= req->firstVModMapKey+req->nVModMapKeys-1;
+ bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ srv->vmodmap[wire->key]= wire->vmods;
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbVirtualModMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_vmodmap_key+
+ changes->map.num_vmodmap_keys-1;
+ if (changes->map.first_vmodmap_key<first)
+ first= changes->map.first_vmodmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_vmodmap_key= first;
+ changes->map.num_vmodmap_keys= (last-first)+1;
+ }
+ return (char *)wire;
+}
+
+int
+ProcXkbSetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbChangesRec change;
+ XkbEventCauseRec cause;
+ int nTypes = 0,nActions,error;
+ char * tmp;
+ CARD8 mapWidths[XkbMaxLegalKeyCode+1];
+ CARD16 symsPerKey[XkbMaxLegalKeyCode+1];
+ Bool sentNKN;
+
+ REQUEST(xkbSetMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
+
+ XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ if ((xkb->min_key_code!=stuff->minKeyCode)||
+ (xkb->max_key_code!=stuff->maxKeyCode)) {
+ if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
+ stuff->minKeyCode= xkb->min_key_code;
+ stuff->maxKeyCode= xkb->max_key_code;
+ }
+ else {
+ if (!XkbIsLegalKeycode(stuff->minKeyCode)) {
+ client->errorValue= _XkbErrCode3(2,stuff->minKeyCode,
+ stuff->maxKeyCode);
+ return BadValue;
+ }
+ if (stuff->minKeyCode>stuff->maxKeyCode) {
+ client->errorValue= _XkbErrCode3(3,stuff->minKeyCode,
+ stuff->maxKeyCode);
+ return BadMatch;
+ }
+ }
+ }
+
+ tmp = (char *)&stuff[1];
+ if ((stuff->present&XkbKeyTypesMask)&&
+ (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp,
+ &nTypes,mapWidths))) {
+ client->errorValue = nTypes;
+ return BadValue;
+ }
+ if ((stuff->present&XkbKeySymsMask)&&
+ (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey,
+ (xkbSymMapWireDesc **)&tmp,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbKeyActionsMask)&&
+ (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey,
+ (CARD8 **)&tmp,&nActions))) {
+ client->errorValue = nActions;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbKeyBehaviorsMask)&&
+ (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbVirtualModsMask)&&
+ (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbExplicitComponentsMask)&&
+ (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbModifierMapMask)&&
+ (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbVirtualModMapMask)&&
+ (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if (((tmp-((char *)stuff))/4)!=stuff->length) {
+ ErrorF("Internal error! Bad length in XkbSetMap (after check)\n");
+ client->errorValue = tmp-((char *)&stuff[1]);
+ return BadLength;
+ }
+ bzero(&change,sizeof(change));
+ sentNKN= False;
+ if ((xkb->min_key_code!=stuff->minKeyCode)||
+ (xkb->max_key_code!=stuff->maxKeyCode)) {
+ Status status;
+ xkbNewKeyboardNotify nkn;
+
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ status= XkbChangeKeycodeRange(xkb,stuff->minKeyCode,stuff->maxKeyCode,
+ &change);
+ if (status!=Success)
+ return status;
+ nkn.minKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetMap;
+ nkn.changed= XkbNKN_KeycodesMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ sentNKN= True;
+ }
+ tmp = (char *)&stuff[1];
+ if (stuff->present&XkbKeyTypesMask) {
+ tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeySymsMask) {
+ tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeyActionsMask) {
+ tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeyBehaviorsMask) {
+ tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbVirtualModsMask)
+ tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbExplicitComponentsMask)
+ tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbModifierMapMask)
+ tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbVirtualModMapMask)
+ tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change);
+ if (((tmp-((char *)stuff))/4)!=stuff->length) {
+ ErrorF("Internal error! Bad length in XkbSetMap (after set)\n");
+ client->errorValue = tmp-((char *)&stuff[1]);
+ return BadLength;
+ }
+ if (stuff->flags&XkbSetMapRecomputeActions) {
+ KeyCode first,last,firstMM,lastMM;
+ if (change.map.num_key_syms>0) {
+ first= change.map.first_key_sym;
+ last= first+change.map.num_key_syms-1;
+ }
+ else first= last= 0;
+ if (change.map.num_modmap_keys>0) {
+ firstMM= change.map.first_modmap_key;
+ lastMM= first+change.map.num_modmap_keys-1;
+ }
+ else firstMM= lastMM= 0;
+ if ((last>0) && (lastMM>0)) {
+ if (firstMM<first)
+ first= firstMM;
+ if (lastMM>last)
+ last= lastMM;
+ }
+ else if (lastMM>0) {
+ first= firstMM;
+ last= lastMM;
+ }
+ if (last>0) {
+ unsigned check= 0;
+ XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ }
+ }
+ if (!sentNKN)
+ XkbSendNotification(dev,&change,&cause);
+
+ XkbUpdateCoreDescription(dev,False);
+ return client->noClientException;
+allocFailure:
+ return BadAlloc;
+}
+
+/***====================================================================***/
+
+static Status
+XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+unsigned size,nGroups;
+
+ nGroups= 0;
+ if (rep->groups!=0) {
+ register int i,bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit)
+ nGroups++;
+ }
+ }
+ size= nGroups*SIZEOF(xkbModsWireDesc);
+ size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
+ rep->length= size/4;
+ return Success;
+}
+
+static int
+XkbSendCompatMap( ClientPtr client,
+ XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+char * data;
+int size;
+
+ size= rep->length*4;
+ if (size>0) {
+ data = (char *)malloc(size);
+ if (data) {
+ register unsigned i,bit;
+ xkbModsWireDesc * grp;
+ XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ for (i=0;i<rep->nSI;i++,sym++,wire++) {
+ wire->sym= sym->sym;
+ wire->mods= sym->mods;
+ wire->match= sym->match;
+ wire->virtualMod= sym->virtual_mod;
+ wire->flags= sym->flags;
+ memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
+ if (client->swapped) {
+ swapl(&wire->sym);
+ }
+ }
+ if (rep->groups) {
+ grp = (xkbModsWireDesc *)wire;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit) {
+ grp->mask= compat->groups[i].mask;
+ grp->realMods= compat->groups[i].real_mods;
+ grp->virtualMods= compat->groups[i].vmods;
+ if (client->swapped) {
+ swaps(&grp->virtualMods);
+ }
+ grp++;
+ }
+ }
+ wire= (xkbSymInterpretWireDesc*)grp;
+ }
+ }
+ else return BadAlloc;
+ }
+ else data= NULL;
+
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swaps(&rep->firstSI);
+ swaps(&rep->nSI);
+ swaps(&rep->nTotalSI);
+ }
+
+ WriteToClient(client, SIZEOF(xkbGetCompatMapReply), rep);
+ if (data) {
+ WriteToClient(client, size, data);
+ free((char *)data);
+ }
+ return client->noClientException;
+}
+
+int
+ProcXkbGetCompatMap(ClientPtr client)
+{
+ xkbGetCompatMapReply rep;
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+
+ REQUEST(xkbGetCompatMapReq);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc;
+ compat= xkb->compat;
+
+ rep.type = X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.firstSI = stuff->firstSI;
+ rep.nSI = stuff->nSI;
+ if (stuff->getAllSI) {
+ rep.firstSI = 0;
+ rep.nSI = compat->num_si;
+ }
+ else if ((((unsigned)stuff->nSI)>0)&&
+ ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
+ client->errorValue = _XkbErrCode2(0x05,compat->num_si);
+ return BadValue;
+ }
+ rep.nTotalSI = compat->num_si;
+ rep.groups= stuff->groups;
+ XkbComputeGetCompatMapReplySize(compat,&rep);
+ return XkbSendCompatMap(client,compat,&rep);
+}
+
+int
+ProcXkbSetCompatMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+ char * data;
+ int nGroups;
+ register unsigned i,bit;
+
+ REQUEST(xkbSetCompatMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ data = (char *)&stuff[1];
+ xkbi = dev->key->xkbInfo;
+ xkb= xkbi->desc;
+ compat= xkb->compat;
+ if ((stuff->nSI>0)||(stuff->truncateSI)) {
+ xkbSymInterpretWireDesc *wire;
+ if (stuff->firstSI>compat->num_si) {
+ client->errorValue = _XkbErrCode2(0x02,compat->num_si);
+ return BadValue;
+ }
+ wire= (xkbSymInterpretWireDesc *)data;
+ wire+= stuff->nSI;
+ data = (char *)wire;
+ }
+ nGroups= 0;
+ if (stuff->groups!=0) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if ( stuff->groups&bit )
+ nGroups++;
+ }
+ }
+ data+= nGroups*SIZEOF(xkbModsWireDesc);
+ if (((data-((char *)stuff))/4)!=stuff->length) {
+ return BadLength;
+ }
+ data = (char *)&stuff[1];
+ if (stuff->nSI>0) {
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ XkbSymInterpretPtr sym;
+ if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) {
+ compat->num_si= stuff->firstSI+stuff->nSI;
+ compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
+ compat->num_si,
+ XkbSymInterpretRec);
+ if (!compat->sym_interpret) {
+ compat->num_si= 0;
+ return BadAlloc;
+ }
+ }
+ else if (stuff->truncateSI) {
+ compat->num_si = stuff->firstSI+stuff->nSI;
+ }
+ sym = &compat->sym_interpret[stuff->firstSI];
+ for (i=0;i<stuff->nSI;i++,wire++,sym++) {
+ if (client->swapped) {
+ swapl(&wire->sym);
+ }
+ sym->sym= wire->sym;
+ sym->mods= wire->mods;
+ sym->match= wire->match;
+ sym->flags= wire->flags;
+ sym->virtual_mod= wire->virtualMod;
+ memcpy((char *)&sym->act,(char *)&wire->act,
+ SIZEOF(xkbActionWireDesc));
+ }
+ data = (char *)wire;
+ }
+ else if (stuff->truncateSI) {
+ compat->num_si = stuff->firstSI;
+ }
+
+ if (stuff->groups!=0) {
+ register unsigned i,bit;
+ xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (stuff->groups&bit) {
+ if (client->swapped) {
+ swaps(&wire->virtualMods);
+ }
+ compat->groups[i].mask= wire->realMods;
+ compat->groups[i].real_mods= wire->realMods;
+ compat->groups[i].vmods= wire->virtualMods;
+ if (wire->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkb,wire->virtualMods);
+ compat->groups[i].mask|= tmp;
+ }
+ data+= SIZEOF(xkbModsWireDesc);
+ wire= (xkbModsWireDesc *)data;
+ }
+ }
+ }
+ i= XkbPaddedSize((data-((char *)stuff)));
+ if ((i/4)!=stuff->length) {
+ ErrorF("Internal length error on read in ProcXkbSetCompatMap\n");
+ return BadLength;
+ }
+
+ if (dev->xkb_interest) {
+ xkbCompatMapNotify ev;
+ ev.deviceID = dev->id;
+ ev.changedGroups = stuff->groups;
+ ev.firstSI = stuff->firstSI;
+ ev.nSI = stuff->nSI;
+ ev.nTotalSI = compat->num_si;
+ XkbSendCompatMapNotify(dev,&ev);
+ }
+
+ if (stuff->recomputeActions) {
+ XkbChangesRec change;
+ unsigned check;
+ XkbEventCauseRec cause;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
+ bzero(&change,sizeof(XkbChangesRec));
+ XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
+ &cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ XkbUpdateCoreDescription(dev,False);
+ XkbSendNotification(dev,&change,&cause);
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetIndicatorState(ClientPtr client)
+{
+ xkbGetIndicatorStateReply rep;
+ XkbSrvLedInfoPtr sli;
+ DeviceIntPtr dev;
+
+ REQUEST(xkbGetIndicatorStateReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorStateMask);
+ if (!sli)
+ return BadAlloc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.state = sli->effectiveState;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.state);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), &rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+Status
+XkbComputeGetIndicatorMapReplySize(
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep)
+{
+register int i,bit;
+int nIndicators;
+
+ rep->realIndicators = indicators->phys_indicators;
+ for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit)
+ nIndicators++;
+ }
+ rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
+ return Success;
+}
+
+int
+XkbSendIndicatorMap( ClientPtr client,
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply * rep)
+{
+int length;
+CARD8 * map;
+register int i;
+register unsigned bit;
+
+ length = rep->length*4;
+ if (length>0) {
+ CARD8 *to;
+ to= map= (CARD8 *)malloc(length);
+ if (map) {
+ xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit) {
+ wire->flags= indicators->maps[i].flags;
+ wire->whichGroups= indicators->maps[i].which_groups;
+ wire->groups= indicators->maps[i].groups;
+ wire->whichMods= indicators->maps[i].which_mods;
+ wire->mods= indicators->maps[i].mods.mask;
+ wire->realMods= indicators->maps[i].mods.real_mods;
+ wire->virtualMods= indicators->maps[i].mods.vmods;
+ wire->ctrls= indicators->maps[i].ctrls;
+ if (client->swapped) {
+ swaps(&wire->virtualMods);
+ swapl(&wire->ctrls);
+ }
+ wire++;
+ }
+ }
+ to = (CARD8 *)wire;
+ if ((to-map)!=length) {
+ client->errorValue = _XkbErrCode2(0xff,length);
+ return BadLength;
+ }
+ }
+ else return BadAlloc;
+ }
+ else map = NULL;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->which);
+ swapl(&rep->realIndicators);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), rep);
+ if (map) {
+ WriteToClient(client, length, map);
+ free((char *)map);
+ }
+ return client->noClientException;
+}
+
+int
+ProcXkbGetIndicatorMap(ClientPtr client)
+{
+xkbGetIndicatorMapReply rep;
+DeviceIntPtr dev;
+XkbDescPtr xkb;
+XkbIndicatorPtr leds;
+
+ REQUEST(xkbGetIndicatorMapReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb= dev->key->xkbInfo->desc;
+ leds= xkb->indicators;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ XkbComputeGetIndicatorMapReplySize(leds,&rep);
+ return XkbSendIndicatorMap(client,leds,&rep);
+}
+
+int
+ProcXkbSetIndicatorMap(ClientPtr client)
+{
+ register int i,bit;
+ int nIndicators,why;
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ xkbIndicatorMapWireDesc *from;
+ XkbSrvLedInfoPtr sli;
+ XkbEventCauseRec cause;
+
+ REQUEST(xkbSetIndicatorMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ dev = _XkbLookupKeyboard(stuff->deviceSpec,&why);
+ if (!dev) {
+ client->errorValue = _XkbErrCode2(why,stuff->deviceSpec);
+ return XkbKeyboardErrorCode;
+ }
+ xkbi= dev->key->xkbInfo;
+
+ if (stuff->which==0)
+ return client->noClientException;
+
+ for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit)
+ nIndicators++;
+ }
+ if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
+ (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
+ return BadLength;
+ }
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorMapsMask);
+ if (!sli)
+ return BadAlloc;
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ if (client->swapped) {
+ swaps(&from->virtualMods);
+ swapl(&from->ctrls);
+ }
+ CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
+ from++;
+ }
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ sli->maps[i].flags = from->flags;
+ sli->maps[i].which_groups = from->whichGroups;
+ sli->maps[i].groups = from->groups;
+ sli->maps[i].which_mods = from->whichMods;
+ sli->maps[i].mods.mask = from->mods;
+ sli->maps[i].mods.real_mods = from->mods;
+ sli->maps[i].mods.vmods= from->virtualMods;
+ sli->maps[i].ctrls = from->ctrls;
+ if (from->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods);
+ sli->maps[i].mods.mask= from->mods|tmp;
+ }
+ from++;
+ }
+ }
+
+ XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
+ XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetNamedIndicator(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetNamedIndicatorReply rep;
+ register int i = 0;
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map = NULL;
+ Bool supported;
+
+ REQUEST(xkbGetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_ONLY(stuff->indicator);
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
+ if (!sli)
+ return BadAlloc;
+
+ supported= True;
+ if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
+ if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
+ ((sli->flags&XkbSLI_IsDefault)==0)) {
+ supported= False;
+ }
+ }
+
+ if (supported) {
+ i= 0;
+ map= NULL;
+ if ((sli->names)&&(sli->maps)) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ if (stuff->indicator==sli->names[i]) {
+ map= &sli->maps[i];
+ break;
+ }
+ }
+ }
+ }
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = dev->id;
+ rep.indicator= stuff->indicator;
+ if ((map!=NULL)&&(supported)) {
+ rep.found= True;
+ rep.on= ((sli->effectiveState&(1<<i))!=0);
+ rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
+ rep.ndx= i;
+ rep.flags= map->flags;
+ rep.whichGroups= map->which_groups;
+ rep.groups= map->groups;
+ rep.whichMods= map->which_mods;
+ rep.mods= map->mods.mask;
+ rep.realMods= map->mods.real_mods;
+ rep.virtualMods= map->mods.vmods;
+ rep.ctrls= map->ctrls;
+ rep.supported= True;
+ }
+ else {
+ rep.found= False;
+ rep.on= False;
+ rep.realIndicator= False;
+ rep.ndx= XkbNoIndicator;
+ rep.flags= 0;
+ rep.whichGroups= 0;
+ rep.groups= 0;
+ rep.whichMods= 0;
+ rep.mods= 0;
+ rep.realMods= 0;
+ rep.virtualMods= 0;
+ rep.ctrls= 0;
+ rep.supported= supported;
+ }
+ if ( client->swapped ) {
+ swapl(&rep.length);
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.indicator);
+ swaps(&rep.virtualMods);
+ swapl(&rep.ctrls);
+ }
+
+ WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), &rep);
+ if (!supported) {
+ xkbExtensionDeviceNotify edev;
+
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_UnsupportedFeatureMask;
+ edev.ledClass= stuff->ledClass;
+ edev.ledID= stuff->ledID;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask;
+ edev.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ return client->noClientException;
+}
+
+int
+ProcXkbSetNamedIndicator(ClientPtr client)
+{
+ DeviceIntPtr dev,kbd;
+ XkbIndicatorMapPtr map;
+ XkbSrvLedInfoPtr sli;
+ register int led = 0;
+ unsigned extDevReason;
+ unsigned statec,namec,mapc;
+ XkbEventCauseRec cause;
+ xkbExtensionDeviceNotify ed;
+ XkbChangesRec changes;
+
+ REQUEST(xkbSetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_ONLY(stuff->indicator);
+ CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
+
+ extDevReason= 0;
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,
+ XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
+ if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
+ ((sli->flags&XkbSLI_IsDefault)==0)) {
+ bzero(&ed,sizeof(xkbExtensionDeviceNotify));
+ ed.reason= XkbXI_UnsupportedFeatureMask;
+ ed.ledClass= stuff->ledClass;
+ ed.ledID= stuff->ledID;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.ledState= sli->effectiveState;
+ ed.firstBtn= 0;
+ ed.nBtns= 0;
+ ed.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask;
+ ed.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return client->noClientException;
+ }
+ }
+
+ statec= mapc= namec= 0;
+ map= NULL;
+ if (sli->names && sli->maps) {
+ for (led=0;(led<XkbNumIndicators)&&(map==NULL);led++) {
+ if (sli->names[led]==stuff->indicator) {
+ map= &sli->maps[led];
+ break;
+ }
+ }
+ }
+ if (map==NULL) {
+ if (!stuff->createMap)
+ return client->noClientException;
+ for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) {
+ if ((sli->names[led]==None)&&(!XkbIM_InUse(&sli->maps[led]))) {
+ map= &sli->maps[led];
+ sli->names[led]= stuff->indicator;
+ break;
+ }
+ }
+ if (map==NULL)
+ return client->noClientException;
+ namec|= (1<<led);
+ sli->namesPresent|= ((stuff->indicator!=None)?(1<<led):0);
+ extDevReason|= XkbXI_IndicatorNamesMask;
+ }
+
+ if (stuff->setMap) {
+ map->flags = stuff->flags;
+ map->which_groups = stuff->whichGroups;
+ map->groups = stuff->groups;
+ map->which_mods = stuff->whichMods;
+ map->mods.mask = stuff->realMods;
+ map->mods.real_mods = stuff->realMods;
+ map->mods.vmods= stuff->virtualMods;
+ map->ctrls = stuff->ctrls;
+ mapc|= (1<<led);
+ }
+ if ((stuff->setState)&&((map->flags&XkbIM_NoExplicit)==0)) {
+ if (stuff->on) sli->explicitState|= (1<<led);
+ else sli->explicitState&= ~(1<<led);
+ statec|= ((sli->effectiveState^sli->explicitState)&(1<<led));
+ }
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static CARD32
+_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
+{
+register unsigned int i,bit,nAtoms;
+register CARD32 atomsPresent;
+
+ for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (atoms[i]!=None) {
+ atomsPresent|= bit;
+ nAtoms++;
+ }
+ }
+ if (count)
+ *count= nAtoms;
+ return atomsPresent;
+}
+
+static char *
+_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
+{
+register unsigned int i;
+Atom *atm;
+
+ atm = (Atom *)wire;
+ for (i=0;i<maxAtoms;i++) {
+ if (atoms[i]!=None) {
+ *atm= atoms[i];
+ if (swap) {
+ swapl(atm);
+ }
+ atm++;
+ }
+ }
+ return (char *)atm;
+}
+
+static Status
+XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned which,length;
+register int i;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ which= rep->which;
+ length= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbKeycodesNameMask) length++;
+ if (which&XkbGeometryNameMask) length++;
+ if (which&XkbSymbolsNameMask) length++;
+ if (which&XkbPhysSymbolsNameMask) length++;
+ if (which&XkbTypesNameMask) length++;
+ if (which&XkbCompatNameMask) length++;
+ }
+ else which&= ~XkbComponentNamesMask;
+
+ if (xkb->map!=NULL) {
+ if (which&XkbKeyTypeNamesMask)
+ length+= xkb->map->num_types;
+ rep->nTypes= xkb->map->num_types;
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr pType = xkb->map->types;
+ int nKTLevels = 0;
+
+ length+= XkbPaddedSize(xkb->map->num_types)/4;
+ for (i=0;i<xkb->map->num_types;i++,pType++) {
+ if (pType->level_names!=NULL)
+ nKTLevels+= pType->num_levels;
+ }
+ rep->nKTLevels= nKTLevels;
+ length+= nKTLevels;
+ }
+ }
+ else {
+ rep->nTypes= 0;
+ rep->nKTLevels= 0;
+ which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
+ }
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ rep->indicators= 0;
+ rep->virtualMods= 0;
+ rep->groupNames= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbIndicatorNamesMask) {
+ int nLeds;
+ rep->indicators=
+ _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
+ length+= nLeds;
+ if (nLeds==0)
+ which&= ~XkbIndicatorNamesMask;
+ }
+
+ if (which&XkbVirtualModNamesMask) {
+ int nVMods;
+ rep->virtualMods=
+ _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
+ length+= nVMods;
+ if (nVMods==0)
+ which&= ~XkbVirtualModNamesMask;
+ }
+
+ if (which&XkbGroupNamesMask) {
+ int nGroups;
+ rep->groupNames=
+ _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
+ length+= nGroups;
+ if (nGroups==0)
+ which&= ~XkbGroupNamesMask;
+ }
+
+ if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
+ length+= rep->nKeys;
+ else which&= ~XkbKeyNamesMask;
+
+ if ((which&XkbKeyAliasesMask)&&
+ (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
+ rep->nKeyAliases= xkb->names->num_key_aliases;
+ length+= rep->nKeyAliases*2;
+ }
+ else {
+ which&= ~XkbKeyAliasesMask;
+ rep->nKeyAliases= 0;
+ }
+
+ if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
+ length+= xkb->names->num_rg;
+ else which&= ~XkbRGNamesMask;
+ }
+ else {
+ which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
+ which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
+ which&= ~XkbRGNamesMask;
+ }
+
+ rep->length= length;
+ rep->which= which;
+ return Success;
+}
+
+static int
+XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned i,length,which;
+char * start;
+char * desc;
+
+ length= rep->length*4;
+ which= rep->which;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->which);
+ swaps(&rep->virtualMods);
+ swapl(&rep->indicators);
+ }
+
+ start = desc = (char *)malloc(length);
+ if ( !start )
+ return BadAlloc;
+ if (which&XkbKeycodesNameMask) {
+ *((CARD32 *)desc)= xkb->names->keycodes;
+ if (client->swapped) {
+ swapl((int *)desc);
+ }
+ desc+= 4;
+ }
+ if (which&XkbGeometryNameMask) {
+ *((CARD32 *)desc)= xkb->names->geometry;
+ if (client->swapped) {
+ swapl((int *)desc);
+ }
+ desc+= 4;
+ }
+ if (which&XkbSymbolsNameMask) {
+ *((CARD32 *)desc)= xkb->names->symbols;
+ if (client->swapped) {
+ swapl((int *)desc);
+ }
+ desc+= 4;
+ }
+ if (which&XkbPhysSymbolsNameMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ atm[0]= (CARD32)xkb->names->phys_symbols;
+ if (client->swapped) {
+ swapl(&atm[0]);
+ }
+ desc+= 4;
+ }
+ if (which&XkbTypesNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->types;
+ if (client->swapped) {
+ swapl((int *)desc);
+ }
+ desc+= 4;
+ }
+ if (which&XkbCompatNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->compat;
+ if (client->swapped) {
+ swapl((int *)desc);
+ }
+ desc+= 4;
+ }
+ if (which&XkbKeyTypeNamesMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ register XkbKeyTypePtr type= xkb->map->types;
+
+ for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
+ *atm= (CARD32)type->name;
+ if (client->swapped) {
+ swapl(atm);
+ }
+ }
+ desc= (char *)atm;
+ }
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr type = xkb->map->types;
+ register CARD32 *atm;
+ for (i=0;i<rep->nTypes;i++,type++) {
+ *desc++ = type->num_levels;
+ }
+ desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
+
+ atm= (CARD32 *)desc;
+ type = xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ register unsigned l;
+ if (type->level_names) {
+ for (l=0;l<type->num_levels;l++,atm++) {
+ *atm= type->level_names[l];
+ if (client->swapped) {
+ swapl(atm);
+ }
+ }
+ desc+= type->num_levels*4;
+ }
+ }
+ }
+ if (which&XkbIndicatorNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
+ client->swapped);
+ }
+ if (which&XkbVirtualModNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
+ client->swapped);
+ }
+ if (which&XkbGroupNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
+ client->swapped);
+ }
+ if (which&XkbKeyNamesMask) {
+ for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
+ *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
+ }
+ }
+ if (which&XkbKeyAliasesMask) {
+ XkbKeyAliasPtr pAl;
+ pAl= xkb->names->key_aliases;
+ for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
+ *((XkbKeyAliasPtr)desc)= *pAl;
+ }
+ }
+ if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
+ register CARD32 *atm= (CARD32 *)desc;
+ for (i=0;i<rep->nRadioGroups;i++,atm++) {
+ *atm= (CARD32)xkb->names->radio_groups[i];
+ if (client->swapped) {
+ swapl(atm);
+ }
+ }
+ desc+= rep->nRadioGroups*4;
+ }
+ if ((desc-start)!=(length)) {
+ ErrorF("BOGUS LENGTH in write names, expected %d, got %ld\n",
+ length, (unsigned long)(desc-start));
+ }
+ WriteToClient(client, SIZEOF(xkbGetNamesReply), rep);
+ WriteToClient(client, length, start);
+ free((char *)start);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ xkbGetNamesReply rep;
+
+ REQUEST(xkbGetNamesReq);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ memset(&rep, 0, sizeof(xkbGetNamesReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ rep.nTypes = xkb->map->num_types;
+ rep.firstKey = xkb->min_key_code;
+ rep.nKeys = XkbNumKeys(xkb);
+ if (xkb->names!=NULL) {
+ rep.nKeyAliases= xkb->names->num_key_aliases;
+ rep.nRadioGroups = xkb->names->num_rg;
+ }
+ else {
+ rep.nKeyAliases= rep.nRadioGroups= 0;
+ }
+ XkbComputeGetNamesReplySize(xkb,&rep);
+ return XkbSendNames(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static CARD32 *
+_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
+{
+register int i;
+
+ for (i=0;i<nAtoms;i++,wire++) {
+ if (swapped) {
+ swapl(wire);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
+ *pError= ((Atom)*wire);
+ return NULL;
+ }
+ }
+ return wire;
+}
+
+static CARD32 *
+_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
+ Atom *pError)
+{
+register unsigned i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ if (swapped) {
+ swapl(wire);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
+ *pError= (Atom)*wire;
+ return NULL;
+ }
+ wire++;
+ }
+ return wire;
+}
+
+static Atom *
+_XkbCopyMaskedAtoms( Atom *wire,
+ Atom *dest,
+ int nAtoms,
+ CARD32 present)
+{
+register int i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ dest[i]= *wire++;
+ }
+ return wire;
+}
+
+static Bool
+_XkbCheckTypeName(Atom name,int typeNdx)
+{
+const char * str;
+
+ str= NameForAtom(name);
+ if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
+ (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
+ return False;
+ return True;
+}
+
+int
+ProcXkbSetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ xkbNamesNotify nn;
+ CARD32 *tmp;
+ Atom bad;
+
+ REQUEST(xkbSetNamesReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+ tmp = (CARD32 *)&stuff[1];
+
+ if (stuff->which&XkbKeycodesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGeometryNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbPhysSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbTypesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbCompatNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyTypeNamesMask) {
+ register int i;
+ CARD32 *old;
+ if ( stuff->nTypes<1 ) {
+ client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
+ stuff->nTypes,
+ xkb->map->num_types);
+ return BadValue;
+ }
+ if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
+ client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
+ return BadAccess;
+ }
+ old= tmp;
+ tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ for (i=0;i<stuff->nTypes;i++,old++) {
+ if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
+ client->errorValue= _XkbErrCode2(0x05,i);
+ }
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register unsigned i;
+ XkbKeyTypePtr type;
+ CARD8 * width;
+ if ( stuff->nKTLevels<1 ) {
+ client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
+ xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
+ stuff->nKTLevels,xkb->map->num_types);
+ return BadValue;
+ }
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type = &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]==0)
+ continue;
+ else if (width[i]!=type->num_levels) {
+ client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
+ type->num_levels,width[i]);
+ return BadMatch;
+ }
+ tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ if (stuff->indicators==0) {
+ client->errorValue= 0x08;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ if (stuff->virtualMods==0) {
+ client->errorValue= 0x09;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
+ (CARD32)stuff->virtualMods,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ if (stuff->groupNames==0) {
+ client->errorValue= 0x0a;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
+ (CARD32)stuff->groupNames,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ if (stuff->firstKey<(unsigned)xkb->min_key_code) {
+ client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
+ stuff->firstKey);
+ return BadValue;
+ }
+ if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
+ (stuff->nKeys<1)) {
+ client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
+ stuff->firstKey,stuff->nKeys);
+ return BadValue;
+ }
+ tmp+= stuff->nKeys;
+ }
+ if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
+ tmp+= stuff->nKeyAliases*2;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if ( stuff->nRadioGroups<1 ) {
+ client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
+ return BadValue;
+ }
+ tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if ((tmp-((CARD32 *)stuff))!=stuff->length) {
+ client->errorValue = stuff->length;
+ return BadLength;
+ }
+ if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
+ stuff->nKeyAliases)!=Success) {
+ return BadAlloc;
+ }
+
+ /* everything is okay -- update names */
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= stuff->which;
+ tmp = (CARD32 *)&stuff[1];
+ if (stuff->which&XkbKeycodesNameMask)
+ names->keycodes= *tmp++;
+ if (stuff->which&XkbGeometryNameMask)
+ names->geometry= *tmp++;
+ if (stuff->which&XkbSymbolsNameMask)
+ names->symbols= *tmp++;
+ if (stuff->which&XkbPhysSymbolsNameMask)
+ names->phys_symbols= *tmp++;
+ if (stuff->which&XkbTypesNameMask)
+ names->types= *tmp++;
+ if (stuff->which&XkbCompatNameMask)
+ names->compat= *tmp++;
+ if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
+ register unsigned i;
+ register XkbKeyTypePtr type;
+
+ type= &xkb->map->types[stuff->firstType];
+ for (i=0;i<stuff->nTypes;i++,type++) {
+ type->name= *tmp++;
+ }
+ nn.firstType= stuff->firstType;
+ nn.nTypes= stuff->nTypes;
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register XkbKeyTypePtr type;
+ register unsigned i;
+ CARD8 *width;
+
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type= &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]>0) {
+ if (type->level_names) {
+ register unsigned n;
+ for (n=0;n<width[i];n++) {
+ type->level_names[n]= tmp[n];
+ }
+ }
+ tmp+= width[i];
+ }
+ }
+ nn.firstLevelName= 0;
+ nn.nLevelNames= stuff->nTypes;
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
+ stuff->indicators);
+ nn.changedIndicators= stuff->indicators;
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
+ stuff->virtualMods);
+ nn.changedVirtualMods= stuff->virtualMods;
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
+ stuff->groupNames);
+ nn.changedVirtualMods= stuff->groupNames;
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
+ stuff->nKeys*XkbKeyNameLength);
+ tmp+= stuff->nKeys;
+ nn.firstKey= stuff->firstKey;
+ nn.nKeys= stuff->nKeys;
+ }
+ if (stuff->which&XkbKeyAliasesMask) {
+ if (stuff->nKeyAliases>0) {
+ register int na= stuff->nKeyAliases;
+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
+ return BadAlloc;
+ memcpy((char *)names->key_aliases,(char *)tmp,
+ stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
+ tmp+= stuff->nKeyAliases*2;
+ }
+ else if (names->key_aliases!=NULL) {
+ _XkbFree(names->key_aliases);
+ names->key_aliases= NULL;
+ names->num_key_aliases= 0;
+ }
+ nn.nAliases= names->num_key_aliases;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if (stuff->nRadioGroups>0) {
+ register unsigned i,nrg;
+ nrg= stuff->nRadioGroups;
+ if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
+ return BadAlloc;
+
+ for (i=0;i<stuff->nRadioGroups;i++) {
+ names->radio_groups[i]= tmp[i];
+ }
+ tmp+= stuff->nRadioGroups;
+ }
+ else if (names->radio_groups) {
+ _XkbFree(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ nn.nRadioGroups= names->num_rg;
+ }
+ if (nn.changed) {
+ Bool needExtEvent;
+ needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
+ XkbSendNamesNotify(dev,&nn);
+ if (needExtEvent) {
+ XkbSrvLedInfoPtr sli;
+ xkbExtensionDeviceNotify edev;
+ register int i;
+ register unsigned bit;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorsMask);
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (names->indicators[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_IndicatorNamesMask;
+ edev.ledClass= KbdFeedbackClass;
+ edev.ledID= dev->kbdfeed->ctrl.id;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.supported= XkbXI_AllFeaturesMask;
+ edev.unsupported= 0;
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+#include "xkbgeom.h"
+
+#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
+
+static char *
+XkbWriteCountedString(char *wire,char *str,Bool swap)
+{
+CARD16 len,*pLen;
+
+ len= (str?strlen(str):0);
+ pLen= (CARD16 *)wire;
+ *pLen= len;
+ if (swap) {
+ swaps(pLen);
+ }
+ memcpy(&wire[2],str,len);
+ wire+= ((2+len+3)/4)*4;
+ return wire;
+}
+
+static int
+XkbSizeGeomProperties(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbPropertyPtr prop;
+
+ for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= XkbSizeCountedString(prop->name);
+ size+= XkbSizeCountedString(prop->value);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ wire= XkbWriteCountedString(wire,prop->name,swap);
+ wire= XkbWriteCountedString(wire,prop->value,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
+{
+ return geom->num_key_aliases*(2*XkbKeyNameLength);
+}
+
+static char *
+XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int sz;
+
+ sz= geom->num_key_aliases*(XkbKeyNameLength*2);
+ if (sz>0) {
+ memcpy(wire,(char *)geom->key_aliases,sz);
+ wire+= sz;
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomColors(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbColorPtr color;
+
+ for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= XkbSizeCountedString(color->spec);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbColorPtr color;
+
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ wire= XkbWriteCountedString(wire,color->spec,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomShapes(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbShapePtr shape;
+
+ for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ register XkbOutlinePtr ol;
+ size+= SIZEOF(xkbShapeWireDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ size+= SIZEOF(xkbOutlineWireDesc);
+ size+= ol->num_points*SIZEOF(xkbPointWireDesc);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+int i;
+XkbShapePtr shape;
+xkbShapeWireDesc * shapeWire;
+
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int o;
+ XkbOutlinePtr ol;
+ xkbOutlineWireDesc * olWire;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ shapeWire->name= shape->name;
+ shapeWire->nOutlines= shape->num_outlines;
+ if (shape->primary!=NULL)
+ shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
+ else shapeWire->primaryNdx= XkbNoShape;
+ if (shape->approx!=NULL)
+ shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
+ else shapeWire->approxNdx= XkbNoShape;
+ if (swap) {
+ swapl(&shapeWire->name);
+ }
+ wire= (char *)&shapeWire[1];
+ for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+ olWire= (xkbOutlineWireDesc *)wire;
+ olWire->nPoints= ol->num_points;
+ olWire->cornerRadius= ol->corner_radius;
+ wire= (char *)&olWire[1];
+ ptWire= (xkbPointWireDesc *)wire;
+ for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
+ ptWire[p].x= pt->x;
+ ptWire[p].y= pt->y;
+ if (swap) {
+ swaps(&ptWire[p].x);
+ swaps(&ptWire[p].y);
+ }
+ }
+ wire= (char *)&ptWire[ol->num_points];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
+{
+register int i,size;
+
+ for (i=size=0;i<num_doodads;i++,doodad++) {
+ size+= SIZEOF(xkbAnyDoodadWireDesc);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= XkbSizeCountedString(doodad->text.text);
+ size+= XkbSizeCountedString(doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= XkbSizeCountedString(doodad->logo.logo_name);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
+{
+register int i;
+xkbDoodadWireDesc * doodadWire;
+
+ for (i=0;i<num_doodads;i++,doodad++) {
+ doodadWire= (xkbDoodadWireDesc *)wire;
+ wire= (char *)&doodadWire[1];
+ bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
+ doodadWire->any.name= doodad->any.name;
+ doodadWire->any.type= doodad->any.type;
+ doodadWire->any.priority= doodad->any.priority;
+ doodadWire->any.top= doodad->any.top;
+ doodadWire->any.left= doodad->any.left;
+ if (swap) {
+ swapl(&doodadWire->any.name);
+ swaps(&doodadWire->any.top);
+ swaps(&doodadWire->any.left);
+ }
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodadWire->shape.angle= doodad->shape.angle;
+ doodadWire->shape.colorNdx= doodad->shape.color_ndx;
+ doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
+ if (swap) {
+ swaps(&doodadWire->shape.angle);
+ }
+ break;
+ case XkbTextDoodad:
+ doodadWire->text.angle= doodad->text.angle;
+ doodadWire->text.width= doodad->text.width;
+ doodadWire->text.height= doodad->text.height;
+ doodadWire->text.colorNdx= doodad->text.color_ndx;
+ if (swap) {
+ swaps(&doodadWire->text.angle);
+ swaps(&doodadWire->text.width);
+ swaps(&doodadWire->text.height);
+ }
+ wire= XkbWriteCountedString(wire,doodad->text.text,swap);
+ wire= XkbWriteCountedString(wire,doodad->text.font,swap);
+ break;
+ case XkbIndicatorDoodad:
+ doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
+ doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
+ doodadWire->indicator.offColorNdx=
+ doodad->indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodadWire->logo.angle= doodad->logo.angle;
+ doodadWire->logo.colorNdx= doodad->logo.color_ndx;
+ doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
+ wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
+ break;
+ default:
+ ErrorF("Unknown doodad type %d in XkbWriteGeomDoodads\n",
+ doodad->any.type);
+ ErrorF("Ignored\n");
+ break;
+ }
+ }
+ return wire;
+}
+
+static char *
+XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
+{
+register int r;
+XkbOverlayRowPtr row;
+xkbOverlayWireDesc * olWire;
+
+ olWire= (xkbOverlayWireDesc *)wire;
+ olWire->name= ol->name;
+ olWire->nRows= ol->num_rows;
+ if (swap) {
+ swapl(&olWire->name);
+ }
+ wire= (char *)&olWire[1];
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ unsigned int k;
+ XkbOverlayKeyPtr key;
+ xkbOverlayRowWireDesc * rowWire;
+ rowWire= (xkbOverlayRowWireDesc *)wire;
+ rowWire->rowUnder= row->row_under;
+ rowWire->nKeys= row->num_keys;
+ wire= (char *)&rowWire[1];
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ xkbOverlayKeyWireDesc * keyWire;
+ keyWire= (xkbOverlayKeyWireDesc *)wire;
+ memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
+ memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
+ wire= (char *)&keyWire[1];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomSections(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbSectionPtr section;
+
+ for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= SIZEOF(xkbSectionWireDesc);
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
+ size+= SIZEOF(xkbRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
+ }
+ }
+ if (section->doodads)
+ size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
+ if (section->overlays) {
+ int o;
+ XkbOverlayPtr ol;
+ for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
+ int r;
+ XkbOverlayRowPtr row;
+ size+= SIZEOF(xkbOverlayWireDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ size+= SIZEOF(xkbOverlayRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
+ }
+ }
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+XkbSectionPtr section;
+xkbSectionWireDesc * sectionWire;
+
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ sectionWire= (xkbSectionWireDesc *)wire;
+ sectionWire->name= section->name;
+ sectionWire->top= section->top;
+ sectionWire->left= section->left;
+ sectionWire->width= section->width;
+ sectionWire->height= section->height;
+ sectionWire->angle= section->angle;
+ sectionWire->priority= section->priority;
+ sectionWire->nRows= section->num_rows;
+ sectionWire->nDoodads= section->num_doodads;
+ sectionWire->nOverlays= section->num_overlays;
+ sectionWire->pad= 0;
+ if (swap) {
+ swapl(&sectionWire->name);
+ swaps(&sectionWire->top);
+ swaps(&sectionWire->left);
+ swaps(&sectionWire->width);
+ swaps(&sectionWire->height);
+ swaps(&sectionWire->angle);
+ }
+ wire= (char *)&sectionWire[1];
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ xkbRowWireDesc * rowWire;
+ for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
+ rowWire= (xkbRowWireDesc *)wire;
+ rowWire->top= row->top;
+ rowWire->left= row->left;
+ rowWire->nKeys= row->num_keys;
+ rowWire->vertical= row->vertical;
+ rowWire->pad= 0;
+ if (swap) {
+ swaps(&rowWire->top);
+ swaps(&rowWire->left);
+ }
+ wire= (char *)&rowWire[1];
+ if (row->keys) {
+ int k;
+ XkbKeyPtr key;
+ xkbKeyWireDesc * keyWire;
+ keyWire= (xkbKeyWireDesc *)wire;
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
+ keyWire[k].gap= key->gap;
+ keyWire[k].shapeNdx= key->shape_ndx;
+ keyWire[k].colorNdx= key->color_ndx;
+ if (swap) {
+ swaps(&keyWire[k].gap);
+ }
+ }
+ wire= (char *)&keyWire[row->num_keys];
+ }
+ }
+ }
+ if (section->doodads) {
+ wire= XkbWriteGeomDoodads(wire,
+ section->num_doodads,section->doodads,
+ swap);
+ }
+ if (section->overlays) {
+ register int o;
+ for (o=0;o<section->num_overlays;o++) {
+ wire= XkbWriteGeomOverlay(wire,&section->overlays[o],swap);
+ }
+ }
+ }
+ return wire;
+}
+
+static Status
+XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Atom name)
+{
+int len;
+
+ if (geom!=NULL) {
+ len= XkbSizeCountedString(geom->label_font);
+ len+= XkbSizeGeomProperties(geom);
+ len+= XkbSizeGeomColors(geom);
+ len+= XkbSizeGeomShapes(geom);
+ len+= XkbSizeGeomSections(geom);
+ len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
+ len+= XkbSizeGeomKeyAliases(geom);
+ rep->length= len/4;
+ rep->found= True;
+ rep->name= geom->name;
+ rep->widthMM= geom->width_mm;
+ rep->heightMM= geom->height_mm;
+ rep->nProperties= geom->num_properties;
+ rep->nColors= geom->num_colors;
+ rep->nShapes= geom->num_shapes;
+ rep->nSections= geom->num_sections;
+ rep->nDoodads= geom->num_doodads;
+ rep->nKeyAliases= geom->num_key_aliases;
+ rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
+ rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
+ }
+ else {
+ rep->length= 0;
+ rep->found= False;
+ rep->name= name;
+ rep->widthMM= rep->heightMM= 0;
+ rep->nProperties= rep->nColors= rep->nShapes= 0;
+ rep->nSections= rep->nDoodads= 0;
+ rep->nKeyAliases= 0;
+ rep->labelColorNdx= rep->baseColorNdx= 0;
+ }
+ return Success;
+}
+
+static int
+XkbSendGeometry( ClientPtr client,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Bool freeGeom)
+{
+ char *desc,*start;
+ int len;
+
+ if (geom!=NULL) {
+ len= rep->length*4;
+ start= desc= (char *)malloc(len);
+ if (!start)
+ return BadAlloc;
+ desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
+ if ( rep->nProperties>0 )
+ desc = XkbWriteGeomProperties(desc,geom,client->swapped);
+ if ( rep->nColors>0 )
+ desc = XkbWriteGeomColors(desc,geom,client->swapped);
+ if ( rep->nShapes>0 )
+ desc = XkbWriteGeomShapes(desc,geom,client->swapped);
+ if ( rep->nSections>0 )
+ desc = XkbWriteGeomSections(desc,geom,client->swapped);
+ if ( rep->nDoodads>0 )
+ desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
+ client->swapped);
+ if ( rep->nKeyAliases>0 )
+ desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
+ if ((desc-start)!=(len)) {
+ ErrorF("BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ }
+ else {
+ len= 0;
+ start= NULL;
+ }
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber);
+ swapl(&rep->length);
+ swapl(&rep->name);
+ swaps(&rep->widthMM);
+ swaps(&rep->heightMM);
+ swaps(&rep->nProperties);
+ swaps(&rep->nColors);
+ swaps(&rep->nShapes);
+ swaps(&rep->nSections);
+ swaps(&rep->nDoodads);
+ swaps(&rep->nKeyAliases);
+ }
+ WriteToClient(client, SIZEOF(xkbGetGeometryReply), rep);
+ if (len>0)
+ WriteToClient(client, len, start);
+ if (start!=NULL)
+ free((char *)start);
+ if (freeGeom)
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetGeometryReply rep;
+ XkbGeometryPtr geom;
+ Bool shouldFree;
+ Status status;
+
+ REQUEST(xkbGetGeometryReq);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
+ rep.type= X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber= client->sequence;
+ rep.length= 0;
+ status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
+ if (status!=Success)
+ return status;
+ else return XkbSendGeometry(client,geom,&rep,shouldFree);
+}
+
+/***====================================================================***/
+
+static Status
+_GetCountedString(char **wire_inout, ClientPtr client, char **str)
+{
+char * wire, *next;
+CARD16 len;
+
+ wire= *wire_inout;
+ len = *(CARD16 *) wire;
+ if (client->swapped) {
+ swaps(&len);
+ }
+ next = wire + XkbPaddedSize(len + 2);
+ /* Check we're still within the size of the request */
+ if (client->req_len <
+ bytes_to_int32(next - (char *) client->requestBuffer))
+ return BadValue;
+ *str = malloc(len + 1);
+ if (!*str)
+ return BadAlloc;
+ memcpy(*str, &wire[2], len);
+ *(*str + len) = '\0';
+ *wire_inout = next;
+ return Success;
+}
+
+static Status
+_CheckSetDoodad( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+char * wire;
+xkbDoodadWireDesc * dWire;
+xkbAnyDoodadWireDesc any;
+xkbTextDoodadWireDesc text;
+XkbDoodadPtr doodad;
+Status status;
+
+ dWire= (xkbDoodadWireDesc *)(*wire_inout);
+ any = dWire->any;
+ wire= (char *)&dWire[1];
+ if (client->swapped) {
+ swapl(&any.name);
+ swaps(&any.top);
+ swaps(&any.left);
+ swaps(&any.angle);
+ }
+ CHK_ATOM_ONLY(dWire->any.name);
+ doodad = XkbAddGeomDoodad(geom, section, any.name);
+ if (!doodad)
+ return BadAlloc;
+ doodad->any.type= dWire->any.type;
+ doodad->any.priority= dWire->any.priority;
+ doodad->any.top = any.top;
+ doodad->any.left = any.left;
+ doodad->any.angle = any.angle;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ if (dWire->shape.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
+ dWire->shape.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->shape.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
+ dWire->shape.shapeNdx);
+ return BadMatch;
+ }
+ doodad->shape.color_ndx= dWire->shape.colorNdx;
+ doodad->shape.shape_ndx= dWire->shape.shapeNdx;
+ break;
+ case XkbTextDoodad:
+ if (dWire->text.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
+ dWire->text.colorNdx);
+ return BadMatch;
+ }
+ text = dWire->text;
+ if (client->swapped) {
+ swaps(&text.width);
+ swaps(&text.height);
+ }
+ doodad->text.width= text.width;
+ doodad->text.height= text.height;
+ doodad->text.color_ndx= dWire->text.colorNdx;
+ status = _GetCountedString(&wire, client, &doodad->text.text);
+ if (status != Success)
+ return status;
+ status = _GetCountedString(&wire, client, &doodad->text.font);
+ if (status != Success) {
+ free (doodad->text.text);
+ return status;
+ }
+ break;
+ case XkbIndicatorDoodad:
+ if (dWire->indicator.onColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
+ dWire->indicator.onColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.offColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
+ dWire->indicator.offColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
+ dWire->indicator.shapeNdx);
+ return BadMatch;
+ }
+ doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
+ doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
+ doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
+ break;
+ case XkbLogoDoodad:
+ if (dWire->logo.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
+ dWire->logo.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->logo.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
+ dWire->logo.shapeNdx);
+ return BadMatch;
+ }
+ doodad->logo.color_ndx= dWire->logo.colorNdx;
+ doodad->logo.shape_ndx= dWire->logo.shapeNdx;
+ status = _GetCountedString(&wire, client, &doodad->logo.logo_name);
+ if (status != Success)
+ return status;
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
+ return BadValue;
+ }
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetOverlay( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+register int r;
+char * wire;
+XkbOverlayPtr ol;
+xkbOverlayWireDesc * olWire;
+xkbOverlayRowWireDesc * rWire;
+
+ wire= *wire_inout;
+ olWire= (xkbOverlayWireDesc *)wire;
+ if (client->swapped) {
+ swapl(&olWire->name);
+ }
+ CHK_ATOM_ONLY(olWire->name);
+ ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
+ rWire= (xkbOverlayRowWireDesc *)&olWire[1];
+ for (r=0;r<olWire->nRows;r++) {
+ register int k;
+ xkbOverlayKeyWireDesc * kWire;
+ XkbOverlayRowPtr row;
+
+ if (rWire->rowUnder>section->num_rows) {
+ client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
+ rWire->rowUnder);
+ return BadMatch;
+ }
+ row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
+ kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++,kWire++) {
+ if (XkbAddGeomOverlayKey(ol,row,
+ (char *)kWire->over,(char *)kWire->under)==NULL) {
+ client->errorValue= _XkbErrCode3(0x21,r,k);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbOverlayRowWireDesc *)kWire;
+ }
+ olWire= (xkbOverlayWireDesc *)rWire;
+ wire= (char *)olWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetSections( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+Status status;
+register int s;
+char * wire;
+xkbSectionWireDesc * sWire;
+XkbSectionPtr section;
+
+ wire= *wire_inout;
+ if (req->nSections<1)
+ return Success;
+ sWire= (xkbSectionWireDesc *)wire;
+ for (s=0;s<req->nSections;s++) {
+ register int r;
+ xkbRowWireDesc * rWire;
+ if (client->swapped) {
+ swapl(&sWire->name);
+ swaps(&sWire->top);
+ swaps(&sWire->left);
+ swaps(&sWire->width);
+ swaps(&sWire->height);
+ swaps(&sWire->angle);
+ }
+ CHK_ATOM_ONLY(sWire->name);
+ section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
+ sWire->nDoodads,sWire->nOverlays);
+ if (!section)
+ return BadAlloc;
+ section->priority= sWire->priority;
+ section->top= sWire->top;
+ section->left= sWire->left;
+ section->width= sWire->width;
+ section->height= sWire->height;
+ section->angle= sWire->angle;
+ rWire= (xkbRowWireDesc *)&sWire[1];
+ for (r=0;r<sWire->nRows;r++) {
+ register int k;
+ XkbRowPtr row;
+ xkbKeyWireDesc * kWire;
+ if (client->swapped) {
+ swaps(&rWire->top);
+ swaps(&rWire->left);
+ }
+ row= XkbAddGeomRow(section,rWire->nKeys);
+ if (!row)
+ return BadAlloc;
+ row->top= rWire->top;
+ row->left= rWire->left;
+ row->vertical= rWire->vertical;
+ kWire= (xkbKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++) {
+ XkbKeyPtr key;
+ key= XkbAddGeomKey(row);
+ if (!key)
+ return BadAlloc;
+ memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
+ key->gap= kWire[k].gap;
+ key->shape_ndx= kWire[k].shapeNdx;
+ key->color_ndx= kWire[k].colorNdx;
+ if (key->shape_ndx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
+ geom->num_shapes);
+ return BadMatch;
+ }
+ if (key->color_ndx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
+ geom->num_colors);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
+ }
+ wire= (char *)rWire;
+ if (sWire->nDoodads>0) {
+ register int d;
+ for (d=0;d<sWire->nDoodads;d++) {
+ status=_CheckSetDoodad(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ if (sWire->nOverlays>0) {
+ register int o;
+ for (o=0;o<sWire->nOverlays;o++) {
+ status= _CheckSetOverlay(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ sWire= (xkbSectionWireDesc *)wire;
+ }
+ wire= (char *)sWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetShapes( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+register int i;
+char * wire;
+
+ wire= *wire_inout;
+ if (req->nShapes<1) {
+ client->errorValue= _XkbErrCode2(0x06,req->nShapes);
+ return BadValue;
+ }
+ else {
+ xkbShapeWireDesc * shapeWire;
+ XkbShapePtr shape;
+ register int o;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ for (i=0;i<req->nShapes;i++) {
+ xkbOutlineWireDesc * olWire;
+ XkbOutlinePtr ol;
+ shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
+ if (!shape)
+ return BadAlloc;
+ olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
+ for (o=0;o<shapeWire->nOutlines;o++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+
+ ol= XkbAddGeomOutline(shape,olWire->nPoints);
+ if (!ol)
+ return BadAlloc;
+ ol->corner_radius= olWire->cornerRadius;
+ ptWire= (xkbPointWireDesc *)&olWire[1];
+ for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
+ pt->x= ptWire[p].x;
+ pt->y= ptWire[p].y;
+ if (client->swapped) {
+ swaps(&pt->x);
+ swaps(&pt->y);
+ }
+ }
+ ol->num_points= olWire->nPoints;
+ olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
+ }
+ if (shapeWire->primaryNdx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire->primaryNdx];
+ if (shapeWire->approxNdx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire->approxNdx];
+ shapeWire= (xkbShapeWireDesc *)olWire;
+ }
+ wire= (char *)shapeWire;
+ }
+ if (geom->num_shapes!=req->nShapes) {
+ client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
+ return BadMatch;
+ }
+
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetGeom( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ ClientPtr client)
+{
+register int i;
+Status status;
+char * wire;
+
+ wire= (char *)&req[1];
+ status = _GetCountedString(&wire, client, &geom->label_font);
+ if (status != Success)
+ return status;
+
+ for (i=0;i<req->nProperties;i++) {
+ char *name,*val;
+ status = _GetCountedString(&wire, client, &name);
+ if (status != Success)
+ return status;
+ status = _GetCountedString(&wire, client, &val);
+ if (status != Success) {
+ free(name);
+ return status;
+ }
+ if (XkbAddGeomProperty(geom,name,val)==NULL) {
+ free(name);
+ free(val);
+ return BadAlloc;
+ }
+ free(name);
+ free(val);
+ }
+
+ if (req->nColors<2) {
+ client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
+ return BadValue;
+ }
+ if (req->baseColorNdx>req->nColors) {
+ client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx>req->nColors) {
+ client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx==req->baseColorNdx) {
+ client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
+ req->labelColorNdx);
+ return BadMatch;
+ }
+
+ for (i=0;i<req->nColors;i++) {
+ char *name;
+
+ status = _GetCountedString(&wire, client, &name);
+ if (status != Success)
+ return status;
+ if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
+ free(name);
+ return BadAlloc;
+ }
+ free(name);
+ }
+ if (req->nColors!=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
+ return BadMatch;
+ }
+ geom->label_color= &geom->colors[req->labelColorNdx];
+ geom->base_color= &geom->colors[req->baseColorNdx];
+
+ if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
+ return status;
+
+ if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
+ return status;
+
+ for (i=0;i<req->nDoodads;i++) {
+ status=_CheckSetDoodad(&wire,geom,NULL,client);
+ if (status!=Success)
+ return status;
+ }
+
+ for (i=0;i<req->nKeyAliases;i++) {
+ if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
+ return BadAlloc;
+ wire+= 2*XkbKeyNameLength;
+ }
+ return Success;
+}
+
+int
+ProcXkbSetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbGeometryPtr geom,old;
+ XkbGeometrySizesRec sizes;
+ Status status;
+ XkbDescPtr xkb;
+ Bool new_name;
+ xkbNewKeyboardNotify nkn;
+
+ REQUEST(xkbSetGeometryReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ xkb= dev->key->xkbInfo->desc;
+ old= xkb->geom;
+ xkb->geom= NULL;
+
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= stuff->nProperties;
+ sizes.num_colors= stuff->nColors;
+ sizes.num_shapes= stuff->nShapes;
+ sizes.num_sections= stuff->nSections;
+ sizes.num_doodads= stuff->nDoodads;
+ sizes.num_key_aliases= stuff->nKeyAliases;
+ if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
+ xkb->geom= old;
+ return status;
+ }
+ geom= xkb->geom;
+ geom->name= stuff->name;
+ geom->width_mm= stuff->widthMM;
+ geom->height_mm= stuff->heightMM;
+ if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= old;
+ return status;
+ }
+ new_name= (xkb->names->geometry!=geom->name);
+ xkb->names->geometry= geom->name;
+ if (old)
+ XkbFreeGeometry(old,XkbGeomAllMask,True);
+ if (new_name) {
+ xkbNamesNotify nn;
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= XkbGeometryNameMask;
+ XkbSendNamesNotify(dev,&nn);
+ }
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetGeometry;
+ nkn.changed= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbPerClientFlags(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbPerClientFlagsReply rep;
+ XkbInterestPtr interest;
+
+ REQUEST(xkbPerClientFlagsReq);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
+ CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
+
+ interest = XkbFindClientResource((DevicePtr)dev,client);
+ memset(&rep, 0, sizeof(xkbPerClientFlagsReply));
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->change) {
+ client->xkbClientFlags&= ~stuff->change;
+ client->xkbClientFlags|= stuff->value;
+ }
+ if (stuff->change&XkbPCF_AutoResetControlsMask) {
+ Bool want;
+ want= stuff->value&XkbPCF_AutoResetControlsMask;
+ if (interest && !want) {
+ interest->autoCtrls= interest->autoCtrlValues= 0;
+ }
+ else if (want && (!interest)) {
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ interest= XkbAddClientResource((DevicePtr)dev,client,id);
+ if (!interest)
+ return BadAlloc;
+ }
+ if (interest && want ) {
+ register unsigned affect;
+ affect= stuff->ctrlsToChange;
+
+ CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
+ CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
+
+ interest->autoCtrls&= ~affect;
+ interest->autoCtrlValues&= ~affect;
+ interest->autoCtrls|= stuff->autoCtrls&affect;
+ interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
+ }
+ }
+ rep.supported = XkbPCF_AllFlagsMask;
+ rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
+ if (interest) {
+ rep.autoCtrls= interest->autoCtrls;
+ rep.autoCtrlValues= interest->autoCtrlValues;
+ }
+ else {
+ rep.autoCtrls= rep.autoCtrlValues= 0;
+ }
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.supported);
+ swapl(&rep.value);
+ swapl(&rep.autoCtrls);
+ swapl(&rep.autoCtrlValues);
+ }
+ WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), &rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
+/* and wildcards */
+static unsigned char componentSpecLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+/* same as above but accepts percent, plus and bar too */
+static unsigned char componentExprLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+static char *
+GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
+{
+int len;
+register int i;
+unsigned char *wire,*str,*tmp,*legal;
+
+ if (allowExpr) legal= &componentExprLegal[0];
+ else legal= &componentSpecLegal[0];
+
+ wire= *pWire;
+ len= (*(unsigned char *)wire++);
+ if (len>0) {
+ str= (unsigned char *)_XkbCalloc(1, len+1);
+ if (str) {
+ tmp= str;
+ for (i=0;i<len;i++) {
+ if (legal[(*wire)/8]&(1<<((*wire)%8)))
+ *tmp++= *wire++;
+ else wire++;
+ }
+ if (tmp!=str)
+ *tmp++= '\0';
+ else {
+ _XkbFree(str);
+ str= NULL;
+ }
+ }
+ else {
+ *errRtrn= BadAlloc;
+ }
+ }
+ else {
+ str= NULL;
+ }
+ *pWire= wire;
+ return (char *)str;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbListComponents(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbListComponentsReply rep;
+ unsigned len;
+ int status;
+ unsigned char * str;
+ XkbSrvListInfoRec list;
+
+ REQUEST(xkbListComponentsReq);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ bzero(&list,sizeof(XkbSrvListInfoRec));
+ list.maxRtrn= stuff->maxNames;
+ list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+ if ((status=XkbDDXList(dev,&list,client))!=Success) {
+ if (list.pool) {
+ _XkbFree(list.pool);
+ list.pool= NULL;
+ }
+ return status;
+ }
+ bzero(&rep,sizeof(xkbListComponentsReply));
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = XkbPaddedSize(list.nPool)/4;
+ rep.nKeymaps = list.nFound[_XkbListKeymaps];
+ rep.nKeycodes = list.nFound[_XkbListKeycodes];
+ rep.nTypes = list.nFound[_XkbListTypes];
+ rep.nCompatMaps = list.nFound[_XkbListCompat];
+ rep.nSymbols = list.nFound[_XkbListSymbols];
+ rep.nGeometries = list.nFound[_XkbListGeometry];
+ rep.extra= 0;
+ if (list.nTotal>list.maxRtrn)
+ rep.extra = (list.nTotal-list.maxRtrn);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.nKeymaps);
+ swaps(&rep.nKeycodes);
+ swaps(&rep.nTypes);
+ swaps(&rep.nCompatMaps);
+ swaps(&rep.nSymbols);
+ swaps(&rep.nGeometries);
+ swaps(&rep.extra);
+ }
+ WriteToClient(client,SIZEOF(xkbListComponentsReply),&rep);
+ if (list.nPool && list.pool) {
+ WriteToClient(client,XkbPaddedSize(list.nPool), list.pool);
+ _XkbFree(list.pool);
+ list.pool= NULL;
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetKbdByName(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbFileInfo finfo;
+ xkbGetKbdByNameReply rep;
+ xkbGetMapReply mrep;
+ xkbGetCompatMapReply crep;
+ xkbGetIndicatorMapReply irep;
+ xkbGetNamesReply nrep;
+ xkbGetGeometryReply grep;
+ XkbComponentNamesRec names;
+ XkbDescPtr xkb;
+ unsigned char * str;
+ char mapFile[PATH_MAX];
+ unsigned len;
+ unsigned fwant,fneed,reported;
+ int status;
+ Bool geom_changed;
+
+ REQUEST(xkbGetKbdByNameReq);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc;
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ names.keymap= GetComponentSpec(&str,True,&status);
+ names.keycodes= GetComponentSpec(&str,True,&status);
+ names.types= GetComponentSpec(&str,True,&status);
+ names.compat= GetComponentSpec(&str,True,&status);
+ names.symbols= GetComponentSpec(&str,True,&status);
+ names.geometry= GetComponentSpec(&str,True,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+
+ CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
+ CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
+
+ if (stuff->load)
+ fwant= XkbGBN_AllComponentsMask;
+ else fwant= stuff->want|stuff->need;
+ if (!names.keymap) {
+ if ((!names.compat)&&
+ (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
+ names.compat= Xstrdup("%");
+ }
+ if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
+ names.types= Xstrdup("%");
+ }
+ if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
+ names.symbols= Xstrdup("%");
+ }
+ geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
+ if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
+ names.geometry= Xstrdup("%");
+ geom_changed= False;
+ }
+ }
+ else {
+ geom_changed= True;
+ }
+
+ bzero(mapFile,PATH_MAX);
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ rep.loaded= False;
+ fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask;
+ fneed= XkbConvertGetByNameComponents(True,stuff->need);
+ rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed);
+ if (stuff->load) {
+ fneed|= XkmKeymapRequired;
+ fwant|= XkmKeymapLegal;
+ }
+ if ((fwant|fneed)&XkmSymbolsMask) {
+ fneed|= XkmKeyNamesIndex|XkmTypesIndex;
+ fwant|= XkmIndicatorsIndex;
+ }
+ rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&finfo,
+ mapFile,PATH_MAX);
+ rep.newKeyboard= False;
+ rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
+
+ stuff->want|= stuff->need;
+ if (finfo.xkb==NULL)
+ rep.reported= 0;
+ else {
+ if (stuff->load)
+ rep.loaded= True;
+ if (stuff->load ||
+ ((rep.reported&XkbGBN_SymbolsMask) && (finfo.xkb->compat))) {
+ XkbChangesRec changes;
+ bzero(&changes,sizeof(changes));
+ XkbUpdateDescActions(finfo.xkb,
+ finfo.xkb->min_key_code,XkbNumKeys(finfo.xkb),
+ &changes);
+ }
+
+ if (finfo.xkb->map==NULL)
+ rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
+ else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
+ mrep.type= X_Reply;
+ mrep.deviceID = dev->id;
+ mrep.sequenceNumber= client->sequence;
+ mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
+ mrep.minKeyCode = finfo.xkb->min_key_code;
+ mrep.maxKeyCode = finfo.xkb->max_key_code;
+ mrep.present = 0;
+ mrep.totalSyms = mrep.totalActs =
+ mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
+ mrep.totalModMapKeys= 0;
+ if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
+ mrep.present|= XkbKeyTypesMask;
+ mrep.firstType = 0;
+ mrep.nTypes = mrep.totalTypes= finfo.xkb->map->num_types;
+ }
+ else {
+ mrep.firstType = mrep.nTypes= 0;
+ mrep.totalTypes= 0;
+ }
+ if (rep.reported&XkbGBN_ClientSymbolsMask) {
+ mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
+ mrep.firstKeySym = mrep.firstModMapKey= finfo.xkb->min_key_code;
+ mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(finfo.xkb);
+ }
+ else {
+ mrep.firstKeySym= mrep.firstModMapKey= 0;
+ mrep.nKeySyms= mrep.nModMapKeys= 0;
+ }
+ if (rep.reported&XkbGBN_ServerSymbolsMask) {
+ mrep.present|= XkbAllServerInfoMask;
+ mrep.virtualMods= ~0;
+ mrep.firstKeyAct = mrep.firstKeyBehavior =
+ mrep.firstKeyExplicit = finfo.xkb->min_key_code;
+ mrep.nKeyActs = mrep.nKeyBehaviors =
+ mrep.nKeyExplicit = XkbNumKeys(finfo.xkb);
+ }
+ else {
+ mrep.virtualMods= 0;
+ mrep.firstKeyAct= mrep.firstKeyBehavior=
+ mrep.firstKeyExplicit = 0;
+ mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
+ }
+ XkbComputeGetMapReplySize(finfo.xkb,&mrep);
+ rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
+ }
+ if (finfo.xkb->compat==NULL)
+ rep.reported&= ~XkbGBN_CompatMapMask;
+ else if (rep.reported&XkbGBN_CompatMapMask) {
+ crep.type= X_Reply;
+ crep.deviceID= dev->id;
+ crep.sequenceNumber= client->sequence;
+ crep.length= 0;
+ crep.groups= XkbAllGroupsMask;
+ crep.firstSI= 0;
+ crep.nSI= crep.nTotalSI= finfo.xkb->compat->num_si;
+ XkbComputeGetCompatMapReplySize(finfo.xkb->compat,&crep);
+ rep.length+= SIZEOF(xGenericReply)/4+crep.length;
+ }
+ if (finfo.xkb->indicators==NULL)
+ rep.reported&= ~XkbGBN_IndicatorMapMask;
+ else if (rep.reported&XkbGBN_IndicatorMapMask) {
+ irep.type= X_Reply;
+ irep.deviceID= dev->id;
+ irep.sequenceNumber= client->sequence;
+ irep.length= 0;
+ irep.which= XkbAllIndicatorsMask;
+ XkbComputeGetIndicatorMapReplySize(finfo.xkb->indicators,&irep);
+ rep.length+= SIZEOF(xGenericReply)/4+irep.length;
+ }
+ if (finfo.xkb->names==NULL)
+ rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
+ else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
+ nrep.type= X_Reply;
+ nrep.deviceID= dev->id;
+ nrep.sequenceNumber= client->sequence;
+ nrep.length= 0;
+ nrep.minKeyCode= finfo.xkb->min_key_code;
+ nrep.maxKeyCode= finfo.xkb->max_key_code;
+ if (rep.reported&XkbGBN_OtherNamesMask) {
+ nrep.which= XkbAllNamesMask;
+ if (finfo.xkb->map!=NULL)
+ nrep.nTypes= finfo.xkb->map->num_types;
+ else nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= XkbAllGroupsMask;
+ nrep.virtualMods= XkbAllVirtualModsMask;
+ nrep.indicators= XkbAllIndicatorsMask;
+ nrep.nRadioGroups= finfo.xkb->names->num_rg;
+ }
+ else {
+ nrep.which= 0;
+ nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= 0;
+ nrep.virtualMods= 0;
+ nrep.indicators= 0;
+ nrep.nRadioGroups= 0;
+ }
+ if (rep.reported&XkbGBN_KeyNamesMask) {
+ nrep.which|= XkbKeyNamesMask;
+ nrep.firstKey= finfo.xkb->min_key_code;
+ nrep.nKeys= XkbNumKeys(finfo.xkb);
+ nrep.nKeyAliases= finfo.xkb->names->num_key_aliases;
+ if (nrep.nKeyAliases)
+ nrep.which|= XkbKeyAliasesMask;
+ }
+ else {
+ nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
+ nrep.firstKey= nrep.nKeys= 0;
+ nrep.nKeyAliases= 0;
+ }
+ XkbComputeGetNamesReplySize(finfo.xkb,&nrep);
+ rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
+ }
+ if (finfo.xkb->geom==NULL)
+ rep.reported&= ~XkbGBN_GeometryMask;
+ else if (rep.reported&XkbGBN_GeometryMask) {
+ grep.type= X_Reply;
+ grep.deviceID= dev->id;
+ grep.sequenceNumber= client->sequence;
+ grep.length= 0;
+ grep.found= True;
+ grep.pad= 0;
+ grep.widthMM= grep.heightMM= 0;
+ grep.nProperties= grep.nColors= grep.nShapes= 0;
+ grep.nSections= grep.nDoodads= 0;
+ grep.baseColorNdx= grep.labelColorNdx= 0;
+ XkbComputeGetGeometryReplySize(finfo.xkb->geom,&grep,None);
+ rep.length+= SIZEOF(xGenericReply)/4+grep.length;
+ }
+ }
+
+ reported= rep.reported;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.found);
+ swaps(&rep.reported);
+ }
+ WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), &rep);
+ if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
+ XkbSendMap(client,finfo.xkb,&mrep);
+ if (reported&XkbGBN_CompatMapMask)
+ XkbSendCompatMap(client,finfo.xkb->compat,&crep);
+ if (reported&XkbGBN_IndicatorMapMask)
+ XkbSendIndicatorMap(client,finfo.xkb->indicators,&irep);
+ if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
+ XkbSendNames(client,finfo.xkb,&nrep);
+ if (reported&XkbGBN_GeometryMask)
+ XkbSendGeometry(client,finfo.xkb->geom,&grep,False);
+ if (rep.loaded) {
+ XkbDescPtr old_xkb;
+ xkbNewKeyboardNotify nkn;
+ int i,nG,nTG;
+ old_xkb= xkb;
+ xkb= finfo.xkb;
+ dev->key->xkbInfo->desc= xkb;
+ finfo.xkb= old_xkb; /* so it'll get freed automatically */
+
+ *xkb->ctrls= *old_xkb->ctrls;
+ for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ nG= XkbKeyNumGroups(xkb,i);
+ if (nG>=XkbNumKbdGroups) {
+ nTG= XkbNumKbdGroups;
+ break;
+ }
+ if (nG>nTG) {
+ nTG= nG;
+ }
+ }
+ xkb->ctrls->num_groups= nTG;
+
+ memcpy(dev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ XkbUpdateCoreDescription(dev,True);
+
+ if (dev->kbdfeed && dev->kbdfeed->xkb_sli) {
+ XkbSrvLedInfoPtr old_sli;
+ XkbSrvLedInfoPtr sli;
+ old_sli = dev->kbdfeed->xkb_sli;
+ dev->kbdfeed->xkb_sli = NULL;
+ sli = XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,0);
+ if (sli) {
+ sli->explicitState = old_sli->explicitState;
+ sli->effectiveState = old_sli->effectiveState;
+ }
+ dev->kbdfeed->xkb_sli = sli;
+ XkbFreeSrvLedInfo(old_sli);
+ }
+
+ memset(&nkn, 0, sizeof(xkbNewKeyboardNotify));
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= finfo.xkb->min_key_code;
+ nkn.maxKeyCode= finfo.xkb->max_key_code;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbGetKbdByName;
+ nkn.changed= XkbNKN_KeycodesMask;
+ if (geom_changed)
+ nkn.changed|= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ }
+ if ((finfo.xkb!=NULL)&&(finfo.xkb!=xkb)) {
+ XkbFreeKeyboard(finfo.xkb,XkbAllComponentsMask,True);
+ finfo.xkb= NULL;
+ }
+ if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; }
+ if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; }
+ if (names.types) { _XkbFree(names.types); names.types= NULL; }
+ if (names.compat) { _XkbFree(names.compat); names.compat= NULL; }
+ if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; }
+ if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+ComputeDeviceLedInfoSize( DeviceIntPtr dev,
+ unsigned int what,
+ XkbSrvLedInfoPtr sli)
+{
+int nNames,nMaps;
+register unsigned n,bit;
+
+ if (sli==NULL)
+ return 0;
+ nNames= nMaps= 0;
+ if ((what&XkbXI_IndicatorNamesMask)==0)
+ sli->namesPresent= 0;
+ if ((what&XkbXI_IndicatorMapsMask)==0)
+ sli->mapsPresent= 0;
+
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (sli->names && sli->names[n]!=None) {
+ sli->namesPresent|= bit;
+ nNames++;
+ }
+ if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
+ sli->mapsPresent|= bit;
+ nMaps++;
+ }
+ }
+ return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
+}
+
+static int
+CheckDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ xkbGetDeviceInfoReply * rep,
+ ClientPtr client)
+{
+int nFBs= 0;
+int length= 0;
+Bool classOk;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else {
+ client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+ }
+ }
+ classOk= False;
+ if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ classOk= True;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!kf->xkb_sli)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ classOk= True;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!lf->xkb_sli)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if (nFBs>0) {
+ if (rep->supported&XkbXI_IndicatorsMask) {
+ rep->nDeviceLedFBs= nFBs;
+ rep->length+= (length/4);
+ }
+ return Success;
+ }
+ if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
+ else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+}
+
+static int
+SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc wire;
+int length;
+
+ length= 0;
+ wire.ledClass= sli->class;
+ wire.ledID= sli->id;
+ wire.namesPresent= sli->namesPresent;
+ wire.mapsPresent= sli->mapsPresent;
+ wire.physIndicators= sli->physIndicators;
+ wire.state= sli->effectiveState;
+ if (client->swapped) {
+ swaps(&wire.ledClass);
+ swaps(&wire.ledID);
+ swapl(&wire.namesPresent);
+ swapl(&wire.mapsPresent);
+ swapl(&wire.physIndicators);
+ swapl(&wire.state);
+ }
+ WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc), &wire);
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (sli->namesPresent|sli->mapsPresent) {
+ register unsigned i,bit;
+ if (sli->namesPresent) {
+ CARD32 awire;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->namesPresent&bit) {
+ awire= (CARD32)sli->names[i];
+ if (client->swapped) {
+ swapl(&awire);
+ }
+ WriteToClient(client,4, &awire);
+ length+= 4;
+ }
+ }
+ }
+ if (sli->mapsPresent) {
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ xkbIndicatorMapWireDesc iwire;
+ if (sli->mapsPresent&bit) {
+ iwire.flags= sli->maps[i].flags;
+ iwire.whichGroups= sli->maps[i].which_groups;
+ iwire.groups= sli->maps[i].groups;
+ iwire.whichMods= sli->maps[i].which_mods;
+ iwire.mods= sli->maps[i].mods.mask;
+ iwire.realMods= sli->maps[i].mods.real_mods;
+ iwire.virtualMods= sli->maps[i].mods.vmods;
+ iwire.ctrls= sli->maps[i].ctrls;
+ if (client->swapped) {
+ swaps(&iwire.virtualMods);
+ swapl(&iwire.ctrls);
+ }
+ WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
+ (char *)&iwire);
+ length+= SIZEOF(xkbIndicatorMapWireDesc);
+ }
+ }
+ }
+ }
+ return length;
+}
+
+static int
+SendDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ unsigned wantLength,
+ ClientPtr client)
+{
+int length= 0;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ }
+ if ((dev->kbdfeed)&&
+ ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ length+= SendDeviceLedInfo(kf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if ((dev->leds)&&
+ ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ length+= SendDeviceLedInfo(lf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if (length==wantLength)
+ return Success;
+ else return BadLength;
+}
+
+int
+ProcXkbGetDeviceInfo(ClientPtr client)
+{
+DeviceIntPtr dev;
+xkbGetDeviceInfoReply rep;
+int status,nDeviceLedFBs;
+unsigned length,nameLen;
+CARD16 ledClass,ledID;
+unsigned wanted,supported;
+char * str;
+
+ REQUEST(xkbGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ wanted= stuff->wanted;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
+
+ if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
+ wanted&= ~XkbXI_ButtonActionsMask;
+ if ((!dev->kbdfeed)&&(!dev->leds))
+ wanted&= ~XkbXI_IndicatorsMask;
+ wanted&= ~XkbXIUnsupported;
+
+ nameLen= XkbSizeCountedString(dev->name);
+ bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
+ rep.type = X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = nameLen/4;
+ rep.present = wanted;
+ rep.supported = XkbXI_AllDeviceFeaturesMask&(~XkbXIUnsupported);
+ rep.unsupported = XkbXIUnsupported;
+ rep.firstBtnWanted = rep.nBtnsWanted = 0;
+ rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
+ if (dev->button)
+ rep.totalBtns= dev->button->numButtons;
+ else rep.totalBtns= 0;
+ rep.devType= dev->type;
+ rep.hasOwnState= (dev->key && dev->key->xkbInfo);
+ rep.nDeviceLedFBs = 0;
+ if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
+ else rep.dfltKbdFB= XkbXINone;
+ if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
+ else rep.dfltLedFB= XkbXINone;
+
+ ledClass= stuff->ledClass;
+ ledID= stuff->ledID;
+
+ rep.firstBtnWanted= rep.nBtnsWanted= 0;
+ rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
+ if (wanted&XkbXI_ButtonActionsMask) {
+ if (stuff->allBtns) {
+ stuff->firstBtn= 0;
+ stuff->nBtns= dev->button->numButtons;
+ }
+
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
+ stuff->firstBtn,
+ stuff->nBtns);
+ return BadValue;
+ }
+ else {
+ rep.firstBtnWanted= stuff->firstBtn;
+ rep.nBtnsWanted= stuff->nBtns;
+ if (dev->button->xkb_acts!=NULL) {
+ XkbAction *act;
+ register int i;
+
+ rep.firstBtnRtrn= stuff->firstBtn;
+ rep.nBtnsRtrn= stuff->nBtns;
+ act= &dev->button->xkb_acts[rep.firstBtnWanted];
+ for (i=0;i<rep.nBtnsRtrn;i++,act++) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.firstBtnRtrn+= i;
+ rep.nBtnsRtrn-= i;
+ act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
+ for (i=0;i<rep.nBtnsRtrn;i++,act--) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.nBtnsRtrn-= i;
+ }
+ rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
+ }
+ }
+
+ if (wanted&XkbXI_IndicatorsMask) {
+ status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
+ if (status!=Success)
+ return status;
+ }
+ length= rep.length*4;
+ supported= rep.supported;
+ nDeviceLedFBs = rep.nDeviceLedFBs;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.present);
+ swaps(&rep.supported);
+ swaps(&rep.unsupported);
+ swaps(&rep.nDeviceLedFBs);
+
+ // FIXME: rep.type here is an Atom... this might go terribly wrong...
+
+ swapl((int *)&rep.type);
+ }
+ WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), &rep);
+
+ str= (char*) malloc(nameLen);
+ if (!str)
+ return BadAlloc;
+ XkbWriteCountedString(str,dev->name,client->swapped);
+ WriteToClient(client,nameLen,str);
+ free(str);
+ length-= nameLen;
+
+ if (rep.nBtnsRtrn>0) {
+ int sz;
+ xkbActionWireDesc * awire;
+ sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
+ awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
+ WriteToClient(client,sz, awire);
+ length-= sz;
+ }
+ if (nDeviceLedFBs>0) {
+ status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
+ if (status!=Success)
+ return status;
+ }
+ else if (length!=0) {
+#ifdef DEBUG
+ ErrorF("Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
+ ErrorF(" Wrote %d fewer bytes than expected\n",length);
+#endif
+ return BadLength;
+ }
+ if (stuff->wanted&(~supported)) {
+ xkbExtensionDeviceNotify ed;
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.ledClass= ledClass;
+ ed.ledID= ledID;
+ ed.ledsDefined= 0;
+ ed.ledState= 0;
+ ed.firstBtn= ed.nBtns= 0;
+ ed.reason= XkbXI_UnsupportedFeatureMask;
+ ed.supported= supported;
+ ed.unsupported= stuff->wanted&(~supported);
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ }
+ return client->noClientException;
+}
+
+static char *
+CheckSetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ int num,
+ int * status_rtrn,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbSrvLedInfoPtr sli;
+
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ if (client->swapped) {
+ swaps(&ledWire->ledClass);
+ swaps(&ledWire->ledID);
+ swapl(&ledWire->namesPresent);
+ swapl(&ledWire->mapsPresent);
+ swapl(&ledWire->physIndicators);
+ }
+
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorsMask);
+ if (sli!=NULL) {
+ register int n;
+ register unsigned bit;
+ int nMaps,nNames;
+ CARD32 *atomWire;
+ xkbIndicatorMapWireDesc *mapWire;
+
+ nMaps= nNames= 0;
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit)
+ nNames++;
+ if (ledWire->mapsPresent&bit)
+ nMaps++;
+ }
+ atomWire= (CARD32 *)&ledWire[1];
+ if (nNames>0) {
+ for (n=0;n<nNames;n++) {
+ if (client->swapped) {
+ swapl(atomWire);
+ }
+ CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
+ *status_rtrn,NULL);
+ atomWire++;
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (nMaps>0) {
+ for (n=0;n<nMaps;n++) {
+ if (client->swapped) {
+ swaps(&mapWire->virtualMods);
+ swapl(&mapWire->ctrls);
+ }
+ CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
+ XkbIM_UseAnyGroup,
+ client->errorValue,
+ *status_rtrn,NULL);
+ CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
+ client->errorValue,
+ *status_rtrn,NULL);
+ mapWire++;
+ }
+ }
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ else {
+ /* SHOULD NEVER HAPPEN */
+ return (char *)ledWire;
+ }
+ }
+ return (char *)ledWire;
+}
+
+static char *
+SetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ unsigned changed,
+ int num,
+ int * status_rtrn,
+ ClientPtr client,
+ xkbExtensionDeviceNotify *ev)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbEventCauseRec cause;
+unsigned namec,mapc,statec;
+xkbExtensionDeviceNotify ed;
+XkbChangesRec changes;
+DeviceIntPtr kbd;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ register int n;
+ register unsigned bit;
+ CARD32 * atomWire;
+ xkbIndicatorMapWireDesc * mapWire;
+ XkbSrvLedInfoPtr sli;
+
+ namec= mapc= statec= 0;
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorMapsMask);
+ if (!sli) {
+ /* SHOULD NEVER HAPPEN!! */
+ return (char *)ledWire;
+ }
+
+ atomWire= (CARD32 *)&ledWire[1];
+ if (changed&XkbXI_IndicatorNamesMask) {
+ namec= sli->namesPresent|ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ }
+ if (ledWire->namesPresent) {
+ sli->namesPresent= ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit) {
+ sli->names[n]= (Atom)*atomWire;
+ if (sli->names[n]==None)
+ ledWire->namesPresent&= ~bit;
+ atomWire++;
+ }
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (changed&XkbXI_IndicatorMapsMask) {
+ mapc= sli->mapsPresent|ledWire->mapsPresent;
+ sli->mapsPresent= ledWire->mapsPresent;
+ bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
+ }
+ if (ledWire->mapsPresent) {
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->mapsPresent&bit) {
+ sli->maps[n].flags= mapWire->flags;
+ sli->maps[n].which_groups= mapWire->whichGroups;
+ sli->maps[n].groups= mapWire->groups;
+ sli->maps[n].which_mods= mapWire->whichMods;
+ sli->maps[n].mods.mask= mapWire->mods;
+ sli->maps[n].mods.real_mods=mapWire->realMods;
+ sli->maps[n].mods.vmods= mapWire->virtualMods;
+ sli->maps[n].ctrls= mapWire->ctrls;
+ mapWire++;
+ }
+ }
+ }
+ if (changed&XkbXI_IndicatorStateMask) {
+ statec= sli->effectiveState^ledWire->state;
+ sli->explicitState&= ~statec;
+ sli->explicitState|= (ledWire->state&statec);
+ }
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ return (char *)ledWire;
+}
+
+int
+ProcXkbSetDeviceInfo(ClientPtr client)
+{
+DeviceIntPtr dev;
+unsigned change;
+char * wire;
+xkbExtensionDeviceNotify ed;
+
+ REQUEST(xkbSetDeviceInfoReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ change= stuff->change;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,change,(XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask)));
+
+ wire= (char *)&stuff[1];
+ if (change&XkbXI_ButtonActionsMask) {
+ if (!dev->button) {
+ client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
+ return XkbKeyboardErrorCode;
+ }
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
+ dev->button->numButtons);
+ return BadMatch;
+ }
+ wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
+ &status,client);
+ if (status!=Success)
+ return status;
+ }
+ if (((wire-((char *)stuff))/4)!=stuff->length)
+ return BadLength;
+
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ wire= (char *)&stuff[1];
+ if (change&XkbXI_ButtonActionsMask) {
+ int nBtns,sz,i;
+ XkbAction * acts;
+ DeviceIntPtr kbd;
+
+ nBtns= dev->button->numButtons;
+ acts= dev->button->xkb_acts;
+ if (acts==NULL) {
+ acts= _XkbTypedCalloc(nBtns,XkbAction);
+ if (!acts)
+ return BadAlloc;
+ dev->button->xkb_acts= acts;
+ }
+ sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
+ memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
+ wire+= sz;
+ ed.reason|= XkbXI_ButtonActionsMask;
+ ed.firstBtn= stuff->firstBtn;
+ ed.nBtns= stuff->nBtns;
+
+ if (dev->key) kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ acts= &dev->button->xkb_acts[stuff->firstBtn];
+ for (i=0;i<stuff->nBtns;i++,acts++) {
+ if (acts->type!=XkbSA_NoAction)
+ XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
+ }
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= SetDeviceIndicators(wire,dev,change,stuff->nDeviceLedFBs,
+ &status,client,&ed);
+ if (status!=Success)
+ return status;
+ }
+ if ((stuff->change)&&(ed.reason))
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSetDebuggingFlags(ClientPtr client)
+{
+CARD32 newFlags,newCtrls,extraLength;
+xkbSetDebuggingFlagsReply rep;
+
+ REQUEST(xkbSetDebuggingFlagsReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+
+ newFlags= xkbDebugFlags&(~stuff->affectFlags);
+ newFlags|= (stuff->flags&stuff->affectFlags);
+ newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
+ newCtrls|= (stuff->ctrls&stuff->affectCtrls);
+ if (xkbDebugFlags || newFlags || stuff->msgLength) {
+ ErrorF("XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags);
+ if (newCtrls!=xkbDebugCtrls)
+ ErrorF("XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls);
+ }
+ extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
+ if (stuff->msgLength>0) {
+ char *msg;
+ if (extraLength<XkbPaddedSize(stuff->msgLength)) {
+ ErrorF("XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
+ stuff->msgLength,(long)extraLength,
+ XkbPaddedSize(stuff->msgLength));
+ return BadLength;
+ }
+ msg= (char *)&stuff[1];
+ if (msg[stuff->msgLength-1]!='\0') {
+ ErrorF("XkbDebug: message not null-terminated\n");
+ return BadValue;
+ }
+ ErrorF("XkbDebug: %s\n",msg);
+ }
+ xkbDebugFlags = newFlags;
+ xkbDebugCtrls = newCtrls;
+
+ XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks);
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.currentFlags = newFlags;
+ rep.currentCtrls = newCtrls;
+ rep.supportedFlags = ~0;
+ rep.supportedCtrls = ~0;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.currentFlags);
+ swapl(&rep.currentCtrls);
+ swapl(&rep.supportedFlags);
+ swapl(&rep.supportedCtrls);
+ }
+ WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), &rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+ProcXkbDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return ProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return ProcXkbSelectEvents(client);
+ case X_kbBell:
+ return ProcXkbBell(client);
+ case X_kbGetState:
+ return ProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return ProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return ProcXkbGetControls(client);
+ case X_kbSetControls:
+ return ProcXkbSetControls(client);
+ case X_kbGetMap:
+ return ProcXkbGetMap(client);
+ case X_kbSetMap:
+ return ProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return ProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return ProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return ProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return ProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return ProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return ProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return ProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return ProcXkbGetNames(client);
+ case X_kbSetNames:
+ return ProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return ProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return ProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return ProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return ProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return ProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return ProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return ProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return ProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+XkbClientGone(void * data,XID id)
+{
+ DevicePtr pXDev = (DevicePtr)data;
+
+ if (!XkbRemoveResourceClient(pXDev,id)) {
+ ErrorF("Internal Error! bad RemoveResourceClient in XkbClientGone\n");
+ }
+ return 1;
+}
+
+/*ARGSUSED*/
+static void
+XkbResetProc(ExtensionEntry *extEntry)
+{
+}
+
+void
+XkbExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
+ ProcXkbDispatch, SProcXkbDispatch,
+ XkbResetProc, StandardMinorOpcode))) {
+ XkbReqCode = (unsigned char)extEntry->base;
+ XkbEventBase = (unsigned char)extEntry->eventBase;
+ XkbErrorBase = (unsigned char)extEntry->errorBase;
+ XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
+ RT_XKBCLIENT = CreateNewResourceType(XkbClientGone);
+ }
+ return;
+}
+
+
diff --git a/nx-X11/programs/Xserver/xkb/xkb.h b/nx-X11/programs/Xserver/xkb/xkb.h
new file mode 100644
index 000000000..7bf3a9c61
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkb.h
@@ -0,0 +1,70 @@
+extern int ProcXkbUseExtension(ClientPtr client);
+extern int ProcXkbSelectEvents(ClientPtr client);
+extern int ProcXkbBell(ClientPtr client);
+extern int ProcXkbGetState(ClientPtr client);
+extern int ProcXkbLatchLockState(ClientPtr client);
+extern int ProcXkbGetControls(ClientPtr client);
+extern int ProcXkbSetControls(ClientPtr client);
+extern int ProcXkbGetMap(ClientPtr client);
+extern int ProcXkbSetMap(ClientPtr client);
+extern int ProcXkbGetCompatMap(ClientPtr client);
+extern int ProcXkbSetCompatMap(ClientPtr client);
+extern int ProcXkbGetIndicatorState(ClientPtr client);
+extern int ProcXkbGetIndicatorMap(ClientPtr client);
+extern int ProcXkbSetIndicatorMap(ClientPtr client);
+extern int ProcXkbGetNamedIndicator(ClientPtr client);
+extern int ProcXkbSetNamedIndicator(ClientPtr client);
+extern int ProcXkbGetNames(ClientPtr client);
+extern int ProcXkbSetNames(ClientPtr client);
+extern int ProcXkbGetGeometry(ClientPtr client);
+extern int ProcXkbSetGeometry(ClientPtr client);
+extern int ProcXkbPerClientFlags(ClientPtr client);
+extern int ProcXkbListComponents(ClientPtr client);
+extern int ProcXkbGetKbdByName(ClientPtr client);
+extern int ProcXkbGetDeviceInfo(ClientPtr client);
+extern int ProcXkbSetDeviceInfo(ClientPtr client);
+extern int ProcXkbSetDebuggingFlags(ClientPtr client);
+
+extern int XkbSetRepeatRate(DeviceIntPtr dev, int timeout, int interval, int major, int minor);
+extern int XkbGetRepeatRate(DeviceIntPtr dev, int *timeout, int *interval);
+
+extern void XkbExtensionInit(void);
+
+extern Status XkbComputeGetIndicatorMapReplySize(
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep);
+extern int XkbSendIndicatorMap(
+ ClientPtr client,
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep);
+
+extern void XkbComputeCompatState(XkbSrvInfoPtr xkbi);
+extern void XkbSetPhysicalLockingKey(DeviceIntPtr dev, unsigned key);
+
+extern Bool XkbFilterEvents(ClientPtr pClient, int nEvents, xEvent *xE);
+
+extern Bool XkbApplyLEDChangeToKeyboard(
+ XkbSrvInfoPtr xkbi,
+ XkbIndicatorMapPtr map,
+ Bool on,
+ XkbChangesPtr change);
+
+extern Bool XkbWriteRulesProp(ClientPtr client, void * closure);
+
+extern XkbAction XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button);
+
+/* extern Status XkbMergeFile(XkbDescPtr xkb, XkbFileInfo finfo); */
+
+extern Bool XkbDDXCompileNamedKeymap(
+ XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ char * nameRtrn,
+ int nameRtrnLen);
+
+extern Bool XkbDDXCompileKeymapByNames(
+ XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ char * nameRtrn,
+ int nameRtrnLen);
diff --git a/nx-X11/programs/Xserver/xkb/xkbAccessX.c b/nx-X11/programs/Xserver/xkb/xkbAccessX.c
new file mode 100644
index 000000000..4069ac209
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbAccessX.c
@@ -0,0 +1,744 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "inputstr.h"
+#include <xkbsrv.h>
+#if !defined(WIN32)
+#include <sys/time.h>
+#endif
+
+int XkbDfltRepeatDelay= 660;
+int XkbDfltRepeatInterval= 40;
+void * XkbLastRepeatEvent= NULL;
+
+#define DFLT_TIMEOUT_CTRLS (XkbAX_KRGMask|XkbStickyKeysMask|XkbMouseKeysMask)
+#define DFLT_TIMEOUT_OPTS (XkbAX_IndicatorFBMask)
+
+unsigned short XkbDfltAccessXTimeout= 120;
+unsigned int XkbDfltAccessXTimeoutMask= DFLT_TIMEOUT_CTRLS;
+unsigned int XkbDfltAccessXTimeoutValues= 0;
+unsigned int XkbDfltAccessXTimeoutOptionsMask= DFLT_TIMEOUT_OPTS;
+unsigned int XkbDfltAccessXTimeoutOptionsValues= 0;
+unsigned int XkbDfltAccessXFeedback= XkbAccessXFeedbackMask;
+unsigned short XkbDfltAccessXOptions= XkbAX_AllOptionsMask & ~(XkbAX_IndicatorFBMask|XkbAX_SKReleaseFBMask|XkbAX_SKRejectFBMask);
+
+void
+AccessXComputeCurveFactor(XkbSrvInfoPtr xkbi,XkbControlsPtr ctrls)
+{
+ xkbi->mouseKeysCurve= 1.0+(((double)ctrls->mk_curve)*0.001);
+ xkbi->mouseKeysCurveFactor= ( ((double)ctrls->mk_max_speed)/
+ pow((double)ctrls->mk_time_to_max,xkbi->mouseKeysCurve));
+ return;
+}
+
+void
+AccessXInit(DeviceIntPtr keybd)
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+
+ xkbi->shiftKeyCount= 0;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->inactiveKey= 0;
+ xkbi->slowKey= 0;
+ xkbi->repeatKey= 0;
+ xkbi->krgTimerActive= _OFF_TIMER;
+ xkbi->beepType= _BEEP_NONE;
+ xkbi->beepCount= 0;
+ xkbi->mouseKeyTimer= NULL;
+ xkbi->slowKeysTimer= NULL;
+ xkbi->bounceKeysTimer= NULL;
+ xkbi->repeatKeyTimer= NULL;
+ xkbi->krgTimer= NULL;
+ xkbi->beepTimer= NULL;
+ ctrls->repeat_delay = XkbDfltRepeatDelay;
+ ctrls->repeat_interval = XkbDfltRepeatInterval;
+ ctrls->debounce_delay = 300;
+ ctrls->slow_keys_delay = 300;
+ ctrls->mk_delay = 160;
+ ctrls->mk_interval = 40;
+ ctrls->mk_time_to_max = 30;
+ ctrls->mk_max_speed = 30;
+ ctrls->mk_curve = 500;
+ ctrls->mk_dflt_btn = 1;
+ ctrls->ax_timeout = XkbDfltAccessXTimeout;
+ ctrls->axt_ctrls_mask = XkbDfltAccessXTimeoutMask;
+ ctrls->axt_ctrls_values = XkbDfltAccessXTimeoutValues;
+ ctrls->axt_opts_mask = XkbDfltAccessXTimeoutOptionsMask;
+ ctrls->axt_opts_values = XkbDfltAccessXTimeoutOptionsValues;
+ if (XkbDfltAccessXTimeout)
+ ctrls->enabled_ctrls |= XkbAccessXTimeoutMask;
+ else
+ ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask;
+ ctrls->enabled_ctrls |= XkbDfltAccessXFeedback;
+ ctrls->ax_options = XkbDfltAccessXOptions;
+ AccessXComputeCurveFactor(xkbi,ctrls);
+ return;
+}
+
+/************************************************************************/
+/* */
+/* AccessXKeyboardEvent */
+/* */
+/* Generate a synthetic keyboard event. */
+/* */
+/************************************************************************/
+static void
+AccessXKeyboardEvent(DeviceIntPtr keybd,
+ BYTE type,
+ BYTE keyCode,
+ Bool isRepeat)
+{
+xEvent xE;
+
+ xE.u.u.type = type;
+ xE.u.u.detail = keyCode;
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ ErrorF("AXKE: Key %d %s\n",keyCode,(xE.u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+
+ if (_XkbIsPressEvent(type))
+ XkbDDXKeyClick(keybd,keyCode,TRUE);
+ else if (isRepeat)
+ XkbLastRepeatEvent= (void *)&xE;
+ XkbProcessKeyboardEvent(&xE,keybd,1L);
+ XkbLastRepeatEvent= NULL;
+ return;
+
+} /* AccessXKeyboardEvent */
+
+/************************************************************************/
+/* */
+/* AccessXKRGTurnOn */
+/* */
+/* Turn the keyboard response group on. */
+/* */
+/************************************************************************/
+static void
+AccessXKRGTurnOn(DeviceIntPtr dev,CARD16 KRGControl,xkbControlsNotify *pCN)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old= *ctrls;
+ ctrls->enabled_ctrls |= (KRGControl&XkbAX_KRGMask);
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,KRGControl);
+ return;
+
+} /* AccessXKRGTurnOn */
+
+/************************************************************************/
+/* */
+/* AccessXKRGTurnOff */
+/* */
+/* Turn the keyboard response group off. */
+/* */
+/************************************************************************/
+static void
+AccessXKRGTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls &= ~XkbAX_KRGMask;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ unsigned changes= old.enabled_ctrls^ctrls->enabled_ctrls;
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,changes);
+ }
+ return;
+
+} /* AccessXKRGTurnOff */
+
+/************************************************************************/
+/* */
+/* AccessXStickyKeysTurnOn */
+/* */
+/* Turn StickyKeys on. */
+/* */
+/************************************************************************/
+static void
+AccessXStickyKeysTurnOn(DeviceIntPtr dev,xkbControlsNotify *pCN)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls |= XkbStickyKeysMask;
+ xkbi->shiftKeyCount = 0;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,XkbStickyKeysMask);
+ }
+ return;
+
+} /* AccessXStickyKeysTurnOn */
+
+/************************************************************************/
+/* */
+/* AccessXStickyKeysTurnOff */
+/* */
+/* Turn StickyKeys off. */
+/* */
+/************************************************************************/
+static void
+AccessXStickyKeysTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls &= ~XkbStickyKeysMask;
+ xkbi->shiftKeyCount = 0;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,XkbStickyKeysMask);
+ }
+#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF
+ XkbClearAllLatchesAndLocks(dev,xkbi,False,&cause);
+#endif
+ return;
+} /* AccessXStickyKeysTurnOff */
+
+static CARD32
+AccessXKRGExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+xkbControlsNotify cn;
+
+ if (xkbi->krgTimerActive==_KRG_WARN_TIMER) {
+ XkbDDXAccessXBeep((DeviceIntPtr)arg,_BEEP_SLOW_WARN,XkbStickyKeysMask);
+ xkbi->krgTimerActive= _KRG_TIMER;
+ return 4000;
+ }
+ xkbi->krgTimerActive= _OFF_TIMER;
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbSlowKeysMask)
+ AccessXKRGTurnOff((DeviceIntPtr)arg,&cn);
+ else AccessXKRGTurnOn((DeviceIntPtr)arg,XkbSlowKeysMask,&cn);
+ return 0;
+}
+
+static CARD32
+AccessXRepeatKeyExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+KeyCode key;
+
+ if (xkbi->repeatKey==0)
+ return 0;
+ key= xkbi->repeatKey;
+ AccessXKeyboardEvent((DeviceIntPtr)arg,KeyRelease,key,True);
+ AccessXKeyboardEvent((DeviceIntPtr)arg,KeyPress,key,True);
+ return xkbi->desc->ctrls->repeat_interval;
+}
+
+void
+AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi,KeyCode key)
+{
+ if (xkbi->repeatKey==key)
+ xkbi->repeatKey= 0;
+ return;
+}
+
+static CARD32
+AccessXSlowKeyExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+DeviceIntPtr keybd;
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ keybd= (DeviceIntPtr)arg;
+ xkbi= keybd->key->xkbInfo;
+ xkb= xkbi->desc;
+ ctrls= xkb->ctrls;
+ if (xkbi->slowKey!=0) {
+ xkbAccessXNotify ev;
+ KeySym *sym= XkbKeySymsPtr(xkb,xkbi->slowKey);
+ ev.detail= XkbAXN_SKAccept;
+ ev.keycode= xkbi->slowKey;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask);
+ AccessXKeyboardEvent(keybd,KeyPress,xkbi->slowKey,False);
+ /* check for magic sequences */
+ if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) &&
+ ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)))
+ xkbi->shiftKeyCount++;
+
+ /* Start repeating if necessary. Stop autorepeating if the user
+ * presses a non-modifier key that doesn't autorepeat.
+ */
+ if (keybd->kbdfeed->ctrl.autoRepeat &&
+ ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) &&
+ (ctrls->enabled_ctrls&XkbRepeatKeysMask)) {
+ if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey))
+ {
+ xkbi->repeatKey = xkbi->slowKey;
+ xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
+ 0, ctrls->repeat_delay,
+ AccessXRepeatKeyExpire, (void *)keybd);
+ }
+ }
+ }
+ return 0;
+}
+
+static CARD32
+AccessXBounceKeyExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+
+ xkbi->inactiveKey= 0;
+ return 0;
+}
+
+static CARD32
+AccessXTimeoutExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+DeviceIntPtr dev = (DeviceIntPtr)arg;
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+XkbControlsRec old;
+xkbControlsNotify cn;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ if (xkbi->lastPtrEventTime) {
+ unsigned timeToWait = (ctrls->ax_timeout*1000);
+ unsigned timeElapsed = (now-xkbi->lastPtrEventTime);
+
+ if (timeToWait > timeElapsed)
+ return (timeToWait - timeElapsed);
+ }
+ old= *ctrls;
+ xkbi->shiftKeyCount= 0;
+ ctrls->enabled_ctrls&= ~ctrls->axt_ctrls_mask;
+ ctrls->enabled_ctrls|=
+ (ctrls->axt_ctrls_values&ctrls->axt_ctrls_mask);
+ if (ctrls->axt_opts_mask) {
+ ctrls->ax_options&= ~ctrls->axt_opts_mask;
+ ctrls->ax_options|= (ctrls->axt_opts_values&ctrls->axt_opts_mask);
+ }
+ if (XkbComputeControlsNotify(dev,&old,ctrls,&cn,False)) {
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ XkbSetCauseUnknown(&cause);
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (ctrls->ax_options!=old.ax_options) {
+ unsigned set,cleared,bell;
+ set= ctrls->ax_options&(~old.ax_options);
+ cleared= (~ctrls->ax_options)&old.ax_options;
+ if (set && cleared) bell= _BEEP_FEATURE_CHANGE;
+ else if (set) bell= _BEEP_FEATURE_ON;
+ else bell= _BEEP_FEATURE_OFF;
+ XkbDDXAccessXBeep(dev,bell,XkbAccessXTimeoutMask);
+ }
+ xkbi->krgTimerActive= _OFF_TIMER;
+ return 0;
+}
+
+
+/************************************************************************/
+/* */
+/* AccessXFilterPressEvent */
+/* */
+/* Filter events before they get any further if SlowKeys is turned on. */
+/* In addition, this routine handles the ever so popular magic key */
+/* acts for turning various accessibility features on/off. */
+/* */
+/* Returns TRUE if this routine has discarded the event. */
+/* Returns FALSE if the event needs further processing. */
+/* */
+/************************************************************************/
+Bool
+AccessXFilterPressEvent( register xEvent * xE,
+ register DeviceIntPtr keybd,
+ int count)
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+Bool ignoreKeyEvent = FALSE;
+KeyCode key = xE->u.u.detail;
+KeySym * sym = XkbKeySymsPtr(xkbi->desc,key);
+
+ if (ctrls->enabled_ctrls&XkbAccessXKeysMask) {
+ /* check for magic sequences */
+ if ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)) {
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SlowWarnFBMask)) {
+ xkbi->krgTimerActive = _KRG_WARN_TIMER;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 4000,
+ AccessXKRGExpire, (void *)keybd);
+ }
+ else {
+ xkbi->krgTimerActive = _KRG_TIMER;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 8000,
+ AccessXKRGExpire, (void *)keybd);
+ }
+ if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) {
+ CARD32 now= GetTimeInMillis();
+ if ((now-xkbi->lastShiftEventTime)>15000)
+ xkbi->shiftKeyCount= 1;
+ else xkbi->shiftKeyCount++;
+ xkbi->lastShiftEventTime= now;
+ }
+ }
+ else {
+ if (xkbi->krgTimerActive) {
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer,0, 0, NULL, NULL);
+ xkbi->krgTimerActive= _OFF_TIMER;
+ }
+ }
+ }
+
+ /* Don't transmit the KeyPress if SlowKeys is turned on;
+ * The wakeup handler will synthesize one for us if the user
+ * has held the key long enough.
+ */
+ if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
+ xkbAccessXNotify ev;
+ /* If key was already pressed, ignore subsequent press events
+ * from the server's autorepeat
+ */
+ if(xkbi->slowKey == key)
+ return TRUE;
+ ev.detail= XkbAXN_SKPress;
+ ev.keycode= key;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKPressFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_SLOW_PRESS,XkbSlowKeysMask);
+ xkbi->slowKey= key;
+ xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer,
+ 0, ctrls->slow_keys_delay,
+ AccessXSlowKeyExpire, (void *)keybd);
+ ignoreKeyEvent = TRUE;
+ }
+
+ /* Don't transmit the KeyPress if BounceKeys is turned on
+ * and the user pressed the same key within a given time period
+ * from the last release.
+ */
+ else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) &&
+ (key == xkbi->inactiveKey)) {
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_BKRejectFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_BOUNCE_REJECT,XkbBounceKeysMask);
+ ignoreKeyEvent = TRUE;
+ }
+
+ /* Start repeating if necessary. Stop autorepeating if the user
+ * presses a non-modifier key that doesn't autorepeat.
+ */
+ if (XkbDDXUsesSoftRepeat(keybd)) {
+ if ((keybd->kbdfeed->ctrl.autoRepeat) &&
+ ((ctrls->enabled_ctrls&(XkbSlowKeysMask|XkbRepeatKeysMask))==
+ XkbRepeatKeysMask)) {
+ if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key))
+ {
+#ifdef DEBUG
+ if (xkbDebugFlags&0x10)
+ ErrorF("Starting software autorepeat...\n");
+#endif
+ xkbi->repeatKey = key;
+ xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
+ 0, ctrls->repeat_delay,
+ AccessXRepeatKeyExpire, (void *)keybd);
+ }
+ }
+ }
+
+ /* Check for two keys being pressed at the same time. This section
+ * essentially says the following:
+ *
+ * If StickyKeys is on, and a modifier is currently being held down,
+ * and one of the following is true: the current key is not a modifier
+ * or the currentKey is a modifier, but not the only modifier being
+ * held down, turn StickyKeys off if the TwoKeys off ctrl is set.
+ */
+ if ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
+ (xkbi->state.base_mods!=0) &&
+ (XkbAX_NeedOption(ctrls,XkbAX_TwoKeysMask))) {
+ xkbControlsNotify cn;
+ cn.keycode = key;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ AccessXStickyKeysTurnOff(keybd,&cn);
+ }
+
+ if (!ignoreKeyEvent)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ return ignoreKeyEvent;
+} /* AccessXFilterPressEvent */
+
+/************************************************************************/
+/* */
+/* AccessXFilterReleaseEvent */
+/* */
+/* Filter events before they get any further if SlowKeys is turned on. */
+/* In addition, this routine handles the ever so popular magic key */
+/* acts for turning various accessibility features on/off. */
+/* */
+/* Returns TRUE if this routine has discarded the event. */
+/* Returns FALSE if the event needs further processing. */
+/* */
+/************************************************************************/
+Bool
+AccessXFilterReleaseEvent( register xEvent * xE,
+ register DeviceIntPtr keybd,
+ int count)
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+KeyCode key = xE->u.u.detail;
+Bool ignoreKeyEvent = FALSE;
+
+ /* Don't transmit the KeyRelease if BounceKeys is on and
+ * this is the release of a key that was ignored due to
+ * BounceKeys.
+ */
+ if (ctrls->enabled_ctrls & XkbBounceKeysMask) {
+ if ((key!=xkbi->mouseKey)&&(!BitIsOn(keybd->key->down,key)))
+ ignoreKeyEvent = TRUE;
+ xkbi->inactiveKey= key;
+ xkbi->bounceKeysTimer= TimerSet(xkbi->bounceKeysTimer, 0,
+ ctrls->debounce_delay,
+ AccessXBounceKeyExpire, (void *)keybd);
+ }
+
+ /* Don't transmit the KeyRelease if SlowKeys is turned on and
+ * the user didn't hold the key long enough. We know we passed
+ * the key if the down bit was set by CoreProcessKeyboadEvent.
+ */
+ if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
+ xkbAccessXNotify ev;
+ unsigned beep_type;
+ ev.keycode= key;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ if (BitIsOn(keybd->key->down,key) | (xkbi->mouseKey == key)) {
+ ev.detail= XkbAXN_SKRelease;
+ beep_type= _BEEP_SLOW_RELEASE;
+ }
+ else {
+ ev.detail= XkbAXN_SKReject;
+ beep_type= _BEEP_SLOW_REJECT;
+ ignoreKeyEvent = TRUE;
+ }
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKRejectFBMask)) {
+ XkbDDXAccessXBeep(keybd,beep_type,XkbSlowKeysMask);
+ }
+ if (xkbi->slowKey==key)
+ xkbi->slowKey= 0;
+ }
+
+ /* Stop Repeating if the user releases the key that is currently
+ * repeating.
+ */
+ if (xkbi->repeatKey==key) {
+ xkbi->repeatKey= 0;
+ }
+
+ if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) {
+ xkbi->lastPtrEventTime= 0;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0,
+ ctrls->ax_timeout*1000,
+ AccessXTimeoutExpire, (void *)keybd);
+ xkbi->krgTimerActive= _ALL_TIMEOUT_TIMER;
+ }
+ else if (xkbi->krgTimerActive!=_OFF_TIMER) {
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL);
+ xkbi->krgTimerActive= _OFF_TIMER;
+ }
+
+ /* Keep track of how many times the Shift key has been pressed.
+ * If it has been pressed and released 5 times in a row, toggle
+ * the state of StickyKeys.
+ */
+ if ((!ignoreKeyEvent)&&(xkbi->shiftKeyCount)) {
+ KeySym *pSym= XkbKeySymsPtr(xkbi->desc,key);
+ if ((pSym[0]!=XK_Shift_L)&&(pSym[0]!=XK_Shift_R)) {
+ xkbi->shiftKeyCount= 0;
+ }
+ else if (xkbi->shiftKeyCount>=5) {
+ xkbControlsNotify cn;
+ cn.keycode = key;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ if (ctrls->enabled_ctrls & XkbStickyKeysMask)
+ AccessXStickyKeysTurnOff(keybd,&cn);
+ else
+ AccessXStickyKeysTurnOn(keybd,&cn);
+ xkbi->shiftKeyCount= 0;
+ }
+ }
+
+ if (!ignoreKeyEvent)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ return ignoreKeyEvent;
+
+} /* AccessXFilterReleaseEvent */
+
+/************************************************************************/
+/* */
+/* ProcessPointerEvent */
+/* */
+/* This routine merely sets the shiftKeyCount and clears the keyboard */
+/* response group timer (if necessary) on a mouse event. This is so */
+/* multiple shifts with just the mouse and shift-drags with the mouse */
+/* don't accidentally turn on StickyKeys or the Keyboard Response Group.*/
+/* */
+/************************************************************************/
+void
+ProcessPointerEvent( register xEvent * xE,
+ register DeviceIntPtr mouse,
+ int count)
+{
+DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice();
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+unsigned changed = 0;
+
+ xkbi->shiftKeyCount = 0;
+ xkbi->lastPtrEventTime= xE->u.keyButtonPointer.time;
+
+ if (xE->u.u.type==ButtonPress) {
+ changed |= XkbPointerButtonMask;
+ }
+ else if (xE->u.u.type==ButtonRelease) {
+ xkbi->lockedPtrButtons&= ~(1<<(xE->u.u.detail&0x7));
+ changed |= XkbPointerButtonMask;
+ }
+ CoreProcessPointerEvent(xE,mouse,count);
+
+ xkbi->state.ptr_buttons = mouse->button->state;
+
+ /* clear any latched modifiers */
+ if ( xkbi->state.latched_mods && (xE->u.u.type==ButtonRelease) ) {
+ unsigned changed_leds;
+ XkbStateRec oldState;
+ XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ oldState= xkbi->state;
+ XkbLatchModifiers(dev,0xFF,0x00);
+
+ XkbComputeDerivedState(xkbi);
+ changed |= XkbStateChangedFlags(&oldState,&xkbi->state);
+ if (changed&sli->usedComponents) {
+ changed_leds= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed_leds) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause,(xE->u.u.detail&0x7),xE->u.u.type);
+ XkbUpdateIndicators(dev,changed_leds,True,NULL,&cause);
+ }
+ }
+ dev->key->state= XkbStateFieldFromRec(&xkbi->state);
+ }
+
+ if (((xkbi->flags&_XkbStateNotifyInProgress)==0)&&(changed!=0)) {
+ xkbStateNotify sn;
+ sn.keycode= xE->u.u.detail;
+ sn.eventType= xE->u.u.type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+
+} /* ProcessPointerEvent */
+
+
+
+
diff --git a/nx-X11/programs/Xserver/xkb/xkbActions.c b/nx-X11/programs/Xserver/xkb/xkbActions.c
new file mode 100644
index 000000000..3dd09e08d
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbActions.c
@@ -0,0 +1,1428 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+#include <ctype.h>
+
+static unsigned int _xkbServerGeneration;
+int xkbDevicePrivateIndex = -1;
+
+void
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
+ void * data)
+{
+ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+ ProcessInputProc tmp = device->public.processInputProc;
+ if(xkbPrivPtr->unwrapProc)
+ xkbPrivPtr->unwrapProc = NULL;
+
+ UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr);
+ proc(device,data);
+ WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ tmp,xkbUnwrapProc);
+}
+
+
+void
+XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
+{
+ xkbDeviceInfoPtr xkbPrivPtr;
+
+ if (serverGeneration != _xkbServerGeneration) {
+ if ((xkbDevicePrivateIndex = AllocateDevicePrivateIndex()) == -1)
+ return;
+ _xkbServerGeneration = serverGeneration;
+ }
+ if (!AllocateDevicePrivate(device, xkbDevicePrivateIndex))
+ return;
+
+ xkbPrivPtr = (xkbDeviceInfoPtr) malloc(sizeof(xkbDeviceInfoRec));
+ if (!xkbPrivPtr)
+ return;
+ xkbPrivPtr->unwrapProc = NULL;
+
+ device->devPrivates[xkbDevicePrivateIndex].ptr = xkbPrivPtr;
+ WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ proc,xkbUnwrapProc);
+}
+
+#ifdef XINPUT
+extern void ProcessOtherEvent(
+ xEvent * /* xE */,
+ DeviceIntPtr /* dev */,
+ int /* count */
+);
+#endif
+
+/***====================================================================***/
+
+static XkbAction
+_FixUpAction(XkbDescPtr xkb,XkbAction *act)
+{
+static XkbAction fake;
+
+ if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ if (XkbDisableLockActions) {
+ switch (act->type) {
+ case XkbSA_LockMods:
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->mods.mask;
+ return fake;
+ case XkbSA_LatchMods:
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->mods.mask;
+ return fake;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_ISODfltIsGroup) {
+ fake.group.type = XkbSA_SetGroup;
+ fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso));
+ }
+ else {
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->iso.mask;
+ }
+ return fake;
+ case XkbSA_LockGroup:
+ case XkbSA_LatchGroup:
+ /* We want everything from the latch/lock action except the
+ * type should be changed to set.
+ */
+ fake = *act;
+ fake.group.type = XkbSA_SetGroup;
+ return fake;
+ }
+ }
+ else
+ if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
+ if (act->any.type==XkbSA_SetMods) {
+ fake.mods.type = XkbSA_LatchMods;
+ fake.mods.mask = act->mods.mask;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.mods.flags= XkbSA_ClearLocks;
+ return fake;
+ }
+ if (act->any.type==XkbSA_SetGroup) {
+ fake.group.type = XkbSA_LatchGroup;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.group.flags= XkbSA_ClearLocks;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
+ return fake;
+ }
+ }
+ return *act;
+}
+
+static XkbAction
+XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
+{
+int effectiveGroup;
+int col;
+XkbDescPtr xkb;
+XkbKeyTypePtr type;
+XkbAction * pActs;
+static XkbAction fake;
+
+ xkb= xkbi->desc;
+ if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ pActs= XkbKeyActionsPtr(xkb,key);
+ col= 0;
+ effectiveGroup= xkbState->group;
+ if (effectiveGroup!=XkbGroup1Index) {
+ if (XkbKeyNumGroups(xkb,key)>(unsigned)1) {
+ if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) {
+ unsigned gi= XkbKeyGroupInfo(xkb,key);
+ switch (XkbOutOfRangeGroupAction(gi)) {
+ default:
+ case XkbWrapIntoRange:
+ effectiveGroup %= XkbKeyNumGroups(xkb,key);
+ break;
+ case XkbClampIntoRange:
+ effectiveGroup = XkbKeyNumGroups(xkb,key)-1;
+ break;
+ case XkbRedirectIntoRange:
+ effectiveGroup= XkbOutOfRangeGroupInfo(gi);
+ if (effectiveGroup>=XkbKeyNumGroups(xkb,key))
+ effectiveGroup= 0;
+ break;
+ }
+ }
+ }
+ else effectiveGroup= XkbGroup1Index;
+ col+= (effectiveGroup*XkbKeyGroupsWidth(xkb,key));
+ }
+ type= XkbKeyKeyType(xkb,key,effectiveGroup);
+ if (type->map!=NULL) {
+ register unsigned i,mods;
+ register XkbKTMapEntryPtr entry;
+ mods= xkbState->mods&type->mods.mask;
+ for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
+ if ((entry->active)&&(entry->mods.mask==mods)) {
+ col+= entry->level;
+ break;
+ }
+ }
+ }
+ if (pActs[col].any.type==XkbSA_NoAction)
+ return pActs[col];
+ fake= _FixUpAction(xkb,&pActs[col]);
+ return fake;
+}
+
+XkbAction
+XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
+{
+XkbAction fake;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
+ fake= _FixUpAction(kbd->key->xkbInfo->desc,
+ &dev->button->xkb_acts[button-1]);
+ return fake;
+ }
+ }
+ fake.any.type= XkbSA_NoAction;
+ return fake;
+}
+
+/***====================================================================***/
+
+#define SYNTHETIC_KEYCODE 1
+#define BTN_ACT_FLAG 0x100
+
+typedef struct _XkbFilter {
+ CARD16 keycode;
+ CARD8 what;
+ CARD8 active;
+ CARD8 filterOthers;
+ CARD32 priv;
+ XkbAction upAction;
+ int (*filter)(
+ XkbSrvInfoPtr /* xkbi */,
+ struct _XkbFilter * /* filter */,
+ unsigned /* keycode */,
+ XkbAction * /* action */
+ );
+ struct _XkbFilter *next;
+} XkbFilterRec,*XkbFilterPtr;
+
+static int
+_XkbFilterSetState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction *pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
+ filter->priv = 0;
+ filter->filter = _XkbFilterSetState;
+ if (pAction->type==XkbSA_SetMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods= pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ if (filter->upAction.type==XkbSA_SetMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
+ }
+ }
+ else {
+ if (filter->upAction.group.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_group = 0;
+ }
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ }
+ filter->active = 0;
+ }
+ else {
+ filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+#define LATCH_KEY_DOWN 1
+#define LATCH_PENDING 2
+#define NO_LATCH 3
+
+static int
+_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = LATCH_KEY_DOWN;
+ filter->filter = _XkbFilterLatchState;
+ if (pAction->type==XkbSA_LatchMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if ( pAction && (filter->priv==LATCH_PENDING) ) {
+ if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
+ filter->active = 0;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ }
+ else if ((pAction->type==filter->upAction.type)&&
+ (pAction->mods.flags==filter->upAction.mods.flags)&&
+ (pAction->mods.mask==filter->upAction.mods.mask)) {
+ if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_LockMods;
+ else pAction->group.type= XkbSA_LockGroup;
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
+ (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
+ XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
+ }
+ }
+ else {
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_SetMods;
+ else pAction->group.type= XkbSA_SetGroup;
+ }
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ filter->active = 0;
+ }
+ }
+ else if (filter->keycode==keycode) { /* release */
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ int needBeep;
+ int beepType= _BEEP_NONE;
+
+ needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
+ XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
+ (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
+ xkbi->state.locked_mods&= ~xkbi->clearMods;
+ filter->priv= NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ else {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
+ (xkbi->state.locked_group)) {
+ xkbi->state.locked_group = 0;
+ filter->priv = NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ if (filter->priv==NO_LATCH) {
+ filter->active= 0;
+ }
+ else {
+ filter->priv= LATCH_PENDING;
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ needBeep = xkbi->state.latched_mods ? needBeep : 0;
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ }
+ else {
+ xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
+ }
+ if (needBeep && (beepType==_BEEP_NONE))
+ beepType= _BEEP_STICKY_LATCH;
+ }
+ if (needBeep && (beepType!=_BEEP_NONE))
+ XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
+ }
+ else if (filter->priv==LATCH_KEY_DOWN) {
+ filter->priv= NO_LATCH;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterLockState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (pAction&&(pAction->type==XkbSA_LockGroup)) {
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->state.locked_group= XkbSAGroup(&pAction->group);
+ else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
+ return 1;
+ }
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterLockState;
+ filter->upAction = *pAction;
+ xkbi->state.locked_mods^= pAction->mods.mask;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ xkbi->clearMods = filter->upAction.mods.mask;
+ }
+ return 1;
+}
+
+#define ISO_KEY_DOWN 0
+#define NO_ISO_LOCK 1
+
+static int
+_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ CARD8 flags= pAction->iso.flags;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = ISO_KEY_DOWN;
+ filter->upAction = *pAction;
+ filter->filter = _XkbFilterISOLock;
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = XkbSAGroup(&pAction->iso);
+ xkbi->setMods = 0;
+ }
+ else {
+ xkbi->setMods = pAction->iso.mask;
+ xkbi->groupChange = 0;
+ }
+ if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
+ filter->priv= NO_ISO_LOCK;
+ xkbi->state.locked_mods^= xkbi->state.base_mods;
+ }
+ if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
+/* 6/22/93 (ef) -- lock groups if group key is down first */
+ }
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+/* 6/22/93 (ef) -- lock mouse buttons if they're down */
+ }
+ }
+ else if (filter->keycode==keycode) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
+ xkbi->clearMods = 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
+ }
+ else {
+ xkbi->clearMods= filter->upAction.iso.mask;
+ xkbi->groupChange= 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_mods^= filter->upAction.iso.mask;
+ }
+ filter->active = 0;
+ }
+ else if (pAction) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ switch (pAction->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods:
+ if (!(flags&XkbSA_ISONoAffectMods)) {
+ pAction->type= XkbSA_LockMods;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetGroup: case XkbSA_LatchGroup:
+ if (!(flags&XkbSA_ISONoAffectGroup)) {
+ pAction->type= XkbSA_LockGroup;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+ pAction->type= XkbSA_LockPtrBtn;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetControls:
+ if (!(flags&XkbSA_ISONoAffectCtrls)) {
+ pAction->type= XkbSA_LockControls;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+
+static CARD32
+_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,void * arg)
+{
+XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+int dx,dy;
+
+ if (xkbi->mouseKey==0)
+ return 0;
+
+ if (xkbi->mouseKeysAccel) {
+ if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
+ double step;
+ xkbi->mouseKeysCounter++;
+ step= xkbi->mouseKeysCurveFactor*
+ pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
+ if (xkbi->mouseKeysDX<0)
+ dx= floor( ((double)xkbi->mouseKeysDX)*step );
+ else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
+ if (xkbi->mouseKeysDY<0)
+ dy= floor( ((double)xkbi->mouseKeysDY)*step );
+ else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
+ }
+ else {
+ dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
+ dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
+ }
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
+ dx= xkbi->mouseKeysDX;
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
+ dy= xkbi->mouseKeysDY;
+ }
+ else {
+ dx= xkbi->mouseKeysDX;
+ dy= xkbi->mouseKeysDY;
+ }
+ XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
+ return xkbi->desc->ctrls->mk_interval;
+}
+
+static int
+_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+int x,y;
+Bool accel;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerMove;
+ filter->upAction= *pAction;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->mouseKey= keycode;
+ accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
+ x= XkbPtrActionX(&pAction->ptr);
+ y= XkbPtrActionY(&pAction->ptr);
+ XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ xkbi->mouseKeysAccel= accel&&
+ (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
+ xkbi->mouseKeysFlags= pAction->ptr.flags;
+ xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
+ xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
+ xkbi->desc->ctrls->mk_delay,
+ _XkbPtrAccelExpire,(void *)xkbi);
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ if (xkbi->mouseKey==keycode) {
+ xkbi->mouseKey= 0;
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
+ NULL, NULL);
+ }
+ }
+ return 0;
+}
+
+static int
+_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ int button= pAction->btn.button;
+
+ if (button==XkbSA_UseDfltButton)
+ button = xkbi->desc->ctrls->mk_dflt_btn;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerBtn;
+ filter->upAction= *pAction;
+ filter->upAction.btn.button= button;
+ switch (pAction->type) {
+ case XkbSA_LockPtrBtn:
+ if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
+ ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
+ xkbi->lockedPtrButtons|= (1<<button);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ XkbDDXFakePointerButton(ButtonPress,button);
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ {
+ register int i,nClicks;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ if (pAction->btn.count>0) {
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakePointerButton(ButtonPress,button);
+ XkbDDXFakePointerButton(ButtonRelease,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakePointerButton(ButtonPress,button);
+ }
+ break;
+ case XkbSA_SetPtrDflt:
+ {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ XkbControlsRec old;
+ xkbControlsNotify cn;
+
+ old= *ctrls;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ switch (pAction->dflt.affect) {
+ case XkbSA_AffectDfltBtn:
+ if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
+ ctrls->mk_dflt_btn=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ else {
+ ctrls->mk_dflt_btn+=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ if (ctrls->mk_dflt_btn>5)
+ ctrls->mk_dflt_btn= 5;
+ else if (ctrls->mk_dflt_btn<1)
+ ctrls->mk_dflt_btn= 1;
+ }
+ break;
+ default:
+ ErrorF(
+ "Attempt to change unknown pointer default (%d) ignored\n",
+ pAction->dflt.affect);
+ break;
+ }
+ if (XkbComputeControlsNotify(xkbi->device,
+ &old,xkbi->desc->ctrls,
+ &cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ }
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button= filter->upAction.btn.button;
+
+ switch (filter->upAction.type) {
+ case XkbSA_LockPtrBtn:
+ if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
+ ((xkbi->lockedPtrButtons&(1<<button))==0)) {
+ break;
+ }
+ xkbi->lockedPtrButtons&= ~(1<<button);
+ case XkbSA_PtrBtn:
+ XkbDDXFakePointerButton(ButtonRelease,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterControls( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbControlsRec old;
+XkbControlsPtr ctrls;
+DeviceIntPtr kbd;
+unsigned int change;
+XkbEventCauseRec cause;
+
+ kbd= xkbi->device;
+ ctrls= xkbi->desc->ctrls;
+ old= *ctrls;
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ change= XkbActionCtrls(&pAction->ctrls);
+ filter->priv = change;
+ filter->filter = _XkbFilterControls;
+ filter->upAction = *pAction;
+
+ if (pAction->type==XkbSA_LockControls) {
+ filter->priv= (ctrls->enabled_ctrls&change);
+ change&= ~ctrls->enabled_ctrls;
+ }
+
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls|= change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyPress);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ change= filter->priv;
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls&= ~change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyRelease;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyRelease);
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbMessageAction * pMsg;
+DeviceIntPtr kbd;
+
+ kbd= xkbi->device;
+ if (filter->keycode==0) { /* initial press */
+ pMsg= &pAction->msg;
+ if ((pMsg->flags&XkbSA_MessageOnRelease)||
+ ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterActionMessage;
+ filter->upAction = *pAction;
+ }
+ if (pMsg->flags&XkbSA_MessageOnPress) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 1;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,
+ (char *)pMsg->message,XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ else if (filter->keycode==keycode) {
+ pMsg= &filter->upAction.msg;
+ if (pMsg->flags&XkbSA_MessageOnRelease) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 0;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,(char *)pMsg->message,
+ XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ return 0;
+}
+
+static int
+_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+unsigned realMods;
+xEvent ev;
+int x,y;
+XkbStateRec old;
+unsigned mods,mask,oldCoreState = 0,oldCorePrevState = 0;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
+
+ if ((filter->keycode!=0)&&(filter->keycode!=keycode))
+ return 1;
+
+ GetSpritePosition(&x,&y);
+ ev.u.keyButtonPointer.time = GetTimeInMillis();
+ ev.u.keyButtonPointer.rootX = x;
+ ev.u.keyButtonPointer.rootY = y;
+
+ if (filter->keycode==0) { /* initial press */
+ if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
+ (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
+ return 1;
+ }
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterRedirectKey;
+ filter->upAction = *pAction;
+
+ ev.u.u.type = KeyPress;
+ ev.u.u.detail = pAction->redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&pAction->redirect);
+ mods= XkbSARedirectVMods(&pAction->redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= pAction->redirect.mods_mask;
+ mods|= pAction->redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ oldCoreState= xkbi->device->key->state;
+ oldCorePrevState= xkbi->device->key->prev_state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ xkbi->device->key->state= xkbi->device->key->prev_state=
+ xkbi->state.mods;
+ }
+
+ realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
+ xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+ xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
+ xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
+
+ if ( mask || mods ) {
+ xkbi->device->key->state= oldCoreState;
+ xkbi->device->key->prev_state= oldCorePrevState;
+ xkbi->state= old;
+ }
+ }
+ else if (filter->keycode==keycode) {
+
+ ev.u.u.type = KeyRelease;
+ ev.u.u.detail = filter->upAction.redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
+ mods= XkbSARedirectVMods(&filter->upAction.redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= filter->upAction.redirect.mods_mask;
+ mods|= filter->upAction.redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ oldCoreState= xkbi->device->key->state;
+ oldCorePrevState= xkbi->device->key->prev_state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ xkbi->device->key->state= xkbi->device->key->prev_state=
+ xkbi->state.mods;
+ }
+
+ realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
+ xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+ xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
+ xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
+
+ if ( mask || mods ) {
+ xkbi->device->key->state= oldCoreState;
+ xkbi->device->key->prev_state= oldCorePrevState;
+ xkbi->state= old;
+ }
+
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ DeviceIntPtr dev = xkbi->device;
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterSwitchScreen;
+ AccessXCancelRepeatKey(xkbi, keycode);
+ XkbDDXSwitchScreen(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+
+#ifdef XFree86Server
+static int
+_XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ DeviceIntPtr dev = xkbi->device;
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterXF86Private;
+ XkbDDXPrivate(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+#ifdef XINPUT
+
+static int
+_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+DeviceIntPtr dev;
+int button;
+
+ if (filter->keycode==0) { /* initial press */
+ dev= _XkbLookupButtonDevice(pAction->devbtn.device,NULL);
+ if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
+ return 1;
+
+ button= pAction->devbtn.button;
+ if ((button<1)||(button>dev->button->numButtons))
+ return 1;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterDeviceBtn;
+ filter->upAction= *pAction;
+ switch (pAction->type) {
+ case XkbSA_LockDeviceBtn:
+ if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
+ (dev->button->down[button/8]&(1L<<(button%8))))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,True,button);
+ filter->upAction.type= XkbSA_NoAction;
+ break;
+ case XkbSA_DeviceBtn:
+ if (pAction->devbtn.count>0) {
+ int nClicks,i;
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakeDeviceButton(dev,True,button);
+ XkbDDXFakeDeviceButton(dev,False,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakeDeviceButton(dev,True,button);
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button;
+
+ filter->active= 0;
+ dev= _XkbLookupButtonDevice(filter->upAction.devbtn.device,NULL);
+ if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
+ return 1;
+
+ button= filter->upAction.btn.button;
+ switch (filter->upAction.type) {
+ case XkbSA_LockDeviceBtn:
+ if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
+ ((dev->button->down[button/8]&(1L<<(button%8)))==0))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,False,button);
+ break;
+ case XkbSA_DeviceBtn:
+ XkbDDXFakeDeviceButton(dev,False,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+#endif
+
+static int szFilters = 0;
+static XkbFilterPtr filters = NULL;
+
+static XkbFilterPtr
+_XkbNextFreeFilter(
+ void
+)
+{
+register int i;
+
+ if (szFilters==0) {
+ szFilters = 4;
+ filters = _XkbTypedCalloc(szFilters,XkbFilterRec);
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ }
+ for (i=0;i<szFilters;i++) {
+ if (!filters[i].active) {
+ filters[i].keycode = 0;
+ return &filters[i];
+ }
+ }
+ szFilters*=2;
+ filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec);
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec));
+ return &filters[szFilters/2];
+}
+
+static int
+_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
+{
+register int i,send;
+
+ send= 1;
+ for (i=0;i<szFilters;i++) {
+ if ((filters[i].active)&&(filters[i].filter))
+ send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send);
+ }
+ return send;
+}
+
+void
+XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count)
+{
+int key,bit,i;
+CARD8 realMods;
+XkbSrvInfoPtr xkbi;
+KeyClassPtr keyc;
+int changed,sendEvent;
+Bool genStateNotify;
+XkbStateRec oldState;
+XkbAction act;
+XkbFilterPtr filter;
+Bool keyEvent;
+Bool pressEvent;
+#ifdef XINPUT
+Bool xiEvent;
+#endif
+
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
+
+ keyc= kbd->key;
+ xkbi= keyc->xkbInfo;
+ key= xE->u.u.detail;
+ if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
+ oldState= xkbi->state;
+ xkbi->flags|= _XkbStateNotifyInProgress;
+ genStateNotify= True;
+ }
+ else genStateNotify= False;
+
+ xkbi->clearMods = xkbi->setMods = 0;
+ xkbi->groupChange = 0;
+
+ sendEvent = 1;
+#ifdef XINPUT
+ keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
+ (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
+ pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
+ (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
+ xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)||
+ (xE->u.u.type==DeviceButtonPress)||
+ (xE->u.u.type==DeviceButtonRelease);
+#else
+ keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease);
+ pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress);
+#endif
+
+ if (pressEvent) {
+ if (keyEvent)
+ act = XkbGetKeyAction(xkbi,&xkbi->state,key);
+ else {
+ act = XkbGetButtonAction(kbd,dev,key);
+ key|= BTN_ACT_FLAG;
+ }
+ sendEvent = _XkbApplyFilters(xkbi,key,&act);
+ if (sendEvent) {
+ switch (act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_SetGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LatchMods:
+ case XkbSA_LatchGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LockMods:
+ case XkbSA_LockGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ISOLock:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
+ break;
+ case XkbSA_MovePtr:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ case XkbSA_SetPtrDflt:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_Terminate:
+ sendEvent= XkbDDXTerminateServer(dev,key,&act);
+ break;
+ case XkbSA_SwitchScreen:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ActionMessage:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
+ break;
+ case XkbSA_RedirectKey:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
+ break;
+#ifdef XINPUT
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
+ break;
+#endif
+#ifdef XFree86Server
+ case XkbSA_XFree86Private:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
+ break;
+#endif
+ }
+ }
+ }
+ else {
+ if (!keyEvent)
+ key|= BTN_ACT_FLAG;
+ sendEvent = _XkbApplyFilters(xkbi,key,NULL);
+ }
+
+ if (xkbi->groupChange!=0)
+ xkbi->state.base_group+= xkbi->groupChange;
+ if (xkbi->setMods) {
+ for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
+ if (xkbi->setMods&bit) {
+ keyc->modifierKeyCount[i]++;
+ xkbi->state.base_mods|= bit;
+ xkbi->setMods&= ~bit;
+ }
+ }
+ }
+ if (xkbi->clearMods) {
+ for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
+ if (xkbi->clearMods&bit) {
+ keyc->modifierKeyCount[i]--;
+ if (keyc->modifierKeyCount[i]<=0) {
+ xkbi->state.base_mods&= ~bit;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ xkbi->clearMods&= ~bit;
+ }
+ }
+ }
+
+ if (sendEvent) {
+#ifdef XINPUT
+ if (xiEvent)
+ ProcessOtherEvent(xE,dev,count);
+ else
+#endif
+ if (keyEvent) {
+ realMods = keyc->modifierMap[key];
+ keyc->modifierMap[key] = 0;
+ UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr);
+ dev->public.processInputProc(xE,dev,count);
+ COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr,
+ ProcessKeyboardEvent,xkbUnwrapProc);
+ keyc->modifierMap[key] = realMods;
+ }
+ else CoreProcessPointerEvent(xE,dev,count);
+ }
+ else if (keyEvent)
+ FixKeyState(xE,dev);
+
+ xkbi->prev_state= oldState;
+ XkbComputeDerivedState(xkbi);
+ keyc->prev_state= keyc->state;
+ keyc->state= XkbStateFieldFromRec(&xkbi->state);
+ changed = XkbStateChangedFlags(&oldState,&xkbi->state);
+ if (genStateNotify) {
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= key;
+ sn.eventType= xE->u.u.type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+ xkbi->flags&= ~_XkbStateNotifyInProgress;
+ }
+ changed= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause,key,xE->u.u.type);
+ XkbUpdateIndicators(dev,changed,True,NULL,&cause);
+ }
+ return;
+}
+
+int
+XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+unsigned clear;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ clear= (mask&(~latches));
+ xkbi->state.latched_mods&= ~clear;
+ /* Clear any pending latch to locks.
+ */
+ act.type = XkbSA_NoAction;
+ _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
+ act.type = XkbSA_LatchMods;
+ act.mods.flags = 0;
+ act.mods.mask = mask&latches;
+ filter = _XkbNextFreeFilter();
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+int
+XkbLatchGroup(DeviceIntPtr pXDev,int group)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ act.type = XkbSA_LatchGroup;
+ act.group.flags = 0;
+ XkbSASetGroup(&act.group,group);
+ filter = _XkbNextFreeFilter();
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+/***====================================================================***/
+
+void
+XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
+ XkbSrvInfoPtr xkbi,
+ Bool genEv,
+ XkbEventCausePtr cause)
+{
+XkbStateRec os;
+xkbStateNotify sn;
+
+ sn.changed= 0;
+ os= xkbi->state;
+ if (os.latched_mods) { /* clear all latches */
+ XkbLatchModifiers(dev,~0,0);
+ sn.changed|= XkbModifierLatchMask;
+ }
+ if (os.latched_group) {
+ XkbLatchGroup(dev,0);
+ sn.changed|= XkbGroupLatchMask;
+ }
+ if (os.locked_mods) {
+ xkbi->state.locked_mods= 0;
+ sn.changed|= XkbModifierLockMask;
+ }
+ if (os.locked_group) {
+ xkbi->state.locked_group= 0;
+ sn.changed|= XkbGroupLockMask;
+ }
+ if ( genEv && sn.changed) {
+ CARD32 changed;
+
+ XkbComputeDerivedState(xkbi);
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,sn.changed,False);
+ if (changed) {
+ XkbUpdateIndicators(dev,changed,True,NULL,cause);
+ }
+ }
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/xkbDflts.h b/nx-X11/programs/Xserver/xkb/xkbDflts.h
new file mode 100644
index 000000000..c3c28524b
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbDflts.h
@@ -0,0 +1,517 @@
+/* This file generated automatically by xkbcomp */
+/* DO NOT EDIT */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef DEFAULT_H
+#define DEFAULT_H 1
+
+#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1)
+#define DPYTYPE char *
+#define NUM_KEYS 1
+
+#define vmod_NumLock 0
+#define vmod_Alt 1
+#define vmod_LevelThree 2
+#define vmod_AltGr 3
+#define vmod_ScrollLock 4
+
+#define vmod_NumLockMask (1<<0)
+#define vmod_AltMask (1<<1)
+#define vmod_LevelThreeMask (1<<2)
+#define vmod_AltGrMask (1<<3)
+#define vmod_ScrollLockMask (1<<4)
+
+/* types name is "default" */
+static Atom lnames_ONE_LEVEL[1];
+
+static XkbKTMapEntryRec map_TWO_LEVEL[1]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } }
+};
+static Atom lnames_TWO_LEVEL[2];
+
+static XkbKTMapEntryRec map_ALPHABETIC[2]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 1, 0, { LockMask, LockMask, 0 } }
+};
+static XkbModsRec preserve_ALPHABETIC[2]= {
+ { 0, 0, 0 },
+ { LockMask, LockMask, 0 }
+};
+static Atom lnames_ALPHABETIC[2];
+
+static XkbKTMapEntryRec map_KEYPAD[2]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 0, 1, { 0, 0, vmod_NumLockMask } }
+};
+static Atom lnames_KEYPAD[2];
+
+static XkbKTMapEntryRec map_PC_BREAK[1]= {
+ { 1, 1, { ControlMask, ControlMask, 0 } }
+};
+static Atom lnames_PC_BREAK[2];
+
+static XkbKTMapEntryRec map_PC_SYSRQ[1]= {
+ { 0, 1, { 0, 0, vmod_AltMask } }
+};
+static Atom lnames_PC_SYSRQ[2];
+
+static XkbKTMapEntryRec map_CTRL_ALT[1]= {
+ { 0, 1, { ControlMask, ControlMask, vmod_AltMask } }
+};
+static Atom lnames_CTRL_ALT[2];
+
+static XkbKTMapEntryRec map_THREE_LEVEL[3]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 0, 2, { 0, 0, vmod_LevelThreeMask } },
+ { 0, 2, { ShiftMask, ShiftMask, vmod_LevelThreeMask } }
+};
+static Atom lnames_THREE_LEVEL[3];
+
+static XkbKTMapEntryRec map_SHIFT_ALT[1]= {
+ { 0, 1, { ShiftMask, ShiftMask, vmod_AltMask } }
+};
+static Atom lnames_SHIFT_ALT[2];
+
+static XkbKeyTypeRec dflt_types[]= {
+ {
+ { 0, 0, 0 },
+ 1,
+ 0, NULL, NULL,
+ None, lnames_ONE_LEVEL
+ },
+ {
+ { ShiftMask, ShiftMask, 0 },
+ 2,
+ 1, map_TWO_LEVEL, NULL,
+ None, lnames_TWO_LEVEL
+ },
+ {
+ { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
+ 2,
+ 2, map_ALPHABETIC, preserve_ALPHABETIC,
+ None, lnames_ALPHABETIC
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_NumLockMask },
+ 2,
+ 2, map_KEYPAD, NULL,
+ None, lnames_KEYPAD
+ },
+ {
+ { ControlMask, ControlMask, 0 },
+ 2,
+ 1, map_PC_BREAK, NULL,
+ None, lnames_PC_BREAK
+ },
+ {
+ { 0, 0, vmod_AltMask },
+ 2,
+ 1, map_PC_SYSRQ, NULL,
+ None, lnames_PC_SYSRQ
+ },
+ {
+ { ControlMask, ControlMask, vmod_AltMask },
+ 2,
+ 1, map_CTRL_ALT, NULL,
+ None, lnames_CTRL_ALT
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_LevelThreeMask },
+ 3,
+ 3, map_THREE_LEVEL, NULL,
+ None, lnames_THREE_LEVEL
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_AltMask },
+ 2,
+ 1, map_SHIFT_ALT, NULL,
+ None, lnames_SHIFT_ALT
+ }
+};
+#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))
+
+
+static void
+initTypeNames(DPYTYPE dpy)
+{
+ dflt_types[0].name= GET_ATOM(dpy,"ONE_LEVEL");
+ lnames_ONE_LEVEL[0]= GET_ATOM(dpy,"Any");
+ dflt_types[1].name= GET_ATOM(dpy,"TWO_LEVEL");
+ lnames_TWO_LEVEL[0]= GET_ATOM(dpy,"Base");
+ lnames_TWO_LEVEL[1]= GET_ATOM(dpy,"Shift");
+ dflt_types[2].name= GET_ATOM(dpy,"ALPHABETIC");
+ lnames_ALPHABETIC[0]= GET_ATOM(dpy,"Base");
+ lnames_ALPHABETIC[1]= GET_ATOM(dpy,"Caps");
+ dflt_types[3].name= GET_ATOM(dpy,"KEYPAD");
+ lnames_KEYPAD[0]= GET_ATOM(dpy,"Base");
+ lnames_KEYPAD[1]= GET_ATOM(dpy,"Number");
+ dflt_types[4].name= GET_ATOM(dpy,"PC_BREAK");
+ lnames_PC_BREAK[0]= GET_ATOM(dpy,"Base");
+ lnames_PC_BREAK[1]= GET_ATOM(dpy,"Control");
+ dflt_types[5].name= GET_ATOM(dpy,"PC_SYSRQ");
+ lnames_PC_SYSRQ[0]= GET_ATOM(dpy,"Base");
+ lnames_PC_SYSRQ[1]= GET_ATOM(dpy,"Alt");
+ dflt_types[6].name= GET_ATOM(dpy,"CTRL+ALT");
+ lnames_CTRL_ALT[0]= GET_ATOM(dpy,"Base");
+ lnames_CTRL_ALT[1]= GET_ATOM(dpy,"Ctrl+Alt");
+ dflt_types[7].name= GET_ATOM(dpy,"THREE_LEVEL");
+ lnames_THREE_LEVEL[0]= GET_ATOM(dpy,"Base");
+ lnames_THREE_LEVEL[1]= GET_ATOM(dpy,"Shift");
+ lnames_THREE_LEVEL[2]= GET_ATOM(dpy,"Level3");
+ dflt_types[8].name= GET_ATOM(dpy,"SHIFT+ALT");
+ lnames_SHIFT_ALT[0]= GET_ATOM(dpy,"Base");
+ lnames_SHIFT_ALT[1]= GET_ATOM(dpy,"Shift+Alt");
+}
+/* compat name is "default" */
+static XkbSymInterpretRec dfltSI[69]= {
+ { XK_ISO_Level2_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_Exactly, ShiftMask,
+ 255,
+ { XkbSA_LatchMods, { 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Eisu_Shift, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Eisu_toggle, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Kana_Shift, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Kana_Lock, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Shift_Lock, 0x0000,
+ XkbSI_AnyOf, ShiftMask|LockMask,
+ 255,
+ { XkbSA_LockMods, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Num_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 0,
+ { XkbSA_LockMods, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_Alt_L, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 1,
+ { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Alt_R, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 1,
+ { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Scroll_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 4,
+ { XkbSA_LockMods, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 255,
+ { XkbSA_ISOLock, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_Level3_Shift, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff,
+ 2,
+ { XkbSA_SetMods, { 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } },
+ { XK_ISO_Level3_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff,
+ 2,
+ { XkbSA_LatchMods, { 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } } },
+ { XK_Mode_switch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_SetGroup, { 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_1, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_End, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_2, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_Down, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_3, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_Next, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } } },
+ { XK_KP_4, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Left, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_6, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Right, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_7, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_Home, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_8, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_Up, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_9, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_Prior, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, { 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00 } } },
+ { XK_KP_5, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Begin, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_F1, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Divide, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_F2, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Multiply, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_F3, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Subtract, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Separator, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Add, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_0, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Insert, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Decimal, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_KP_Delete, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Button_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Button1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Button2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Button3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_DblClick_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_DblClick1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_DblClick2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_DblClick3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, { 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Drag_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Drag1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Drag2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_Drag3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, { 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_EnableKeys, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } } },
+ { XK_Pointer_Accelerate, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } } },
+ { XK_Pointer_DfltBtnNext, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_Pointer_DfltBtnPrev, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, { 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_AccessX_Enable, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } } },
+
+#ifndef NX_TRANS_SOCKET
+
+ /*
+ * Make sure that the server can't be killed
+ * by pressing this key-sequence.
+ */
+
+ { XK_Terminate_Server, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_Terminate, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+
+#endif
+
+ { XK_ISO_Group_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LatchGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_Next_Group, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LockGroup, { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_Prev_Group, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LockGroup, { 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_First_Group, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockGroup, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { XK_ISO_Last_Group, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockGroup, { 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
+ { NoSymbol, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_LockMods, { 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } } },
+ { NoSymbol, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 255,
+ { XkbSA_SetMods, { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }
+};
+#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))
+
+static XkbCompatMapRec compatMap= {
+ dfltSI,
+ { /* group compatibility */
+ { 0, 0, 0 },
+ { 0, 0, vmod_AltGrMask },
+ { 0, 0, vmod_AltGrMask },
+ { 0, 0, vmod_AltGrMask }
+ },
+ num_dfltSI, num_dfltSI
+};
+
+static XkbIndicatorRec indicators= {
+ 0x0,
+ {
+ { 0x80, 0, 0x00, XkbIM_UseEffective, { LockMask, LockMask, 0 }, 0 },
+ { 0x80, 0, 0x00, XkbIM_UseEffective, { 0, 0, vmod_NumLockMask }, 0 },
+ { 0x80, 0, 0x00, XkbIM_UseLocked, { ShiftMask, ShiftMask, 0 }, 0 },
+ { 0x80, 0, 0x00, 0, { 0, 0, 0 }, XkbMouseKeysMask },
+ { 0x80, 0, 0x00, XkbIM_UseLocked, { 0, 0, vmod_ScrollLockMask }, 0 },
+ { 0x80, XkbIM_UseEffective, 0xfe, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 },
+ { 0x00, 0, 0x00, 0, { 0, 0, 0 }, 0 }
+ }
+};
+static void
+initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)
+{
+ xkb->names->indicators[ 0]= GET_ATOM(dpy,"Caps Lock");
+ xkb->names->indicators[ 1]= GET_ATOM(dpy,"Num Lock");
+ xkb->names->indicators[ 2]= GET_ATOM(dpy,"Shift Lock");
+ xkb->names->indicators[ 3]= GET_ATOM(dpy,"Mouse Keys");
+ xkb->names->indicators[ 4]= GET_ATOM(dpy,"Scroll Lock");
+ xkb->names->indicators[ 5]= GET_ATOM(dpy,"Group 2");
+}
+#endif /* DEFAULT_H */
diff --git a/nx-X11/programs/Xserver/xkb/xkbEvents.c b/nx-X11/programs/Xserver/xkb/xkbEvents.c
new file mode 100644
index 000000000..60c26ff1f
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbEvents.c
@@ -0,0 +1,1048 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/extensions/XI.h>
+#include "inputstr.h"
+#include "windowstr.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+
+/***====================================================================***/
+
+void
+XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
+{
+register int i;
+Time time;
+CARD16 changed;
+
+ pNKN->type = XkbEventCode + XkbEventBase;
+ pNKN->xkbType = XkbNewKeyboardNotify;
+ pNKN->time = time = GetTimeInMillis();
+ changed = pNKN->changed;
+
+ for (i=1; i<currentMaxClients; i++) {
+ if ((!clients[i]) || clients[i]->clientGone ||
+ (clients[i]->requestVector==InitialVector)) {
+ continue;
+ }
+
+ if (clients[i]->xkbClientFlags&_XkbClientInitialized) {
+ if (clients[i]->newKeyboardNotifyMask&changed) {
+ pNKN->sequenceNumber = clients[i]->sequence;
+ pNKN->time = time;
+ pNKN->changed = changed;
+ if ( clients[i]->swapped ) {
+ swaps(&pNKN->sequenceNumber);
+ swapl(&pNKN->time);
+ swaps(&pNKN->changed);
+ }
+ WriteToClient(clients[i],sizeof(xEvent), pNKN);
+ if (changed&XkbNKN_KeycodesMask) {
+ clients[i]->minKC= pNKN->minKeyCode;
+ clients[i]->maxKC= pNKN->maxKeyCode;
+ }
+ }
+ }
+ else if (changed&XkbNKN_KeycodesMask) {
+ xEvent event;
+ event.u.u.type= MappingNotify;
+ event.u.mappingNotify.request= MappingKeyboard;
+ event.u.mappingNotify.firstKeyCode= clients[i]->minKC;
+ event.u.mappingNotify.count= clients[i]->maxKC-clients[i]->minKC+1;
+ event.u.u.sequenceNumber= clients[i]->sequence;
+ if (clients[i]->swapped) {
+ swaps(&event.u.u.sequenceNumber);
+ }
+ WriteToClient(clients[i],SIZEOF(xEvent), &event);
+ event.u.mappingNotify.request= MappingModifier;
+ WriteToClient(clients[i],SIZEOF(xEvent), &event);
+ }
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN)
+{
+XkbSrvInfoPtr xkbi;
+XkbStatePtr state;
+XkbInterestPtr interest;
+Time time;
+register CARD16 changed,bState;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+ xkbi = kbd->key->xkbInfo;
+ state= &xkbi->state;
+
+ pSN->type = XkbEventCode + XkbEventBase;
+ pSN->xkbType = XkbStateNotify;
+ pSN->deviceID = kbd->id;
+ pSN->time = time = GetTimeInMillis();
+ pSN->mods = state->mods;
+ pSN->baseMods = state->base_mods;
+ pSN->latchedMods = state->latched_mods;
+ pSN->lockedMods = state->locked_mods;
+ pSN->group = state->group;
+ pSN->baseGroup = state->base_group;
+ pSN->latchedGroup = state->latched_group;
+ pSN->lockedGroup = state->locked_group;
+ pSN->compatState = state->compat_state;
+ pSN->grabMods = state->grab_mods;
+ pSN->compatGrabMods = state->compat_grab_mods;
+ pSN->lookupMods = state->lookup_mods;
+ pSN->compatLookupMods = state->compat_lookup_mods;
+ pSN->ptrBtnState = state->ptr_buttons;
+ changed = pSN->changed;
+ bState= pSN->ptrBtnState;
+
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->stateNotifyMask&changed)) {
+ pSN->sequenceNumber = interest->client->sequence;
+ pSN->time = time;
+ pSN->changed = changed;
+ pSN->ptrBtnState = bState;
+ if ( interest->client->swapped ) {
+ swaps(&pSN->sequenceNumber);
+ swapl(&pSN->time);
+ swaps(&pSN->changed);
+ swaps(&pSN->ptrBtnState);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pSN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbSendMapNotify(DeviceIntPtr kbd,xkbMapNotify *pMN)
+{
+int i;
+XkbSrvInfoPtr xkbi;
+unsigned time = 0,initialized;
+CARD16 changed;
+
+ xkbi = kbd->key->xkbInfo;
+ initialized= 0;
+
+ changed = pMN->changed;
+ pMN->minKeyCode= xkbi->desc->min_key_code;
+ pMN->maxKeyCode= xkbi->desc->max_key_code;
+ for (i=1; i<currentMaxClients; i++) {
+ if (clients[i] && ! clients[i]->clientGone &&
+ (clients[i]->requestVector != InitialVector) &&
+ (clients[i]->xkbClientFlags&_XkbClientInitialized) &&
+ (clients[i]->mapNotifyMask&changed))
+ {
+ if (!initialized) {
+ pMN->type = XkbEventCode + XkbEventBase;
+ pMN->xkbType = XkbMapNotify;
+ pMN->deviceID = kbd->id;
+ time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pMN->time= time;
+ pMN->sequenceNumber = clients[i]->sequence;
+ pMN->changed = changed;
+ if ( clients[i]->swapped ) {
+ swaps(&pMN->sequenceNumber);
+ swapl(&pMN->time);
+ swaps(&pMN->changed);
+ }
+ WriteToClient(clients[i],sizeof(xEvent), pMN);
+ }
+ }
+ return;
+}
+
+int
+XkbComputeControlsNotify( DeviceIntPtr kbd,
+ XkbControlsPtr old,
+ XkbControlsPtr new,
+ xkbControlsNotify * pCN,
+ Bool forceCtrlProc)
+{
+int i;
+CARD32 changedControls;
+
+ changedControls= 0;
+ if (old->enabled_ctrls!=new->enabled_ctrls)
+ changedControls|= XkbControlsEnabledMask;
+ if ((old->repeat_delay!=new->repeat_delay)||
+ (old->repeat_interval!=new->repeat_interval))
+ changedControls|= XkbRepeatKeysMask;
+ for (i = 0; i < XkbPerKeyBitArraySize; i++)
+ if (old->per_key_repeat[i] != new->per_key_repeat[i])
+ changedControls|= XkbPerKeyRepeatMask;
+ if (old->slow_keys_delay!=new->slow_keys_delay)
+ changedControls|= XkbSlowKeysMask;
+ if (old->debounce_delay!=new->debounce_delay)
+ changedControls|= XkbBounceKeysMask;
+ if ((old->mk_delay!=new->mk_delay)||
+ (old->mk_interval!=new->mk_interval)||
+ (old->mk_dflt_btn!=new->mk_dflt_btn))
+ changedControls|= XkbMouseKeysMask;
+ if ((old->mk_time_to_max!=new->mk_time_to_max)||
+ (old->mk_curve!=new->mk_curve)||
+ (old->mk_max_speed!=new->mk_max_speed))
+ changedControls|= XkbMouseKeysAccelMask;
+ if (old->ax_options!=new->ax_options)
+ changedControls|= XkbAccessXKeysMask;
+ if ((old->ax_options^new->ax_options) & XkbAX_SKOptionsMask)
+ changedControls|= XkbStickyKeysMask;
+ if ((old->ax_options^new->ax_options) & XkbAX_FBOptionsMask)
+ changedControls|= XkbAccessXFeedbackMask;
+ if ((old->ax_timeout!=new->ax_timeout)||
+ (old->axt_ctrls_mask!=new->axt_ctrls_mask)||
+ (old->axt_ctrls_values!=new->axt_ctrls_values)||
+ (old->axt_opts_mask!=new->axt_opts_mask)||
+ (old->axt_opts_values!= new->axt_opts_values)) {
+ changedControls|= XkbAccessXTimeoutMask;
+ }
+ if ((old->internal.mask!=new->internal.mask)||
+ (old->internal.real_mods!=new->internal.real_mods)||
+ (old->internal.vmods!=new->internal.vmods))
+ changedControls|= XkbInternalModsMask;
+ if ((old->ignore_lock.mask!=new->ignore_lock.mask)||
+ (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)||
+ (old->ignore_lock.vmods!=new->ignore_lock.vmods))
+ changedControls|= XkbIgnoreLockModsMask;
+
+ if (new->enabled_ctrls&XkbRepeatKeysMask)
+ kbd->kbdfeed->ctrl.autoRepeat=TRUE;
+ else kbd->kbdfeed->ctrl.autoRepeat=FALSE;
+
+ if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc &&
+ (changedControls || forceCtrlProc))
+ (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl);
+
+ if ((!changedControls)&&(old->num_groups==new->num_groups))
+ return 0;
+
+ if (!kbd->xkb_interest)
+ return 0;
+
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = new->enabled_ctrls;
+ pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls);
+ pCN->numGroups = new->num_groups;
+
+ return 1;
+}
+
+void
+XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN)
+{
+int initialized;
+CARD32 changedControls, enabledControls, enabledChanges = 0;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time = 0;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+ xkbi = kbd->key->xkbInfo;
+
+ initialized = 0;
+ enabledControls = xkbi->desc->ctrls->enabled_ctrls;
+ changedControls = pCN->changedControls;
+ pCN->numGroups= xkbi->desc->ctrls->num_groups;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->ctrlsNotifyMask&changedControls)) {
+ if (!initialized) {
+ pCN->type = XkbEventCode + XkbEventBase;
+ pCN->xkbType = XkbControlsNotify;
+ pCN->deviceID = kbd->id;
+ pCN->time = time = GetTimeInMillis();
+ enabledChanges = pCN->enabledControlChanges;
+ initialized= 1;
+ }
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = enabledControls;
+ pCN->enabledControlChanges = enabledChanges;
+ pCN->sequenceNumber = interest->client->sequence;
+ pCN->time = time;
+ if ( interest->client->swapped ) {
+ swaps(&pCN->sequenceNumber);
+ swapl(&pCN->changedControls);
+ swapl(&pCN->enabledControls);
+ swapl(&pCN->enabledControlChanges);
+ swapl(&pCN->time);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pCN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD32 state,changed;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ state = pEv->state;
+ changed = pEv->changed;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (((xkbType==XkbIndicatorStateNotify)&&
+ (interest->iStateNotifyMask&changed))||
+ ((xkbType==XkbIndicatorMapNotify)&&
+ (interest->iMapNotifyMask&changed)))) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = xkbType;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->state = state;
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ swapl(&pEv->changed);
+ swapl(&pEv->state);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+
+void
+XkbHandleBell( BOOL force,
+ BOOL eventOnly,
+ DeviceIntPtr kbd,
+ CARD8 percent,
+ void * pCtrl,
+ CARD8 class,
+ Atom name,
+ WindowPtr pWin,
+ ClientPtr pClient)
+{
+xkbBellNotify bn;
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+CARD8 id;
+CARD16 pitch,duration;
+Time time = 0;
+XID winID = 0;
+
+ xkbi = kbd->key->xkbInfo;
+
+ if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&&
+ (!eventOnly)) {
+ (*kbd->kbdfeed->BellProc)(percent,kbd,(void *)pCtrl,class);
+ }
+ interest = kbd->xkb_interest;
+ if ((!interest)||(force))
+ return;
+
+ if ((class==0)||(class==KbdFeedbackClass)) {
+ KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl;
+ id= pKeyCtrl->id;
+ pitch= pKeyCtrl->bell_pitch;
+ duration= pKeyCtrl->bell_duration;
+ }
+ else if (class==BellFeedbackClass) {
+ BellCtrl *pBellCtrl= (BellCtrl *)pCtrl;
+ id= pBellCtrl->id;
+ pitch= pBellCtrl->pitch;
+ duration= pBellCtrl->duration;
+ }
+ else return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->bellNotifyMask)) {
+ if (!initialized) {
+ time = GetTimeInMillis();
+ bn.type = XkbEventCode + XkbEventBase;
+ bn.xkbType = XkbBellNotify;
+ bn.deviceID = kbd->id;
+ bn.bellClass = class;
+ bn.bellID = id;
+ bn.percent= percent;
+ bn.eventOnly = (eventOnly!=0);
+ winID= (pWin?pWin->drawable.id:None);
+ initialized= 1;
+ }
+ bn.sequenceNumber = interest->client->sequence;
+ bn.time = time;
+ bn.pitch = pitch;
+ bn.duration = duration;
+ bn.name = name;
+ bn.window= winID;
+ if ( interest->client->swapped ) {
+ swaps(&bn.sequenceNumber);
+ swapl(&bn.time);
+ swaps(&bn.pitch);
+ swaps(&bn.duration);
+ swapl(&bn.name);
+ swapl(&bn.window);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), &bn);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 sk_delay,db_delay;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ sk_delay= pEv->slowKeysDelay;
+ db_delay= pEv->debounceDelay;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->accessXNotifyMask&(1<<pEv->detail))) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbAccessXNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->slowKeysDelay = sk_delay;
+ pEv->debounceDelay = db_delay;
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ swaps(&pEv->slowKeysDelay);
+ swaps(&pEv->debounceDelay);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 changed,changedVirtualMods;
+CARD32 changedIndicators;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ changed= pEv->changed;
+ changedIndicators= pEv->changedIndicators;
+ changedVirtualMods= pEv->changedVirtualMods;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->namesNotifyMask&pEv->changed)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbNamesNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->changedIndicators = changedIndicators;
+ pEv->changedVirtualMods= changedVirtualMods;
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ swaps(&pEv->changed);
+ swapl(&pEv->changedIndicators);
+ swaps(&pEv->changedVirtualMods);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD16 firstSI = 0, nSI = 0, nTotalSI = 0;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->compatNotifyMask)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbCompatMapNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ firstSI= pEv->firstSI;
+ nSI= pEv->nSI;
+ nTotalSI= pEv->nTotalSI;
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->firstSI = firstSI;
+ pEv->nSI = nSI;
+ pEv->nTotalSI = nTotalSI;
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ swaps(&pEv->firstSI);
+ swaps(&pEv->nSI);
+ swaps(&pEv->nTotalSI);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv)
+{
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time = 0;
+
+ xkbi = kbd->key->xkbInfo;
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ pEv->mods= xkbi->state.mods;
+ pEv->group= xkbi->state.group;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->actionMessageMask)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbActionMessage;
+ pEv->deviceID = kbd->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendExtensionDeviceNotify( DeviceIntPtr dev,
+ ClientPtr client,
+ xkbExtensionDeviceNotify * pEv)
+{
+int initialized;
+XkbInterestPtr interest;
+Time time = 0;
+CARD32 defined, state;
+CARD16 reason, supported = 0;
+
+ interest = dev->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ reason= pEv->reason;
+ defined= pEv->ledsDefined;
+ state= pEv->ledState;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->extDevNotifyMask&reason)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbExtensionDeviceNotify;
+ pEv->deviceID = dev->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ supported= pEv->supported;
+ initialized= 1;
+ }
+ else {
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->ledsDefined= defined;
+ pEv->ledState= state;
+ pEv->reason= reason;
+ pEv->supported= supported;
+ }
+ if (client!=interest->client) {
+ /* only report UnsupportedFeature to the client that */
+ /* issued the failing request */
+ pEv->reason&= ~XkbXI_UnsupportedFeatureMask;
+ if ((interest->extDevNotifyMask&reason)==0)
+ continue;
+ }
+ if ( interest->client->swapped ) {
+ swaps(&pEv->sequenceNumber);
+ swapl(&pEv->time);
+ swapl(&pEv->ledsDefined);
+ swapl(&pEv->ledState);
+ swaps(&pEv->reason);
+ swaps(&pEv->supported);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+XkbSendNotification( DeviceIntPtr kbd,
+ XkbChangesPtr pChanges,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= NULL;
+ if (pChanges->state_changes) {
+ xkbStateNotify sn;
+ sn.changed= pChanges->state_changes;
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ XkbSendStateNotify(kbd,&sn);
+ }
+ if (pChanges->map.changed) {
+ xkbMapNotify mn;
+ memset(&mn, 0, sizeof(xkbMapNotify));
+ mn.changed= pChanges->map.changed;
+ mn.firstType= pChanges->map.first_type;
+ mn.nTypes= pChanges->map.num_types;
+ mn.firstKeySym= pChanges->map.first_key_sym;
+ mn.nKeySyms= pChanges->map.num_key_syms;
+ mn.firstKeyAct= pChanges->map.first_key_act;
+ mn.nKeyActs= pChanges->map.num_key_acts;
+ mn.firstKeyBehavior= pChanges->map.first_key_behavior;
+ mn.nKeyBehaviors= pChanges->map.num_key_behaviors;
+ mn.virtualMods= pChanges->map.vmods;
+ mn.firstKeyExplicit= pChanges->map.first_key_explicit;
+ mn.nKeyExplicit= pChanges->map.num_key_explicit;
+ mn.firstModMapKey= pChanges->map.first_modmap_key;
+ mn.nModMapKeys= pChanges->map.num_modmap_keys;
+ mn.firstVModMapKey= pChanges->map.first_vmodmap_key;
+ mn.nVModMapKeys= pChanges->map.num_vmodmap_keys;
+ XkbSendMapNotify(kbd,&mn);
+ }
+ if ((pChanges->ctrls.changed_ctrls)||
+ (pChanges->ctrls.enabled_ctrls_changes)) {
+ xkbControlsNotify cn;
+ memset(&cn, 0, sizeof(xkbControlsNotify));
+ cn.changedControls= pChanges->ctrls.changed_ctrls;
+ cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes;
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+ if (pChanges->indicators.map_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ memset(&in, 0, sizeof(xkbIndicatorNotify));
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.map_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in);
+ }
+ if (pChanges->indicators.state_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ memset(&in, 0, sizeof(xkbIndicatorNotify));
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.state_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in);
+ }
+ if (pChanges->names.changed) {
+ xkbNamesNotify nn;
+ memset(&nn, 0, sizeof(xkbNamesNotify));
+ nn.changed= pChanges->names.changed;
+ nn.firstType= pChanges->names.first_type;
+ nn.nTypes= pChanges->names.num_types;
+ nn.firstLevelName= pChanges->names.first_lvl;
+ nn.nLevelNames= pChanges->names.num_lvls;
+ nn.nRadioGroups= pChanges->names.num_rg;
+ nn.changedVirtualMods= pChanges->names.changed_vmods;
+ nn.changedIndicators= pChanges->names.changed_indicators;
+ XkbSendNamesNotify(kbd,&nn);
+ }
+ if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) {
+ xkbCompatMapNotify cmn;
+ memset(&cmn, 0, sizeof(xkbCompatMapNotify));
+ cmn.changedGroups= pChanges->compat.changed_groups;
+ cmn.firstSI= pChanges->compat.first_si;
+ cmn.nSI= pChanges->compat.num_si;
+ cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si;
+ XkbSendCompatMapNotify(kbd,&cmn);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE)
+{
+int i, button_mask;
+DeviceIntPtr pXDev = (DeviceIntPtr)LookupKeyboardDevice();
+XkbSrvInfoPtr xkbi;
+
+ xkbi= pXDev->key->xkbInfo;
+ if ( pClient->xkbClientFlags & _XkbClientInitialized ) {
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x10)&&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ ErrorF("XKbFilterWriteEvents:\n");
+ ErrorF(" Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+ ErrorF(" XkbLastRepeatEvent!=xE (0x%x!=0x%x) %s\n",
+ XkbLastRepeatEvent,xE,
+ ((XkbLastRepeatEvent!=(void *)xE)?"True":"False"));
+ ErrorF(" (xkbClientEventsFlags&XWDA)==0 (0x%x) %s\n",
+ pClient->xkbClientFlags,
+ (_XkbWantsDetectableAutoRepeat(pClient)?"True":"False"));
+ ErrorF(" !IsRelease(%d) %s\n",xE[0].u.u.type,
+ (!_XkbIsReleaseEvent(xE[0].u.u.type))?"True":"False");
+ }
+#endif /* DEBUG */
+ if ( (XkbLastRepeatEvent==(void *)xE) &&
+ (_XkbWantsDetectableAutoRepeat(pClient)) &&
+ (_XkbIsReleaseEvent(xE[0].u.u.type)) ) {
+ return False;
+ }
+ if ((pXDev->grab != NullGrab) && pXDev->fromPassiveGrab &&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ register unsigned state,flags;
+
+ flags= pClient->xkbClientFlags;
+ state= xkbi->state.compat_grab_mods;
+ if (flags & XkbPCF_GrabsUseXKBStateMask) {
+ int group;
+ if (flags&XkbPCF_LookupStateWhenGrabbed) {
+ group= xkbi->state.group;
+ state= xkbi->state.lookup_mods;
+ }
+ else {
+ state= xkbi->state.grab_mods;
+ group= xkbi->state.base_group+xkbi->state.latched_group;
+ if ((group<0)||(group>=xkbi->desc->ctrls->num_groups)) {
+ group= XkbAdjustGroup(group,xkbi->desc->ctrls);
+ }
+ }
+ state = XkbBuildCoreState(state, group);
+ }
+ else if (flags&XkbPCF_LookupStateWhenGrabbed)
+ state= xkbi->state.compat_lookup_mods;
+ xE[0].u.keyButtonPointer.state= state;
+ }
+ button_mask = 1 << xE[0].u.u.detail;
+ if (xE[0].u.u.type == ButtonPress &&
+ ((xE[0].u.keyButtonPointer.state >> 7) & button_mask) == button_mask &&
+ (xkbi->lockedPtrButtons & button_mask) == button_mask) {
+#ifdef DEBUG
+ /* If the MouseKeys is pressed, and the "real" mouse is also pressed
+ * when the mouse is released, the server does not behave properly.
+ * Faking a release of the button here solves the problem.
+ */
+ ErrorF("Faking release of button %d\n", xE[0].u.u.detail);
+#endif
+ XkbDDXFakePointerButton(ButtonRelease, xE[0].u.u.detail);
+ }
+ }
+ else {
+ register CARD8 type;
+
+ for (i=0;i<nEvents;i++) {
+ type= xE[i].u.u.type;
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ XkbStatePtr s= &xkbi->state;
+ ErrorF("XKbFilterWriteEvents (non-XKB):\n");
+ ErrorF("event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+ ErrorF("lookup= 0x%02x, grab= 0x%02x\n",s->lookup_mods,
+ s->grab_mods);
+ ErrorF("compat lookup= 0x%02x, grab= 0x%02x\n",
+ s->compat_lookup_mods,
+ s->compat_grab_mods);
+ }
+#endif
+ if ( (type>=KeyPress)&&(type<=MotionNotify) ) {
+ CARD16 old,new;
+
+ old= xE[i].u.keyButtonPointer.state&(~0x1f00);
+ new= xE[i].u.keyButtonPointer.state&0x1F00;
+
+ if (old==XkbStateFieldFromRec(&xkbi->state))
+ new|= xkbi->state.compat_lookup_mods;
+ else new|= xkbi->state.compat_grab_mods;
+ xE[i].u.keyButtonPointer.state= new;
+ }
+ else if ((type==EnterNotify)||(type==LeaveNotify)) {
+ xE->u.enterLeave.state&= 0x1F00;
+ xE->u.enterLeave.state|= xkbi->state.compat_grab_mods;
+ }
+ button_mask = 1 << xE[i].u.u.detail;
+ if (type == ButtonPress &&
+ ((xE[i].u.keyButtonPointer.state >> 7) & button_mask) == button_mask &&
+ (xkbi->lockedPtrButtons & button_mask) == button_mask) {
+#ifdef DEBUG
+ ErrorF("Faking release of button %d\n", xE[i].u.u.detail);
+#endif
+ XkbDDXFakePointerButton(ButtonRelease, xE[i].u.u.detail);
+ }
+ }
+ }
+ return True;
+}
+
+/***====================================================================***/
+
+XkbInterestPtr
+XkbFindClientResource(DevicePtr inDev,ClientPtr client)
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ while (interest){
+ if (interest->client==client) {
+ return interest;
+ }
+ interest = interest->next;
+ }
+ }
+ return NULL;
+}
+
+XkbInterestPtr
+XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id)
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ interest = dev->xkb_interest;
+ while (interest) {
+ if (interest->client==client)
+ return ((interest->resource==id)?interest:NULL);
+ interest = interest->next;
+ }
+ interest = _XkbTypedAlloc(XkbInterestRec);
+ bzero(interest,sizeof(XkbInterestRec));
+ if (interest) {
+ interest->dev = dev;
+ interest->client = client;
+ interest->resource = id;
+ interest->stateNotifyMask= 0;
+ interest->ctrlsNotifyMask= 0;
+ interest->namesNotifyMask= 0;
+ interest->compatNotifyMask= 0;
+ interest->bellNotifyMask= FALSE;
+ interest->accessXNotifyMask= 0;
+ interest->iStateNotifyMask= 0;
+ interest->iMapNotifyMask= 0;
+ interest->altSymsNotifyMask= 0;
+ interest->next = dev->xkb_interest;
+ dev->xkb_interest= interest;
+ return interest;
+ }
+ return NULL;
+}
+
+int
+XkbRemoveClient(DevicePtr inDev,ClientPtr client)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+unsigned long autoCtrls,autoValues;
+Bool found;
+
+ found= False;
+ autoCtrls= autoValues= 0;
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ if (interest && (interest->client==client)){
+ dev->xkb_interest = interest->next;
+ autoCtrls= interest->autoCtrls;
+ autoValues= interest->autoCtrlValues;
+ _XkbFree(interest);
+ found= True;
+ }
+ while ((!found)&&(interest->next)) {
+ if (interest->next->client==client) {
+ XkbInterestPtr victim = interest->next;
+ interest->next = victim->next;
+ autoCtrls= victim->autoCtrls;
+ autoValues= victim->autoCtrlValues;
+ _XkbFree(victim);
+ found= True;
+ }
+ interest = interest->next;
+ }
+ }
+ if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
+ XkbEventCauseRec cause;
+
+ xkbi= dev->key->xkbInfo;
+ XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
+ XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
+ }
+ return found;
+}
+
+int
+XkbRemoveResourceClient(DevicePtr inDev,XID id)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+Bool found;
+unsigned long autoCtrls,autoValues;
+ClientPtr client = NULL;
+
+ found= False;
+ autoCtrls= autoValues= 0;
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ if (interest && (interest->resource==id)){
+ dev->xkb_interest = interest->next;
+ autoCtrls= interest->autoCtrls;
+ autoValues= interest->autoCtrlValues;
+ client= interest->client;
+ _XkbFree(interest);
+ found= True;
+ }
+ while ((!found)&&(interest->next)) {
+ if (interest->next->resource==id) {
+ XkbInterestPtr victim = interest->next;
+ interest->next = victim->next;
+ autoCtrls= victim->autoCtrls;
+ autoValues= victim->autoCtrlValues;
+ client= victim->client;
+ _XkbFree(victim);
+ found= True;
+ }
+ interest = interest->next;
+ }
+ }
+ if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
+ XkbEventCauseRec cause;
+
+ xkbi= dev->key->xkbInfo;
+ XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
+ XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
+ }
+ return found;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbInit.c b/nx-X11/programs/Xserver/xkb/xkbInit.c
new file mode 100644
index 000000000..4553cce9e
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbInit.c
@@ -0,0 +1,1045 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef HAVE_XKB_CONFIG_H
+#include <xkb-config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/Xatom.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "opaque.h"
+#include "property.h"
+#include "scrnintstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include <nx-X11/extensions/XKMformat.h>
+#include "xkbfile.h"
+#include "xkb.h"
+
+#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1)
+
+#if defined(ultrix) || defined(__alpha) || defined(__alpha__)
+#define LED_COMPOSE 2
+#define LED_CAPS 3
+#define LED_SCROLL 4
+#define LED_NUM 5
+#define PHYS_LEDS 0x1f
+#else
+#ifdef sun
+#define LED_NUM 1
+#define LED_SCROLL 2
+#define LED_COMPOSE 3
+#define LED_CAPS 4
+#define PHYS_LEDS 0x0f
+#else
+#define LED_CAPS 1
+#define LED_NUM 2
+#define LED_SCROLL 3
+#define PHYS_LEDS 0x07
+#endif
+#endif
+
+#define MAX_TOC 16
+typedef struct _SrvXkmInfo {
+ DeviceIntPtr dev;
+ FILE * file;
+ XkbFileInfo xkbinfo;
+} SrvXkmInfo;
+
+
+/***====================================================================***/
+
+#ifndef XKB_BASE_DIRECTORY
+#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb"
+#endif
+#ifndef XKB_BIN_DIRECTORY
+#define XKB_BIN_DIRECTORY XKB_BASE_DIRECTORY
+#endif
+#ifndef XKB_DFLT_RULES_FILE
+#define XKB_DFLT_RULES_FILE "base"
+#endif
+#ifndef XKB_DFLT_KB_LAYOUT
+#define XKB_DFLT_KB_LAYOUT "us"
+#endif
+#ifndef XKB_DFLT_KB_MODEL
+#define XKB_DFLT_KB_MODEL "dflt"
+#endif
+#ifndef XKB_DFLT_KB_VARIANT
+#define XKB_DFLT_KB_VARIANT NULL
+#endif
+#ifndef XKB_DFLT_KB_OPTIONS
+#define XKB_DFLT_KB_OPTIONS NULL
+#endif
+#ifndef XKB_DFLT_DISABLED
+#define XKB_DFLT_DISABLED True
+#endif
+#ifndef XKB_DFLT_RULES_PROP
+#define XKB_DFLT_RULES_PROP True
+#endif
+
+char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
+char * XkbBinDirectory= XKB_BIN_DIRECTORY;
+char * XkbInitialMap= NULL;
+int XkbWantAccessX= 0;
+static XkbFileInfo * _XkbInitFileInfo= NULL;
+char * XkbDB= NULL;
+int XkbAutoLoad= 1;
+
+static Bool rulesDefined= False;
+static char * XkbRulesFile= NULL;
+static char * XkbModelDflt= NULL;
+static char * XkbLayoutDflt= NULL;
+static char * XkbVariantDflt= NULL;
+static char * XkbOptionsDflt= NULL;
+
+char * XkbModelUsed= NULL;
+char * XkbLayoutUsed= NULL;
+char * XkbVariantUsed= NULL;
+char * XkbOptionsUsed= NULL;
+
+int _XkbClientMajor= XkbMajorVersion;
+int _XkbClientMinor= XkbMinorVersion;
+
+Bool noXkbExtension= XKB_DFLT_DISABLED;
+Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
+
+/***====================================================================***/
+
+char *
+XkbGetRulesDflts(XkbRF_VarDefsPtr defs)
+{
+ if (XkbModelDflt) defs->model= XkbModelDflt;
+ else defs->model= XKB_DFLT_KB_MODEL;
+ if (XkbLayoutDflt) defs->layout= XkbLayoutDflt;
+ else defs->layout= XKB_DFLT_KB_LAYOUT;
+ if (XkbVariantDflt) defs->variant= XkbVariantDflt;
+ else defs->variant= XKB_DFLT_KB_VARIANT;
+ if (XkbOptionsDflt) defs->options= XkbOptionsDflt;
+ else defs->options= XKB_DFLT_KB_OPTIONS;
+ return (rulesDefined?XkbRulesFile:XKB_DFLT_RULES_FILE);
+}
+
+Bool
+XkbWriteRulesProp(ClientPtr client, void * closure)
+{
+int len,out;
+Atom name;
+char * pval;
+
+ if (rulesDefined && (!XkbRulesFile))
+ return False;
+ len= (XkbRulesFile?strlen(XkbRulesFile):strlen(XKB_DFLT_RULES_FILE));
+ len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+ len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+ len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+ len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+ if (len<1)
+ return True;
+
+ len+= 5; /* trailing NULs */
+
+ name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
+ if (name==None) {
+ ErrorF("Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ pval= (char*) malloc(len);
+ if (!pval) {
+ ErrorF("Allocation error: %s proprerty not created\n",
+ _XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ out= 0;
+ if (XkbRulesFile) {
+ strcpy(&pval[out],XkbRulesFile);
+ out+= strlen(XkbRulesFile);
+ } else {
+ strcpy(&pval[out],XKB_DFLT_RULES_FILE);
+ out+= strlen(XKB_DFLT_RULES_FILE);
+ }
+ pval[out++]= '\0';
+ if (XkbModelUsed) {
+ strcpy(&pval[out],XkbModelUsed);
+ out+= strlen(XkbModelUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbLayoutUsed) {
+ strcpy(&pval[out],XkbLayoutUsed);
+ out+= strlen(XkbLayoutUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbVariantUsed) {
+ strcpy(&pval[out],XkbVariantUsed);
+ out+= strlen(XkbVariantUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbOptionsUsed) {
+ strcpy(&pval[out],XkbOptionsUsed);
+ out+= strlen(XkbOptionsUsed);
+ }
+ pval[out++]= '\0';
+ if (out!=len) {
+ ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
+ out,len);
+ }
+ ChangeWindowProperty(screenInfo.screens[0]->root,name,XA_STRING,8,PropModeReplace,
+ len,pval,True);
+ free(pval);
+ return True;
+}
+
+void
+XkbSetRulesUsed(XkbRF_VarDefsPtr defs)
+{
+ if (XkbModelUsed)
+ _XkbFree(XkbModelUsed);
+ XkbModelUsed= (defs->model?Xstrdup(defs->model):NULL);
+ if (XkbLayoutUsed)
+ _XkbFree(XkbLayoutUsed);
+ XkbLayoutUsed= (defs->layout?Xstrdup(defs->layout):NULL);
+ if (XkbVariantUsed)
+ _XkbFree(XkbVariantUsed);
+ XkbVariantUsed= (defs->variant?Xstrdup(defs->variant):NULL);
+ if (XkbOptionsUsed)
+ _XkbFree(XkbOptionsUsed);
+ XkbOptionsUsed= (defs->options?Xstrdup(defs->options):NULL);
+ if (XkbWantRulesProp)
+ QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+ return;
+}
+
+/**
+ * Set the default RMLVO for the next device to be initialised.
+ * If a parameter is NULL, the previous setting will be used. Use empty
+ * strings if you want to delete a previous setting.
+ *
+ * If @rulesFile is NULL and no previous @rulesFile has been set, the
+ * built-in default is chosen as default.
+ */
+
+void
+XkbSetRulesDflts(char *rulesFile,char *model,char *layout,
+ char *variant,char *options)
+{
+ if (!rulesFile && !XkbRulesFile)
+ {
+ LogMessage(X_WARNING, "[xkb] No rule given, and no previous rule "
+ "defined. Defaulting to '%s'.\n",
+ XKB_DFLT_RULES_FILE);
+ rulesFile = XKB_DFLT_RULES_FILE;
+ }
+
+ if (rulesFile) {
+ if (XkbRulesFile)
+ _XkbFree(XkbRulesFile);
+ XkbRulesFile= Xstrdup(rulesFile);
+ rulesDefined= True;
+ }
+
+ if (model) {
+ if (XkbModelDflt)
+ _XkbFree(XkbModelDflt);
+ XkbModelDflt= Xstrdup(model);
+ }
+ if (layout) {
+ if (XkbLayoutDflt)
+ _XkbFree(XkbLayoutDflt);
+ XkbLayoutDflt= Xstrdup(layout);
+ }
+ if (variant) {
+ if (XkbVariantDflt)
+ _XkbFree(XkbVariantDflt);
+ XkbVariantDflt= Xstrdup(variant);
+ }
+ if (options) {
+ if (XkbOptionsDflt)
+ _XkbFree(XkbOptionsDflt);
+ XkbOptionsDflt= Xstrdup(options);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+#if defined(luna)
+#define XKB_DDX_PERMANENT_LOCK 1
+#endif
+
+#include "xkbDflts.h"
+
+/* A dummy to keep the compiler quiet */
+void * xkbBogus = &indicators;
+
+static Bool
+XkbInitKeyTypes(XkbDescPtr xkb,SrvXkmInfo *file)
+{
+ if (file->xkbinfo.defined&XkmTypesMask)
+ return True;
+ initTypeNames(NULL);
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
+ return False;
+ if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
+ Success) {
+ return False;
+ }
+ xkb->map->size_types= xkb->map->num_types= num_dflt_types;
+ return True;
+}
+
+static void
+XkbInitRadioGroups(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+{
+ xkbi->nRadioGroups = 0;
+ xkbi->radioGroups = NULL;
+ return;
+}
+
+
+static Status
+XkbInitCompatStructs(XkbDescPtr xkb,SrvXkmInfo *file)
+{
+register int i;
+XkbCompatMapPtr compat;
+
+ if (file->xkbinfo.defined&XkmCompatMapMask)
+ return Success;
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
+ return BadAlloc;
+ compat = xkb->compat;
+ if (compat->sym_interpret) {
+ compat->num_si = num_dfltSI;
+ memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ compat->groups[i]= compatMap.groups[i];
+ if (compat->groups[i].vmods!=0) {
+ unsigned mask;
+ mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
+ compat->groups[i].mask= compat->groups[i].real_mods|mask;
+ }
+ else compat->groups[i].mask= compat->groups[i].real_mods;
+ }
+ return Success;
+}
+
+static void
+XkbInitSemantics(XkbDescPtr xkb,SrvXkmInfo *file)
+{
+ XkbInitKeyTypes(xkb,file);
+ XkbInitCompatStructs(xkb,file);
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+XkbInitNames(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+{
+XkbDescPtr xkb;
+XkbNamesPtr names;
+Status rtrn;
+Atom unknown;
+
+ xkb= xkbi->desc;
+ if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
+ return rtrn;
+ unknown= CREATE_ATOM("unknown");
+ names = xkb->names;
+ if (names->keycodes==None) names->keycodes= unknown;
+ if (names->geometry==None) names->geometry= unknown;
+ if (names->phys_symbols==None) names->phys_symbols= unknown;
+ if (names->symbols==None) names->symbols= unknown;
+ if (names->types==None) names->types= unknown;
+ if (names->compat==None) names->compat= unknown;
+ if ((file->xkbinfo.defined&XkmVirtualModsMask)==0) {
+ if (names->vmods[vmod_NumLock]==None)
+ names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
+ if (names->vmods[vmod_Alt]==None)
+ names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
+ if (names->vmods[vmod_AltGr]==None)
+ names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
+ }
+
+ if (((file->xkbinfo.defined&XkmIndicatorsMask)==0)||
+ ((file->xkbinfo.defined&XkmGeometryMask)==0)) {
+ initIndicatorNames(NULL,xkb);
+ if (names->indicators[LED_CAPS-1]==None)
+ names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
+ if (names->indicators[LED_NUM-1]==None)
+ names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
+ if (names->indicators[LED_SCROLL-1]==None)
+ names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
+#ifdef LED_COMPOSE
+ if (names->indicators[LED_COMPOSE-1]==None)
+ names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
+#endif
+ }
+#ifdef DEBUG_RADIO_GROUPS
+ if (names->num_rg<1) {
+ names->radio_groups= (Atom *)_XkbCalloc(RG_COUNT, sizeof(Atom));
+ if (names->radio_groups) {
+ names->num_rg = RG_COUNT;
+ names->radio_groups[RG_BOGUS_FUNCTION_GROUP]= CREATE_ATOM("BOGUS");
+ }
+ }
+#endif
+ if (xkb->geom!=NULL)
+ names->geometry= xkb->geom->name;
+ else names->geometry= unknown;
+ return Success;
+}
+
+static Status
+XkbInitIndicatorMap(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+{
+XkbDescPtr xkb;
+XkbIndicatorPtr map;
+XkbSrvLedInfoPtr sli;
+
+ xkb= xkbi->desc;
+ if (XkbAllocIndicatorMaps(xkb)!=Success)
+ return BadAlloc;
+ if ((file->xkbinfo.defined&XkmIndicatorsMask)==0) {
+ map= xkb->indicators;
+ map->phys_indicators = PHYS_LEDS;
+ map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_CAPS-1].mods.mask= LockMask;
+ map->maps[LED_CAPS-1].mods.real_mods= LockMask;
+
+ map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_NUM-1].mods.mask= 0;
+ map->maps[LED_NUM-1].mods.real_mods= 0;
+ map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
+
+/* Metro Link */
+ map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_SCROLL-1].mods.mask= Mod3Mask;
+ map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask;
+/* Metro Link */
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+ return Success;
+}
+
+static Status
+XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+{
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ xkb= xkbi->desc;
+ /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ FatalError("Couldn't allocate keyboard controls\n");
+ ctrls= xkb->ctrls;
+ if ((file->xkbinfo.defined&XkmSymbolsMask)==0)
+ ctrls->num_groups = 1;
+ ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
+ ctrls->internal.mask = 0;
+ ctrls->internal.real_mods = 0;
+ ctrls->internal.vmods = 0;
+ ctrls->ignore_lock.mask = 0;
+ ctrls->ignore_lock.real_mods = 0;
+ ctrls->ignore_lock.vmods = 0;
+ ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
+ XkbMouseKeysAccelMask|XkbAudibleBellMask|
+ XkbIgnoreGroupLockMask;
+ if (XkbWantAccessX)
+ ctrls->enabled_ctrls|= XkbAccessXKeysMask;
+ AccessXInit(pXDev);
+ return Success;
+}
+
+void
+XkbInitDevice(DeviceIntPtr pXDev)
+{
+int i;
+XkbSrvInfoPtr xkbi;
+XkbChangesRec changes;
+SrvXkmInfo file;
+unsigned check;
+XkbEventCauseRec cause;
+
+ file.dev= pXDev;
+ file.file=NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ bzero(&changes,sizeof(XkbChangesRec));
+ if (XkbAutoLoad && (XkbInitialMap!=NULL)) {
+ if ((file.file=XkbDDXOpenConfigFile(XkbInitialMap,NULL,0))!=NULL) {
+ XkmReadFile(file.file,0,XkmKeymapLegal,&file.xkbinfo);
+ if (file.xkbinfo.xkb==NULL) {
+ LogMessage(X_ERROR,
+ "Error loading keymap file %s (%s in %s)\n"
+ "\treverting to defaults\n",
+ XkbInitialMap, _XkbErrMessages[_XkbErrCode],
+ (_XkbErrLocation?_XkbErrLocation:"unknown"));
+ fclose(file.file);
+ file.file= NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ }
+ else {
+ if (_XkbInitFileInfo!=NULL) {
+ XkbDescPtr tmp;
+ if ((tmp=_XkbInitFileInfo->xkb)!=NULL) {
+ XkbFreeKeyboard(tmp,XkbAllComponentsMask,True);
+ _XkbInitFileInfo->xkb= NULL;
+ }
+ }
+ _XkbInitFileInfo= &file.xkbinfo;
+ }
+ }
+ else {
+ LogMessage(X_ERROR, "Error opening keymap file %s, reverting to defaults\n",
+ XkbInitialMap);
+ }
+ }
+ pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec);
+ if ( xkbi ) {
+ XkbDescPtr xkb;
+ if ((_XkbInitFileInfo!=NULL)&&(_XkbInitFileInfo->xkb!=NULL)) {
+ file.xkbinfo= *_XkbInitFileInfo;
+ xkbi->desc= _XkbInitFileInfo->xkb;
+ _XkbInitFileInfo= NULL;
+ }
+ else {
+ xkbi->desc= XkbAllocKeyboard();
+ if (!xkbi->desc)
+ FatalError("Couldn't allocate keyboard description\n");
+ xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ }
+ xkb= xkbi->desc;
+ if (xkb->min_key_code == 0)
+ xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ if (xkb->max_key_code == 0)
+ xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)||
+ (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) {
+ /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */
+ /* the other here, but for now just complain */
+ /* can't just update the core range without */
+ /* reallocating the KeySymsRec (pain) */
+ ErrorF("Internal Error!! XKB and core keymap have different range\n");
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success)
+ FatalError("Couldn't allocate client map in XkbInitDevice\n");
+ i= XkbNumKeys(xkb)/3+1;
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success)
+ FatalError("Couldn't allocate server map in XkbInitDevice\n");
+
+ xkbi->dfltPtrDelta=1;
+ xkbi->device = pXDev;
+
+ file.xkbinfo.xkb= xkb;
+ XkbInitSemantics(xkb,&file);
+ XkbInitNames(xkbi,&file);
+ XkbInitRadioGroups(xkbi,&file);
+
+ /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */
+ bzero(&xkbi->state,sizeof(XkbStateRec));
+
+ XkbInitControls(pXDev,xkbi,&file);
+
+ if (file.xkbinfo.defined&XkmSymbolsMask)
+ memcpy(pXDev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ else
+ memcpy(xkb->map->modmap,pXDev->key->modifierMap,xkb->max_key_code+1);
+
+ XkbInitIndicatorMap(xkbi,&file);
+
+ XkbDDXInitDevice(pXDev);
+
+ if (!(file.xkbinfo.defined&XkmSymbolsMask)) {
+ XkbUpdateKeyTypesFromCore(pXDev,xkb->min_key_code,XkbNumKeys(xkb),
+ &changes);
+ }
+ else {
+ XkbUpdateCoreDescription(pXDev,True);
+ }
+ XkbSetCauseUnknown(&cause);
+ XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes,
+ &check,&cause);
+ /* For sanity. The first time the connection
+ * is opened, the client side min and max are set
+ * using QueryMinMaxKeyCodes() which grabs them
+ * from pXDev.
+ */
+ pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code;
+ pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code;
+ }
+ if (file.file!=NULL)
+ fclose(file.file);
+ return;
+}
+
+#if MAP_LENGTH > XkbMaxKeyCount
+#undef XkbMaxKeyCount
+#define XkbMaxKeyCount MAP_LENGTH
+#endif
+
+Bool
+XkbInitKeyboardDeviceStruct(
+ DeviceIntPtr dev,
+ XkbComponentNamesPtr names,
+ KeySymsPtr pSymsIn,
+ CARD8 pModsIn[],
+ void (*bellProc)(
+ int /*percent*/,
+ DeviceIntPtr /*device*/,
+ void * /*ctrl*/,
+ int),
+ void (*ctrlProc)(
+ DeviceIntPtr /*device*/,
+ KeybdCtrl * /*ctrl*/))
+{
+XkbFileInfo finfo;
+KeySymsRec tmpSyms,*pSyms;
+CARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods;
+char name[PATH_MAX],*rules;
+Bool ok=False;
+XPointer config;
+XkbComponentNamesRec cfgNames;
+XkbRF_VarDefsRec defs;
+
+ if ((dev->key!=NULL)||(dev->kbdfeed!=NULL))
+ return False;
+ pSyms= pSymsIn;
+ pMods= pModsIn;
+ bzero(&defs,sizeof(XkbRF_VarDefsRec));
+ bzero(&cfgNames,sizeof(XkbComponentNamesRec));
+ rules= XkbGetRulesDflts(&defs);
+ config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev);
+
+ /*
+ * The strings are duplicated because it is not guaranteed that
+ * they are allocated, or that they are allocated for every server
+ * generation. Eventually they will be freed at the end of this
+ * function.
+ */
+ if (names->keymap) names->keymap = Xstrdup(names->keymap);
+ if (names->keycodes) names->keycodes = Xstrdup(names->keycodes);
+ if (names->types) names->types = Xstrdup(names->types);
+ if (names->compat) names->compat = Xstrdup(names->compat);
+ if (names->geometry) names->geometry = Xstrdup(names->geometry);
+ if (names->symbols) names->symbols = Xstrdup(names->symbols);
+
+ if (defs.model && defs.layout && rules) {
+ XkbComponentNamesRec rNames;
+ bzero(&rNames,sizeof(XkbComponentNamesRec));
+ if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) {
+ if (rNames.keymap) {
+ if (!names->keymap)
+ names->keymap = rNames.keymap;
+ else _XkbFree(rNames.keymap);
+ }
+ if (rNames.keycodes) {
+ if (!names->keycodes)
+ names->keycodes = rNames.keycodes;
+ else
+ _XkbFree(rNames.keycodes);
+ }
+ if (rNames.types) {
+ if (!names->types)
+ names->types = rNames.types;
+ else _XkbFree(rNames.types);
+ }
+ if (rNames.compat) {
+ if (!names->compat)
+ names->compat = rNames.compat;
+ else _XkbFree(rNames.compat);
+ }
+ if (rNames.symbols) {
+ if (!names->symbols)
+ names->symbols = rNames.symbols;
+ else _XkbFree(rNames.symbols);
+ }
+ if (rNames.geometry) {
+ if (!names->geometry)
+ names->geometry = rNames.geometry;
+ else _XkbFree(rNames.geometry);
+ }
+ XkbSetRulesUsed(&defs);
+ }
+ }
+ if (cfgNames.keymap){
+ if (names->keymap) _XkbFree(names->keymap);
+ names->keymap= cfgNames.keymap;
+ }
+ if (cfgNames.keycodes){
+ if (names->keycodes) _XkbFree(names->keycodes);
+ names->keycodes= cfgNames.keycodes;
+ }
+ if (cfgNames.types) {
+ if (names->types) _XkbFree(names->types);
+ names->types= cfgNames.types;
+ }
+ if (cfgNames.compat) {
+ if (names->compat) _XkbFree(names->compat);
+ names->compat= cfgNames.compat;
+ }
+ if (cfgNames.symbols){
+ if (names->symbols) _XkbFree(names->symbols);
+ names->symbols= cfgNames.symbols;
+ }
+ if (cfgNames.geometry) {
+ if (names->geometry) _XkbFree(names->geometry);
+ names->geometry= cfgNames.geometry;
+ }
+
+ if (names->keymap) {
+ XkbComponentNamesRec tmpNames;
+ bzero(&tmpNames,sizeof(XkbComponentNamesRec));
+ tmpNames.keymap = names->keymap;
+ ok = (Bool) XkbDDXLoadKeymapByNames(dev,&tmpNames,XkmAllIndicesMask,0,
+ &finfo,name,PATH_MAX);
+ }
+ if (!(ok && (finfo.xkb!=NULL)))
+ ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0,
+ &finfo,name,PATH_MAX);
+
+ if (ok && (finfo.xkb!=NULL)) {
+ XkbDescPtr xkb;
+ KeyCode minKC,maxKC;
+
+ xkb= finfo.xkb;
+ minKC= xkb->min_key_code;
+ maxKC= xkb->max_key_code;
+ if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&&
+ ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) {
+ if (xkb->map!=NULL) {
+ KeySym *inSym,*outSym;
+ int width= pSymsIn->mapWidth;
+
+ tmpSyms.minKeyCode= minKC;
+ tmpSyms.maxKeyCode= maxKC;
+
+ if (minKC<pSymsIn->minKeyCode)
+ minKC= pSymsIn->minKeyCode;
+ if (maxKC>pSymsIn->maxKeyCode)
+ maxKC= pSymsIn->maxKeyCode;
+
+ tmpSyms.mapWidth= width;
+ tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym);
+ inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width];
+ outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width];
+ memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym));
+ pSyms= &tmpSyms;
+ }
+ if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) {
+ bzero(tmpMods,XkbMaxKeyCount);
+ memcpy(tmpMods,xkb->map->modmap,maxKC+1);
+ pMods= tmpMods;
+ }
+ }
+ _XkbInitFileInfo= &finfo;
+ }
+ else {
+ LogMessage(X_WARNING, "Couldn't load XKB keymap, falling back to pre-XKB keymap\n");
+ }
+ ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc);
+ if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo))
+ XkbDDXApplyConfig(config,dev->key->xkbInfo);
+ _XkbInitFileInfo= NULL;
+ if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) {
+ _XkbFree(pSyms->map);
+ pSyms->map= NULL;
+ }
+
+ if (names->keymap) _XkbFree(names->keymap);
+ names->keymap = NULL;
+ if (names->keycodes) _XkbFree(names->keycodes);
+ names->keycodes = NULL;
+ if (names->types) _XkbFree(names->types);
+ names->types = NULL;
+ if (names->compat) _XkbFree(names->compat);
+ names->compat = NULL;
+ if (names->geometry) _XkbFree(names->geometry);
+ names->geometry = NULL;
+ if (names->symbols) _XkbFree(names->symbols);
+ names->symbols = NULL;
+
+ return ok;
+}
+
+/***====================================================================***/
+
+ /*
+ * InitKeyClassDeviceStruct initializes the key class before it
+ * initializes the keyboard feedback class for a device.
+ * UpdateActions can't set up the correct autorepeat for keyboard
+ * initialization because the keyboard feedback isn't created yet.
+ * Instead, UpdateActions notes the "correct" autorepeat in the
+ * SrvInfo structure and InitKbdFeedbackClass calls UpdateAutoRepeat
+ * to apply the computed autorepeat once the feedback class exists.
+ *
+ * DIX will apply the changed autorepeat, so there's no need to
+ * do so here. This function returns True if both RepeatKeys and
+ * the core protocol autorepeat ctrls are set (i.e. should use
+ * software autorepeat), false otherwise.
+ *
+ * This function also computes the autorepeat accelerators for the
+ * default indicator feedback.
+ */
+int
+XkbFinishDeviceInit(DeviceIntPtr pXDev)
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+int softRepeat;
+XkbSrvLedInfoPtr sli;
+
+ xkbi = NULL;
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) {
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ if (pXDev->kbdfeed) {
+ xkbi->kbdProc= pXDev->kbdfeed->CtrlProc;
+ pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc;
+ }
+ if (pXDev->kbdfeed->ctrl.autoRepeat)
+ xkb->ctrls->enabled_ctrls|= XkbRepeatKeysMask;
+ softRepeat= (xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0;
+ if (pXDev->kbdfeed) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,
+ xkb->ctrls->per_key_repeat,XkbPerKeyBitArraySize);
+ softRepeat= softRepeat&&pXDev->kbdfeed->ctrl.autoRepeat;
+ }
+ }
+ else softRepeat= 0;
+ sli= XkbFindSrvLedInfo(pXDev,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli && xkbi)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+#ifdef DEBUG
+ else ErrorF("No indicator feedback in XkbFinishInit (shouldn't happen)!\n");
+#endif
+ return softRepeat;
+}
+
+ /*
+ * Be very careful about what does and doesn't get freed by this
+ * function. To reduce fragmentation, XkbInitDevice allocates a
+ * single huge block per device and divides it up into most of the
+ * fixed-size structures for the device. Don't free anything that
+ * is part of this larger block.
+ */
+void
+XkbFreeInfo(XkbSrvInfoPtr xkbi)
+{
+ if (xkbi->radioGroups) {
+ _XkbFree(xkbi->radioGroups);
+ xkbi->radioGroups= NULL;
+ }
+ if (xkbi->mouseKeyTimer) {
+ TimerFree(xkbi->mouseKeyTimer);
+ xkbi->mouseKeyTimer= NULL;
+ }
+ if (xkbi->slowKeysTimer) {
+ TimerFree(xkbi->slowKeysTimer);
+ xkbi->slowKeysTimer= NULL;
+ }
+ if (xkbi->bounceKeysTimer) {
+ TimerFree(xkbi->bounceKeysTimer);
+ xkbi->bounceKeysTimer= NULL;
+ }
+ if (xkbi->repeatKeyTimer) {
+ TimerFree(xkbi->repeatKeyTimer);
+ xkbi->repeatKeyTimer= NULL;
+ }
+ if (xkbi->krgTimer) {
+ TimerFree(xkbi->krgTimer);
+ xkbi->krgTimer= NULL;
+ }
+ xkbi->beepType= _BEEP_NONE;
+ if (xkbi->beepTimer) {
+ TimerFree(xkbi->beepTimer);
+ xkbi->beepTimer= NULL;
+ }
+ if (xkbi->desc) {
+ XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True);
+ xkbi->desc= NULL;
+ }
+ _XkbFree(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+extern unsigned short XkbDfltAccessXTimeout;
+extern unsigned int XkbDfltAccessXTimeoutMask;
+extern unsigned int XkbDfltAccessXFeedback;
+extern unsigned char XkbDfltAccessXOptions;
+
+int
+XkbProcessArguments(int argc,char *argv[],int i)
+{
+ if (strcmp(argv[i],"-kb")==0) {
+ noXkbExtension= True;
+ return 1;
+ }
+ else if (strcmp(argv[i],"+kb")==0) {
+ noXkbExtension= False;
+ return 1;
+ }
+ else if (strncmp(argv[i], "-xkbdir", 7) == 0) {
+ if(++i < argc) {
+#if !defined(WIN32) && !defined(__CYGWIN__)
+ if (getuid() != geteuid()) {
+ LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n");
+ return -1;
+ } else
+#endif
+ {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbBaseDirectory= argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbdir pathname too long\n");
+ return -1;
+ }
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-xkbmap", 7) == 0) {
+ if(++i < argc) {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbInitialMap= argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbmap pathname too long\n");
+ return -1;
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-xkbdb", 7) == 0) {
+ if(++i < argc) {
+ if (strlen(argv[i]) < PATH_MAX) {
+ XkbDB= argv[i];
+ return 2;
+ } else {
+ LogMessage(X_ERROR, "-xkbdb pathname too long\n");
+ return -1;
+ }
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-noloadxkb", 7) == 0) {
+ XkbAutoLoad= 0;
+ return 1;
+ }
+ else if ((strncmp(argv[i],"-accessx",8)==0)||
+ (strncmp(argv[i],"+accessx",8)==0)) {
+ int j=1;
+ if (argv[i][0]=='-')
+ XkbWantAccessX= 0;
+ else {
+ XkbWantAccessX= 1;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXTimeout = atoi(argv[++i]);
+ j++;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ /*
+ * presumption that the reasonably useful range of
+ * values fits in 0..MAXINT since SunOS 4 doesn't
+ * have strtoul.
+ */
+ XkbDfltAccessXTimeoutMask=(unsigned int)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ if (argv[++i][0] == '1' )
+ XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
+ else
+ XkbDfltAccessXFeedback=0;
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXOptions=(unsigned char)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ }
+ }
+ return j;
+ }
+ if (strcmp (argv[i], "-ar1") == 0) { /* -ar1 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatDelay = (long)atoi(argv[i]);
+ return 2;
+ }
+ if (strcmp (argv[i], "-ar2") == 0) { /* -ar2 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatInterval = (long)atoi(argv[i]);
+ return 2;
+ }
+ return 0;
+}
+
+void
+XkbUseMsg(void)
+{
+ ErrorF("The X Keyboard Extension adds the following arguments:\n");
+ ErrorF("-kb disable the X Keyboard Extension\n");
+ ErrorF("+kb enable the X Keyboard Extension\n");
+ ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
+ ErrorF(" enable/disable accessx key sequences\n");
+ ErrorF("-ar1 set XKB autorepeat delay\n");
+ ErrorF("-ar2 set XKB autorepeat interval\n");
+ ErrorF("-noloadxkb don't load XKB keymap description\n");
+ ErrorF("-xkbdb file that contains default XKB keymaps\n");
+ ErrorF("-xkbmap XKB keyboard description to load on startup\n");
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbLEDs.c b/nx-X11/programs/Xserver/xkb/xkbLEDs.c
new file mode 100644
index 000000000..a93d69f3f
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbLEDs.c
@@ -0,0 +1,1064 @@
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#include <nx-X11/extensions/XI.h>
+#include <xkbsrv.h>
+#include "xkb.h"
+
+/***====================================================================***/
+
+ /*
+ * unsigned
+ * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
+ *
+ * Given a keyboard and a set of state components that have changed,
+ * this function returns the indicators on the default keyboard
+ * feedback that might be affected. It also reports whether or not
+ * any extension devices might be affected in check_devs_rtrn.
+ */
+
+unsigned
+XkbIndicatorsToUpdate( DeviceIntPtr dev,
+ unsigned long state_changes,
+ Bool enable_changes)
+{
+register unsigned update= 0;
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+
+ if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
+ update|= sli->usesEffective;
+ if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
+ update|= sli->usesBase;
+ if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
+ update|= sli->usesLatched;
+ if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
+ update|= sli->usesLocked;
+ if (state_changes&XkbCompatStateMask)
+ update|= sli->usesCompat;
+ if (enable_changes)
+ update|= sli->usesControls;
+ return update;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ * XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
+ *
+ * Some indicators "drive" the keyboard when their state is explicitly
+ * changed, as described in section 9.2.1 of the XKB protocol spec.
+ * This function updates the state and controls for the keyboard
+ * specified by 'xkbi' to reflect any changes that are required
+ * when the indicator described by 'map' is turned on or off. The
+ * extent of the changes is reported in change, which must be defined.
+ */
+Bool
+XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
+ XkbIndicatorMapPtr map,
+ Bool on,
+ XkbChangesPtr change)
+{
+Bool ctrlChange,stateChange;
+XkbStatePtr state;
+
+ if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
+ return False;
+ ctrlChange= stateChange= False;
+ if (map->ctrls) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ unsigned old;
+
+ old= ctrls->enabled_ctrls;
+ if (on) ctrls->enabled_ctrls|= map->ctrls;
+ else ctrls->enabled_ctrls&= ~map->ctrls;
+ if (old!=ctrls->enabled_ctrls) {
+ change->ctrls.changed_ctrls= XkbControlsEnabledMask;
+ change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
+ ctrlChange= True;
+ }
+ }
+ state= &xkbi->state;
+ if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
+ register int i;
+ register unsigned bit,match;
+
+ if (on) match= (map->groups)&XkbAllGroupsMask;
+ else match= (~map->groups)&XkbAllGroupsMask;
+ if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ if (map->which_groups&XkbIM_UseLatched)
+ XkbLatchGroup(xkbi->device,0); /* unlatch group */
+ state->locked_group= i;
+ stateChange= True;
+ }
+ else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ state->locked_group= 0;
+ XkbLatchGroup(xkbi->device,i);
+ stateChange= True;
+ }
+ }
+ if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
+ if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ register unsigned long old;
+ old= state->locked_mods;
+ if (on) state->locked_mods|= map->mods.mask;
+ else state->locked_mods&= ~map->mods.mask;
+ if (state->locked_mods!=old)
+ stateChange= True;
+ }
+ if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ register unsigned long newmods;
+ newmods= state->latched_mods;
+ if (on) newmods|= map->mods.mask;
+ else newmods&= ~map->mods.mask;
+ if (newmods!=state->locked_mods) {
+ newmods&= map->mods.mask;
+ XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
+ stateChange= True;
+ }
+ }
+ }
+ return (stateChange || ctrlChange);
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbSetIndicators(dev,affect,values,cause)
+ *
+ * Attempts to change the indicators specified in 'affect' to the
+ * states specified in 'values' for the default keyboard feedback
+ * on the keyboard specified by 'dev.' Attempts to change indicator
+ * state might be ignored or have no affect, depending on the XKB
+ * indicator map for any affected indicators, as described in section
+ * 9.2 of the XKB protocol specification.
+ *
+ * If 'changes' is non-NULL, this function notes any changes to the
+ * keyboard state, controls, or indicator state that result from this
+ * attempted change. If 'changes' is NULL, this function generates
+ * XKB events to report any such changes to interested clients.
+ *
+ * If 'cause' is non-NULL, it specifies the reason for the change,
+ * as reported in some XKB events. If it is NULL, this function
+ * assumes that the change is the result of a core protocol
+ * ChangeKeyboardMapping request.
+ */
+
+void
+XkbSetIndicators( DeviceIntPtr dev,
+ CARD32 affect,
+ CARD32 values,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+XkbChangesRec changes;
+xkbExtensionDeviceNotify ed;
+unsigned side_affected;
+
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ sli->explicitState&= ~affect;
+ sli->explicitState|= (affect&values);
+ XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
+
+ side_affected= 0;
+ if (changes.state_changes!=0)
+ side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,False);
+ if (changes.ctrls.enabled_ctrls_changes)
+ side_affected|= sli->usesControls;
+
+ if (side_affected) {
+ XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
+ affect|= side_affected;
+ }
+ if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+
+ XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ * ComputeAutoState(map,state,ctrls)
+ *
+ * This function reports the effect of applying the specified
+ * indicator map given the specified state and controls, as
+ * described in section 9.2 of the XKB protocol specification.
+ */
+
+static Bool
+ComputeAutoState( XkbIndicatorMapPtr map,
+ XkbStatePtr state,
+ XkbControlsPtr ctrls)
+{
+Bool on;
+CARD8 mods,group;
+
+ on= False;
+ mods= group= 0;
+ if (map->which_mods&XkbIM_UseAnyMods) {
+ if (map->which_mods&XkbIM_UseBase)
+ mods|= state->base_mods;
+ if (map->which_mods&XkbIM_UseLatched)
+ mods|= state->latched_mods;
+ if (map->which_mods&XkbIM_UseLocked)
+ mods|= state->locked_mods;
+ if (map->which_mods&XkbIM_UseEffective)
+ mods|= state->mods;
+ if (map->which_mods&XkbIM_UseCompat)
+ mods|= state->compat_state;
+ on = ((map->mods.mask&mods)!=0);
+ on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
+ }
+ if (map->which_groups&XkbIM_UseAnyGroup) {
+ if (map->which_groups&XkbIM_UseBase)
+ group|= (1L << state->base_group);
+ if (map->which_groups&XkbIM_UseLatched)
+ group|= (1L << state->latched_group);
+ if (map->which_groups&XkbIM_UseLocked)
+ group|= (1L << state->locked_group);
+ if (map->which_groups&XkbIM_UseEffective)
+ group|= (1L << state->group);
+ on = on||(((map->groups&group)!=0)||(map->groups==0));
+ }
+ if (map->ctrls)
+ on = on||(ctrls->enabled_ctrls&map->ctrls);
+ return on;
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
+ *
+ * Applies the indicator maps for any indicators specified in
+ * 'update' from the default keyboard feedback on the device
+ * specified by 'dev.'
+ *
+ * If 'changes' is NULL, this function generates and XKB events
+ * required to report the necessary changes, otherwise it simply
+ * notes the indicators with changed state.
+ *
+ * If 'check_edevs' is True, this function also checks the indicator
+ * maps for any open extension devices that have them, and updates
+ * the state of any extension device indicators as necessary.
+ */
+
+void
+XkbUpdateIndicators( DeviceIntPtr dev,
+ register CARD32 update,
+ Bool check_edevs,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
+ if (check_edevs)
+ XkbUpdateAllDeviceIndicators(changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
+{
+DeviceIntPtr edev;
+XkbSrvLedInfoPtr sli;
+
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ if (edev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=edev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ }
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbCheckIndicatorMaps(dev,sli,which)
+ *
+ * Updates the 'indicator accelerators' for the indicators specified
+ * by 'which' in the feedback specified by 'sli.' The indicator
+ * accelerators are internal to the server and are used to simplify
+ * and speed up the process of figuring out which indicators might
+ * be affected by a particular change in keyboard state or controls.
+ */
+
+void
+XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
+{
+register unsigned i,bit;
+XkbIndicatorMapPtr map;
+XkbDescPtr xkb;
+
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ dev= (DeviceIntPtr)LookupKeyboardDevice();
+
+ sli->usesBase&= ~which;
+ sli->usesLatched&= ~which;
+ sli->usesLocked&= ~which;
+ sli->usesEffective&= ~which;
+ sli->usesCompat&= ~which;
+ sli->usesControls&= ~which;
+ sli->mapsPresent&= ~which;
+
+ xkb= dev->key->xkbInfo->desc;
+ for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
+ if (which&bit) {
+ CARD8 what;
+
+ if (!XkbIM_InUse(map))
+ continue;
+ sli->mapsPresent|= bit;
+
+ what= (map->which_mods|map->which_groups);
+ if (what&XkbIM_UseBase)
+ sli->usesBase|= bit;
+ if (what&XkbIM_UseLatched)
+ sli->usesLatched|= bit;
+ if (what&XkbIM_UseLocked)
+ sli->usesLocked|= bit;
+ if (what&XkbIM_UseEffective)
+ sli->usesEffective|= bit;
+ if (what&XkbIM_UseCompat)
+ sli->usesCompat|= bit;
+ if (map->ctrls)
+ sli->usesControls|= bit;
+
+ map->mods.mask= map->mods.real_mods;
+ if (map->mods.vmods!=0) {
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ }
+ }
+ }
+ sli->usedComponents= 0;
+ if (sli->usesBase)
+ sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
+ if (sli->usesLatched)
+ sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
+ if (sli->usesLocked)
+ sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
+ if (sli->usesEffective)
+ sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
+ if (sli->usesCompat)
+ sli->usedComponents|= XkbCompatStateMask;
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
+ *
+ * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
+ * 'kf' or 'lf' on the keyboard specified by 'dev.'
+ *
+ * If 'needed_parts' is non-zero, this function makes sure that any
+ * of the parts speicified therein are allocated.
+ */
+XkbSrvLedInfoPtr
+XkbAllocSrvLedInfo( DeviceIntPtr dev,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+Bool checkAccel;
+Bool checkNames;
+
+ sli= NULL;
+ checkAccel= checkNames= False;
+ if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
+ kf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec);
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= KbdFeedbackClass;
+ sli->id= kf->ctrl.id;
+ sli->fb.kf= kf;
+
+ sli->autoState= 0;
+ sli->explicitState= kf->ctrl.leds;
+ sli->effectiveState= kf->ctrl.leds;
+
+ if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->flags|= XkbSLI_IsDefault;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ sli->names= xkb->names->indicators;
+ sli->maps= xkb->indicators->maps;
+ checkNames= checkAccel= True;
+ }
+ else {
+ sli->physIndicators= XkbAllIndicatorsMask;
+ sli->names= NULL;
+ sli->maps= NULL;
+ }
+ }
+ else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ if (xkb->names->indicators!=sli->names) {
+ checkNames= True;
+ sli->names= xkb->names->indicators;
+ }
+ if (xkb->indicators->maps!=sli->maps) {
+ checkAccel= True;
+ sli->maps= xkb->indicators->maps;
+ }
+ }
+ else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
+ lf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec);
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= LedFeedbackClass;
+ sli->id= lf->ctrl.id;
+ sli->fb.lf= lf;
+
+ sli->physIndicators= lf->ctrl.led_mask;
+ sli->autoState= 0;
+ sli->explicitState= lf->ctrl.led_values;
+ sli->effectiveState= lf->ctrl.led_values;
+ sli->maps= NULL;
+ sli->names= NULL;
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom);
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec);
+ if (checkNames) {
+ register unsigned i,bit;
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->names[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ }
+ if (checkAccel)
+ XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
+ return sli;
+}
+
+void
+XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
+{
+ if ((sli->flags&XkbSLI_IsDefault)==0) {
+ if (sli->maps) _XkbFree(sli->maps);
+ if (sli->names) _XkbFree(sli->names);
+ }
+ sli->maps= NULL;
+ sli->names= NULL;
+ _XkbFree(sli);
+ return;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbFindSrvLedInfo(dev,class,id,needed_parts)
+ *
+ * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
+ * on the device specified by 'dev.' If the class and id specify
+ * a valid device feedback, this function returns the existing
+ * feedback or allocates a new one.
+ *
+ */
+
+XkbSrvLedInfoPtr
+XkbFindSrvLedInfo( DeviceIntPtr dev,
+ unsigned class,
+ unsigned id,
+ unsigned needed_parts)
+{
+XkbSrvLedInfoPtr sli;
+
+ /* optimization to check for most common case */
+ if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
+ XkbSrvLedInfoPtr sli;
+ sli= dev->kbdfeed->xkb_sli;
+ if (dev->kbdfeed->xkb_sli==NULL) {
+ sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
+ dev->kbdfeed->xkb_sli= sli;
+ }
+ return dev->kbdfeed->xkb_sli;
+ }
+
+ sli= NULL;
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else return NULL;
+ }
+ if (class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ if (kf->xkb_sli==NULL)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
+ sli= kf->xkb_sli;
+ break;
+ }
+ }
+ }
+ else if (class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ if (lf->xkb_sli==NULL)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
+ sli= lf->xkb_sli;
+ break;
+ }
+ }
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom);
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec);
+ return sli;
+}
+
+/***====================================================================***/
+
+void
+XkbFlushLedEvents( DeviceIntPtr dev,
+ DeviceIntPtr kbd,
+ XkbSrvLedInfoPtr sli,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (changes) {
+ if (changes->indicators.state_changes)
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendNotification(kbd,changes,cause);
+ bzero((char *)changes,sizeof(XkbChangesRec));
+
+ if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) {
+ if (sli->effectiveState)
+ /* it appears that the which parameter is not used */
+ XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask);
+ else
+ XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask);
+ }
+ }
+ if (ed && (ed->reason)) {
+ if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendExtensionDeviceNotify(dev,cause->client,ed);
+ }
+ bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedNameChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_names,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_names==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->names.changed|= XkbIndicatorNamesMask;
+ changes->names.changed_indicators|= changed_names;
+ }
+
+ ed->reason|= (XkbXI_IndicatorNamesMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorNamesMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
+ *
+ * Handles all of the secondary effects of the changes to the
+ * feedback specified by 'sli' on the device specified by 'dev.'
+ *
+ * If 'changed_maps' specifies any indicators, this function generates
+ * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
+ * events to report the changes, and recalculates the effective
+ * state of each indicator with a changed map. If any indicators
+ * change state, the server generates XkbExtensionDeviceNotify and
+ * XkbIndicatorStateNotify events as appropriate.
+ *
+ * If 'changes' is non-NULL, this function updates it to reflect
+ * any changes to the keyboard state or controls or to the 'core'
+ * indicator names, maps, or state. If 'changes' is NULL, this
+ * function generates XKB events as needed to report the changes.
+ * If 'dev' is not a keyboard device, any changes are reported
+ * for the core keyboard.
+ *
+ * The 'cause' specifies the reason for the event (key event or
+ * request) for the change, as reported in some XKB events.
+ */
+
+void
+XkbApplyLedMapChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_maps,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_maps==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.map_changes|= changed_maps;
+ }
+
+ XkbCheckIndicatorMaps(dev,sli,changed_maps);
+
+ ed->reason|= (XkbXI_IndicatorMapsMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorMapsMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbApplyLedStateChanges(DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_leds,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+XkbIndicatorMapPtr map;
+unsigned oldState;
+Bool kb_changed;
+
+ if (changed_leds==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ xkbi= kbd->key->xkbInfo;
+
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+
+ kb_changed= False;
+ affected= changed_leds;
+ oldState= sli->effectiveState;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if (map->flags&XkbIM_NoExplicit) {
+ sli->explicitState&= ~bit;
+ continue;
+ }
+ if (map->flags&XkbIM_LEDDrivesKB) {
+ Bool on= ((sli->explicitState&bit)!=0);
+ if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
+ kb_changed= True;
+ }
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
+ changes->indicators.state_changes|= affected;
+ if (affected) {
+ ed->reason|= (XkbXI_IndicatorStateMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ }
+
+ if (kb_changed) {
+ XkbComputeDerivedState(kbd->key->xkbInfo);
+ XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
+ }
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ if (kb_changed)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbUpdateLedAutoState( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned maps_to_check,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr kbd;
+XkbStatePtr state;
+XkbControlsPtr ctrls;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+register XkbIndicatorMapPtr map;
+unsigned oldState;
+
+ if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
+ return;
+
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ state= &kbd->key->xkbInfo->state;
+ ctrls= kbd->key->xkbInfo->desc->ctrls;
+ affected= maps_to_check;
+ oldState= sli->effectiveState;
+ sli->autoState&= ~affected;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
+ sli->autoState|= bit;
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+ if (affected==0)
+ return;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.state_changes|= affected;
+ }
+
+ ed->reason|= (XkbXI_IndicatorStateMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+_UpdateButtonVMods( XkbDescPtr xkb,
+ unsigned num_btns,
+ XkbAction * acts,
+ unsigned changed,
+ xkbExtensionDeviceNotify * ed_inout)
+{
+register int i;
+
+ for (i=0;i<num_btns;i++,acts++) {
+ if ((acts->any.type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,acts,changed)) {
+ if ((ed_inout->reason&XkbXI_ButtonActionsMask)==0) {
+ ed_inout->reason|= XkbXI_ButtonActionsMask;
+ ed_inout->firstBtn= i;
+ ed_inout->nBtns= 1;
+ }
+ else {
+ ed_inout->nBtns= (i-ed_inout->firstBtn)+1;
+ }
+ }
+ }
+ return;
+}
+
+static void
+_UpdateMapVMods( XkbDescPtr xkb,
+ register XkbIndicatorMapPtr map,
+ unsigned changed_vmods,
+ unsigned * changed_maps_rtrn)
+{
+register int i;
+
+ *changed_maps_rtrn= 0;
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed_vmods) {
+ map->mods.mask= map->mods.real_mods;
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ *changed_maps_rtrn|= (1L<<i);
+ }
+ }
+ return;
+}
+
+static void
+_UpdateDeviceVMods( DeviceIntPtr dev,
+ XkbDescPtr xkb,
+ unsigned changed,
+ XkbEventCausePtr cause)
+{
+xkbExtensionDeviceNotify ed;
+XkbSrvLedInfoPtr sli;
+unsigned changed_maps;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ _UpdateButtonVMods(xkb,dev->button->numButtons,
+ dev->button->xkb_acts,changed,&ed);
+ }
+ if (dev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps);
+ if (changed_maps) {
+ if (ed.reason&XkbXI_IndicatorsMask) {
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ ed.reason= 0;
+ ed.firstBtn= ed.nBtns;
+ }
+ ed.ledClass= sli->class;
+ ed.ledID= sli->id;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.reason|= XkbXI_IndicatorMapsMask;
+ XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause);
+ }
+ }
+ }
+ if (dev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps);
+ if (changed_maps) {
+ if (ed.reason&XkbXI_IndicatorsMask) {
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ ed.reason= 0;
+ ed.firstBtn= ed.nBtns;
+ }
+ ed.ledClass= sli->class;
+ ed.ledID= sli->id;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.reason|= XkbXI_IndicatorMapsMask;
+ XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause);
+ }
+ }
+ }
+ if (ed.reason!=0)
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ return;
+}
+
+void
+XkbApplyVModChangesToAllDevices( DeviceIntPtr dev,
+ XkbDescPtr xkb,
+ unsigned changed,
+ XkbEventCausePtr cause)
+{
+DeviceIntPtr edev;
+ if (dev!=(DeviceIntPtr)LookupKeyboardDevice())
+ return;
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->key)
+ continue;
+ _UpdateDeviceVMods(edev,xkb,changed,cause);
+ }
+ for (edev=inputInfo.off_devices;edev!=NULL;edev=edev->next) {
+ if (edev->key)
+ continue;
+ _UpdateDeviceVMods(edev,xkb,changed,cause);
+ }
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c
new file mode 100644
index 000000000..9c13d99b5
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c
@@ -0,0 +1,185 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include <ctype.h>
+
+
+/***====================================================================***/
+
+void
+XkbProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+{
+KeyClassPtr keyc = keybd->key;
+XkbSrvInfoPtr xkbi;
+int key;
+XkbBehavior behavior;
+unsigned ndx;
+
+ xkbi= keyc->xkbInfo;
+ key= xE->u.u.detail;
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ ErrorF("XkbPKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+
+ if ( (xkbi->repeatKey==key) && (xE->u.u.type==KeyRelease) &&
+ ((xkbi->desc->ctrls->enabled_ctrls&XkbRepeatKeysMask)==0) ) {
+ AccessXCancelRepeatKey(xkbi,key);
+ }
+
+ behavior= xkbi->desc->server->behaviors[key];
+ /* The "permanent" flag indicates a hard-wired behavior that occurs */
+ /* below XKB, such as a key that physically locks. XKB does not */
+ /* do anything to implement the behavior, but it *does* report that */
+ /* key is hardwired */
+ if ((behavior.type&XkbKB_Permanent)==0) {
+ switch (behavior.type) {
+ case XkbKB_Default:
+ if (( xE->u.u.type == KeyPress ) &&
+ (keyc->down[key>>3] & (1<<(key&7)))) {
+ XkbLastRepeatEvent= (void *)xE;
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type = KeyPress;
+ XkbHandleActions(keybd,keybd,xE,count);
+ XkbLastRepeatEvent= NULL;
+ return;
+ }
+ else if ((xE->u.u.type==KeyRelease) &&
+ (!(keyc->down[key>>3]&(1<<(key&7))))) {
+ XkbLastRepeatEvent= (void *)&xE;
+ xE->u.u.type = KeyPress;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ XkbLastRepeatEvent= NULL;
+ return;
+ }
+ break;
+ case XkbKB_Lock:
+ if ( xE->u.u.type == KeyRelease )
+ return;
+ else {
+ int bit= 1<<(key&7);
+ if ( keyc->down[key>>3]&bit )
+ xE->u.u.type= KeyRelease;
+ }
+ break;
+ case XkbKB_RadioGroup:
+ ndx= (behavior.data&(~XkbKB_RGAllowNone));
+ if ( ndx<xkbi->nRadioGroups ) {
+ XkbRadioGroupPtr rg;
+
+ if ( xE->u.u.type == KeyRelease )
+ return;
+
+ rg = &xkbi->radioGroups[ndx];
+ if ( rg->currentDown == xE->u.u.detail ) {
+ if (behavior.data&XkbKB_RGAllowNone) {
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ rg->currentDown= 0;
+ }
+ return;
+ }
+ if ( rg->currentDown!=0 ) {
+ int key = xE->u.u.detail;
+ xE->u.u.type= KeyRelease;
+ xE->u.u.detail= rg->currentDown;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type= KeyPress;
+ xE->u.u.detail= key;
+ }
+ rg->currentDown= key;
+ }
+ else ErrorF("InternalError! Illegal radio group %d\n",ndx);
+ break;
+ case XkbKB_Overlay1: case XkbKB_Overlay2:
+ {
+ unsigned which;
+ if (behavior.type==XkbKB_Overlay1) which= XkbOverlay1Mask;
+ else which= XkbOverlay2Mask;
+ if ( (xkbi->desc->ctrls->enabled_ctrls&which)==0 )
+ break;
+ if ((behavior.data>=xkbi->desc->min_key_code)&&
+ (behavior.data<=xkbi->desc->max_key_code)) {
+ xE->u.u.detail= behavior.data;
+ /* 9/11/94 (ef) -- XXX! need to match release with */
+ /* press even if the state of the */
+ /* corresponding overlay control */
+ /* changes while the key is down */
+ }
+ }
+ break;
+ default:
+ ErrorF("unknown key behavior 0x%04x\n",behavior.type);
+#if defined(MetroLink)
+ return;
+#else
+ break;
+#endif
+ }
+ }
+ XkbHandleActions(keybd,keybd,xE,count);
+ return;
+}
+
+void
+ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+{
+KeyClassPtr keyc = keybd->key;
+XkbSrvInfoPtr xkbi;
+
+ xkbi= keyc->xkbInfo;
+
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ int key= xE->u.u.detail;
+ ErrorF("PKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ if ((xkbi->desc->ctrls->enabled_ctrls&XkbAllFilteredEventsMask)==0)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ else if (xE->u.u.type==KeyPress)
+ AccessXFilterPressEvent(xE,keybd,count);
+ else if (xE->u.u.type==KeyRelease)
+ AccessXFilterReleaseEvent(xE,keybd,count);
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c b/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c
new file mode 100644
index 000000000..65a1e8a5d
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbPrOtherEv.c
@@ -0,0 +1,81 @@
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+
+#include <nx-X11/extensions/XI.h>
+#include <nx-X11/extensions/XIproto.h>
+
+extern void ProcessOtherEvent(
+ xEvent * /* xE */,
+ DeviceIntPtr /* dev */,
+ int /* count */
+);
+
+/***====================================================================***/
+
+void
+XkbProcessOtherEvent(xEvent *xE,DeviceIntPtr dev,int count)
+{
+Bool xkbCares,isBtn;
+
+ xkbCares= True;
+ isBtn= False;
+ switch ( xE->u.u.type ) {
+ case KeyPress: xE->u.u.type= DeviceKeyPress; break;
+ case KeyRelease: xE->u.u.type= DeviceKeyRelease; break;
+ case ButtonPress: xE->u.u.type= DeviceButtonPress;
+ isBtn= True;
+ break;
+ case ButtonRelease: xE->u.u.type= DeviceButtonRelease;
+ isBtn= True;
+ break;
+ default: xkbCares= False; break;
+ }
+ if (xkbCares) {
+ if ((!isBtn)||((dev->button)&&(dev->button->xkb_acts))) {
+ DeviceIntPtr kbd;
+ if (dev->key) kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ XkbHandleActions(dev,kbd,xE,count);
+ return;
+ }
+ }
+ ProcessOtherEvent(xE,dev,count);
+ return;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/xkbSwap.c b/nx-X11/programs/Xserver/xkb/xkbSwap.c
new file mode 100644
index 000000000..ed5b2ff04
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbSwap.c
@@ -0,0 +1,543 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "stdio.h"
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include <xkbsrv.h>
+#include "xkbstr.h"
+#include "extnsionst.h"
+#include "xkb.h"
+
+ /*
+ * REQUEST SWAPPING
+ */
+static int
+SProcXkbUseExtension(ClientPtr client)
+{
+
+ REQUEST(xkbUseExtensionReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ swaps(&stuff->wantedMajor);
+ swaps(&stuff->wantedMinor);
+ return ProcXkbUseExtension(client);
+}
+
+static int
+SProcXkbSelectEvents(ClientPtr client)
+{
+
+ REQUEST(xkbSelectEventsReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->affectWhich);
+ swaps(&stuff->clear);
+ swaps(&stuff->selectAll);
+ swaps(&stuff->affectMap);
+ swaps(&stuff->map);
+ if ((stuff->affectWhich&(~XkbMapNotifyMask))!=0) {
+ union {
+ BOOL *b;
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if (((bit&maskLeft)==0)||(ndx==XkbMapNotify))
+ continue;
+ maskLeft&= ~bit;
+ if ((stuff->selectAll&bit)||(stuff->clear&bit))
+ continue;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ case XkbStateNotify:
+ case XkbNamesNotify:
+ case XkbAccessXNotify:
+ case XkbExtensionDeviceNotify:
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ case XkbIndicatorStateNotify:
+ case XkbIndicatorMapNotify:
+ size= 4;
+ break;
+ case XkbBellNotify:
+ case XkbActionMessage:
+ case XkbCompatMapNotify:
+ size= 1;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(0x1,bit);
+ return BadValue;
+ }
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ swaps(&from.c16[0]);
+ swaps(&from.c16[1]);
+ }
+ else if (size==4) {
+ swapl(&from.c32[0]);
+ swapl(&from.c32[1]);
+ }
+ else {
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ if (dataLeft>2) {
+ ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ }
+ return ProcXkbSelectEvents(client);
+}
+
+static int
+SProcXkbBell(ClientPtr client)
+{
+ REQUEST(xkbBellReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbBellReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->bellClass);
+ swaps(&stuff->bellID);
+ swapl(&stuff->name);
+ swapl(&stuff->window);
+ swaps(&stuff->pitch);
+ swaps(&stuff->duration);
+ return ProcXkbBell(client);
+}
+
+static int
+SProcXkbGetState(ClientPtr client)
+{
+ REQUEST(xkbGetStateReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+ swaps(&stuff->deviceSpec);
+ return ProcXkbGetState(client);
+}
+
+static int
+SProcXkbLatchLockState(ClientPtr client)
+{
+ REQUEST(xkbLatchLockStateReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->groupLatch);
+ return ProcXkbLatchLockState(client);
+}
+
+static int
+SProcXkbGetControls(ClientPtr client)
+{
+ REQUEST(xkbGetControlsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+ swaps(&stuff->deviceSpec);
+ return ProcXkbGetControls(client);
+}
+
+static int
+SProcXkbSetControls(ClientPtr client)
+{
+ REQUEST(xkbSetControlsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->affectInternalVMods);
+ swaps(&stuff->internalVMods);
+ swaps(&stuff->affectIgnoreLockVMods);
+ swaps(&stuff->ignoreLockVMods);
+ swaps(&stuff->axOptions);
+ swapl(&stuff->affectEnabledCtrls);
+ swapl(&stuff->enabledCtrls);
+ swapl(&stuff->changeCtrls);
+ swaps(&stuff->repeatDelay);
+ swaps(&stuff->repeatInterval);
+ swaps(&stuff->slowKeysDelay);
+ swaps(&stuff->debounceDelay);
+ swaps(&stuff->mkDelay);
+ swaps(&stuff->mkInterval);
+ swaps(&stuff->mkTimeToMax);
+ swaps(&stuff->mkMaxSpeed);
+ swaps(&stuff->mkCurve);
+ swaps(&stuff->axTimeout);
+ swapl(&stuff->axtCtrlsMask);
+ swapl(&stuff->axtCtrlsValues);
+ swaps(&stuff->axtOptsMask);
+ swaps(&stuff->axtOptsValues);
+ return ProcXkbSetControls(client);
+}
+
+static int
+SProcXkbGetMap(ClientPtr client)
+{
+ REQUEST(xkbGetMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->full);
+ swaps(&stuff->partial);
+ swaps(&stuff->virtualMods);
+ return ProcXkbGetMap(client);
+}
+
+static int
+SProcXkbSetMap(ClientPtr client)
+{
+ REQUEST(xkbSetMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->present);
+ swaps(&stuff->flags);
+ swaps(&stuff->totalSyms);
+ swaps(&stuff->totalActs);
+ swaps(&stuff->virtualMods);
+ return ProcXkbSetMap(client);
+}
+
+
+static int
+SProcXkbGetCompatMap(ClientPtr client)
+{
+ REQUEST(xkbGetCompatMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->firstSI);
+ swaps(&stuff->nSI);
+ return ProcXkbGetCompatMap(client);
+}
+
+static int
+SProcXkbSetCompatMap(ClientPtr client)
+{
+ REQUEST(xkbSetCompatMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->firstSI);
+ swaps(&stuff->nSI);
+ return ProcXkbSetCompatMap(client);
+}
+
+static int
+SProcXkbGetIndicatorState(ClientPtr client)
+{
+ REQUEST(xkbGetIndicatorStateReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+ swaps(&stuff->deviceSpec);
+ return ProcXkbGetIndicatorState(client);
+}
+
+static int
+SProcXkbGetIndicatorMap(ClientPtr client)
+{
+ REQUEST(xkbGetIndicatorMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->which);
+ return ProcXkbGetIndicatorMap(client);
+}
+
+static int
+SProcXkbSetIndicatorMap(ClientPtr client)
+{
+ REQUEST(xkbSetIndicatorMapReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->which);
+ return ProcXkbSetIndicatorMap(client);
+}
+
+static int
+SProcXkbGetNamedIndicator(ClientPtr client)
+{
+ REQUEST(xkbGetNamedIndicatorReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->ledClass);
+ swaps(&stuff->ledID);
+ swapl(&stuff->indicator);
+ return ProcXkbGetNamedIndicator(client);
+}
+
+static int
+SProcXkbSetNamedIndicator(ClientPtr client)
+{
+ REQUEST(xkbSetNamedIndicatorReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->ledClass);
+ swaps(&stuff->ledID);
+ swapl(&stuff->indicator);
+ swaps(&stuff->virtualMods);
+ swapl(&stuff->ctrls);
+ return ProcXkbSetNamedIndicator(client);
+}
+
+
+static int
+SProcXkbGetNames(ClientPtr client)
+{
+ REQUEST(xkbGetNamesReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->which);
+ return ProcXkbGetNames(client);
+}
+
+static int
+SProcXkbSetNames(ClientPtr client)
+{
+ REQUEST(xkbSetNamesReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->virtualMods);
+ swapl(&stuff->which);
+ swapl(&stuff->indicators);
+ swaps(&stuff->totalKTLevelNames);
+ return ProcXkbSetNames(client);
+}
+
+static int
+SProcXkbGetGeometry(ClientPtr client)
+{
+ REQUEST(xkbGetGeometryReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->name);
+ return ProcXkbGetGeometry(client);
+}
+
+static int
+SProcXkbSetGeometry(ClientPtr client)
+{
+ REQUEST(xkbSetGeometryReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->name);
+ swaps(&stuff->widthMM);
+ swaps(&stuff->heightMM);
+ swaps(&stuff->nProperties);
+ swaps(&stuff->nColors);
+ swaps(&stuff->nDoodads);
+ swaps(&stuff->nKeyAliases);
+ return ProcXkbSetGeometry(client);
+}
+
+static int
+SProcXkbPerClientFlags(ClientPtr client)
+{
+ REQUEST(xkbPerClientFlagsReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+ swaps(&stuff->deviceSpec);
+ swapl(&stuff->change);
+ swapl(&stuff->value);
+ swapl(&stuff->ctrlsToChange);
+ swapl(&stuff->autoCtrls);
+ swapl(&stuff->autoCtrlValues);
+ return ProcXkbPerClientFlags(client);
+}
+
+static int
+SProcXkbListComponents(ClientPtr client)
+{
+ REQUEST(xkbListComponentsReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->maxNames);
+ return ProcXkbListComponents(client);
+}
+
+static int
+SProcXkbGetKbdByName(ClientPtr client)
+{
+ REQUEST(xkbGetKbdByNameReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->want);
+ swaps(&stuff->need);
+ return ProcXkbGetKbdByName(client);
+}
+
+static int
+SProcXkbGetDeviceInfo(ClientPtr client)
+{
+ REQUEST(xkbGetDeviceInfoReq);
+
+ swaps(&stuff->length);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->wanted);
+ swaps(&stuff->ledClass);
+ swaps(&stuff->ledID);
+ return ProcXkbGetDeviceInfo(client);
+}
+
+static int
+SProcXkbSetDeviceInfo(ClientPtr client)
+{
+ REQUEST(xkbSetDeviceInfoReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+ swaps(&stuff->deviceSpec);
+ swaps(&stuff->change);
+ swaps(&stuff->nDeviceLedFBs);
+ return ProcXkbSetDeviceInfo(client);
+}
+
+static int
+SProcXkbSetDebuggingFlags(ClientPtr client)
+{
+ REQUEST(xkbSetDebuggingFlagsReq);
+
+ swaps(&stuff->length);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+ swapl(&stuff->affectFlags);
+ swapl(&stuff->flags);
+ swapl(&stuff->affectCtrls);
+ swapl(&stuff->ctrls);
+ swaps(&stuff->msgLength);
+ return ProcXkbSetDebuggingFlags(client);
+}
+
+int
+SProcXkbDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return SProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return SProcXkbSelectEvents(client);
+ case X_kbBell:
+ return SProcXkbBell(client);
+ case X_kbGetState:
+ return SProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return SProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return SProcXkbGetControls(client);
+ case X_kbSetControls:
+ return SProcXkbSetControls(client);
+ case X_kbGetMap:
+ return SProcXkbGetMap(client);
+ case X_kbSetMap:
+ return SProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return SProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return SProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return SProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return SProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return SProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return SProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return SProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return SProcXkbGetNames(client);
+ case X_kbSetNames:
+ return SProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return SProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return SProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return SProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return SProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return SProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return SProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return SProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return SProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbUtils.c b/nx-X11/programs/Xserver/xkb/xkbUtils.c
new file mode 100644
index 000000000..f4b7db3c6
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbUtils.c
@@ -0,0 +1,979 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#define XK_CYRILLIC
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include "xkb.h"
+
+#ifdef MODE_SWITCH
+extern Bool noKME; /* defined in os/utils.c */
+#endif
+
+int XkbDisableLockActions = 0;
+
+/***====================================================================***/
+
+#ifndef RETURN_SHOULD_REPEAT
+#define RETURN_SHOULD_REPEAT 0
+#endif
+
+/***====================================================================***/
+
+DeviceIntPtr
+_XkbLookupAnyDevice(int id,int *why_rtrn)
+{
+DeviceIntPtr dev = NULL;
+
+ dev= (DeviceIntPtr)LookupKeyboardDevice();
+ if ((id==XkbUseCoreKbd)||(dev->id==id))
+ return dev;
+
+ dev= (DeviceIntPtr)LookupPointerDevice();
+ if ((id==XkbUseCorePtr)||(dev->id==id))
+ return dev;
+
+ if (id&(~0xff))
+ dev = NULL;
+
+ dev= (DeviceIntPtr)LookupDevice(id);
+ if (dev!=NULL)
+ return dev;
+ if ((!dev)&&(why_rtrn))
+ *why_rtrn= XkbErr_BadDevice;
+ return dev;
+}
+
+DeviceIntPtr
+_XkbLookupKeyboard(int id,int *why_rtrn)
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->key)||(!dev->key->xkbInfo)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+_XkbLookupBellDevice(int id,int *why_rtrn)
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->kbdfeed)&&(!dev->bell)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+_XkbLookupLedDevice(int id,int *why_rtrn)
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->kbdfeed)&&(!dev->leds)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+_XkbLookupButtonDevice(int id,int *why_rtrn)
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if (!dev->button) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+void
+XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+{
+register unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0)
+ act->mods.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0)
+ act->iso.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ }
+ return;
+}
+
+unsigned
+XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
+{
+register int i,bit;
+register unsigned mask;
+
+ for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (vmask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ return mask;
+}
+
+
+Bool
+XkbApplyVModChanges( XkbSrvInfoPtr xkbi,
+ unsigned changed,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+{
+XkbDescPtr xkb;
+Bool check;
+
+ xkb= xkbi->desc;
+#ifdef DEBUG
+{
+register unsigned i,bit;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((changed&bit)==0)
+ continue;
+ if (xkbDebugFlags)
+ ErrorF("Should be applying: change vmod %d to 0x%x\n",i,
+ xkb->server->vmods[i]);
+ }
+}
+#endif
+ check= XkbApplyVirtualModChanges(xkb,changed,changes);
+ XkbApplyVModChangesToAllDevices(xkbi->device,xkb,changed,cause);
+
+ if (needChecksRtrn!=NULL) {
+ if (check)
+ *needChecksRtrn= XkbStateNotifyMask|XkbIndicatorStateNotifyMask;
+ else *needChecksRtrn= 0;
+ }
+ else if (check) {
+ /* 7/12/95 (ef) -- XXX check compatibility and/or indicator state */
+ }
+ return 1;
+}
+
+/***====================================================================***/
+
+void
+XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+XkbDescPtr xkb;
+unsigned key,nG,explicit;
+KeySymsPtr pCore;
+int types[XkbNumKbdGroups];
+KeySym tsyms[XkbMaxSymsPerKey],*syms;
+XkbMapChangesPtr mc;
+
+ xkb= pXDev->key->xkbInfo->desc;
+#ifdef NOTYET
+ if (first<xkb->min_key_code) {
+ if (first>=XkbMinLegalKeyCode) {
+ xkb->min_key_code= first;
+ /* 1/12/95 (ef) -- XXX! should zero out the new maps */
+ changes->map.changed|= XkbKeycodesMask;
+generate a NewKeyboard notify here?
+ }
+ }
+#endif
+ if (first+num-1>xkb->max_key_code) {
+ /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
+ num= xkb->max_key_code-first+1;
+ }
+
+ mc= (changes?(&changes->map):NULL);
+
+ pCore= &pXDev->key->curKeySyms;
+ syms= &pCore->map[(first-xkb->min_key_code)*pCore->mapWidth];
+ for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
+ tsyms);
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ }
+ if (changes->map.changed&XkbKeySymsMask) {
+ CARD8 oldLast,newLast;
+ oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_sym)
+ changes->map.first_key_sym = first;
+ if (oldLast>newLast)
+ newLast= oldLast;
+ changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = num;
+ }
+ return;
+}
+
+void
+XkbUpdateDescActions( XkbDescPtr xkb,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+{
+register unsigned key;
+
+ for (key=first;key<(first+num);key++) {
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask)) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes->map.changed&XkbVirtualModsMask)
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+
+ if (changes->map.changed&XkbKeyActionsMask) {
+ CARD8 oldLast,newLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_act)
+ changes->map.first_key_act = first;
+ if (newLast>oldLast)
+ newLast= oldLast;
+ changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
+ }
+ else {
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act = first;
+ changes->map.num_key_acts = num;
+ }
+ return;
+}
+
+void
+XkbUpdateActions( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+CARD8 * repeat;
+
+ if (needChecksRtrn)
+ *needChecksRtrn= 0;
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ repeat= xkb->ctrls->per_key_repeat;
+
+ if (pXDev->kbdfeed)
+ memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,32);
+
+ XkbUpdateDescActions(xkb,first,num,changes);
+
+ if ((pXDev->kbdfeed)&&
+ (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, 32);
+ (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
+ }
+ return;
+}
+
+void
+XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize)
+{
+register int key,tmp;
+int maxSymsPerKey,maxKeysPerMod;
+int first,last,firstCommon,lastCommon;
+XkbDescPtr xkb;
+KeyClassPtr keyc;
+CARD8 keysPerMod[XkbNumModifiers];
+
+ if (!keybd || !keybd->key || !keybd->key->xkbInfo)
+ return;
+ xkb= keybd->key->xkbInfo->desc;
+ keyc= keybd->key;
+ maxSymsPerKey= maxKeysPerMod= 0;
+ bzero(keysPerMod,sizeof(keysPerMod));
+ memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&&
+ (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) {
+ first= firstCommon= xkb->min_key_code;
+ last= lastCommon= xkb->max_key_code;
+ }
+ else if (resize) {
+ keyc->curKeySyms.minKeyCode= xkb->min_key_code;
+ keyc->curKeySyms.maxKeyCode= xkb->max_key_code;
+ tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc);
+ keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
+ if (!keyc->curKeySyms.map)
+ FatalError("Couldn't allocate keysyms\n");
+ first= firstCommon= xkb->min_key_code;
+ last= lastCommon= xkb->max_key_code;
+ }
+ else {
+ if (xkb->min_key_code<keyc->curKeySyms.minKeyCode) {
+ first= xkb->min_key_code;
+ firstCommon= keyc->curKeySyms.minKeyCode;
+ }
+ else {
+ firstCommon= xkb->min_key_code;
+ first= keyc->curKeySyms.minKeyCode;
+ }
+ if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) {
+ lastCommon= keyc->curKeySyms.maxKeyCode;
+ last= xkb->max_key_code;
+ }
+ else {
+ lastCommon= xkb->max_key_code;
+ last= keyc->curKeySyms.maxKeyCode;
+ }
+ }
+
+ /* determine sizes */
+ for (key=first;key<=last;key++) {
+ if (XkbKeycodeInRange(xkb,key)) {
+ int nGroups;
+ int w;
+ nGroups= XkbKeyNumGroups(xkb,key);
+ tmp= 0;
+ if (nGroups>0) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
+ tmp+= 2;
+ else tmp+= w + 2;
+ }
+ if (nGroups>1) {
+ if (tmp <= 2) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
+ tmp+= 2;
+ else tmp+= w;
+ } else {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))>2)
+ tmp+= w - 2;
+ }
+ }
+ if (nGroups>2)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
+ if (nGroups>3)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
+ if (tmp>maxSymsPerKey)
+ maxSymsPerKey= tmp;
+ }
+ if (_XkbCoreKeycodeInRange(keyc,key)) {
+ if (keyc->modifierMap[key]!=0) {
+ register unsigned bit,i,mask;
+ mask= keyc->modifierMap[key];
+ for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+ if (mask&bit) {
+ keysPerMod[i]++;
+ if (keysPerMod[i]>maxKeysPerMod)
+ maxKeysPerMod= keysPerMod[i];
+ }
+ }
+ }
+ }
+ }
+
+ if (maxKeysPerMod>0) {
+ tmp= maxKeysPerMod*XkbNumModifiers;
+ if (keyc->modifierKeyMap==NULL)
+ keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp);
+ else if (keyc->maxKeysPerModifier<maxKeysPerMod)
+ keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp);
+ if (keyc->modifierKeyMap==NULL)
+ FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n");
+ bzero(keyc->modifierKeyMap,tmp);
+ }
+ else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) {
+ _XkbFree(keyc->modifierKeyMap);
+ keyc->modifierKeyMap= NULL;
+ }
+ keyc->maxKeysPerModifier= maxKeysPerMod;
+
+ if (maxSymsPerKey>0) {
+ tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc);
+ keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
+ if (keyc->curKeySyms.map==NULL)
+ FatalError("Couldn't allocate symbols map in UpdateCore\n");
+ }
+ else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) {
+ _XkbFree(keyc->curKeySyms.map);
+ keyc->curKeySyms.map= NULL;
+ }
+ keyc->curKeySyms.mapWidth= maxSymsPerKey;
+
+ bzero(keysPerMod,sizeof(keysPerMod));
+ for (key=firstCommon;key<=lastCommon;key++) {
+ if (keyc->curKeySyms.map!=NULL) {
+ KeySym *pCore,*pXKB;
+ unsigned nGroups,groupWidth,n,nOut;
+
+ nGroups= XkbKeyNumGroups(xkb,key);
+ n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey;
+ pCore= &keyc->curKeySyms.map[n];
+ bzero(pCore,maxSymsPerKey*sizeof(KeySym));
+ pXKB= XkbKeySymsPtr(xkb,key);
+ nOut= 2;
+ if (nGroups>0) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
+ if (groupWidth>0) pCore[0]= pXKB[0];
+ if (groupWidth>1) pCore[1]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[2+n]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut= groupWidth;
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ nOut+= 2;
+ if (nGroups>1) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
+ if (groupWidth>0) pCore[2]= pXKB[0];
+ if (groupWidth>1) pCore[3]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[nOut+(n-2)]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut+= (groupWidth-2);
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ for (n=XkbGroup3Index;n<nGroups;n++) {
+ register int s;
+ groupWidth= XkbKeyGroupWidth(xkb,key,n);
+ for (s=0;s<groupWidth;s++) {
+ pCore[nOut++]= pXKB[s];
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ }
+ if (!pCore[2] && !pCore[3] && maxSymsPerKey >= 6 &&
+ (pCore[4] || pCore[5])) {
+ pCore[2] = pCore[4];
+ pCore[3] = pCore[5];
+ }
+ }
+ if (keyc->modifierMap[key]!=0) {
+ register unsigned bit,i,mask;
+ mask= keyc->modifierMap[key];
+ for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+ if (mask&bit) {
+ tmp= i*maxKeysPerMod+keysPerMod[i];
+ keyc->modifierKeyMap[tmp]= key;
+ keysPerMod[i]++;
+ }
+ }
+ }
+ }
+#ifdef MODE_SWITCH
+ /* Fix up any of the KME stuff if we changed the core description.
+ */
+ if (!noKME)
+ HandleKeyBinding(keyc, &keyc->curKeySyms);
+#endif
+ return;
+}
+
+void
+XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
+{
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
+ xkbControlsNotify cn;
+ XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
+ XkbControlsRec old;
+ old = *ctrls;
+
+ if (key== -1) { /* global autorepeat setting changed */
+ if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+ else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
+ }
+ else if (pXDev->kbdfeed) {
+ ctrls->per_key_repeat[key/8] =
+ pXDev->kbdfeed->ctrl.autoRepeats[key/8];
+ }
+
+ if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,True))
+ XkbSendControlsNotify(pXDev,&cn);
+ }
+ return;
+}
+
+void
+XkbApplyMappingChange( DeviceIntPtr kbd,
+ CARD8 request,
+ KeyCode firstKey,
+ CARD8 num,
+ ClientPtr client)
+{
+XkbEventCauseRec cause;
+XkbChangesRec changes;
+unsigned check;
+
+ if (kbd->key->xkbInfo==NULL)
+ XkbInitDevice(kbd);
+ bzero(&changes,sizeof(XkbChangesRec));
+ check= 0;
+ if (request==MappingKeyboard) {
+ XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client);
+ XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes);
+ XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
+ }
+ else if (request==MappingModifier) {
+ XkbDescPtr xkb= kbd->key->xkbInfo->desc;
+
+ XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
+
+ num = xkb->max_key_code-xkb->min_key_code+1;
+ memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1);
+
+ changes.map.changed|= XkbModifierMapMask;
+ changes.map.first_modmap_key= xkb->min_key_code;
+ changes.map.num_modmap_keys= num;
+ XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
+ }
+ /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */
+ XkbSendNotification(kbd,&changes,&cause);
+ return;
+}
+
+void
+XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+xkbMapNotify mn;
+
+ xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
+ bzero(&mn,sizeof(mn));
+ mn.changed= XkbExplicitComponentsMask;
+ mn.firstKeyExplicit= key;
+ mn.nKeyExplicit= 1;
+ XkbSendMapNotify(dev,&mn);
+ return;
+}
+
+unsigned
+XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
+{
+int changed;
+
+ changed=(old->group!=new->group?XkbGroupStateMask:0);
+ changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
+ changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
+ changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
+ changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
+ changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
+ changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
+ changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
+ changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
+ changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
+ if (old->compat_grab_mods!=new->compat_grab_mods)
+ changed|= XkbCompatGrabModsMask;
+ changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
+ if (old->compat_lookup_mods!=new->compat_lookup_mods)
+ changed|= XkbCompatLookupModsMask;
+ changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
+ return changed;
+}
+
+void
+XkbComputeCompatState(XkbSrvInfoPtr xkbi)
+{
+CARD16 grp_mask;
+XkbStatePtr state= &xkbi->state;
+XkbCompatMapPtr map;
+
+ map= xkbi->desc->compat;
+ grp_mask= map->groups[state->group].mask;
+ state->compat_state = state->mods|grp_mask;
+ state->compat_lookup_mods= state->lookup_mods|grp_mask;
+
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
+ grp_mask= map->groups[state->base_group].mask;
+ state->compat_grab_mods= state->grab_mods|grp_mask;
+ return;
+}
+
+unsigned
+XkbAdjustGroup(int group,XkbControlsPtr ctrls)
+{
+unsigned act;
+
+ act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
+ if (group<0) {
+ while ( group < 0 ) {
+ if (act==XkbClampIntoRange) {
+ group= XkbGroup1Index;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group+= ctrls->num_groups;
+ }
+ }
+ }
+ else if (group>=ctrls->num_groups) {
+ if (act==XkbClampIntoRange) {
+ group= ctrls->num_groups-1;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group%= ctrls->num_groups;
+ }
+ }
+ return group;
+}
+
+void
+XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
+{
+XkbStatePtr state= &xkbi->state;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+unsigned char grp;
+
+ state->mods= (state->base_mods|state->latched_mods);
+ state->mods|= state->locked_mods;
+ state->lookup_mods= state->mods&(~ctrls->internal.mask);
+ state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
+ state->grab_mods|=
+ ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask);
+
+
+ grp= state->locked_group;
+ if (grp>=ctrls->num_groups)
+ state->locked_group= XkbAdjustGroup(grp,ctrls);
+
+ grp= state->locked_group+state->base_group+state->latched_group;
+ if (grp>=ctrls->num_groups)
+ state->group= XkbAdjustGroup(grp,ctrls);
+ else state->group= grp;
+ XkbComputeCompatState(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
+ unsigned which,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+ if (which&XkbStateNotifyMask) {
+ XkbStateRec old;
+ old= xkbi->state;
+ changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
+ XkbComputeDerivedState(xkbi);
+ }
+ if (which&XkbIndicatorStateNotifyMask)
+ XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,True,changes,
+ cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+XkbSetPhysicalLockingKey(DeviceIntPtr dev,unsigned key)
+{
+XkbDescPtr xkb;
+
+ xkb= dev->key->xkbInfo->desc;
+ if ((key>=xkb->min_key_code) && (key<=xkb->max_key_code)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock|XkbKB_Permanent;
+ }
+ else ErrorF("Internal Error! Bad XKB info in SetPhysicalLockingKey\n");
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
+ unsigned long change,
+ unsigned long newValues,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+{
+XkbControlsPtr ctrls;
+unsigned old;
+XkbSrvLedInfoPtr sli;
+
+ ctrls= xkbi->desc->ctrls;
+ old= ctrls->enabled_ctrls;
+ ctrls->enabled_ctrls&= ~change;
+ ctrls->enabled_ctrls|= (change&newValues);
+ if (old==ctrls->enabled_ctrls)
+ return False;
+ if (cause!=NULL) {
+ xkbControlsNotify cn;
+ cn.numGroups= ctrls->num_groups;
+ cn.changedControls|= XkbControlsEnabledMask;
+ cn.enabledControls= ctrls->enabled_ctrls;
+ cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ else {
+ /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
+ /* is non-zero, the controls in question changed already in "this" */
+ /* request and this change merely undoes the previous one. By the */
+ /* same token, we have to figure out whether or not ControlsEnabled */
+ /* should be set or not in the changes structure */
+ changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
+ if (changes->ctrls.enabled_ctrls_changes)
+ changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
+ else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(xkbi->device,sli->usesControls,True,changes,cause);
+ return True;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+
+XkbGeometryPtr
+XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
+{
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbDescPtr xkb= xkbi->desc;
+
+ *shouldFree= 0;
+ if (name==None) {
+ if (xkb->geom!=NULL)
+ return xkb->geom;
+ name= xkb->names->geometry;
+ }
+ if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
+ return xkb->geom;
+ else if ((name==xkb->names->geometry)&&(xkb->geom==NULL)) {
+ FILE *file= XkbDDXOpenConfigFile(XkbInitialMap,NULL,0);
+ if (file!=NULL) {
+ XkbFileInfo xkbFInfo;
+ xkmFileInfo finfo;
+ xkmSectionInfo toc[MAX_TOC],*entry;
+ bzero(&xkbFInfo,sizeof(xkbFInfo));
+ xkbFInfo.xkb= xkb;
+ if (XkmReadTOC(file,&finfo,MAX_TOC,toc)) {
+ entry= XkmFindTOCEntry(&finfo,toc,XkmGeometryIndex);
+ if (entry!=NULL)
+ XkmReadFileSection(file,entry,&xkbFInfo,NULL);
+ }
+ fclose(file);
+ if (xkb->geom) {
+ *shouldFree= 0;
+ return xkb->geom;
+ }
+ }
+ }
+ *shouldFree= 1;
+ return NULL;
+}
+
+void
+XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
+{
+ *lower = sym;
+ *upper = sym;
+ switch(sym >> 8) {
+ case 0: /* Latin 1 */
+ if ((sym >= XK_A) && (sym <= XK_Z))
+ *lower += (XK_a - XK_A);
+ else if ((sym >= XK_a) && (sym <= XK_z))
+ *upper -= (XK_a - XK_A);
+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ *lower += (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+ *upper -= (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+ *lower += (XK_oslash - XK_Ooblique);
+ else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+ *upper -= (XK_oslash - XK_Ooblique);
+ break;
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XK_Aogonek)
+ *lower = XK_aogonek;
+ else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+ *lower += (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_Scaron && sym <= XK_Zacute)
+ *lower += (XK_scaron - XK_Scaron);
+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+ *lower += (XK_zcaron - XK_Zcaron);
+ else if (sym == XK_aogonek)
+ *upper = XK_Aogonek;
+ else if (sym >= XK_lstroke && sym <= XK_sacute)
+ *upper -= (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_scaron && sym <= XK_zacute)
+ *upper -= (XK_scaron - XK_Scaron);
+ else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+ *upper -= (XK_zcaron - XK_Zcaron);
+ else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+ *lower += (XK_racute - XK_Racute);
+ else if (sym >= XK_racute && sym <= XK_tcedilla)
+ *upper -= (XK_racute - XK_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+ *lower += (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+ *lower += (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+ *upper -= (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+ *upper -= (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+ *lower += (XK_cabovedot - XK_Cabovedot);
+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+ *upper -= (XK_cabovedot - XK_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+ *lower += (XK_rcedilla - XK_Rcedilla);
+ else if (sym >= XK_rcedilla && sym <= XK_tslash)
+ *upper -= (XK_rcedilla - XK_Rcedilla);
+ else if (sym == XK_ENG)
+ *lower = XK_eng;
+ else if (sym == XK_eng)
+ *upper = XK_ENG;
+ else if (sym >= XK_Amacron && sym <= XK_Umacron)
+ *lower += (XK_amacron - XK_Amacron);
+ else if (sym >= XK_amacron && sym <= XK_umacron)
+ *upper -= (XK_amacron - XK_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+ *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+ sym != XK_Greek_iotaaccentdieresis &&
+ sym != XK_Greek_upsilonaccentdieresis)
+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+ sym != XK_Greek_finalsmallsigma)
+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+ break;
+ }
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbconfig.c b/nx-X11/programs/Xserver/xkb/xkbconfig.c
new file mode 100644
index 000000000..5fcd594bc
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbconfig.c
@@ -0,0 +1,1335 @@
+/************************************************************
+ Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <nx-X11/Xfuncs.h>
+
+#include <nx-X11/Xfuncs.h>
+
+
+#include <nx-X11/X.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include <xkbsrv.h>
+
+#include <nx-X11/extensions/XKBconfig.h>
+
+/***====================================================================***/
+
+#define XKBCF_MAX_STR_LEN 100
+static char _XkbCF_rtrn[XKBCF_MAX_STR_LEN+1];
+
+static int
+ScanIdent(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
+{
+register int i;
+char * str;
+
+ val_rtrn->str= str= _XkbCF_rtrn;
+ for (i=0;(isalpha(ch)||isdigit(ch)||(ch=='_'));ch=getc(file)) {
+ if (i<XKBCF_MAX_STR_LEN)
+ str[i++]= ch;
+ }
+ if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
+ ungetc(ch,file);
+ str[i]= '\0';
+ return XkbCF_Ident;
+}
+
+static int
+ScanString(FILE *file,int quote,XkbCFScanResultPtr val_rtrn)
+{
+int ch,nInBuf;
+
+ nInBuf = 0;
+ while ( ((ch=getc(file))!=EOF) && (ch!='\n') && (ch!=quote) ) {
+ if ( ch == '\\' ) {
+ if ((ch = getc(file))!=EOF) {
+ if ( ch=='n' ) ch = '\n';
+ else if ( ch == 't' ) ch = '\t';
+ else if ( ch == 'v' ) ch = '\v';
+ else if ( ch == 'b' ) ch = '\b';
+ else if ( ch == 'r' ) ch = '\r';
+ else if ( ch == 'f' ) ch = '\f';
+ else if ( ch == 'e' ) ch = '\033';
+ else if ( ch == '0' ) {
+ int tmp,stop;
+ ch = stop = 0;
+ if (((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
+ (tmp!='8') && (tmp!='9')) {
+ ch= (ch*8)+(tmp-'0');
+ }
+ else {
+ stop= 1;
+ ungetc(tmp,file);
+ }
+ if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
+ (tmp!='8') && (tmp!='9')) {
+ ch= (ch*8)+(tmp-'0');
+ }
+ else {
+ stop= 1;
+ ungetc(tmp,file);
+ }
+ if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
+ (tmp!='8') && (tmp!='9')) {
+ ch= (ch*8)+(tmp-'0');
+ }
+ else {
+ stop= 1;
+ ungetc(tmp,file);
+ }
+ }
+ }
+ else return XkbCF_EOF;
+ }
+
+ if ( nInBuf < XKBCF_MAX_STR_LEN-1 )
+ _XkbCF_rtrn[nInBuf++] = ch;
+ }
+ if ( ch == quote ) {
+ _XkbCF_rtrn[nInBuf++] = '\0';
+ val_rtrn->str= _XkbCF_rtrn;
+ return XkbCF_String;
+ }
+ return XkbCF_UnterminatedString;
+}
+
+static int
+ScanInteger(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
+{
+int i;
+
+ if (isdigit(ch))
+ ungetc(ch,file);
+ if (fscanf(file,"%i",&i)==1) {
+ val_rtrn->ival= i;
+ return XkbCF_Integer;
+ }
+ return XkbCF_Unknown;
+}
+
+int
+XkbCFScan(FILE *file,XkbCFScanResultPtr val_rtrn,XkbConfigRtrnPtr rtrn)
+{
+int ch;
+
+ do {
+ ch= getc(file);
+ } while ((ch=='\t')||(ch==' '));
+ if (isalpha(ch))
+ return ScanIdent(file,ch,val_rtrn);
+ else if (isdigit(ch))
+ return ScanInteger(file,ch,val_rtrn);
+ else if (ch=='"')
+ return ScanString(file,ch,val_rtrn);
+ else if (ch=='\n') {
+ rtrn->line++;
+ return XkbCF_EOL;
+ }
+ else if (ch==';')
+ return XkbCF_Semi;
+ else if (ch=='=')
+ return XkbCF_Equals;
+ else if (ch=='+') {
+ ch= getc(file);
+ if (ch=='=')
+ return XkbCF_PlusEquals;
+ if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
+ ungetc(ch,file);
+ return XkbCF_Plus;
+ }
+ else if (ch=='-') {
+ ch= getc(file);
+ if (ch=='=')
+ return XkbCF_MinusEquals;
+ if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
+ ungetc(ch,file);
+ return XkbCF_Minus;
+ }
+ else if (ch==EOF)
+ return XkbCF_EOF;
+ else if ((ch=='#')||((ch=='/')&&(getc(file)=='/'))) {
+ while ((ch!='\n')&&(ch!=EOF))
+ ch= getc(file);
+ rtrn->line++;
+ return XkbCF_EOL;
+ }
+ return XkbCF_Unknown;
+}
+
+/***====================================================================***/
+
+#define _XkbCF_Illegal 0
+#define _XkbCF_Keymap 1
+#define _XkbCF_Keycodes 2
+#define _XkbCF_Geometry 3
+#define _XkbCF_PhysSymbols 4
+#define _XkbCF_Symbols 5
+#define _XkbCF_Types 6
+#define _XkbCF_CompatMap 7
+
+#define _XkbCF_RulesFile 8
+#define _XkbCF_Model 9
+#define _XkbCF_Layout 10
+#define _XkbCF_Variant 11
+#define _XkbCF_Options 12
+
+#define _XkbCF_InitialMods 13
+#define _XkbCF_InitialCtrls 14
+
+#define _XkbCF_ClickVolume 15
+#define _XkbCF_BellVolume 16
+#define _XkbCF_BellPitch 17
+#define _XkbCF_BellDuration 18
+#define _XkbCF_RepeatDelay 19
+#define _XkbCF_RepeatInterval 20
+#define _XkbCF_SlowKeysDelay 21
+#define _XkbCF_DebounceDelay 22
+#define _XkbCF_MouseKeysDelay 23
+#define _XkbCF_MouseKeysInterval 24
+#define _XkbCF_MouseKeysTimeToMax 25
+#define _XkbCF_MouseKeysMaxSpeed 26
+#define _XkbCF_MouseKeysCurve 27
+#define _XkbCF_AccessXTimeout 28
+#define _XkbCF_AccessXTimeoutCtrlsOn 29
+#define _XkbCF_AccessXTimeoutCtrlsOff 30
+#define _XkbCF_AccessXTimeoutOptsOn 31
+#define _XkbCF_AccessXTimeoutOptsOff 32
+
+#define _XkbCF_IgnoreLockMods 33
+#define _XkbCF_IgnoreGroupLock 34
+#define _XkbCF_InternalMods 35
+
+#define _XkbCF_GroupsWrap 36
+#define _XkbCF_InitialFeedback 37
+
+static Bool
+AddCtrlByName(XkbConfigRtrnPtr rtrn,char *name,unsigned long *ctrls_rtrn)
+{
+ if ((_XkbStrCaseCmp(name,"repeat")==0)||
+ (_XkbStrCaseCmp(name,"repeatkeys")==0))
+ *ctrls_rtrn= XkbRepeatKeysMask;
+ else if (_XkbStrCaseCmp(name,"slowkeys")==0)
+ *ctrls_rtrn= XkbSlowKeysMask;
+ else if (_XkbStrCaseCmp(name,"bouncekeys")==0)
+ *ctrls_rtrn= XkbBounceKeysMask;
+ else if (_XkbStrCaseCmp(name,"stickykeys")==0)
+ *ctrls_rtrn= XkbStickyKeysMask;
+ else if (_XkbStrCaseCmp(name,"mousekeys")==0)
+ *ctrls_rtrn= XkbMouseKeysMask;
+ else if (_XkbStrCaseCmp(name,"mousekeysaccel")==0)
+ *ctrls_rtrn= XkbMouseKeysAccelMask;
+ else if (_XkbStrCaseCmp(name,"accessxkeys")==0)
+ *ctrls_rtrn= XkbAccessXKeysMask;
+ else if (_XkbStrCaseCmp(name,"accessxtimeout")==0)
+ *ctrls_rtrn= XkbAccessXTimeoutMask;
+ else if (_XkbStrCaseCmp(name,"accessxfeedback")==0)
+ *ctrls_rtrn= XkbAccessXFeedbackMask;
+ else if (_XkbStrCaseCmp(name,"audiblebell")==0)
+ *ctrls_rtrn= XkbAudibleBellMask;
+ else if (_XkbStrCaseCmp(name,"overlay1")==0)
+ *ctrls_rtrn= XkbOverlay1Mask;
+ else if (_XkbStrCaseCmp(name,"overlay2")==0)
+ *ctrls_rtrn= XkbOverlay2Mask;
+ else if (_XkbStrCaseCmp(name,"ignoregrouplock")==0)
+ *ctrls_rtrn= XkbIgnoreGroupLockMask;
+ else {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ return True;
+}
+
+static Bool
+AddAXTimeoutOptByName( XkbConfigRtrnPtr rtrn,
+ char * name,
+ unsigned short * opts_rtrn)
+{
+ if (_XkbStrCaseCmp(name,"slowkeyspress")==0)
+ *opts_rtrn= XkbAX_SKPressFBMask;
+ else if (_XkbStrCaseCmp(name,"slowkeysaccept")==0)
+ *opts_rtrn= XkbAX_SKAcceptFBMask;
+ else if (_XkbStrCaseCmp(name,"feature")==0)
+ *opts_rtrn= XkbAX_FeatureFBMask;
+ else if (_XkbStrCaseCmp(name,"slowwarn")==0)
+ *opts_rtrn= XkbAX_SlowWarnFBMask;
+ else if (_XkbStrCaseCmp(name,"indicator")==0)
+ *opts_rtrn= XkbAX_IndicatorFBMask;
+ else if (_XkbStrCaseCmp(name,"stickykeys")==0)
+ *opts_rtrn= XkbAX_StickyKeysFBMask;
+ else if (_XkbStrCaseCmp(name,"twokeys")==0)
+ *opts_rtrn= XkbAX_TwoKeysMask;
+ else if (_XkbStrCaseCmp(name,"latchtolock")==0)
+ *opts_rtrn= XkbAX_LatchToLockMask;
+ else if (_XkbStrCaseCmp(name,"slowkeysrelease")==0)
+ *opts_rtrn= XkbAX_SKReleaseFBMask;
+ else if (_XkbStrCaseCmp(name,"slowkeysreject")==0)
+ *opts_rtrn= XkbAX_SKRejectFBMask;
+ else if (_XkbStrCaseCmp(name,"bouncekeysreject")==0)
+ *opts_rtrn= XkbAX_BKRejectFBMask;
+ else if (_XkbStrCaseCmp(name,"dumbbell")==0)
+ *opts_rtrn= XkbAX_DumbBellFBMask;
+ else {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ return True;
+}
+
+XkbConfigUnboundModPtr
+XkbCFAddModByName( XkbConfigRtrnPtr rtrn,
+ int what,
+ char * name,
+ Bool merge,
+ XkbConfigUnboundModPtr last)
+{
+ if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) {
+ rtrn->sz_unbound_mods+= 5;
+ rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods,
+ rtrn->sz_unbound_mods,
+ XkbConfigUnboundModRec);
+ if (rtrn->unbound_mods==NULL) {
+ rtrn->error= XkbCF_BadAlloc;
+ return False;
+ }
+ }
+ if (last==NULL) {
+ last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
+ last->what= what;
+ last->mods= 0;
+ last->vmods= 0;
+ last->merge= merge;
+ last->name= NULL;
+ }
+ if (_XkbStrCaseCmp(name,"shift")==0)
+ last->mods|= ShiftMask;
+ else if (_XkbStrCaseCmp(name,"lock")==0)
+ last->mods|= LockMask;
+ else if ((_XkbStrCaseCmp(name,"control")==0)||
+ (_XkbStrCaseCmp(name,"ctrl")==0))
+ last->mods|= ControlMask;
+ else if (_XkbStrCaseCmp(name,"mod1")==0)
+ last->mods|= Mod1Mask;
+ else if (_XkbStrCaseCmp(name,"mod2")==0)
+ last->mods|= Mod2Mask;
+ else if (_XkbStrCaseCmp(name,"mod3")==0)
+ last->mods|= Mod3Mask;
+ else if (_XkbStrCaseCmp(name,"mod4")==0)
+ last->mods|= Mod4Mask;
+ else if (_XkbStrCaseCmp(name,"mod5")==0)
+ last->mods|= Mod5Mask;
+ else {
+ if (last->name!=NULL) {
+ last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
+ last->what= what;
+ last->mods= 0;
+ last->vmods= 0;
+ last->merge= merge;
+ last->name= NULL;
+ }
+ last->name= Xstrdup(name);
+ }
+ return last;
+}
+
+int
+XkbCFBindMods(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
+{
+register int n,v;
+Atom name;
+XkbConfigUnboundModPtr mod;
+int missing;
+
+ if (rtrn->num_unbound_mods<1)
+ return 0;
+ if ((xkb==NULL) || (xkb->names==NULL))
+ return -1;
+
+ missing= 0;
+ for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
+ if (mod->name!=NULL) {
+ name= XkbInternAtom(xkb->dpy,mod->name,True);
+ if (name==None)
+ continue;
+ for (v=0;v<XkbNumVirtualMods;v++) {
+ if (xkb->names->vmods[v]==name) {
+ mod->vmods= (1<<v);
+ _XkbFree(mod->name);
+ mod->name= NULL;
+ break;
+ }
+ }
+ if (mod->name!=NULL)
+ missing++;
+ }
+ }
+ return missing;
+}
+
+Bool
+XkbCFApplyMods(XkbConfigRtrnPtr rtrn,int what,XkbConfigModInfoPtr info)
+{
+register int n;
+XkbConfigUnboundModPtr mod;
+
+ if (rtrn->num_unbound_mods<1)
+ return True;
+
+ for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
+ if (mod->what!=what)
+ continue;
+ if (mod->merge==XkbCF_MergeRemove) {
+ info->mods_clear|= mod->mods;
+ info->vmods_clear|= mod->vmods;
+ }
+ else {
+ if (mod->merge==XkbCF_MergeSet)
+ info->replace= True;
+ info->mods|= mod->mods;
+ info->vmods|= mod->vmods;
+ }
+ if (mod->name==NULL) {
+ mod->what= _XkbCF_Illegal;
+ }
+ else {
+ mod->mods= 0;
+ mod->vmods= 0;
+ }
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+DefaultParser( FILE * file,
+ XkbConfigFieldsPtr fields,
+ XkbConfigFieldPtr field,
+ XkbDescPtr xkb,
+ XkbConfigRtrnPtr rtrn)
+{
+int tok;
+XkbCFScanResultRec val;
+char ** str;
+int merge;
+unsigned long * ctrls, ctrls_mask;
+unsigned short * opts, opts_mask;
+int * pival, sign;
+int onoff;
+XkbConfigUnboundModPtr last;
+unsigned what;
+
+ tok= XkbCFScan(file,&val,rtrn);
+ str= NULL;
+ onoff= 0;
+ pival= NULL;
+ switch (field->field_id) {
+ case _XkbCF_RulesFile: if (!str) str= &rtrn->rules_file;
+ case _XkbCF_Model: if (!str) str= &rtrn->model;
+ case _XkbCF_Layout: if (!str) str= &rtrn->layout;
+ case _XkbCF_Variant: if (!str) str= &rtrn->variant;
+ case _XkbCF_Options: if (!str) str= &rtrn->options;
+ case _XkbCF_Keymap: if (!str) str= &rtrn->keymap;
+ case _XkbCF_Keycodes: if (!str) str= &rtrn->keycodes;
+ case _XkbCF_Geometry: if (!str) str= &rtrn->geometry;
+ case _XkbCF_PhysSymbols:if (!str) str= &rtrn->phys_symbols;
+ case _XkbCF_Symbols: if (!str) str= &rtrn->symbols;
+ case _XkbCF_Types: if (!str) str= &rtrn->types;
+ case _XkbCF_CompatMap: if (!str) str= &rtrn->compat;
+ if (tok!=XkbCF_Equals) {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_String)&&(tok!=XkbCF_Ident)) {
+ rtrn->error= XkbCF_ExpectedString;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedEOS;
+ return False;
+ }
+ if (*str!=NULL)
+ _XkbFree(*str);
+ *str= Xstrdup(val.str);
+ break;
+ case _XkbCF_InitialMods:
+ case _XkbCF_IgnoreLockMods:
+ case _XkbCF_InternalMods:
+ what= XkbCF_InitialMods;
+ if (field->field_id==_XkbCF_InitialMods)
+ rtrn->defined|= (what=XkbCF_InitialMods);
+ else if (field->field_id==_XkbCF_InternalMods)
+ rtrn->defined|= (what=XkbCF_InternalMods);
+ else if (field->field_id==_XkbCF_IgnoreLockMods)
+ rtrn->defined|= (what=XkbCF_IgnoreLockMods);
+ if (tok==XkbCF_Equals) merge= XkbCF_MergeSet;
+ else if (tok==XkbCF_MinusEquals) merge= XkbCF_MergeRemove;
+ else if (tok==XkbCF_PlusEquals) merge= XkbCF_MergeAdd;
+ else {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedModifier;
+ return False;
+ }
+ last= NULL;
+ while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
+ rtrn->error= XkbCF_ExpectedModifier;
+ return False;
+ }
+ last=XkbCFAddModByName(rtrn,what,val.str,merge,last);
+ if (last==NULL)
+ return False;
+ if (merge==XkbCF_MergeSet)
+ merge= XkbCF_MergeAdd;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
+ if (tok!=XkbCF_Plus) {
+ rtrn->error= XkbCF_ExpectedOperator;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ }
+ }
+ break;
+ case _XkbCF_InitialCtrls:
+ rtrn->defined|= XkbCF_InitialCtrls;
+ ctrls= NULL;
+ if (tok==XkbCF_PlusEquals)
+ ctrls= &rtrn->initial_ctrls;
+ else if (tok==XkbCF_MinusEquals)
+ ctrls= &rtrn->initial_ctrls_clear;
+ else if (tok==XkbCF_Equals) {
+ ctrls= &rtrn->initial_ctrls;
+ rtrn->replace_initial_ctrls= True;
+ *ctrls= 0;
+ }
+ else {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
+ return False;
+ }
+ *ctrls |= ctrls_mask;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
+ if (tok!=XkbCF_Plus) {
+ rtrn->error= XkbCF_ExpectedOperator;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ }
+ }
+ break;
+ case _XkbCF_AccessXTimeoutCtrlsOn:
+ case _XkbCF_AccessXTimeoutCtrlsOff:
+ opts= NULL;
+ if (tok==XkbCF_MinusEquals) {
+ ctrls= &rtrn->axt_ctrls_ignore;
+ opts= &rtrn->axt_opts_ignore;
+ }
+ else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
+ if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
+ ctrls= &rtrn->axt_ctrls_off;
+ opts= &rtrn->axt_opts_off;
+ if (tok==XkbCF_Equals)
+ rtrn->replace_axt_ctrls_off= True;
+ }
+ else {
+ ctrls= &rtrn->axt_ctrls_on;
+ opts= &rtrn->axt_opts_on;
+ if (tok==XkbCF_Equals)
+ rtrn->replace_axt_ctrls_on= True;
+ }
+ *ctrls= 0;
+ }
+ else {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
+ if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
+ return False;
+ *opts |= opts_mask;
+ if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
+ rtrn->defined|= XkbCF_AccessXTimeoutOptsOff;
+ if (rtrn->replace_axt_ctrls_off)
+ rtrn->replace_axt_opts_off= True;
+ }
+ else {
+ rtrn->defined|= XkbCF_AccessXTimeoutOptsOn;
+ if (rtrn->replace_axt_ctrls_on)
+ rtrn->replace_axt_opts_on= True;
+ }
+ }
+ else
+ *ctrls |= ctrls_mask;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
+ if (tok!=XkbCF_Plus) {
+ rtrn->error= XkbCF_ExpectedOperator;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ }
+ }
+ break;
+ case _XkbCF_InitialFeedback:
+ rtrn->defined|= XkbCF_InitialOpts;
+ opts= NULL;
+ if (tok==XkbCF_PlusEquals)
+ opts= &rtrn->initial_opts;
+ else if (tok==XkbCF_MinusEquals)
+ opts= &rtrn->initial_opts_clear;
+ else if (tok==XkbCF_Equals) {
+ opts= &rtrn->initial_opts;
+ rtrn->replace_initial_opts= True;
+ *opts= 0;
+ }
+ else {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedAXOption;
+ return False;
+ }
+ while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
+ rtrn->error= XkbCF_ExpectedAXOption;
+ return False;
+ }
+ if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) {
+ return False;
+ }
+ *opts |= opts_mask;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
+ if (tok!=XkbCF_Plus) {
+ rtrn->error= XkbCF_ExpectedOperator;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ }
+ }
+ break;
+ case _XkbCF_AccessXTimeoutOptsOff:
+ case _XkbCF_AccessXTimeoutOptsOn:
+ opts= NULL;
+ if (tok==XkbCF_MinusEquals)
+ opts= &rtrn->axt_opts_ignore;
+ else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
+ if (field->field_id==_XkbCF_AccessXTimeoutOptsOff) {
+ opts= &rtrn->axt_opts_off;
+ if (tok==XkbCF_Equals)
+ rtrn->replace_axt_opts_off= True;
+ }
+ else {
+ opts= &rtrn->axt_opts_on;
+ if (tok==XkbCF_Equals)
+ rtrn->replace_axt_opts_on= True;
+ }
+ *opts = 0;
+ }
+ else {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
+ rtrn->error= XkbCF_ExpectedControl;
+ return False;
+ }
+ if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
+ return False;
+ *opts |= opts_mask;
+
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
+ if (tok!=XkbCF_Plus) {
+ rtrn->error= XkbCF_ExpectedOperator;
+ return False;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ }
+ }
+ break;
+ case _XkbCF_ClickVolume:
+ if (!pival) {
+ pival= &rtrn->click_volume;
+ onoff= 100;
+ }
+ case _XkbCF_BellVolume:
+ if (!pival) {
+ pival= &rtrn->bell_volume;
+ onoff= 100;
+ }
+ case _XkbCF_BellPitch:
+ if (!pival)
+ pival= &rtrn->bell_pitch;
+ case _XkbCF_BellDuration:
+ if (!pival)
+ pival= &rtrn->bell_duration;
+ case _XkbCF_RepeatDelay:
+ if (!pival)
+ pival= &rtrn->repeat_delay;
+ case _XkbCF_RepeatInterval:
+ if (!pival)
+ pival= &rtrn->repeat_interval;
+ case _XkbCF_SlowKeysDelay:
+ if (!pival)
+ pival= &rtrn->slow_keys_delay;
+ case _XkbCF_DebounceDelay:
+ if (!pival)
+ pival= &rtrn->debounce_delay;
+ case _XkbCF_MouseKeysDelay:
+ if (!pival)
+ pival= &rtrn->mk_delay;
+ case _XkbCF_MouseKeysInterval:
+ if (!pival)
+ pival= &rtrn->mk_interval;
+ case _XkbCF_MouseKeysTimeToMax:
+ if (!pival)
+ pival= &rtrn->mk_time_to_max;
+ case _XkbCF_MouseKeysMaxSpeed:
+ if (!pival)
+ pival= &rtrn->mk_max_speed;
+ case _XkbCF_MouseKeysCurve:
+ if (!pival)
+ pival= &rtrn->mk_curve;
+ case _XkbCF_AccessXTimeout:
+ if (!pival)
+ pival= &rtrn->ax_timeout;
+ if (tok!=XkbCF_Equals) {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) {
+ /* This can be a negative value */
+ tok = XkbCFScan(file,&val,rtrn);
+ sign = -1;
+ }
+ else
+ sign = 1;
+ if (tok!=XkbCF_Integer) {
+ Bool ok= False;
+ if ((onoff)&&(tok==XkbCF_Ident)&&(val.str!=NULL)) {
+ if (_XkbStrCaseCmp(val.str,"on")) {
+ val.ival= onoff;
+ ok= True;
+ }
+ else if (_XkbStrCaseCmp(val.str,"off")) {
+ val.ival= 0;
+ ok= True;
+ }
+ }
+ if (!ok) {
+ rtrn->error= XkbCF_ExpectedInteger;
+ goto BAILOUT;
+ }
+ }
+ *pival= val.ival * sign;
+ if (field->field_id == _XkbCF_AccessXTimeout)
+ rtrn->defined|=XkbCF_AccessXTimeout;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedEOS;
+ return False;
+ }
+ break;
+ case _XkbCF_GroupsWrap:
+ if (tok!=XkbCF_Equals) {
+ rtrn->error= XkbCF_MissingEquals;
+ goto BAILOUT;
+ }
+ tok= XkbCFScan(file,&val,rtrn);
+ if (tok==XkbCF_Ident) {
+ if (_XkbStrCaseCmp(val.str,"wrap")==0) {
+ rtrn->groups_wrap= XkbSetGroupInfo(0,XkbWrapIntoRange,0);
+ }
+ else if (_XkbStrCaseCmp(val.str,"clamp")==0) {
+ rtrn->groups_wrap= XkbSetGroupInfo(0,XkbClampIntoRange,0);
+ }
+ else {
+ rtrn->error= XkbCF_ExpectedOORGroupBehavior;
+ return False;
+ }
+ }
+ else if ((tok==XkbCF_Integer)&&(XkbIsLegalGroup(val.ival-1))) {
+ rtrn->groups_wrap= XkbSetGroupInfo(0,XkbRedirectIntoRange,
+ val.ival-1);
+ }
+ else {
+ rtrn->error= XkbCF_ExpectedOORGroupBehavior;
+ return False;
+ }
+ rtrn->defined|= XkbCF_GroupsWrap;
+ tok= XkbCFScan(file,&val,rtrn);
+ if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
+ rtrn->error= XkbCF_ExpectedEOS;
+ return False;
+ }
+ break;
+ default:
+ rtrn->error= XkbCF_ExpectedInteger;
+ goto BAILOUT;
+
+ }
+ return True;
+BAILOUT:
+ return False;
+}
+
+static Bool
+DefaultCleanUp(XkbConfigRtrnPtr rtrn)
+{
+ if (rtrn->keymap) _XkbFree(rtrn->keymap);
+ if (rtrn->keycodes) _XkbFree(rtrn->keycodes);
+ if (rtrn->geometry) _XkbFree(rtrn->geometry);
+ if (rtrn->phys_symbols) _XkbFree(rtrn->phys_symbols);
+ if (rtrn->symbols) _XkbFree(rtrn->symbols);
+ if (rtrn->types) _XkbFree(rtrn->types);
+ if (rtrn->compat) _XkbFree(rtrn->compat);
+ rtrn->keycodes= rtrn->geometry= NULL;
+ rtrn->symbols= rtrn->phys_symbols= NULL;
+ rtrn->types= rtrn->compat= NULL;
+ if ((rtrn->unbound_mods!=NULL)&&(rtrn->num_unbound_mods>0)) {
+ register int i;
+ for (i=0;i<rtrn->num_unbound_mods;i++) {
+ if (rtrn->unbound_mods[i].name!=NULL) {
+ _XkbFree(rtrn->unbound_mods[i].name);
+ rtrn->unbound_mods[i].name= NULL;
+ }
+ }
+ _XkbFree(rtrn->unbound_mods);
+ rtrn->sz_unbound_mods= 0;
+ rtrn->num_unbound_mods= 0;
+ rtrn->unbound_mods= NULL;
+ }
+ return True;
+}
+
+static Bool
+DefaultApplyNames(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
+{
+char *str;
+
+ if (XkbAllocNames(xkb,XkbComponentNamesMask,0,0)!=Success)
+ return False;
+ if ((str=rtrn->keycodes)!=NULL) {
+ xkb->names->keycodes= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->keycodes= NULL;
+ }
+ if ((str=rtrn->geometry)!=NULL) {
+ xkb->names->geometry= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->geometry= NULL;
+ }
+ if ((str=rtrn->symbols)!=NULL) {
+ xkb->names->symbols= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->symbols= NULL;
+ }
+ if ((str=rtrn->phys_symbols)!=NULL) {
+ xkb->names->phys_symbols= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->phys_symbols= NULL;
+ }
+ if ((str=rtrn->types)!=NULL) {
+ xkb->names->types= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->types= NULL;
+ }
+ if ((str=rtrn->compat)!=NULL) {
+ xkb->names->compat= XkbInternAtom(xkb->dpy,str,False);
+ _XkbFree(str);
+ rtrn->compat= NULL;
+ }
+ return True;
+}
+
+static Bool
+DefaultApplyControls(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
+{
+unsigned on,off;
+XkbControlsPtr ctrls;
+unsigned int mask;
+
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ return False;
+ ctrls= xkb->ctrls;
+ if (rtrn->replace_initial_ctrls)
+ ctrls->enabled_ctrls= rtrn->initial_ctrls;
+ else ctrls->enabled_ctrls|= rtrn->initial_ctrls;
+ ctrls->enabled_ctrls&= ~rtrn->initial_ctrls_clear;
+ if (rtrn->internal_mods.replace) {
+ ctrls->internal.real_mods= rtrn->internal_mods.mods;
+ ctrls->internal.vmods= rtrn->internal_mods.vmods;
+ }
+ else {
+ ctrls->internal.real_mods&= ~rtrn->internal_mods.mods_clear;
+ ctrls->internal.vmods&= ~rtrn->internal_mods.vmods_clear;
+ ctrls->internal.real_mods|= rtrn->internal_mods.mods;
+ ctrls->internal.vmods|= rtrn->internal_mods.vmods;
+ }
+ mask= 0;
+ (void)XkbVirtualModsToReal(xkb,ctrls->internal.vmods,&mask);
+ ctrls->internal.mask= (ctrls->internal.real_mods|mask);
+
+ if (rtrn->ignore_lock_mods.replace) {
+ ctrls->ignore_lock.real_mods= rtrn->ignore_lock_mods.mods;
+ ctrls->ignore_lock.vmods= rtrn->ignore_lock_mods.vmods;
+ }
+ else {
+ ctrls->ignore_lock.real_mods&= ~rtrn->ignore_lock_mods.mods_clear;
+ ctrls->ignore_lock.vmods&= ~rtrn->ignore_lock_mods.vmods_clear;
+ ctrls->ignore_lock.real_mods|= rtrn->ignore_lock_mods.mods;
+ ctrls->ignore_lock.vmods|= rtrn->ignore_lock_mods.vmods;
+ }
+ mask= 0;
+ (void)XkbVirtualModsToReal(xkb,ctrls->ignore_lock.vmods,&mask);
+ ctrls->ignore_lock.mask= (ctrls->ignore_lock.real_mods|mask);
+
+ if (rtrn->repeat_delay>0)
+ ctrls->repeat_delay= rtrn->repeat_delay;
+ if (rtrn->repeat_interval>0)
+ ctrls->repeat_interval= rtrn->repeat_interval;
+ if (rtrn->slow_keys_delay>0)
+ ctrls->slow_keys_delay= rtrn->slow_keys_delay;
+ if (rtrn->debounce_delay>0)
+ ctrls->debounce_delay= rtrn->debounce_delay;
+ if (rtrn->mk_delay>0)
+ ctrls->mk_delay= rtrn->mk_delay;
+ if (rtrn->mk_interval>0)
+ ctrls->mk_interval= rtrn->mk_interval;
+ if (rtrn->mk_time_to_max>0)
+ ctrls->mk_time_to_max= rtrn->mk_time_to_max;
+ if (rtrn->mk_max_speed>0)
+ ctrls->mk_max_speed= rtrn->mk_max_speed;
+ if (rtrn->mk_curve>0)
+ ctrls->mk_curve= rtrn->mk_curve;
+ if (rtrn->defined&XkbCF_AccessXTimeout && rtrn->ax_timeout > 0)
+ ctrls->ax_timeout= rtrn->ax_timeout;
+
+ /* any value set to both off and on is reset to ignore */
+ if ((off=(rtrn->axt_ctrls_on&rtrn->axt_ctrls_off))!=0)
+ rtrn->axt_ctrls_ignore|= off;
+
+ /* ignore takes priority over on and off */
+ rtrn->axt_ctrls_on&= ~rtrn->axt_ctrls_ignore;
+ rtrn->axt_ctrls_off&= ~rtrn->axt_ctrls_ignore;
+
+ if (!rtrn->replace_axt_ctrls_off) {
+ off= (ctrls->axt_ctrls_mask&(~ctrls->axt_ctrls_values));
+ off&= ~rtrn->axt_ctrls_on;
+ off|= rtrn->axt_ctrls_off;
+ }
+ else off= rtrn->axt_ctrls_off;
+ if (!rtrn->replace_axt_ctrls_on) {
+ on= (ctrls->axt_ctrls_mask&ctrls->axt_ctrls_values);
+ on&= ~rtrn->axt_ctrls_off;
+ on|= rtrn->axt_ctrls_on;
+ }
+ else on= rtrn->axt_ctrls_on;
+ ctrls->axt_ctrls_mask= (on|off)&~rtrn->axt_ctrls_ignore;
+ ctrls->axt_ctrls_values= on&~rtrn->axt_ctrls_ignore;
+
+ /* any value set to both off and on is reset to ignore */
+ if ((off=(rtrn->axt_opts_on&rtrn->axt_opts_off))!=0)
+ rtrn->axt_opts_ignore|= off;
+
+ /* ignore takes priority over on and off */
+ rtrn->axt_opts_on&= ~rtrn->axt_opts_ignore;
+ rtrn->axt_opts_off&= ~rtrn->axt_opts_ignore;
+
+ if (rtrn->replace_axt_opts_off) {
+ off= (ctrls->axt_opts_mask&(~ctrls->axt_opts_values));
+ off&= ~rtrn->axt_opts_on;
+ off|= rtrn->axt_opts_off;
+ }
+ else off= rtrn->axt_opts_off;
+ if (!rtrn->replace_axt_opts_on) {
+ on= (ctrls->axt_opts_mask&ctrls->axt_opts_values);
+ on&= ~rtrn->axt_opts_off;
+ on|= rtrn->axt_opts_on;
+ }
+ else on= rtrn->axt_opts_on;
+ ctrls->axt_opts_mask= (unsigned short)((on|off)&~rtrn->axt_ctrls_ignore);
+ ctrls->axt_opts_values= (unsigned short)(on&~rtrn->axt_ctrls_ignore);
+
+ if (rtrn->defined&XkbCF_GroupsWrap) {
+ int n;
+ n= XkbNumGroups(ctrls->groups_wrap);
+ rtrn->groups_wrap= XkbSetNumGroups(rtrn->groups_wrap,n);
+ ctrls->groups_wrap= rtrn->groups_wrap;
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+DefaultFinish( XkbConfigFieldsPtr fields,
+ XkbDescPtr xkb,
+ XkbConfigRtrnPtr rtrn,
+ int what)
+{
+ if ((what==XkbCF_Destroy)||(what==XkbCF_CleanUp))
+ return DefaultCleanUp(rtrn);
+ if (what==XkbCF_Check) {
+ if ((rtrn->symbols==NULL)&&(rtrn->phys_symbols!=NULL))
+ rtrn->symbols= Xstrdup(rtrn->phys_symbols);
+ }
+ if ((what==XkbCF_Apply)||(what==XkbCF_Check)) {
+ if (xkb && xkb->names && (rtrn->num_unbound_mods>0))
+ XkbCFBindMods(rtrn,xkb);
+ XkbCFApplyMods(rtrn,XkbCF_InitialMods,&rtrn->initial_mods);
+ XkbCFApplyMods(rtrn,XkbCF_InternalMods,&rtrn->internal_mods);
+ XkbCFApplyMods(rtrn,XkbCF_IgnoreLockMods,&rtrn->ignore_lock_mods);
+ }
+ if (what==XkbCF_Apply) {
+ if (xkb!=NULL) {
+ DefaultApplyNames(rtrn,xkb);
+ DefaultApplyControls(rtrn,xkb);
+ XkbCFBindMods(rtrn,xkb);
+ }
+ }
+ return True;
+}
+
+static XkbConfigFieldRec _XkbCFDfltFields[] = {
+ { "rules", _XkbCF_RulesFile },
+ { "model", _XkbCF_Model },
+ { "layout", _XkbCF_Layout },
+ { "variant", _XkbCF_Variant },
+ { "options", _XkbCF_Options },
+ { "keymap", _XkbCF_Keymap },
+ { "keycodes", _XkbCF_Keycodes },
+ { "geometry", _XkbCF_Geometry },
+ { "realsymbols",_XkbCF_PhysSymbols },
+ { "actualsymbols",_XkbCF_PhysSymbols },
+ { "symbols", _XkbCF_Symbols },
+ { "symbolstouse",_XkbCF_Symbols },
+ { "types", _XkbCF_Types },
+ { "compat", _XkbCF_CompatMap },
+ { "modifiers", _XkbCF_InitialMods },
+ { "controls", _XkbCF_InitialCtrls },
+ { "click", _XkbCF_ClickVolume },
+ { "clickvolume",_XkbCF_ClickVolume },
+ { "bell", _XkbCF_BellVolume },
+ { "bellvolume", _XkbCF_BellVolume },
+ { "bellpitch", _XkbCF_BellPitch },
+ { "bellduration",_XkbCF_BellDuration },
+ { "repeatdelay",_XkbCF_RepeatDelay },
+ { "repeatinterval",_XkbCF_RepeatInterval },
+ { "slowkeysdelay",_XkbCF_SlowKeysDelay },
+ { "debouncedelay",_XkbCF_DebounceDelay },
+ { "mousekeysdelay",_XkbCF_MouseKeysDelay },
+ { "mousekeysinterval",_XkbCF_MouseKeysInterval },
+ { "mousekeystimetomax",_XkbCF_MouseKeysTimeToMax },
+ { "mousekeysmaxspeed",_XkbCF_MouseKeysMaxSpeed },
+ { "mousekeyscurve",_XkbCF_MouseKeysCurve },
+ { "accessxtimeout",_XkbCF_AccessXTimeout },
+ { "axtimeout",_XkbCF_AccessXTimeout },
+ { "accessxtimeoutctrlson",_XkbCF_AccessXTimeoutCtrlsOn },
+ { "axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn },
+ { "accessxtimeoutctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
+ { "axtctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
+ { "accessxtimeoutfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
+ { "axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
+ { "accessxtimeoutfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
+ { "axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
+ { "ignorelockmods",_XkbCF_IgnoreLockMods },
+ { "ignorelockmodifiers",_XkbCF_IgnoreLockMods },
+ { "ignoregrouplock",_XkbCF_IgnoreGroupLock },
+ { "internalmods",_XkbCF_InternalMods },
+ { "internalmodifiers",_XkbCF_InternalMods },
+ { "outofrangegroups",_XkbCF_GroupsWrap },
+ { "groups", _XkbCF_GroupsWrap },
+ { "feedback", _XkbCF_InitialFeedback },
+};
+#define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec))
+
+static XkbConfigFieldsRec _XkbCFDflts = {
+ 0, /* cfg_id */
+ _XkbCFNumDfltFields, /* num_fields */
+ _XkbCFDfltFields, /* fields */
+ DefaultParser, /* parser */
+ DefaultFinish, /* finish */
+ NULL, /* priv */
+ NULL /* next */
+};
+
+XkbConfigFieldsPtr XkbCFDflts= &_XkbCFDflts;
+
+/***====================================================================***/
+
+XkbConfigFieldsPtr
+XkbCFDup(XkbConfigFieldsPtr fields)
+{
+XkbConfigFieldsPtr pNew;
+
+ pNew= _XkbTypedAlloc(XkbConfigFieldsRec);
+ if (pNew!=NULL) {
+ memcpy(pNew,fields,sizeof(XkbConfigFieldsRec));
+ if ((pNew->fields!=NULL)&&(pNew->num_fields>0)) {
+ pNew->fields= _XkbTypedCalloc(pNew->num_fields,XkbConfigFieldRec);
+ if (pNew->fields) {
+ memcpy(fields->fields,pNew->fields,
+ (pNew->num_fields*sizeof(XkbConfigFieldRec)));
+ }
+ else {
+ _XkbFree(pNew);
+ return NULL;
+ }
+ }
+ else {
+ pNew->num_fields= 0;
+ pNew->fields= NULL;
+ }
+ pNew->next= NULL;
+ }
+ return pNew;
+}
+
+XkbConfigFieldsPtr
+XkbCFFree(XkbConfigFieldsPtr fields,Bool all)
+{
+XkbConfigFieldsPtr next;
+
+ next= NULL;
+ while (fields!=NULL) {
+ next= fields->next;
+ if (fields!=XkbCFDflts) {
+ if (fields->fields) {
+ _XkbFree(fields->fields);
+ fields->fields= NULL;
+ fields->num_fields= 0;
+ }
+ _XkbFree(fields);
+ }
+ fields= (all?next:NULL);
+ }
+ return next;
+}
+
+Bool
+XkbCFApplyRtrnValues( XkbConfigRtrnPtr rtrn,
+ XkbConfigFieldsPtr fields,
+ XkbDescPtr xkb)
+{
+Bool ok;
+
+ if ((fields==NULL)||(rtrn==NULL)||(xkb==NULL))
+ return False;
+ for (ok=True;fields!=NULL;fields=fields->next) {
+ if (fields->finish!=NULL)
+ ok= (*fields->finish)(fields,xkb,rtrn,XkbCF_Apply)&&ok;
+ }
+ return ok;
+}
+
+XkbConfigRtrnPrivPtr
+XkbCFAddPrivate( XkbConfigRtrnPtr rtrn,
+ XkbConfigFieldsPtr fields,
+ XPointer ptr)
+{
+XkbConfigRtrnPrivPtr priv;
+
+ if ((rtrn==NULL)||(fields==NULL))
+ return NULL;
+ priv= _XkbTypedAlloc(XkbConfigRtrnPrivRec);
+ if (priv!=NULL) {
+ priv->cfg_id= fields->cfg_id;
+ priv->priv= ptr;
+ priv->next= rtrn->priv;
+ rtrn->priv= priv;
+ }
+ return priv;
+}
+
+void
+XkbCFFreeRtrn( XkbConfigRtrnPtr rtrn,
+ XkbConfigFieldsPtr fields,
+ XkbDescPtr xkb)
+{
+XkbConfigRtrnPrivPtr tmp,next;
+
+ if ((fields==NULL)||(rtrn==NULL))
+ return;
+ while (fields!=NULL) {
+ if (fields->finish!=NULL)
+ (*fields->finish)(fields,xkb,rtrn,XkbCF_Destroy);
+ fields= fields->next;
+ }
+ for (tmp=rtrn->priv;tmp!=NULL;tmp=next) {
+ next= tmp->next;
+ bzero((char *)tmp,sizeof(XkbConfigRtrnPrivRec));
+ _XkbFree(tmp);
+ }
+ bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
+ return;
+}
+
+Bool
+XkbCFParse( FILE * file,
+ XkbConfigFieldsPtr fields,
+ XkbDescPtr xkb,
+ XkbConfigRtrnPtr rtrn)
+{
+int tok;
+XkbCFScanResultRec val;
+XkbConfigFieldsPtr tmp;
+
+ if ((file==NULL)||(fields==NULL)||(rtrn==NULL))
+ return False;
+ for (tok=0,tmp=fields;tmp!=NULL;tmp=tmp->next,tok++) {
+ fields->cfg_id= tok;
+ }
+ bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
+ rtrn->line= 1;
+ rtrn->click_volume= -1;
+ rtrn->bell_volume= -1;
+ while ((tok=XkbCFScan(file,&val,rtrn))!=XkbCF_EOF) {
+ if (tok==XkbCF_Ident) {
+ Bool done;
+ for (tmp=fields,done=False;(tmp!=NULL)&&(!done);tmp=tmp->next) {
+ register int i;
+ XkbConfigFieldPtr f;
+
+ for (i=0,f=tmp->fields;(i<tmp->num_fields)&&(!done);i++,f++) {
+ if (_XkbStrCaseCmp(val.str,f->field)!=0)
+ continue;
+ if ((*tmp->parser)(file,tmp,f,xkb,rtrn))
+ done= True;
+ else goto BAILOUT;
+ }
+ }
+ }
+ else if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)) {
+ rtrn->error= XkbCF_MissingIdent;
+ goto BAILOUT;
+ }
+ }
+ for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
+ if ((tmp->finish)&&(!(*tmp->finish)(tmp,xkb,rtrn,XkbCF_Check)))
+ goto BAILOUT;
+ }
+ return True;
+BAILOUT:
+ for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
+ if (tmp->finish)
+ (*tmp->finish)(tmp,xkb,rtrn,XkbCF_CleanUp);
+ }
+ return False;
+}
+
+/*ARGSUSED*/
+void
+XkbCFReportError(FILE *file,char *name,int error,int line)
+{
+char * msg;
+
+ switch(error) {
+ case XkbCF_BadAlloc:
+ msg= "allocation failed\n"; break;
+ case XkbCF_UnterminatedString:
+ msg= "unterminated string on line %d"; break;
+ case XkbCF_MissingIdent:
+ msg= "expected identifier on line %d"; break;
+ case XkbCF_MissingEquals:
+ msg= "expected '=' on line %d"; break;
+ case XkbCF_ExpectedEOS:
+ msg= "expected ';' or newline on line %d"; break;
+ case XkbCF_ExpectedBoolean:
+ msg= "expected a boolean value on line %d"; break;
+ case XkbCF_ExpectedInteger:
+ msg= "expected a numeric value on line %d"; break;
+ case XkbCF_ExpectedString:
+ msg= "expected a string on line %d"; break;
+ case XkbCF_ExpectedModifier:
+ msg= "expected a modifier name on line %d"; break;
+ case XkbCF_ExpectedControl:
+ msg= "expected a control name on line %d"; break;
+ case XkbCF_ExpectedAXOption:
+ msg= "expected an AccessX option on line %d"; break;
+ case XkbCF_ExpectedOperator:
+ msg= "expected '+' or '-' on line %d"; break;
+ case XkbCF_ExpectedOORGroupBehavior:
+ msg= "expected wrap, clamp or group number on line %d"; break;
+ default:
+ msg= "unknown error on line %d"; break;
+ }
+ ErrorF(msg,line);
+ if (name) ErrorF(" of %s\n",name);
+ else ErrorF("\n");
+ return;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkberrs.c b/nx-X11/programs/Xserver/xkb/xkberrs.c
new file mode 100644
index 000000000..b14f36d03
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkberrs.c
@@ -0,0 +1,70 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+char * _XkbErrMessages[] = {
+ "success", /* _XkbSuccess */
+ "key names not defined", /* _XkbErrMissingNames */
+ "key types not defined", /* _XkbErrMissingTypes */
+ "required key types not present", /* _XkbErrMissingReqTypes */
+ "symbols not defined", /* _XkbErrMissingSymbols */
+ "virtual modifier bindings not defined",/* _XkbErrMissingVMods */
+ "indicators not defined", /* _XkbErrMissingIndicators */
+ "compatibility map not defined", /* _XkbErrMissingCompatMap */
+ "symbol interpretations not defined", /* _XkbErrMissingSymInterps */
+ "geometry not defined", /* _XkbErrMissingGeometry */
+ "illegal doodad type", /* _XkbErrIllegalDoodad */
+ "illegal TOC type", /* _XkbErrIllegalTOCType */
+ "illegal contents", /* _XkbErrIllegalContents */
+ "empty file", /* _XkbErrEmptyFile */
+ "file not found", /* _XkbErrFileNotFound */
+ "cannot open", /* _XkbErrFileCannotOpen */
+ "bad value", /* _XkbErrBadValue */
+ "bad match", /* _XkbErrBadMatch */
+ "illegal name for type", /* _XkbErrBadTypeName */
+ "illegal width for type", /* _XkbErrBadTypeWidth */
+ "bad file type", /* _XkbErrBadFileType */
+ "bad file version", /* _XkbErrBadFileVersion */
+ "error in Xkm file", /* _XkbErrBadFileFormat */
+ "allocation failed", /* _XkbErrBadAlloc */
+ "bad length", /* _XkbErrBadLength */
+ "X request failed", /* _XkbErrXReqFailure */
+ "not implemented" /* _XkbErrBadImplementation */
+};
+
+unsigned _XkbErrCode;
+char * _XkbErrLocation= NULL;
+unsigned _XkbErrData;
+
diff --git a/nx-X11/programs/Xserver/xkb/xkbfmisc.c b/nx-X11/programs/Xserver/xkb/xkbfmisc.c
new file mode 100644
index 000000000..6545a2879
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbfmisc.c
@@ -0,0 +1,675 @@
+/************************************************************
+ Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <nx-X11/Xos.h>
+#include <nx-X11/Xfuncs.h>
+
+
+#include <nx-X11/X.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+#include "xkb.h"
+
+
+unsigned
+_XkbKSCheckCase(KeySym ks)
+{
+unsigned set,rtrn;
+
+ set= (ks & (~0xff)) >> 8;
+ rtrn= 0;
+ switch (set) {
+ case 0: /* latin 1 */
+ if (((ks>=XK_A)&&(ks<=XK_Z))||
+ ((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) {
+ rtrn|= _XkbKSUpper;
+ }
+ if (((ks>=XK_a)&&(ks<=XK_z))||
+ ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ case 1: /* latin 2 */
+ if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))||
+ ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) {
+ rtrn|= _XkbKSUpper;
+ }
+ if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))||
+ ((ks>=XK_racute)&&(ks<=XK_tcedilla))) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ case 2: /* latin 3 */
+ if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))||
+ ((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) {
+ rtrn|= _XkbKSUpper;
+ }
+ if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))||
+ ((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ case 3: /* latin 4 */
+ if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))||
+ (ks==XK_ENG)||
+ ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) {
+ rtrn|= _XkbKSUpper;
+ }
+ if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))||
+ (ks==XK_eng)||
+ ((ks>=XK_amacron)&&(ks<=XK_umacron))) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ case 18: /* latin 8 */
+ if ((ks==XK_Babovedot)||
+ ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))||
+ ((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))||
+ (ks==XK_Mabovedot)||
+ (ks==XK_Pabovedot)||
+ (ks==XK_Sabovedot)||
+ (ks==XK_Wdiaeresis)||
+ ((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) {
+ rtrn|= _XkbKSUpper;
+ }
+ if ((ks==XK_babovedot)||
+ (ks==XK_dabovedot)||
+ (ks==XK_fabovedot)||
+ (ks==XK_mabovedot)||
+ ((ks>=XK_wgrave)&&(ks<=XK_wacute))||
+ (ks==XK_ygrave)||
+ ((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ case 19: /* latin 9 */
+ if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) {
+ rtrn|= _XkbKSUpper;
+ }
+ if (ks==XK_oe) {
+ rtrn|= _XkbKSLower;
+ }
+ break;
+ }
+ return rtrn;
+}
+
+/***===================================================================***/
+
+int
+_XkbStrCaseCmp(char *str1,char *str2)
+{
+ char buf1[512],buf2[512];
+ char c, *s;
+ register int n;
+
+ for (n=0, s = buf1; (c = *str1++); n++) {
+ if (isupper(c))
+ c = tolower(c);
+ if (n>510)
+ break;
+ *s++ = c;
+ }
+ *s = '\0';
+ for (n=0, s = buf2; (c = *str2++); n++) {
+ if (isupper(c))
+ c = tolower(c);
+ if (n>510)
+ break;
+ *s++ = c;
+ }
+ *s = '\0';
+ return (strcmp(buf1, buf2));
+}
+
+/***===================================================================***/
+
+Bool
+XkbLookupGroupAndLevel( XkbDescPtr xkb,
+ int key,
+ int * mods_inout,
+ int * grp_inout,
+ int * lvl_rtrn)
+{
+int nG,eG;
+
+ if ((!xkb)||(!XkbKeycodeInRange(xkb,key))||(!grp_inout))
+ return False;
+
+ nG= XkbKeyNumGroups(xkb,key);
+ eG= *grp_inout;
+
+ if ( nG==0 ) {
+ *grp_inout= 0;
+ if (lvl_rtrn!=NULL)
+ *lvl_rtrn= 0;
+ return False;
+ }
+ else if ( nG==1 ) {
+ eG= 0;
+ }
+ else if ( eG>=nG ) {
+ unsigned gI= XkbKeyGroupInfo(xkb,key);
+ switch (XkbOutOfRangeGroupAction(gI)) {
+ default:
+ eG %= nG;
+ break;
+ case XkbClampIntoRange:
+ eG = nG-1;
+ break;
+ case XkbRedirectIntoRange:
+ eG = XkbOutOfRangeGroupNumber(gI);
+ if (eG>=nG)
+ eG= 0;
+ break;
+ }
+ }
+ *grp_inout= eG;
+ if (mods_inout!=NULL) {
+ XkbKeyTypePtr type;
+ int preserve;
+
+ type = XkbKeyKeyType(xkb,key,eG);
+ if (lvl_rtrn!=NULL)
+ *lvl_rtrn= 0;
+ preserve= 0;
+ if (type->map) { /* find the shift level */
+ register int i;
+ register XkbKTMapEntryPtr entry;
+ for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+ if ((entry->active)&&
+ (((*mods_inout)&type->mods.mask)==entry->mods.mask)){
+ if (lvl_rtrn!=NULL)
+ *lvl_rtrn= entry->level;
+ if (type->preserve)
+ preserve= type->preserve[i].mask;
+ break;
+ }
+ }
+ }
+ (*mods_inout)&= ~(type->mods.mask&(~preserve));
+ }
+ return True;
+}
+
+/***===================================================================***/
+
+static Bool
+XkbWriteSectionFromName(FILE *file,char *sectionName,char *name)
+{
+ fprintf(file," xkb_%-20s { include \"%s\" };\n",sectionName,name);
+ return True;
+}
+
+#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
+#define COMPLETE(n) ((n)&&(!NEED_DESC(n)))
+
+/* ARGSUSED */
+static void
+_AddIncl( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ int index,
+ void * priv)
+{
+ if ((priv)&&(strcmp((char *)priv,"%")!=0))
+ fprintf(file," include \"%s\"\n",(char *)priv);
+ return;
+}
+
+Bool
+XkbWriteXKBKeymapForNames( FILE * file,
+ XkbComponentNamesPtr names,
+ Display * dpy,
+ XkbDescPtr xkb,
+ unsigned want,
+ unsigned need)
+{
+char * name;
+const char * tmp;
+unsigned complete;
+XkbNamesPtr old_names;
+int multi_section;
+unsigned wantNames,wantConfig,wantDflts;
+XkbFileInfo finfo;
+
+ bzero(&finfo,sizeof(XkbFileInfo));
+
+ complete= 0;
+ if ((name=names->keymap)==NULL) name= "default";
+ if (COMPLETE(names->keycodes)) complete|= XkmKeyNamesMask;
+ if (COMPLETE(names->types)) complete|= XkmTypesMask;
+ if (COMPLETE(names->compat)) complete|= XkmCompatMapMask;
+ if (COMPLETE(names->symbols)) complete|= XkmSymbolsMask;
+ if (COMPLETE(names->geometry)) complete|= XkmGeometryMask;
+ want|= (complete|need);
+ if (want&XkmSymbolsMask)
+ want|= XkmKeyNamesMask|XkmTypesMask;
+
+ if (want==0)
+ return False;
+
+ if (xkb!=NULL) {
+ old_names= xkb->names;
+ finfo.type= 0;
+ finfo.defined= 0;
+ finfo.xkb= xkb;
+ if (!XkbDetermineFileType(&finfo,XkbXKBFile,NULL))
+ return False;
+ }
+ else old_names= NULL;
+
+ wantConfig= want&(~complete);
+ if (xkb!=NULL) {
+ if (wantConfig&XkmTypesMask) {
+ if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes))
+ wantConfig&= ~XkmTypesMask;
+ }
+ if (wantConfig&XkmCompatMapMask) {
+ if ((!xkb->compat) || (xkb->compat->num_si<1))
+ wantConfig&= ~XkmCompatMapMask;
+ }
+ if (wantConfig&XkmSymbolsMask) {
+ if ((!xkb->map) || (!xkb->map->key_sym_map))
+ wantConfig&= ~XkmSymbolsMask;
+ }
+ if (wantConfig&XkmIndicatorsMask) {
+ if (!xkb->indicators)
+ wantConfig&= ~XkmIndicatorsMask;
+ }
+ if (wantConfig&XkmKeyNamesMask) {
+ if ((!xkb->names)||(!xkb->names->keys))
+ wantConfig&= ~XkmKeyNamesMask;
+ }
+ if ((wantConfig&XkmGeometryMask)&&(!xkb->geom))
+ wantConfig&= ~XkmGeometryMask;
+ }
+ else {
+ wantConfig= 0;
+ }
+ complete|= wantConfig;
+
+ wantDflts= 0;
+ wantNames= want&(~complete);
+ if ((xkb!=NULL) && (old_names!=NULL)) {
+ if (wantNames&XkmTypesMask) {
+ if (old_names->types!=None) {
+ tmp= NameForAtom(old_names->types);
+ names->types= Xstrdup(tmp);
+ }
+ else {
+ wantDflts|= XkmTypesMask;
+ }
+ complete|= XkmTypesMask;
+ }
+ if (wantNames&XkmCompatMapMask) {
+ if (old_names->compat!=None) {
+ tmp= NameForAtom(old_names->compat);
+ names->compat= Xstrdup(tmp);
+ }
+ else wantDflts|= XkmCompatMapMask;
+ complete|= XkmCompatMapMask;
+ }
+ if (wantNames&XkmSymbolsMask) {
+ if (old_names->symbols==None)
+ return False;
+ tmp= NameForAtom(old_names->symbols);
+ names->symbols= Xstrdup(tmp);
+ complete|= XkmSymbolsMask;
+ }
+ if (wantNames&XkmKeyNamesMask) {
+ if (old_names->keycodes!=None) {
+ tmp= NameForAtom(old_names->keycodes);
+ names->keycodes= Xstrdup(tmp);
+ }
+ else wantDflts|= XkmKeyNamesMask;
+ complete|= XkmKeyNamesMask;
+ }
+ if (wantNames&XkmGeometryMask) {
+ if (old_names->geometry==None)
+ return False;
+ tmp= NameForAtom(old_names->geometry);
+ names->geometry= Xstrdup(tmp);
+ complete|= XkmGeometryMask;
+ wantNames&= ~XkmGeometryMask;
+ }
+ }
+ if (complete&XkmCompatMapMask)
+ complete|= XkmIndicatorsMask|XkmVirtualModsMask;
+ else if (complete&(XkmSymbolsMask|XkmTypesMask))
+ complete|= XkmVirtualModsMask;
+ if (need & (~complete))
+ return False;
+ if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete)))
+ return False;
+
+ multi_section= 1;
+ if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&&
+ ((complete&(~XkmKeymapLegal))==0)) {
+ fprintf(file,"xkb_keymap \"%s\" {\n",name);
+ }
+ else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&&
+ ((complete&(~XkmSemanticsLegal))==0)) {
+ fprintf(file,"xkb_semantics \"%s\" {\n",name);
+ }
+ else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&&
+ ((complete&(~XkmLayoutLegal))==0)) {
+ fprintf(file,"xkb_layout \"%s\" {\n",name);
+ }
+ else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) {
+ multi_section= 0;
+ }
+ else {
+ return False;
+ }
+
+ wantNames= complete&(~(wantConfig|wantDflts));
+ name= names->keycodes;
+ if (wantConfig&XkmKeyNamesMask)
+ XkbWriteXKBKeycodes(file,&finfo,False,False,_AddIncl,name);
+ else if (wantDflts&XkmKeyNamesMask)
+ fprintf(stderr,"Default symbols not implemented yet!\n");
+ else if (wantNames&XkmKeyNamesMask)
+ XkbWriteSectionFromName(file,"keycodes",name);
+
+ name= names->types;
+ if (wantConfig&XkmTypesMask)
+ XkbWriteXKBKeyTypes(file,&finfo,False,False,_AddIncl,name);
+ else if (wantDflts&XkmTypesMask)
+ fprintf(stderr,"Default types not implemented yet!\n");
+ else if (wantNames&XkmTypesMask)
+ XkbWriteSectionFromName(file,"types",name);
+
+ name= names->compat;
+ if (wantConfig&XkmCompatMapMask)
+ XkbWriteXKBCompatMap(file,&finfo,False,False,_AddIncl,name);
+ else if (wantDflts&XkmCompatMapMask)
+ fprintf(stderr,"Default interps not implemented yet!\n");
+ else if (wantNames&XkmCompatMapMask)
+ XkbWriteSectionFromName(file,"compatibility",name);
+
+ name= names->symbols;
+ if (wantConfig&XkmSymbolsMask)
+ XkbWriteXKBSymbols(file,&finfo,False,False,_AddIncl,name);
+ else if (wantNames&XkmSymbolsMask)
+ XkbWriteSectionFromName(file,"symbols",name);
+
+ name= names->geometry;
+ if (wantConfig&XkmGeometryMask)
+ XkbWriteXKBGeometry(file,&finfo,False,False,_AddIncl,name);
+ else if (wantNames&XkmGeometryMask)
+ XkbWriteSectionFromName(file,"geometry",name);
+
+ if (multi_section)
+ fprintf(file,"};\n");
+ return True;
+}
+
+/***====================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbMergeFile(XkbDescPtr xkb,XkbFileInfo finfo)
+{
+ return BadImplementation;
+}
+
+/***====================================================================***/
+
+int
+XkbFindKeycodeByName(XkbDescPtr xkb,char *name,Bool use_aliases)
+{
+register int i;
+
+ if ((!xkb)||(!xkb->names)||(!xkb->names->keys))
+ return 0;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (strncmp(xkb->names->keys[i].name,name,XkbKeyNameLength)==0)
+ return i;
+ }
+ if (!use_aliases)
+ return 0;
+ if (xkb->geom && xkb->geom->key_aliases) {
+ XkbKeyAliasPtr a;
+ a= xkb->geom->key_aliases;
+ for (i=0;i<xkb->geom->num_key_aliases;i++,a++) {
+ if (strncmp(name,a->alias,XkbKeyNameLength)==0)
+ return XkbFindKeycodeByName(xkb,a->real,False);
+ }
+ }
+ if (xkb->names && xkb->names->key_aliases) {
+ XkbKeyAliasPtr a;
+ a= xkb->names->key_aliases;
+ for (i=0;i<xkb->names->num_key_aliases;i++,a++) {
+ if (strncmp(name,a->alias,XkbKeyNameLength)==0)
+ return XkbFindKeycodeByName(xkb,a->real,False);
+ }
+ }
+ return 0;
+}
+
+
+unsigned
+XkbConvertGetByNameComponents(Bool toXkm,unsigned orig)
+{
+unsigned rtrn;
+
+ rtrn= 0;
+ if (toXkm) {
+ if (orig&XkbGBN_TypesMask) rtrn|= XkmTypesMask;
+ if (orig&XkbGBN_CompatMapMask) rtrn|= XkmCompatMapMask;
+ if (orig&XkbGBN_SymbolsMask) rtrn|= XkmSymbolsMask;
+ if (orig&XkbGBN_IndicatorMapMask) rtrn|= XkmIndicatorsMask;
+ if (orig&XkbGBN_KeyNamesMask) rtrn|= XkmKeyNamesMask;
+ if (orig&XkbGBN_GeometryMask) rtrn|= XkmGeometryMask;
+ }
+ else {
+ if (orig&XkmTypesMask) rtrn|= XkbGBN_TypesMask;
+ if (orig&XkmCompatMapMask) rtrn|= XkbGBN_CompatMapMask;
+ if (orig&XkmSymbolsMask) rtrn|= XkbGBN_SymbolsMask;
+ if (orig&XkmIndicatorsMask) rtrn|= XkbGBN_IndicatorMapMask;
+ if (orig&XkmKeyNamesMask) rtrn|= XkbGBN_KeyNamesMask;
+ if (orig&XkmGeometryMask) rtrn|= XkbGBN_GeometryMask;
+ if (orig!=0) rtrn|= XkbGBN_OtherNamesMask;
+ }
+ return rtrn;
+}
+
+unsigned
+XkbConvertXkbComponents(Bool toXkm,unsigned orig)
+{
+unsigned rtrn;
+
+ rtrn= 0;
+ if (toXkm) {
+ if (orig&XkbClientMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask;
+ if (orig&XkbServerMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask;
+ if (orig&XkbCompatMapMask) rtrn|= XkmCompatMapMask;
+ if (orig&XkbIndicatorMapMask) rtrn|= XkmIndicatorsMask;
+ if (orig&XkbNamesMask) rtrn|= XkmKeyNamesMask;
+ if (orig&XkbGeometryMask) rtrn|= XkmGeometryMask;
+ }
+ else {
+ if (orig!=0) rtrn|= XkbNamesMask;
+ if (orig&XkmTypesMask) rtrn|= XkbClientMapMask;
+ if (orig&XkmCompatMapMask)
+ rtrn|= XkbCompatMapMask|XkbIndicatorMapMask;
+ if (orig&XkmSymbolsMask) rtrn|=XkbClientMapMask|XkbServerMapMask;
+ if (orig&XkmIndicatorsMask) rtrn|= XkbIndicatorMapMask;
+ if (orig&XkmKeyNamesMask)
+ rtrn|= XkbNamesMask|XkbIndicatorMapMask;
+ if (orig&XkmGeometryMask) rtrn|= XkbGeometryMask;
+ }
+ return rtrn;
+}
+
+Bool
+XkbDetermineFileType(XkbFileInfoPtr finfo,int format,int *opts_missing)
+{
+unsigned present;
+XkbDescPtr xkb;
+
+ if ((!finfo)||(!finfo->xkb))
+ return False;
+ if (opts_missing)
+ *opts_missing= 0;
+ xkb= finfo->xkb;
+ present= 0;
+ if ((xkb->names)&&(xkb->names->keys)) present|= XkmKeyNamesMask;
+ if ((xkb->map)&&(xkb->map->types)) present|= XkmTypesMask;
+ if (xkb->compat) present|= XkmCompatMapMask;
+ if ((xkb->map)&&(xkb->map->num_syms>1)) present|= XkmSymbolsMask;
+ if (xkb->indicators) present|= XkmIndicatorsMask;
+ if (xkb->geom) present|= XkmGeometryMask;
+ if (!present)
+ return False;
+ else switch (present) {
+ case XkmKeyNamesMask:
+ finfo->type= XkmKeyNamesIndex;
+ finfo->defined= present;
+ return True;
+ case XkmTypesMask:
+ finfo->type= XkmTypesIndex;
+ finfo->defined= present;
+ return True;
+ case XkmCompatMapMask:
+ finfo->type= XkmCompatMapIndex;
+ finfo->defined= present;
+ return True;
+ case XkmSymbolsMask:
+ if (format!=XkbXKMFile) {
+ finfo->type= XkmSymbolsIndex;
+ finfo->defined= present;
+ return True;
+ }
+ break;
+ case XkmGeometryMask:
+ finfo->type= XkmGeometryIndex;
+ finfo->defined= present;
+ return True;
+ }
+ if ((present&(~XkmSemanticsLegal))==0) {
+ if ((XkmSemanticsRequired&present)==XkmSemanticsRequired) {
+ if (opts_missing)
+ *opts_missing= XkmSemanticsOptional&(~present);
+ finfo->type= XkmSemanticsFile;
+ finfo->defined= present;
+ return True;
+ }
+ }
+ else if ((present&(~XkmLayoutLegal))==0) {
+ if ((XkmLayoutRequired&present)==XkmLayoutRequired) {
+ if (opts_missing)
+ *opts_missing= XkmLayoutOptional&(~present);
+ finfo->type= XkmLayoutFile;
+ finfo->defined= present;
+ return True;
+ }
+ }
+ else if ((present&(~XkmKeymapLegal))==0) {
+ if ((XkmKeymapRequired&present)==XkmKeymapRequired) {
+ if (opts_missing)
+ *opts_missing= XkmKeymapOptional&(~present);
+ finfo->type= XkmKeymapFile;
+ finfo->defined= present;
+ return True;
+ }
+ }
+ return False;
+}
+
+/* all latin-1 alphanumerics, plus parens, slash, minus, underscore and */
+/* wildcards */
+
+static unsigned char componentSpecLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+void
+XkbEnsureSafeMapName(char *name)
+{
+ if (name==NULL)
+ return;
+ while (*name!='\0') {
+ if ((componentSpecLegal[(*name)/8]&(1<<((*name)%8)))==0)
+ *name= '_';
+ name++;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+#define UNMATCHABLE(c) (((c)=='(')||((c)==')')||((c)=='/'))
+
+Bool
+XkbNameMatchesPattern(char *name,char *ptrn)
+{
+ while (ptrn[0]!='\0') {
+ if (name[0]=='\0') {
+ if (ptrn[0]=='*') {
+ ptrn++;
+ continue;
+ }
+ return False;
+ }
+ if (ptrn[0]=='?') {
+ if (UNMATCHABLE(name[0]))
+ return False;
+ }
+ else if (ptrn[0]=='*') {
+ if ((!UNMATCHABLE(name[0]))&&XkbNameMatchesPattern(name+1,ptrn))
+ return True;
+ return XkbNameMatchesPattern(name,ptrn+1);
+ }
+ else if (ptrn[0]!=name[0])
+ return False;
+ name++;
+ ptrn++;
+ }
+ /* if we get here, the pattern is exhausted (-:just like me:-) */
+ return (name[0]=='\0');
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbgeom.h b/nx-X11/programs/Xserver/xkb/xkbgeom.h
new file mode 100644
index 000000000..863f19be5
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbgeom.h
@@ -0,0 +1,655 @@
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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.
+
+********************************************************/
+
+#ifndef _XKBGEOM_H_
+#define _XKBGEOM_H_
+
+#include "xkbstr.h"
+
+#define XkbAddGeomKeyAlias SrvXkbAddGeomKeyAlias
+#define XkbAddGeomColor SrvXkbAddGeomColor
+#define XkbAddGeomDoodad SrvXkbAddGeomDoodad
+#define XkbAddGeomKey SrvXkbAddGeomKey
+#define XkbAddGeomOutline SrvXkbAddGeomOutline
+#define XkbAddGeomOverlay SrvXkbAddGeomOverlay
+#define XkbAddGeomOverlayRow SrvXkbAddGeomOverlayRow
+#define XkbAddGeomOverlayKey SrvXkbAddGeomOverlayKey
+#define XkbAddGeomProperty SrvXkbAddGeomProperty
+#define XkbAddGeomRow SrvXkbAddGeomRow
+#define XkbAddGeomSection SrvXkbAddGeomSection
+#define XkbAddGeomShape SrvXkbAddGeomShape
+#define XkbAllocGeomKeyAliases SrvXkbAllocGeomKeyAliases
+#define XkbAllocGeomColors SrvXkbAllocGeomColors
+#define XkbAllocGeomDoodads SrvXkbAllocGeomDoodads
+#define XkbAllocGeomKeys SrvXkbAllocGeomKeys
+#define XkbAllocGeomOutlines SrvXkbAllocGeomOutlines
+#define XkbAllocGeomPoints SrvXkbAllocGeomPoints
+#define XkbAllocGeomProps SrvXkbAllocGeomProps
+#define XkbAllocGeomRows SrvXkbAllocGeomRows
+#define XkbAllocGeomSectionDoodads SrvXkbAllocGeomSectionDoodads
+#define XkbAllocGeomSections SrvXkbAllocGeomSections
+#define XkbAllocGeomOverlays SrvXkbAllocGeomOverlays
+#define XkbAllocGeomOverlayRows SrvXkbAllocGeomOverlayRows
+#define XkbAllocGeomOverlayKeys SrvXkbAllocGeomOverlayKeys
+#define XkbAllocGeomShapes SrvXkbAllocGeomShapes
+#define XkbAllocGeometry SrvXkbAllocGeometry
+#define XkbFreeGeomKeyAliases SrvXkbFreeGeomKeyAliases
+#define XkbFreeGeomColors SrvXkbFreeGeomColors
+#define XkbFreeGeomDoodads SrvXkbFreeGeomDoodads
+#define XkbFreeGeomProperties SrvXkbFreeGeomProperties
+#define XkbFreeGeomOverlayKeys SrvXkbFreeGeomOverlayKeys
+#define XkbFreeGeomOverlayRows SrvXkbFreeGeomOverlayRows
+#define XkbFreeGeomOverlays SrvXkbFreeGeomOverlays
+#define XkbFreeGeomKeys SrvXkbFreeGeomKeys
+#define XkbFreeGeomRows SrvXkbFreeGeomRows
+#define XkbFreeGeomSections SrvXkbFreeGeomSections
+#define XkbFreeGeomPoints SrvXkbFreeGeomPoints
+#define XkbFreeGeomOutlines SrvXkbFreeGeomOutlines
+#define XkbFreeGeomShapes SrvXkbFreeGeomShapes
+#define XkbFreeGeometry SrvXkbFreeGeometry
+
+typedef struct _XkbProperty {
+ char *name;
+ char *value;
+} XkbPropertyRec,*XkbPropertyPtr;
+
+typedef struct _XkbColor {
+ unsigned int pixel;
+ char * spec;
+} XkbColorRec,*XkbColorPtr;
+
+typedef struct _XkbPoint {
+ short x;
+ short y;
+} XkbPointRec, *XkbPointPtr;
+
+typedef struct _XkbBounds {
+ short x1,y1;
+ short x2,y2;
+} XkbBoundsRec, *XkbBoundsPtr;
+#define XkbBoundsWidth(b) (((b)->x2)-((b)->x1))
+#define XkbBoundsHeight(b) (((b)->y2)-((b)->y1))
+
+typedef struct _XkbOutline {
+ unsigned short num_points;
+ unsigned short sz_points;
+ unsigned short corner_radius;
+ XkbPointPtr points;
+} XkbOutlineRec, *XkbOutlinePtr;
+
+typedef struct _XkbShape {
+ Atom name;
+ unsigned short num_outlines;
+ unsigned short sz_outlines;
+ XkbOutlinePtr outlines;
+ XkbOutlinePtr approx;
+ XkbOutlinePtr primary;
+ XkbBoundsRec bounds;
+} XkbShapeRec, *XkbShapePtr;
+#define XkbOutlineIndex(s,o) ((int)((o)-&(s)->outlines[0]))
+
+typedef struct _XkbShapeDoodad {
+ Atom name;
+ unsigned char type;
+ unsigned char priority;
+ short top;
+ short left;
+ short angle;
+ unsigned short color_ndx;
+ unsigned short shape_ndx;
+} XkbShapeDoodadRec, *XkbShapeDoodadPtr;
+#define XkbShapeDoodadColor(g,d) (&(g)->colors[(d)->color_ndx])
+#define XkbShapeDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx])
+#define XkbSetShapeDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0])
+#define XkbSetShapeDoodadShape(g,d,s) ((d)->shape_ndx= (s)-&(g)->shapes[0])
+
+typedef struct _XkbTextDoodad {
+ Atom name;
+ unsigned char type;
+ unsigned char priority;
+ short top;
+ short left;
+ short angle;
+ short width;
+ short height;
+ unsigned short color_ndx;
+ char * text;
+ char * font;
+} XkbTextDoodadRec, *XkbTextDoodadPtr;
+#define XkbTextDoodadColor(g,d) (&(g)->colors[(d)->color_ndx])
+#define XkbSetTextDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0])
+
+typedef struct _XkbIndicatorDoodad {
+ Atom name;
+ unsigned char type;
+ unsigned char priority;
+ short top;
+ short left;
+ short angle;
+ unsigned short shape_ndx;
+ unsigned short on_color_ndx;
+ unsigned short off_color_ndx;
+} XkbIndicatorDoodadRec, *XkbIndicatorDoodadPtr;
+#define XkbIndicatorDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx])
+#define XkbIndicatorDoodadOnColor(g,d) (&(g)->colors[(d)->on_color_ndx])
+#define XkbIndicatorDoodadOffColor(g,d) (&(g)->colors[(d)->off_color_ndx])
+#define XkbSetIndicatorDoodadOnColor(g,d,c) \
+ ((d)->on_color_ndx= (c)-&(g)->colors[0])
+#define XkbSetIndicatorDoodadOffColor(g,d,c) \
+ ((d)->off_color_ndx= (c)-&(g)->colors[0])
+#define XkbSetIndicatorDoodadShape(g,d,s) \
+ ((d)->shape_ndx= (s)-&(g)->shapes[0])
+
+typedef struct _XkbLogoDoodad {
+ Atom name;
+ unsigned char type;
+ unsigned char priority;
+ short top;
+ short left;
+ short angle;
+ unsigned short color_ndx;
+ unsigned short shape_ndx;
+ char * logo_name;
+} XkbLogoDoodadRec, *XkbLogoDoodadPtr;
+#define XkbLogoDoodadColor(g,d) (&(g)->colors[(d)->color_ndx])
+#define XkbLogoDoodadShape(g,d) (&(g)->shapes[(d)->shape_ndx])
+#define XkbSetLogoDoodadColor(g,d,c) ((d)->color_ndx= (c)-&(g)->colors[0])
+#define XkbSetLogoDoodadShape(g,d,s) ((d)->shape_ndx= (s)-&(g)->shapes[0])
+
+typedef struct _XkbAnyDoodad {
+ Atom name;
+ unsigned char type;
+ unsigned char priority;
+ short top;
+ short left;
+ short angle;
+} XkbAnyDoodadRec, *XkbAnyDoodadPtr;
+
+typedef union _XkbDoodad {
+ XkbAnyDoodadRec any;
+ XkbShapeDoodadRec shape;
+ XkbTextDoodadRec text;
+ XkbIndicatorDoodadRec indicator;
+ XkbLogoDoodadRec logo;
+} XkbDoodadRec, *XkbDoodadPtr;
+
+#define XkbUnknownDoodad 0
+#define XkbOutlineDoodad 1
+#define XkbSolidDoodad 2
+#define XkbTextDoodad 3
+#define XkbIndicatorDoodad 4
+#define XkbLogoDoodad 5
+
+typedef struct _XkbKey {
+ XkbKeyNameRec name;
+ short gap;
+ unsigned char shape_ndx;
+ unsigned char color_ndx;
+} XkbKeyRec, *XkbKeyPtr;
+#define XkbKeyShape(g,k) (&(g)->shapes[(k)->shape_ndx])
+#define XkbKeyColor(g,k) (&(g)->colors[(k)->color_ndx])
+#define XkbSetKeyShape(g,k,s) ((k)->shape_ndx= (s)-&(g)->shapes[0])
+#define XkbSetKeyColor(g,k,c) ((k)->color_ndx= (c)-&(g)->colors[0])
+
+typedef struct _XkbRow {
+ short top;
+ short left;
+ unsigned short num_keys;
+ unsigned short sz_keys;
+ int vertical;
+ XkbKeyPtr keys;
+ XkbBoundsRec bounds;
+} XkbRowRec, *XkbRowPtr;
+
+typedef struct _XkbSection {
+ Atom name;
+ unsigned char priority;
+ short top;
+ short left;
+ unsigned short width;
+ unsigned short height;
+ short angle;
+ unsigned short num_rows;
+ unsigned short num_doodads;
+ unsigned short num_overlays;
+ unsigned short sz_rows;
+ unsigned short sz_doodads;
+ unsigned short sz_overlays;
+ XkbRowPtr rows;
+ XkbDoodadPtr doodads;
+ XkbBoundsRec bounds;
+ struct _XkbOverlay *overlays;
+} XkbSectionRec, *XkbSectionPtr;
+
+typedef struct _XkbOverlayKey {
+ XkbKeyNameRec over;
+ XkbKeyNameRec under;
+} XkbOverlayKeyRec,*XkbOverlayKeyPtr;
+
+typedef struct _XkbOverlayRow {
+ unsigned short row_under;
+ unsigned short num_keys;
+ unsigned short sz_keys;
+ XkbOverlayKeyPtr keys;
+} XkbOverlayRowRec,*XkbOverlayRowPtr;
+
+typedef struct _XkbOverlay {
+ Atom name;
+ XkbSectionPtr section_under;
+ unsigned short num_rows;
+ unsigned short sz_rows;
+ XkbOverlayRowPtr rows;
+ XkbBoundsPtr bounds;
+} XkbOverlayRec,*XkbOverlayPtr;
+
+typedef struct _XkbGeometry {
+ Atom name;
+ unsigned short width_mm;
+ unsigned short height_mm;
+ char * label_font;
+ XkbColorPtr label_color;
+ XkbColorPtr base_color;
+ unsigned short sz_properties;
+ unsigned short sz_colors;
+ unsigned short sz_shapes;
+ unsigned short sz_sections;
+ unsigned short sz_doodads;
+ unsigned short sz_key_aliases;
+ unsigned short num_properties;
+ unsigned short num_colors;
+ unsigned short num_shapes;
+ unsigned short num_sections;
+ unsigned short num_doodads;
+ unsigned short num_key_aliases;
+ XkbPropertyPtr properties;
+ XkbColorPtr colors;
+ XkbShapePtr shapes;
+ XkbSectionPtr sections;
+ XkbDoodadPtr doodads;
+ XkbKeyAliasPtr key_aliases;
+} XkbGeometryRec;
+#define XkbGeomColorIndex(g,c) ((int)((c)-&(g)->colors[0]))
+
+#define XkbGeomPropertiesMask (1<<0)
+#define XkbGeomColorsMask (1<<1)
+#define XkbGeomShapesMask (1<<2)
+#define XkbGeomSectionsMask (1<<3)
+#define XkbGeomDoodadsMask (1<<4)
+#define XkbGeomKeyAliasesMask (1<<5)
+#define XkbGeomAllMask (0x3f)
+
+typedef struct _XkbGeometrySizes {
+ unsigned int which;
+ unsigned short num_properties;
+ unsigned short num_colors;
+ unsigned short num_shapes;
+ unsigned short num_sections;
+ unsigned short num_doodads;
+ unsigned short num_key_aliases;
+} XkbGeometrySizesRec,*XkbGeometrySizesPtr;
+
+_XFUNCPROTOBEGIN
+
+extern XkbPropertyPtr
+XkbAddGeomProperty(
+ XkbGeometryPtr /* geom */,
+ char * /* name */,
+ char * /* value */
+);
+
+extern XkbKeyAliasPtr
+XkbAddGeomKeyAlias(
+ XkbGeometryPtr /* geom */,
+ char * /* alias */,
+ char * /* real */
+);
+
+extern XkbColorPtr
+XkbAddGeomColor(
+ XkbGeometryPtr /* geom */,
+ char * /* spec */,
+ unsigned int /* pixel */
+);
+
+extern XkbOutlinePtr
+XkbAddGeomOutline(
+ XkbShapePtr /* shape */,
+ int /* sz_points */
+);
+
+extern XkbShapePtr
+XkbAddGeomShape(
+ XkbGeometryPtr /* geom */,
+ Atom /* name */,
+ int /* sz_outlines */
+);
+
+extern XkbKeyPtr
+XkbAddGeomKey(
+ XkbRowPtr /* row */
+);
+
+extern XkbRowPtr
+XkbAddGeomRow(
+ XkbSectionPtr /* section */,
+ int /* sz_keys */
+);
+
+extern XkbSectionPtr
+XkbAddGeomSection(
+ XkbGeometryPtr /* geom */,
+ Atom /* name */,
+ int /* sz_rows */,
+ int /* sz_doodads */,
+ int /* sz_overlays */
+);
+
+extern XkbOverlayPtr
+XkbAddGeomOverlay(
+ XkbSectionPtr /* section */,
+ Atom /* name */,
+ int /* sz_rows */
+);
+
+extern XkbOverlayRowPtr
+XkbAddGeomOverlayRow(
+ XkbOverlayPtr /* overlay */,
+ int /* row_under */,
+ int /* sz_keys */
+);
+
+extern XkbOverlayKeyPtr
+XkbAddGeomOverlayKey(
+ XkbOverlayPtr /* overlay */,
+ XkbOverlayRowPtr /* row */,
+ char * /* over */,
+ char * /* under */
+);
+
+extern XkbDoodadPtr
+XkbAddGeomDoodad(
+ XkbGeometryPtr /* geom */,
+ XkbSectionPtr /* section */,
+ Atom /* name */
+);
+
+
+extern void
+XkbFreeGeomKeyAliases(
+ XkbGeometryPtr /* geom */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomColors(
+ XkbGeometryPtr /* geom */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomDoodads(
+ XkbDoodadPtr /* doodads */,
+ int /* nDoodads */,
+ Bool /* freeAll */
+);
+
+
+extern void
+XkbFreeGeomProperties(
+ XkbGeometryPtr /* geom */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomOverlayKeys(
+ XkbOverlayRowPtr /* row */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomOverlayRows(
+ XkbOverlayPtr /* overlay */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomOverlays(
+ XkbSectionPtr /* section */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomKeys(
+ XkbRowPtr /* row */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomRows(
+ XkbSectionPtr /* section */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomSections(
+ XkbGeometryPtr /* geom */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+
+extern void
+XkbFreeGeomPoints(
+ XkbOutlinePtr /* outline */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomOutlines(
+ XkbShapePtr /* shape */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeomShapes(
+ XkbGeometryPtr /* geom */,
+ int /* first */,
+ int /* count */,
+ Bool /* freeAll */
+);
+
+extern void
+XkbFreeGeometry(
+ XkbGeometryPtr /* geom */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern Status
+XkbAllocGeomProps(
+ XkbGeometryPtr /* geom */,
+ int /* nProps */
+);
+
+extern Status
+XkbAllocGeomKeyAliases(
+ XkbGeometryPtr /* geom */,
+ int /* nAliases */
+);
+
+extern Status
+XkbAllocGeomColors(
+ XkbGeometryPtr /* geom */,
+ int /* nColors */
+);
+
+extern Status
+XkbAllocGeomShapes(
+ XkbGeometryPtr /* geom */,
+ int /* nShapes */
+);
+
+extern Status
+XkbAllocGeomSections(
+ XkbGeometryPtr /* geom */,
+ int /* nSections */
+);
+
+extern Status
+XkbAllocGeomOverlays(
+ XkbSectionPtr /* section */,
+ int /* num_needed */
+);
+
+extern Status
+XkbAllocGeomOverlayRows(
+ XkbOverlayPtr /* overlay */,
+ int /* num_needed */
+);
+
+extern Status
+XkbAllocGeomOverlayKeys(
+ XkbOverlayRowPtr /* row */,
+ int /* num_needed */
+);
+
+extern Status
+XkbAllocGeomDoodads(
+ XkbGeometryPtr /* geom */,
+ int /* nDoodads */
+);
+
+extern Status
+XkbAllocGeomSectionDoodads(
+ XkbSectionPtr /* section */,
+ int /* nDoodads */
+);
+
+extern Status
+XkbAllocGeomOutlines(
+ XkbShapePtr /* shape */,
+ int /* nOL */
+);
+
+extern Status
+XkbAllocGeomRows(
+ XkbSectionPtr /* section */,
+ int /* nRows */
+);
+
+extern Status
+XkbAllocGeomPoints(
+ XkbOutlinePtr /* ol */,
+ int /* nPts */
+);
+
+extern Status
+XkbAllocGeomKeys(
+ XkbRowPtr /* row */,
+ int /* nKeys */
+);
+
+extern Status
+XkbAllocGeometry(
+ XkbDescPtr /* xkb */,
+ XkbGeometrySizesPtr /* sizes */
+);
+
+extern Status
+XkbSetGeometry(
+ Display * /* dpy */,
+ unsigned /* deviceSpec */,
+ XkbGeometryPtr /* geom */
+);
+
+extern Bool
+XkbComputeShapeTop(
+ XkbShapePtr /* shape */,
+ XkbBoundsPtr /* bounds */
+);
+
+extern Bool
+XkbComputeShapeBounds(
+ XkbShapePtr /* shape */
+);
+
+extern Bool
+XkbComputeRowBounds(
+ XkbGeometryPtr /* geom */,
+ XkbSectionPtr /* section */,
+ XkbRowPtr /* row */
+);
+
+extern Bool
+XkbComputeSectionBounds(
+ XkbGeometryPtr /* geom */,
+ XkbSectionPtr /* section */
+);
+
+extern char *
+XkbFindOverlayForKey(
+ XkbGeometryPtr /* geom */,
+ XkbSectionPtr /* wanted */,
+ char * /* under */
+);
+
+extern Status
+XkbGetGeometry(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */
+);
+
+extern Status
+XkbGetNamedGeometry(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ Atom /* name */
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XKBSTR_H_ */
diff --git a/nx-X11/programs/Xserver/xkb/xkbout.c b/nx-X11/programs/Xserver/xkb/xkbout.c
new file mode 100644
index 000000000..b76617963
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbout.c
@@ -0,0 +1,1051 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <nx-X11/Xfuncs.h>
+
+
+#include <nx-X11/X.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+
+#include "xkbgeom.h"
+#include "xkbfile.h"
+
+
+#define VMOD_HIDE_VALUE 0
+#define VMOD_SHOW_VALUE 1
+#define VMOD_COMMENT_VALUE 2
+
+static Bool
+WriteXKBVModDecl(FILE *file,Display *dpy,XkbDescPtr xkb,int showValue)
+{
+register int i,nMods;
+Atom * vmodNames;
+
+ if (xkb==NULL)
+ return False;
+ if (xkb->names!=NULL)
+ vmodNames= xkb->names->vmods;
+ else vmodNames= NULL;
+
+ for (i=nMods=0;i<XkbNumVirtualMods;i++) {
+ if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) {
+ if (nMods==0) fprintf(file," virtual_modifiers ");
+ else fprintf(file,",");
+ fprintf(file,"%s",XkbAtomText(dpy,vmodNames[i],XkbXKBFile));
+ if ((showValue!=VMOD_HIDE_VALUE)&&
+ (xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) {
+ if (showValue==VMOD_COMMENT_VALUE) {
+ fprintf(file,"/* = %s */",
+ XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
+ }
+ else {
+ fprintf(file,"= %s",
+ XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
+ }
+ }
+ nMods++;
+ }
+ }
+ if (nMods>0)
+ fprintf(file,";\n\n");
+ return True;
+}
+
+/***====================================================================***/
+
+static Bool
+WriteXKBAction(FILE *file,XkbFileInfo *result,XkbAnyAction *action)
+{
+XkbDescPtr xkb;
+Display * dpy;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)action,XkbXKBFile));
+ return True;
+}
+
+/***====================================================================***/
+
+Bool
+XkbWriteXKBKeycodes( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Atom kcName;
+register unsigned i;
+XkbDescPtr xkb;
+Display * dpy;
+char * alternate;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
+ _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0);
+ return False;
+ }
+ kcName= xkb->names->keycodes;
+ if (kcName!=None)
+ fprintf(file,"xkb_keycodes \"%s\" {\n",
+ XkbAtomText(dpy,kcName,XkbXKBFile));
+ else fprintf(file,"xkb_keycodes {\n");
+ fprintf(file," minimum = %d;\n",xkb->min_key_code);
+ fprintf(file," maximum = %d;\n",xkb->max_key_code);
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (xkb->names->keys[i].name[0]!='\0') {
+ if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
+ alternate= "alternate ";
+ else alternate= "";
+ fprintf(file," %s%6s = %d;\n",alternate,
+ XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile),
+ i);
+ }
+ }
+ if (xkb->indicators!=NULL) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ char *type;
+ if (xkb->indicators->phys_indicators&(1<<i))
+ type= " ";
+ else type= " virtual ";
+ if (xkb->names->indicators[i]!=None) {
+ fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1,
+ XkbAtomText(dpy,xkb->names->indicators[i],XkbXKBFile));
+ }
+ }
+ }
+ if (xkb->names->key_aliases!=NULL) {
+ XkbKeyAliasPtr pAl;
+ pAl= xkb->names->key_aliases;
+ for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) {
+ fprintf(file," alias %6s = %6s;\n",
+ XkbKeyNameText(pAl->alias,XkbXKBFile),
+ XkbKeyNameText(pAl->real,XkbXKBFile));
+ }
+ }
+ if (addOn)
+ (*addOn)(file,result,topLevel,showImplicit,XkmKeyNamesIndex,priv);
+ fprintf(file,"};\n\n");
+ return True;
+}
+
+Bool
+XkbWriteXKBKeyTypes( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Display * dpy;
+register unsigned i,n;
+XkbKeyTypePtr type;
+XkbKTMapEntryPtr entry;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ _XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0);
+ return False;
+ }
+ if (xkb->map->num_types<XkbNumRequiredTypes) {
+ _XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0);
+ return 0;
+ }
+ if ((xkb->names==NULL)||(xkb->names->types==None))
+ fprintf(file,"xkb_types {\n\n");
+ else fprintf(file,"xkb_types \"%s\" {\n\n",
+ XkbAtomText(dpy,xkb->names->types,XkbXKBFile));
+ WriteXKBVModDecl(file,dpy,xkb,
+ (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
+
+ type= xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ fprintf(file," type \"%s\" {\n",
+ XkbAtomText(dpy,type->name,XkbXKBFile));
+ fprintf(file," modifiers= %s;\n",
+ XkbVModMaskText(dpy,xkb,type->mods.real_mods,type->mods.vmods,
+ XkbXKBFile));
+ entry= type->map;
+ for (n=0;n<type->map_count;n++,entry++) {
+ char *str;
+ str=XkbVModMaskText(dpy,xkb,entry->mods.real_mods,entry->mods.vmods,
+ XkbXKBFile);
+ fprintf(file," map[%s]= Level%d;\n",str,entry->level+1);
+ if ((type->preserve)&&((type->preserve[n].real_mods)||
+ (type->preserve[n].vmods))) {
+ fprintf(file," preserve[%s]= ",str);
+ fprintf(file,"%s;\n",XkbVModMaskText(dpy,xkb,
+ type->preserve[n].real_mods,
+ type->preserve[n].vmods,
+ XkbXKBFile));
+ }
+ }
+ if (type->level_names!=NULL) {
+ Atom *name= type->level_names;
+ for (n=0;n<type->num_levels;n++,name++) {
+ if ((*name)==None)
+ continue;
+ fprintf(file," level_name[Level%d]= \"%s\";\n",n+1,
+ XkbAtomText(dpy,*name,XkbXKBFile));
+ }
+ }
+ fprintf(file," };\n");
+ }
+ if (addOn)
+ (*addOn)(file,result,topLevel,showImplicit,XkmTypesIndex,priv);
+ fprintf(file,"};\n\n");
+ return True;
+}
+
+static Bool
+WriteXKBIndicatorMap( FILE * file,
+ XkbFileInfo * result,
+ Atom name,
+ XkbIndicatorMapPtr led,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ fprintf(file," indicator \"%s\" {\n",NameForAtom(name));
+ if (led->flags&XkbIM_NoExplicit)
+ fprintf(file," !allowExplicit;\n");
+ if (led->flags&XkbIM_LEDDrivesKB)
+ fprintf(file," indicatorDrivesKeyboard;\n");
+ if (led->which_groups!=0) {
+ if (led->which_groups!=XkbIM_UseEffective) {
+ fprintf(file," whichGroupState= %s;\n",
+ XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile));
+ }
+ fprintf(file," groups= 0x%02x;\n",led->groups);
+ }
+ if (led->which_mods!=0) {
+ if (led->which_mods!=XkbIM_UseEffective) {
+ fprintf(file," whichModState= %s;\n",
+ XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile));
+ }
+ fprintf(file," modifiers= %s;\n",
+ XkbVModMaskText(xkb->dpy,xkb,
+ led->mods.real_mods,led->mods.vmods,
+ XkbXKBFile));
+ }
+ if (led->ctrls!=0) {
+ fprintf(file," controls= %s;\n",
+ XkbControlsMaskText(led->ctrls,XkbXKBFile));
+ }
+ if (addOn)
+ (*addOn)(file,result,False,True,XkmIndicatorsIndex,priv);
+ fprintf(file," };\n");
+ return True;
+}
+
+Bool
+XkbWriteXKBCompatMap( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Display * dpy;
+register unsigned i;
+XkbSymInterpretPtr interp;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
+ _XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0);
+ return False;
+ }
+ if ((xkb->names==NULL)||(xkb->names->compat==None))
+ fprintf(file,"xkb_compatibility {\n\n");
+ else fprintf(file,"xkb_compatibility \"%s\" {\n\n",
+ XkbAtomText(dpy,xkb->names->compat,XkbXKBFile));
+ WriteXKBVModDecl(file,dpy,xkb,
+ (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
+
+ fprintf(file," interpret.useModMapMods= AnyLevel;\n");
+ fprintf(file," interpret.repeat= False;\n");
+ fprintf(file," interpret.locking= False;\n");
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ fprintf(file," interpret %s+%s(%s) {\n",
+ ((interp->sym==NoSymbol)?"Any":
+ XkbKeysymText(interp->sym,XkbXKBFile)),
+ XkbSIMatchText(interp->match,XkbXKBFile),
+ XkbModMaskText(interp->mods,XkbXKBFile));
+ if (interp->virtual_mod!=XkbNoModifier) {
+ fprintf(file," virtualModifier= %s;\n",
+ XkbVModIndexText(dpy,xkb,interp->virtual_mod,XkbXKBFile));
+ }
+ if (interp->match&XkbSI_LevelOneOnly)
+ fprintf(file," useModMapMods=level1;\n");
+ if (interp->flags&XkbSI_LockingKey)
+ fprintf(file," locking= True;\n");
+ if (interp->flags&XkbSI_AutoRepeat)
+ fprintf(file," repeat= True;\n");
+ fprintf(file," action= ");
+ WriteXKBAction(file,result,&interp->act);
+ fprintf(file,";\n");
+ fprintf(file," };\n");
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ XkbModsPtr gc;
+
+ gc= &xkb->compat->groups[i];
+ if ((gc->real_mods==0)&&(gc->vmods==0))
+ continue;
+ fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb->dpy,xkb,
+ gc->real_mods,gc->vmods,
+ XkbXKBFile));
+ }
+ if (xkb->indicators) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
+ if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)||
+ (map->which_mods!=0)||
+ (map->mods.real_mods!=0)||(map->mods.vmods!=0)||
+ (map->ctrls!=0)) {
+ WriteXKBIndicatorMap(file,result,xkb->names->indicators[i],map,
+ addOn,priv);
+ }
+ }
+ }
+ if (addOn)
+ (*addOn)(file,result,topLevel,showImplicit,XkmCompatMapIndex,priv);
+ fprintf(file,"};\n\n");
+ return True;
+}
+
+Bool
+XkbWriteXKBSymbols( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Display * dpy;
+register unsigned i,tmp;
+XkbDescPtr xkb;
+XkbClientMapPtr map;
+XkbServerMapPtr srv;
+Bool showActions;
+
+ xkb= result->xkb;
+ map= xkb->map;
+ srv= xkb->server;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!map)||(!map->syms)||(!map->key_sym_map)) {
+ _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0);
+ return False;
+ }
+ if ((!xkb->names)||(!xkb->names->keys)) {
+ _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0);
+ return False;
+ }
+ if ((xkb->names==NULL)||(xkb->names->symbols==None))
+ fprintf(file,"xkb_symbols {\n\n");
+ else fprintf(file,"xkb_symbols \"%s\" {\n\n",
+ XkbAtomText(dpy,xkb->names->symbols,XkbXKBFile));
+ for (tmp=i=0;i<XkbNumKbdGroups;i++) {
+ if (xkb->names->groups[i]!=None) {
+ fprintf(file," name[group%d]=\"%s\";\n",i+1,
+ XkbAtomText(dpy,xkb->names->groups[i],XkbXKBFile));
+ tmp++;
+ }
+ }
+ if (tmp>0)
+ fprintf(file,"\n");
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ Bool simple;
+ if ((int)XkbKeyNumSyms(xkb,i)<1)
+ continue;
+ if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
+ continue;
+ simple= True;
+ fprintf(file," key %6s {",
+ XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile));
+ if (srv->explicit) {
+ if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)||
+ (showImplicit)) {
+ int typeNdx,g;
+ Bool multi;
+ char * comment=" ";
+
+ if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0)
+ comment= "//";
+ multi= False;
+ typeNdx= XkbKeyKeyTypeIndex(xkb,i,0);
+ for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) {
+ if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx)
+ multi= True;
+ }
+ if (multi) {
+ for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
+ typeNdx= XkbKeyKeyTypeIndex(xkb,i,g);
+ if (srv->explicit[i]&(1<<g)) {
+ fprintf(file,"\n%s type[group%d]= \"%s\",",
+ comment,g+1,
+ XkbAtomText(dpy,map->types[typeNdx].name,
+ XkbXKBFile));
+ }
+ else if (showImplicit) {
+ fprintf(file,"\n// type[group%d]= \"%s\",",g+1,
+ XkbAtomText(dpy,map->types[typeNdx].name,
+ XkbXKBFile));
+ }
+ }
+ }
+ else {
+ fprintf(file,"\n%s type= \"%s\",",comment,
+ XkbAtomText(dpy,map->types[typeNdx].name,
+ XkbXKBFile));
+ }
+ simple= False;
+ }
+ if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&&
+ (xkb->ctrls!=NULL)) {
+ if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8)))
+ fprintf(file,"\n repeat= Yes,");
+ else fprintf(file,"\n repeat= No,");
+ simple= False;
+ }
+ if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&&
+ (xkb->server->vmodmap[i]!=0)) {
+ if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) {
+ fprintf(file,"\n virtualMods= %s,",
+ XkbVModMaskText(dpy,xkb,0,
+ xkb->server->vmodmap[i],
+ XkbXKBFile));
+ }
+ else if (showImplicit) {
+ fprintf(file,"\n// virtualMods= %s,",
+ XkbVModMaskText(dpy,xkb,0,
+ xkb->server->vmodmap[i],
+ XkbXKBFile));
+ }
+ }
+ }
+ switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) {
+ case XkbClampIntoRange:
+ fprintf(file,"\n groupsClamp,");
+ break;
+ case XkbRedirectIntoRange:
+ fprintf(file,"\n groupsRedirect= Group%d,",
+ XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1);
+ break;
+ }
+ if (srv->behaviors!=NULL) {
+ unsigned type;
+ type= srv->behaviors[i].type&XkbKB_OpMask;
+
+ if (type!=XkbKB_Default) {
+ simple= False;
+ fprintf(file,"\n %s,",
+ XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile));
+ }
+ }
+ if ((srv->explicit==NULL) || showImplicit ||
+ ((srv->explicit[i]&XkbExplicitInterpretMask)!=0))
+ showActions= XkbKeyHasActions(xkb,i);
+ else showActions= False;
+
+ if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions)
+ simple= False;
+ if (simple) {
+ KeySym *syms;
+ unsigned s;
+
+ syms= XkbKeySymsPtr(xkb,i);
+ fprintf(file," [ ");
+ for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) {
+ if (s!=0)
+ fprintf(file,", ");
+ fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile));
+ }
+ fprintf(file," ] };\n");
+ }
+ else {
+ unsigned g,s;
+ KeySym *syms;
+ XkbAction *acts;
+ syms= XkbKeySymsPtr(xkb,i);
+ acts= XkbKeyActionsPtr(xkb,i);
+ for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
+ if (g!=0)
+ fprintf(file,",");
+ fprintf(file,"\n symbols[Group%d]= [ ",g+1);
+ for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
+ if (s!=0)
+ fprintf(file,", ");
+ fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile));
+ }
+ fprintf(file," ]");
+ syms+= XkbKeyGroupsWidth(xkb,i);
+ if (showActions) {
+ fprintf(file,",\n actions[Group%d]= [ ",g+1);
+ for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
+ if (s!=0)
+ fprintf(file,", ");
+ WriteXKBAction(file,result,(XkbAnyAction *)&acts[s]);
+ }
+ fprintf(file," ]");
+ acts+= XkbKeyGroupsWidth(xkb,i);
+ }
+ }
+ fprintf(file,"\n };\n");
+ }
+ }
+ if (map && map->modmap) {
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (map->modmap[i]!=0) {
+ register int n,bit;
+ for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) {
+ if (map->modmap[i]&bit) {
+ char buf[5];
+ memcpy(buf,xkb->names->keys[i].name,4);
+ buf[4]= '\0';
+ fprintf(file," modifier_map %s { <%s> };\n",
+ XkbModIndexText(n,XkbXKBFile),buf);
+ }
+ }
+ }
+ }
+ }
+ if (addOn)
+ (*addOn)(file,result,topLevel,showImplicit,XkmSymbolsIndex,priv);
+ fprintf(file,"};\n\n");
+ return True;
+}
+
+static Bool
+WriteXKBOutline( FILE * file,
+ XkbShapePtr shape,
+ XkbOutlinePtr outline,
+ int lastRadius,
+ int first,
+ int indent)
+{
+register int i;
+XkbPointPtr pt;
+char * iStr;
+
+ fprintf(file,"%s",iStr= XkbIndentText(first));
+ if (first!=indent)
+ iStr= XkbIndentText(indent);
+ if (outline->corner_radius!=lastRadius) {
+ fprintf(file,"corner= %s,",
+ XkbGeomFPText(outline->corner_radius,XkbMessage));
+ if (shape!=NULL) {
+ fprintf(file,"\n%s",iStr);
+ }
+ }
+ if (shape) {
+ if (outline==shape->approx)
+ fprintf(file,"approx= ");
+ else if (outline==shape->primary)
+ fprintf(file,"primary= ");
+ }
+ fprintf(file,"{");
+ for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) {
+ if (i==0) fprintf(file," ");
+ else if ((i%4)==0) fprintf(file,",\n%s ",iStr);
+ else fprintf(file,", ");
+ fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile),
+ XkbGeomFPText(pt->y,XkbXKBFile));
+ }
+ fprintf(file," }");
+ return True;
+}
+
+static Bool
+WriteXKBDoodad( FILE * file,
+ Display * dpy,
+ unsigned indent,
+ XkbGeometryPtr geom,
+ XkbDoodadPtr doodad)
+{
+register char * i_str;
+XkbShapePtr shape;
+XkbColorPtr color;
+
+ i_str= XkbIndentText(indent);
+ fprintf(file,"%s%s \"%s\" {\n",i_str,
+ XkbDoodadTypeText(doodad->any.type,XkbMessage),
+ XkbAtomText(dpy,doodad->any.name,XkbMessage));
+ fprintf(file,"%s top= %s;\n",i_str,
+ XkbGeomFPText(doodad->any.top,XkbXKBFile));
+ fprintf(file,"%s left= %s;\n",i_str,
+ XkbGeomFPText(doodad->any.left,XkbXKBFile));
+ fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority);
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ if (doodad->shape.angle!=0) {
+ fprintf(file,"%s angle= %s;\n",i_str,
+ XkbGeomFPText(doodad->shape.angle,XkbXKBFile));
+ }
+ if (doodad->shape.color_ndx!=0) {
+ fprintf(file,"%s color= \"%s\";\n",i_str,
+ XkbShapeDoodadColor(geom,&doodad->shape)->spec);
+ }
+ shape= XkbShapeDoodadShape(geom,&doodad->shape);
+ fprintf(file,"%s shape= \"%s\";\n",i_str,
+ XkbAtomText(dpy,shape->name,XkbXKBFile));
+ break;
+ case XkbTextDoodad:
+ if (doodad->text.angle!=0) {
+ fprintf(file,"%s angle= %s;\n",i_str,
+ XkbGeomFPText(doodad->text.angle,XkbXKBFile));
+ }
+ if (doodad->text.width!=0) {
+ fprintf(file,"%s width= %s;\n",i_str,
+ XkbGeomFPText(doodad->text.width,XkbXKBFile));
+
+ }
+ if (doodad->text.height!=0) {
+ fprintf(file,"%s height= %s;\n",i_str,
+ XkbGeomFPText(doodad->text.height,XkbXKBFile));
+
+ }
+ if (doodad->text.color_ndx!=0) {
+ color= XkbTextDoodadColor(geom,&doodad->text);
+ fprintf(file,"%s color= \"%s\";\n",i_str,
+ XkbStringText(color->spec,XkbXKBFile));
+ }
+ fprintf(file,"%s XFont= \"%s\";\n",i_str,
+ XkbStringText(doodad->text.font,XkbXKBFile));
+ fprintf(file,"%s text= \"%s\";\n",i_str,
+ XkbStringText(doodad->text.text,XkbXKBFile));
+ break;
+ case XkbIndicatorDoodad:
+ shape= XkbIndicatorDoodadShape(geom,&doodad->indicator);
+ color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator);
+ fprintf(file,"%s onColor= \"%s\";\n",i_str,
+ XkbStringText(color->spec,XkbXKBFile));
+ color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator);
+ fprintf(file,"%s offColor= \"%s\";\n",i_str,
+ XkbStringText(color->spec,XkbXKBFile));
+ fprintf(file,"%s shape= \"%s\";\n",i_str,
+ XkbAtomText(dpy,shape->name,XkbXKBFile));
+ break;
+ case XkbLogoDoodad:
+ fprintf(file,"%s logoName= \"%s\";\n",i_str,
+ XkbStringText(doodad->logo.logo_name,XkbXKBFile));
+ if (doodad->shape.angle!=0) {
+ fprintf(file,"%s angle= %s;\n",i_str,
+ XkbGeomFPText(doodad->logo.angle,XkbXKBFile));
+ }
+ if (doodad->shape.color_ndx!=0) {
+ fprintf(file,"%s color= \"%s\";\n",i_str,
+ XkbLogoDoodadColor(geom,&doodad->logo)->spec);
+ }
+ shape= XkbLogoDoodadShape(geom,&doodad->logo);
+ fprintf(file,"%s shape= \"%s\";\n",i_str,
+ XkbAtomText(dpy,shape->name,XkbXKBFile));
+ break;
+ }
+ fprintf(file,"%s};\n",i_str);
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+WriteXKBOverlay( FILE * file,
+ Display * dpy,
+ unsigned indent,
+ XkbGeometryPtr geom,
+ XkbOverlayPtr ol)
+{
+register char * i_str;
+int r,k,nOut;
+XkbOverlayRowPtr row;
+XkbOverlayKeyPtr key;
+
+ i_str= XkbIndentText(indent);
+ if (ol->name!=None) {
+ fprintf(file,"%soverlay \"%s\" {\n",i_str,
+ XkbAtomText(dpy,ol->name,XkbMessage));
+ }
+ else fprintf(file,"%soverlay {\n",i_str);
+ for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ char *over,*under;
+ over= XkbKeyNameText(key->over.name,XkbXKBFile);
+ under= XkbKeyNameText(key->under.name,XkbXKBFile);
+ if (nOut==0)
+ fprintf(file,"%s %6s=%6s",i_str,under,over);
+ else if ((nOut%4)==0)
+ fprintf(file,",\n%s %6s=%6s",i_str,under,over);
+ else fprintf(file,", %6s=%6s",under,over);
+ nOut++;
+ }
+ }
+ fprintf(file,"\n%s};\n",i_str);
+ return True;
+}
+
+static Bool
+WriteXKBSection( FILE * file,
+ Display * dpy,
+ XkbSectionPtr s,
+ XkbGeometryPtr geom)
+{
+register int i;
+XkbRowPtr row;
+int dfltKeyColor = 0;
+
+ fprintf(file," section \"%s\" {\n",
+ XkbAtomText(dpy,s->name,XkbXKBFile));
+ if (s->rows&&(s->rows->num_keys>0)) {
+ dfltKeyColor= s->rows->keys[0].color_ndx;
+ fprintf(file," key.color= \"%s\";\n",
+ XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile));
+ }
+ fprintf(file," priority= %d;\n",s->priority);
+ fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile));
+ fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile));
+ fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile));
+ fprintf(file," height= %s;\n",
+ XkbGeomFPText(s->height,XkbXKBFile));
+ if (s->angle!=0) {
+ fprintf(file," angle= %s;\n",
+ XkbGeomFPText(s->angle,XkbXKBFile));
+ }
+ for (i=0,row=s->rows;i<s->num_rows;i++,row++) {
+ fprintf(file," row {\n");
+ fprintf(file," top= %s;\n",
+ XkbGeomFPText(row->top,XkbXKBFile));
+ fprintf(file," left= %s;\n",
+ XkbGeomFPText(row->left,XkbXKBFile));
+ if (row->vertical)
+ fprintf(file," vertical;\n");
+ if (row->num_keys>0) {
+ register int k;
+ register XkbKeyPtr key;
+ int forceNL=0;
+ int nThisLine= 0;
+ fprintf(file," keys {\n");
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ XkbShapePtr shape;
+ if (key->color_ndx!=dfltKeyColor)
+ forceNL= 1;
+ if (k==0) {
+ fprintf(file," ");
+ nThisLine= 0;
+ }
+ else if (((nThisLine%2)==1)||(forceNL)) {
+ fprintf(file,",\n ");
+ forceNL= nThisLine= 0;
+ }
+ else {
+ fprintf(file,", ");
+ nThisLine++;
+ }
+ shape= XkbKeyShape(geom,key);
+ fprintf(file,"{ %6s, \"%s\", %3s",
+ XkbKeyNameText(key->name.name,XkbXKBFile),
+ XkbAtomText(dpy,shape->name,XkbXKBFile),
+ XkbGeomFPText(key->gap,XkbXKBFile));
+ if (key->color_ndx!=dfltKeyColor) {
+ fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec);
+ forceNL= 1;
+ }
+ fprintf(file," }");
+ }
+ fprintf(file,"\n };\n");
+ }
+ fprintf(file," };\n");
+ }
+ if (s->doodads!=NULL) {
+ XkbDoodadPtr doodad;
+ for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) {
+ WriteXKBDoodad(file,dpy,8,geom,doodad);
+ }
+ }
+ if (s->overlays!=NULL) {
+ XkbOverlayPtr ol;
+ for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) {
+ WriteXKBOverlay(file,dpy,8,geom,ol);
+ }
+ }
+ fprintf(file," }; // End of \"%s\" section\n\n",
+ XkbAtomText(dpy,s->name,XkbXKBFile));
+ return True;
+}
+
+Bool
+XkbWriteXKBGeometry( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Display * dpy;
+register unsigned i,n;
+XkbDescPtr xkb;
+XkbGeometryPtr geom;
+
+ xkb= result->xkb;
+ if ((!xkb)||(!xkb->geom)) {
+ _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0);
+ return False;
+ }
+ dpy= xkb->dpy;
+ geom= xkb->geom;
+ if (geom->name==None)
+ fprintf(file,"xkb_geometry {\n\n");
+ else fprintf(file,"xkb_geometry \"%s\" {\n\n",
+ XkbAtomText(dpy,geom->name,XkbXKBFile));
+ fprintf(file," width= %s;\n",
+ XkbGeomFPText(geom->width_mm,XkbXKBFile));
+ fprintf(file," height= %s;\n\n",
+ XkbGeomFPText(geom->height_mm,XkbXKBFile));
+
+ if (geom->key_aliases!=NULL) {
+ XkbKeyAliasPtr pAl;
+ pAl= geom->key_aliases;
+ for (i=0;i<geom->num_key_aliases;i++,pAl++) {
+ fprintf(file," alias %6s = %6s;\n",
+ XkbKeyNameText(pAl->alias,XkbXKBFile),
+ XkbKeyNameText(pAl->real,XkbXKBFile));
+ }
+ fprintf(file,"\n");
+ }
+
+ if (geom->base_color!=NULL)
+ fprintf(file," baseColor= \"%s\";\n",
+ XkbStringText(geom->base_color->spec,XkbXKBFile));
+ if (geom->label_color!=NULL)
+ fprintf(file," labelColor= \"%s\";\n",
+ XkbStringText(geom->label_color->spec,XkbXKBFile));
+ if (geom->label_font!=NULL)
+ fprintf(file," xfont= \"%s\";\n",
+ XkbStringText(geom->label_font,XkbXKBFile));
+ if ((geom->num_colors>0)&&(showImplicit)) {
+ XkbColorPtr color;
+ for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) {
+ fprintf(file,"// color[%d]= \"%s\"\n",i,
+ XkbStringText(color->spec,XkbXKBFile));
+ }
+ fprintf(file,"\n");
+ }
+ if (geom->num_properties>0) {
+ XkbPropertyPtr prop;
+ for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) {
+ fprintf(file," %s= \"%s\";\n",prop->name,
+ XkbStringText(prop->value,XkbXKBFile));
+ }
+ fprintf(file,"\n");
+ }
+ if (geom->num_shapes>0) {
+ XkbShapePtr shape;
+ XkbOutlinePtr outline;
+ int lastR;
+ for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+ lastR=0;
+ fprintf(file," shape \"%s\" {",
+ XkbAtomText(dpy,shape->name,XkbXKBFile));
+ outline= shape->outlines;
+ if (shape->num_outlines>1) {
+ for (n=0;n<shape->num_outlines;n++,outline++) {
+ if (n==0) fprintf(file,"\n");
+ else fprintf(file,",\n");
+ WriteXKBOutline(file,shape,outline,lastR,8,8);
+ lastR= outline->corner_radius;
+ }
+ fprintf(file,"\n };\n");
+ }
+ else {
+ WriteXKBOutline(file,NULL,outline,lastR,1,8);
+ fprintf(file," };\n");
+ }
+ }
+ }
+ if (geom->num_sections>0) {
+ XkbSectionPtr section;
+ for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){
+ WriteXKBSection(file,dpy,section,geom);
+ }
+ }
+ if (geom->num_doodads>0) {
+ XkbDoodadPtr doodad;
+ for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
+ WriteXKBDoodad(file,dpy,4,geom,doodad);
+ }
+ }
+ if (addOn)
+ (*addOn)(file,result,topLevel,showImplicit,XkmGeometryIndex,priv);
+ fprintf(file,"};\n\n");
+ return True;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBSemantics( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Bool ok;
+
+ fprintf(file,"xkb_semantics {\n");
+ ok= XkbWriteXKBKeyTypes(file,result,False,False,addOn,priv);
+ ok= ok&&XkbWriteXKBCompatMap(file,result,False,False,addOn,priv);
+ fprintf(file,"};\n");
+ return ok;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBLayout( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Bool ok;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ fprintf(file,"xkb_layout {\n");
+ ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv);
+ ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv);
+ ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv);
+ if (xkb->geom)
+ ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv);
+ fprintf(file,"};\n");
+ return ok;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBKeymap( FILE * file,
+ XkbFileInfo * result,
+ Bool topLevel,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Bool ok;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ fprintf(file,"xkb_keymap {\n");
+ ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv);
+ ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv);
+ ok= ok&&XkbWriteXKBCompatMap(file,result,False,showImplicit,addOn,priv);
+ ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv);
+ if (xkb->geom)
+ ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv);
+ fprintf(file,"};\n");
+ return ok;
+}
+
+Bool
+XkbWriteXKBFile( FILE * out,
+ XkbFileInfo * result,
+ Bool showImplicit,
+ XkbFileAddOnFunc addOn,
+ void * priv)
+{
+Bool ok = False;
+Bool (*func)(
+ FILE * /* file */,
+ XkbFileInfo * /* result */,
+ Bool /* topLevel */,
+ Bool /* showImplicit */,
+ XkbFileAddOnFunc /* addOn */,
+ void * /* priv */
+) = NULL;
+
+ switch (result->type) {
+ case XkmSemanticsFile:
+ func= XkbWriteXKBSemantics;
+ break;
+ case XkmLayoutFile:
+ func= XkbWriteXKBLayout;
+ break;
+ case XkmKeymapFile:
+ func= XkbWriteXKBKeymap;
+ break;
+ case XkmTypesIndex:
+ func= XkbWriteXKBKeyTypes;
+ break;
+ case XkmCompatMapIndex:
+ func= XkbWriteXKBCompatMap;
+ break;
+ case XkmSymbolsIndex:
+ func= XkbWriteXKBSymbols;
+ break;
+ case XkmKeyNamesIndex:
+ func= XkbWriteXKBKeycodes;
+ break;
+ case XkmGeometryFile:
+ case XkmGeometryIndex:
+ func= XkbWriteXKBGeometry;
+ break;
+ case XkmVirtualModsIndex:
+ case XkmIndicatorsIndex:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(result->type,XkbMessage),0);
+ return False;
+ }
+ if (out==NULL) {
+ _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXkbFile",0);
+ ok= False;
+ }
+ else if (func) {
+ ok= (*func)(out,result,True,showImplicit,addOn,priv);
+ }
+ return ok;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbtext.c b/nx-X11/programs/Xserver/xkb/xkbtext.c
new file mode 100644
index 000000000..7c22d25c8
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbtext.c
@@ -0,0 +1,1326 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <nx-X11/Xos.h>
+
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+
+/***====================================================================***/
+
+#define BUFFER_SIZE 512
+
+static char textBuffer[BUFFER_SIZE];
+static int tbNext= 0;
+
+static char *
+tbGetBuffer(unsigned size)
+{
+char *rtrn;
+
+ if (size>=BUFFER_SIZE)
+ return NULL;
+ if ((BUFFER_SIZE-tbNext)<=size)
+ tbNext= 0;
+ rtrn= &textBuffer[tbNext];
+ tbNext+= size;
+ return rtrn;
+}
+
+/***====================================================================***/
+
+char *
+XkbAtomText(Display *dpy,Atom atm,unsigned format)
+{
+char *rtrn,*tmp;
+
+ tmp= (char *)NameForAtom(atm);
+ if (tmp!=NULL) {
+ int len;
+ len= strlen(tmp)+1;
+ if (len>BUFFER_SIZE)
+ len= BUFFER_SIZE-2;
+ rtrn= tbGetBuffer(len);
+ strncpy(rtrn,tmp,len);
+ rtrn[len]= '\0';
+ }
+ else {
+ rtrn= tbGetBuffer(1);
+ rtrn[0]= '\0';
+ }
+ if (format==XkbCFile) {
+ for (tmp=rtrn;*tmp!='\0';tmp++) {
+ if ((tmp==rtrn)&&(!isalpha(*tmp)))
+ *tmp= '_';
+ else if (!isalnum(*tmp))
+ *tmp= '_';
+ }
+ }
+ return XkbStringText(rtrn,format);
+}
+
+/***====================================================================***/
+
+char *
+XkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format)
+{
+register int len;
+register Atom *vmodNames;
+char *rtrn,*tmp;
+char numBuf[20];
+
+ if (xkb && xkb->names)
+ vmodNames= xkb->names->vmods;
+ else vmodNames= NULL;
+
+ tmp= NULL;
+ if (ndx>=XkbNumVirtualMods)
+ tmp= "illegal";
+ else if (vmodNames&&(vmodNames[ndx]!=None))
+ tmp= (char *)NameForAtom(vmodNames[ndx]);
+ if (tmp==NULL)
+ sprintf(tmp=numBuf,"%d",ndx);
+
+ len= strlen(tmp)+1;
+ if (format==XkbCFile)
+ len+= 4;
+ if (len>=BUFFER_SIZE)
+ len= BUFFER_SIZE-1;
+ rtrn= tbGetBuffer(len);
+ if (format==XkbCFile) {
+ strcpy(rtrn,"vmod_");
+ strncpy(&rtrn[5],tmp,len-4);
+ }
+ else strncpy(rtrn,tmp,len);
+ return rtrn;
+}
+
+char *
+XkbVModMaskText( Display * dpy,
+ XkbDescPtr xkb,
+ unsigned modMask,
+ unsigned mask,
+ unsigned format)
+{
+register int i,bit;
+int len;
+char *mm,*rtrn;
+char *str,buf[BUFFER_SIZE];
+
+ if ((modMask==0)&&(mask==0)) {
+ rtrn= tbGetBuffer(5);
+ if (format==XkbCFile)
+ sprintf(rtrn,"0");
+ else sprintf(rtrn,"none");
+ return rtrn;
+ }
+ if (modMask!=0)
+ mm= XkbModMaskText(modMask,format);
+ else mm= NULL;
+
+ str= buf;
+ buf[0]= '\0';
+ if (mask) {
+ char *tmp;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (mask&bit) {
+ tmp= XkbVModIndexText(dpy,xkb,i,format);
+ len= strlen(tmp)+1+(str==buf?0:1);
+ if (format==XkbCFile)
+ len+= 4;
+ if ((str-(buf+len))<=BUFFER_SIZE) {
+ if (str!=buf) {
+ if (format==XkbCFile) *str++= '|';
+ else *str++= '+';
+ len--;
+ }
+ }
+ if (format==XkbCFile)
+ sprintf(str,"%sMask",tmp);
+ else strcpy(str,tmp);
+ str= &str[len-1];
+ }
+ }
+ str= buf;
+ }
+ else str= NULL;
+ if (mm)
+ len= strlen(mm);
+ else len= 0;
+ if (str)
+ len+= strlen(str)+(mm==NULL?0:1);
+ if (len>=BUFFER_SIZE)
+ len= BUFFER_SIZE-1;
+ rtrn= tbGetBuffer(len+1);
+ rtrn[0]= '\0';
+
+ if (mm!=NULL) {
+ i= strlen(mm);
+ if (i>len)
+ i= len;
+ strcpy(rtrn,mm);
+ }
+ else {
+ i=0;
+ }
+ if (str!=NULL) {
+ if (mm!=NULL) {
+ if (format==XkbCFile) strcat(rtrn,"|");
+ else strcat(rtrn,"+");
+ }
+ strncat(rtrn,str,len-i);
+ }
+ rtrn[len]= '\0';
+ return rtrn;
+}
+
+static char *modNames[XkbNumModifiers] = {
+ "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
+};
+
+char *
+XkbModIndexText(unsigned ndx,unsigned format)
+{
+char * rtrn;
+char buf[100];
+
+ if (format==XkbCFile) {
+ if (ndx<XkbNumModifiers)
+ sprintf(buf,"%sMapIndex",modNames[ndx]);
+ else if (ndx==XkbNoModifier)
+ sprintf(buf,"XkbNoModifier");
+ else sprintf(buf,"0x%02x",ndx);
+ }
+ else {
+ if (ndx<XkbNumModifiers)
+ strcpy(buf,modNames[ndx]);
+ else if (ndx==XkbNoModifier)
+ strcpy(buf,"none");
+ else sprintf(buf,"ILLEGAL_%02x",ndx);
+ }
+ rtrn= tbGetBuffer(strlen(buf)+1);
+ strcpy(rtrn,buf);
+ return rtrn;
+}
+
+char *
+XkbModMaskText(unsigned mask,unsigned format)
+{
+register int i,bit;
+char buf[64],*rtrn;
+
+ if ((mask&0xff)==0xff) {
+ if (format==XkbCFile) strcpy(buf,"0xff");
+ else strcpy(buf,"all");
+ }
+ else if ((mask&0xff)==0) {
+ if (format==XkbCFile) strcpy(buf,"0");
+ else strcpy(buf,"none");
+ }
+ else {
+ char *str= buf;
+ buf[0]= '\0';
+ for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+ if (mask&bit) {
+ if (str!=buf) {
+ if (format==XkbCFile) *str++= '|';
+ else *str++= '+';
+ }
+ strcpy(str,modNames[i]);
+ str= &str[strlen(str)];
+ if (format==XkbCFile) {
+ strcpy(str,"Mask");
+ str+= 4;
+ }
+ }
+ }
+ }
+ rtrn= tbGetBuffer(strlen(buf)+1);
+ strcpy(rtrn,buf);
+ return rtrn;
+}
+
+/***====================================================================***/
+
+/*ARGSUSED*/
+char *
+XkbConfigText(unsigned config,unsigned format)
+{
+static char *buf;
+
+ buf= tbGetBuffer(32);
+ switch (config) {
+ case XkmSemanticsFile:
+ strcpy(buf,"Semantics");
+ break;
+ case XkmLayoutFile:
+ strcpy(buf,"Layout");
+ break;
+ case XkmKeymapFile:
+ strcpy(buf,"Keymap");
+ break;
+ case XkmGeometryFile:
+ case XkmGeometryIndex:
+ strcpy(buf,"Geometry");
+ break;
+ case XkmTypesIndex:
+ strcpy(buf,"Types");
+ break;
+ case XkmCompatMapIndex:
+ strcpy(buf,"CompatMap");
+ break;
+ case XkmSymbolsIndex:
+ strcpy(buf,"Symbols");
+ break;
+ case XkmIndicatorsIndex:
+ strcpy(buf,"Indicators");
+ break;
+ case XkmKeyNamesIndex:
+ strcpy(buf,"KeyNames");
+ break;
+ case XkmVirtualModsIndex:
+ strcpy(buf,"VirtualMods");
+ break;
+ default:
+ sprintf(buf,"unknown(%d)",config);
+ break;
+ }
+ return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbKeysymText(KeySym sym,unsigned format)
+{
+static char buf[32],*rtrn;
+
+ if (sym==NoSymbol)
+ strcpy(rtrn=buf,"NoSymbol");
+ else sprintf(rtrn=buf, "0x%lx", (long)sym);
+ return rtrn;
+}
+
+char *
+XkbKeyNameText(char *name,unsigned format)
+{
+char *buf;
+
+ if (format==XkbCFile) {
+ buf= tbGetBuffer(5);
+ memcpy(buf,name,4);
+ buf[4]= '\0';
+ }
+ else {
+ int len;
+ buf= tbGetBuffer(7);
+ buf[0]= '<';
+ memcpy(&buf[1],name,4);
+ buf[5]= '\0';
+ len= strlen(buf);
+ buf[len++]= '>';
+ buf[len]= '\0';
+ }
+ return buf;
+}
+
+/***====================================================================***/
+
+static char *siMatchText[5] = {
+ "NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
+};
+
+char *
+XkbSIMatchText(unsigned type,unsigned format)
+{
+static char buf[40];
+char *rtrn;
+
+ switch (type&XkbSI_OpMask) {
+ case XkbSI_NoneOf: rtrn= siMatchText[0]; break;
+ case XkbSI_AnyOfOrNone: rtrn= siMatchText[1]; break;
+ case XkbSI_AnyOf: rtrn= siMatchText[2]; break;
+ case XkbSI_AllOf: rtrn= siMatchText[3]; break;
+ case XkbSI_Exactly: rtrn= siMatchText[4]; break;
+ default: sprintf(buf,"0x%x",type&XkbSI_OpMask);
+ return buf;
+ }
+ if (format==XkbCFile) {
+ if (type&XkbSI_LevelOneOnly)
+ sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
+ else sprintf(buf,"XkbSI_%s",rtrn);
+ rtrn= buf;
+ }
+ return rtrn;
+}
+
+/***====================================================================***/
+
+static char *imWhichNames[]= {
+ "base",
+ "latched",
+ "locked",
+ "effective",
+ "compat"
+};
+
+char *
+XkbIMWhichStateMaskText(unsigned use_which,unsigned format)
+{
+int len;
+unsigned i,bit,tmp;
+char * buf;
+
+ if (use_which==0) {
+ buf= tbGetBuffer(2);
+ strcpy(buf,"0");
+ return buf;
+ }
+ tmp= use_which&XkbIM_UseAnyMods;
+ for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+ if (tmp&bit) {
+ tmp&= ~bit;
+ len+= strlen(imWhichNames[i])+1;
+ if (format==XkbCFile)
+ len+= 9;
+ }
+ }
+ buf= tbGetBuffer(len+1);
+ tmp= use_which&XkbIM_UseAnyMods;
+ for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+ if (tmp&bit) {
+ tmp&= ~bit;
+ if (format==XkbCFile) {
+ if (len!=0)
+ buf[len++]= '|';
+ sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
+ buf[len+9]= toupper(buf[len+9]);
+ }
+ else {
+ if (len!=0)
+ buf[len++]= '+';
+ sprintf(&buf[len],"%s",imWhichNames[i]);
+ }
+ len+= strlen(&buf[len]);
+ }
+ }
+ return buf;
+}
+
+char *
+XkbAccessXDetailText(unsigned state,unsigned format)
+{
+char *buf,*prefix;
+
+ buf= tbGetBuffer(32);
+ if (format==XkbMessage) prefix= "";
+ else prefix= "XkbAXN_";
+ switch (state){
+ case XkbAXN_SKPress: sprintf(buf,"%sSKPress",prefix); break;
+ case XkbAXN_SKAccept: sprintf(buf,"%sSKAccept",prefix); break;
+ case XkbAXN_SKRelease: sprintf(buf,"%sSKRelease",prefix); break;
+ case XkbAXN_SKReject: sprintf(buf,"%sSKReject",prefix); break;
+ case XkbAXN_BKAccept: sprintf(buf,"%sBKAccept",prefix); break;
+ case XkbAXN_BKReject: sprintf(buf,"%sBKReject",prefix); break;
+ case XkbAXN_AXKWarning: sprintf(buf,"%sAXKWarning",prefix); break;
+ default: sprintf(buf,"ILLEGAL"); break;
+ }
+ return buf;
+}
+
+static char *nknNames[] = {
+ "keycodes", "geometry", "deviceID"
+};
+#define NUM_NKN (sizeof(nknNames)/sizeof(char *))
+
+char *
+XkbNKNDetailMaskText(unsigned detail,unsigned format)
+{
+char *buf,*prefix,*suffix;
+register int i;
+register unsigned bit;
+int len,plen,slen;
+
+
+ if ((detail&XkbAllNewKeyboardEventsMask)==0) {
+ char *tmp = "";
+ if (format==XkbCFile) tmp= "0";
+ else if (format==XkbMessage) tmp= "none";
+ buf= tbGetBuffer(strlen(tmp)+1);
+ strcpy(buf,tmp);
+ return buf;
+ }
+ else if ((detail&XkbAllNewKeyboardEventsMask)==XkbAllNewKeyboardEventsMask){
+ char * tmp;
+ if (format==XkbCFile) tmp= "XkbAllNewKeyboardEventsMask";
+ else tmp= "all";
+ buf= tbGetBuffer(strlen(tmp)+1);
+ strcpy(buf,tmp);
+ return buf;
+ }
+ if (format==XkbMessage) {
+ prefix= "";
+ suffix= "";
+ slen= plen= 0;
+ }
+ else {
+ prefix= "XkbNKN_";
+ plen= 7;
+ if (format==XkbCFile)
+ suffix= "Mask";
+ else suffix= "";
+ slen= strlen(suffix);
+ }
+ for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
+ if (detail&bit) {
+ if (len!=0) len+= 1; /* room for '+' or '|' */
+ len+= plen+slen+strlen(nknNames[i]);
+ }
+ }
+ buf= tbGetBuffer(len+1);
+ buf[0]= '\0';
+ for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
+ if (detail&bit) {
+ if (len!=0) {
+ if (format==XkbCFile) buf[len++]= '|';
+ else buf[len++]= '+';
+ }
+ if (plen) {
+ strcpy(&buf[len],prefix);
+ len+= plen;
+ }
+ strcpy(&buf[len],nknNames[i]);
+ len+= strlen(nknNames[i]);
+ if (slen) {
+ strcpy(&buf[len],suffix);
+ len+= slen;
+ }
+ }
+ }
+ buf[len++]= '\0';
+ return buf;
+}
+
+static char *ctrlNames[] = {
+ "repeatKeys",
+ "slowKeys",
+ "bounceKeys",
+ "stickyKeys",
+ "mouseKeys",
+ "mouseKeysAccel",
+ "accessXKeys",
+ "accessXTimeout",
+ "accessXFeedback",
+ "audibleBell",
+ "overlay1",
+ "overlay2",
+ "ignoreGroupLock"
+};
+
+char *
+XkbControlsMaskText(unsigned ctrls,unsigned format)
+{
+int len;
+unsigned i,bit,tmp;
+char * buf;
+
+ if (ctrls==0) {
+ buf= tbGetBuffer(5);
+ if (format==XkbCFile)
+ strcpy(buf,"0");
+ else strcpy(buf,"none");
+ return buf;
+ }
+ tmp= ctrls&XkbAllBooleanCtrlsMask;
+ for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+ if (tmp&bit) {
+ tmp&= ~bit;
+ len+= strlen(ctrlNames[i])+1;
+ if (format==XkbCFile)
+ len+= 7;
+ }
+ }
+ buf= tbGetBuffer(len+1);
+ tmp= ctrls&XkbAllBooleanCtrlsMask;
+ for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+ if (tmp&bit) {
+ tmp&= ~bit;
+ if (format==XkbCFile) {
+ if (len!=0)
+ buf[len++]= '|';
+ sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
+ buf[len+3]= toupper(buf[len+3]);
+ }
+ else {
+ if (len!=0)
+ buf[len++]= '+';
+ sprintf(&buf[len],"%s",ctrlNames[i]);
+ }
+ len+= strlen(&buf[len]);
+ }
+ }
+ return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbStringText(char *str,unsigned format)
+{
+char * buf;
+register char *in,*out;
+int len;
+Bool ok;
+
+ if (str==NULL) {
+ buf= tbGetBuffer(2);
+ buf[0]='\0';
+ return buf;
+ }
+ else if (format==XkbXKMFile)
+ return str;
+ for (ok= True,len=0,in=str;*in!='\0';in++,len++) {
+ if (!isprint(*in)) {
+ ok= False;
+ switch (*in) {
+ case '\n': case '\t': case '\v':
+ case '\b': case '\r': case '\f':
+ len++;
+ break;
+ default:
+ len+= 4;
+ break;
+ }
+ }
+ }
+ if (ok)
+ return str;
+ buf= tbGetBuffer(len+1);
+ for (in=str,out=buf;*in!='\0';in++) {
+ if (isprint(*in))
+ *out++= *in;
+ else {
+ *out++= '\\';
+ if (*in=='\n') *out++= 'n';
+ else if (*in=='\t') *out++= 't';
+ else if (*in=='\v') *out++= 'v';
+ else if (*in=='\b') *out++= 'b';
+ else if (*in=='\r') *out++= 'r';
+ else if (*in=='\f') *out++= 'f';
+ else if ((*in=='\033')&&(format==XkbXKMFile)) {
+ *out++= 'e';
+ }
+ else {
+ *out++= '0';
+ sprintf(out,"%o",*in);
+ while (*out!='\0')
+ out++;
+ }
+ }
+ }
+ *out++= '\0';
+ return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbGeomFPText(int val,unsigned format)
+{
+int whole,frac;
+char * buf;
+
+ buf= tbGetBuffer(12);
+ if (format==XkbCFile) {
+ sprintf(buf,"%d",val);
+ }
+ else {
+ whole= val/XkbGeomPtsPerMM;
+ frac= val%XkbGeomPtsPerMM;
+ if (frac!=0)
+ sprintf(buf,"%d.%d",whole,frac);
+ else sprintf(buf,"%d",whole);
+ }
+ return buf;
+}
+
+char *
+XkbDoodadTypeText(unsigned type,unsigned format)
+{
+char * buf;
+ if (format==XkbCFile) {
+ buf= tbGetBuffer(24);
+ if (type==XkbOutlineDoodad) strcpy(buf,"XkbOutlineDoodad");
+ else if (type==XkbSolidDoodad) strcpy(buf,"XkbSolidDoodad");
+ else if (type==XkbTextDoodad) strcpy(buf,"XkbTextDoodad");
+ else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
+ else if (type==XkbLogoDoodad) strcpy(buf,"XkbLogoDoodad");
+ else sprintf(buf,"UnknownDoodad%d",type);
+ }
+ else {
+ buf= tbGetBuffer(12);
+ if (type==XkbOutlineDoodad) strcpy(buf,"outline");
+ else if (type==XkbSolidDoodad) strcpy(buf,"solid");
+ else if (type==XkbTextDoodad) strcpy(buf,"text");
+ else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
+ else if (type==XkbLogoDoodad) strcpy(buf,"logo");
+ else sprintf(buf,"unknown%d",type);
+ }
+ return buf;
+}
+
+static char *actionTypeNames[XkbSA_NumActions]= {
+ "NoAction",
+ "SetMods", "LatchMods", "LockMods",
+ "SetGroup", "LatchGroup", "LockGroup",
+ "MovePtr",
+ "PtrBtn", "LockPtrBtn",
+ "SetPtrDflt",
+ "ISOLock",
+ "Terminate", "SwitchScreen",
+ "SetControls", "LockControls",
+ "ActionMessage",
+ "RedirectKey",
+ "DeviceBtn", "LockDeviceBtn"
+};
+
+char *
+XkbActionTypeText(unsigned type,unsigned format)
+{
+static char buf[32];
+char *rtrn;
+
+ if (type<=XkbSA_LastAction) {
+ rtrn= actionTypeNames[type];
+ if (format==XkbCFile) {
+ sprintf(buf,"XkbSA_%s",rtrn);
+ return buf;
+ }
+ return rtrn;
+ }
+ sprintf(buf,"Private");
+ return buf;
+}
+
+/***====================================================================***/
+
+static int
+TryCopyStr(char *to,char *from,int *pLeft)
+{
+register int len;
+ if (*pLeft>0) {
+ len= strlen(from);
+ if (len<((*pLeft)-3)) {
+ strcat(to,from);
+ *pLeft-= len;
+ return True;
+ }
+ }
+ *pLeft= -1;
+ return False;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
+{
+ return True;
+}
+
+static Bool
+CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int* sz)
+{
+XkbModAction * act;
+unsigned tmp;
+
+ act= &action->mods;
+ tmp= XkbModActionVMods(act);
+ TryCopyStr(buf,"modifiers=",sz);
+ if (act->flags&XkbSA_UseModMapMods)
+ TryCopyStr(buf,"modMapMods",sz);
+ else if (act->real_mods || tmp) {
+ TryCopyStr(buf,
+ XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile),
+ sz);
+ }
+ else TryCopyStr(buf,"none",sz);
+ if (act->type==XkbSA_LockMods)
+ return True;
+ if (act->flags&XkbSA_ClearLocks)
+ TryCopyStr(buf,",clearLocks",sz);
+ if (act->flags&XkbSA_LatchToLock)
+ TryCopyStr(buf,",latchToLock",sz);
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbGroupAction * act;
+char tbuf[32];
+
+ act= &action->group;
+ TryCopyStr(buf,"group=",sz);
+ if (act->flags&XkbSA_GroupAbsolute)
+ sprintf(tbuf,"%d",XkbSAGroup(act)+1);
+ else if (XkbSAGroup(act)<0)
+ sprintf(tbuf,"%d",XkbSAGroup(act));
+ else sprintf(tbuf,"+%d",XkbSAGroup(act));
+ TryCopyStr(buf,tbuf,sz);
+ if (act->type==XkbSA_LockGroup)
+ return True;
+ if (act->flags&XkbSA_ClearLocks)
+ TryCopyStr(buf,",clearLocks",sz);
+ if (act->flags&XkbSA_LatchToLock)
+ TryCopyStr(buf,",latchToLock",sz);
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbPtrAction * act;
+int x,y;
+char tbuf[32];
+
+ act= &action->ptr;
+ x= XkbPtrActionX(act);
+ y= XkbPtrActionY(act);
+ if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
+ sprintf(tbuf,"x=%d",x);
+ else sprintf(tbuf,"x=+%d",x);
+ TryCopyStr(buf,tbuf,sz);
+
+ if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
+ sprintf(tbuf,",y=%d",y);
+ else sprintf(tbuf,",y=+%d",y);
+ TryCopyStr(buf,tbuf,sz);
+ if (act->flags&XkbSA_NoAcceleration)
+ TryCopyStr(buf,",!accel",sz);
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbPtrBtnAction * act;
+char tbuf[32];
+
+ act= &action->btn;
+ TryCopyStr(buf,"button=",sz);
+ if ((act->button>0)&&(act->button<6)) {
+ sprintf(tbuf,"%d",act->button);
+ TryCopyStr(buf,tbuf,sz);
+ }
+ else TryCopyStr(buf,"default",sz);
+ if (act->count>0) {
+ sprintf(tbuf,",count=%d",act->count);
+ TryCopyStr(buf,tbuf,sz);
+ }
+ if (action->type==XkbSA_LockPtrBtn) {
+ switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
+ case XkbSA_LockNoLock:
+ sprintf(tbuf,",affect=unlock"); break;
+ case XkbSA_LockNoUnlock:
+ sprintf(tbuf,",affect=lock"); break;
+ case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
+ sprintf(tbuf,",affect=neither"); break;
+ default:
+ sprintf(tbuf,",affect=both"); break;
+ }
+ TryCopyStr(buf,tbuf,sz);
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbPtrDfltAction * act;
+char tbuf[32];
+
+ act= &action->dflt;
+ if (act->affect==XkbSA_AffectDfltBtn) {
+ TryCopyStr(buf,"affect=button,button=",sz);
+ if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
+ sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
+ else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
+ TryCopyStr(buf,tbuf,sz);
+ }
+ return True;
+}
+
+static Bool
+CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbISOAction * act;
+char tbuf[64];
+
+ act= &action->iso;
+ if (act->flags&XkbSA_ISODfltIsGroup) {
+ TryCopyStr(tbuf,"group=",sz);
+ if (act->flags&XkbSA_GroupAbsolute)
+ sprintf(tbuf,"%d",XkbSAGroup(act)+1);
+ else if (XkbSAGroup(act)<0)
+ sprintf(tbuf,"%d",XkbSAGroup(act));
+ else sprintf(tbuf,"+%d",XkbSAGroup(act));
+ TryCopyStr(buf,tbuf,sz);
+ }
+ else {
+ unsigned tmp;
+ tmp= XkbModActionVMods(act);
+ TryCopyStr(buf,"modifiers=",sz);
+ if (act->flags&XkbSA_UseModMapMods)
+ TryCopyStr(buf,"modMapMods",sz);
+ else if (act->real_mods || tmp) {
+ if (act->real_mods) {
+ TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
+ if (tmp)
+ TryCopyStr(buf,"+",sz);
+ }
+ if (tmp)
+ TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz);
+ }
+ else TryCopyStr(buf,"none",sz);
+ }
+ TryCopyStr(buf,",affect=",sz);
+ if ((act->affect&XkbSA_ISOAffectMask)==0)
+ TryCopyStr(buf,"all",sz);
+ else {
+ int nOut= 0;
+ if ((act->affect&XkbSA_ISONoAffectMods)==0) {
+ TryCopyStr(buf,"mods",sz);
+ nOut++;
+ }
+ if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
+ sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
+ sprintf(tbuf,"%spointer",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
+ sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbSwitchScreenAction * act;
+char tbuf[32];
+
+ act= &action->screen;
+ if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
+ sprintf(tbuf,"screen=%d",XkbSAScreen(act));
+ else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
+ TryCopyStr(buf,tbuf,sz);
+ if (act->flags&XkbSA_SwitchApplication)
+ TryCopyStr(buf,",!same",sz);
+ else TryCopyStr(buf,",same",sz);
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,
+ char *buf,int *sz)
+{
+XkbCtrlsAction * act;
+unsigned tmp;
+char tbuf[32];
+
+ act= &action->ctrls;
+ tmp= XkbActionCtrls(act);
+ TryCopyStr(buf,"controls=",sz);
+ if (tmp==0)
+ TryCopyStr(buf,"none",sz);
+ else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
+ TryCopyStr(buf,"all",sz);
+ else {
+ int nOut= 0;
+ if (tmp&XkbRepeatKeysMask) {
+ sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbSlowKeysMask) {
+ sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbBounceKeysMask) {
+ sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbStickyKeysMask) {
+ sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbMouseKeysMask) {
+ sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbMouseKeysAccelMask) {
+ sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbAccessXKeysMask) {
+ sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbAccessXTimeoutMask) {
+ sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbAccessXFeedbackMask) {
+ sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbAudibleBellMask) {
+ sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbOverlay1Mask) {
+ sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbOverlay2Mask) {
+ sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ if (tmp&XkbIgnoreGroupLockMask) {
+ sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
+ TryCopyStr(buf,tbuf,sz);
+ nOut++;
+ }
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbMessageAction * act;
+unsigned all;
+char tbuf[32];
+
+ act= &action->msg;
+ all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
+ TryCopyStr(buf,"report=",sz);
+ if ((act->flags&all)==0)
+ TryCopyStr(buf,"none",sz);
+ else if ((act->flags&all)==all)
+ TryCopyStr(buf,"all",sz);
+ else if (act->flags&XkbSA_MessageOnPress)
+ TryCopyStr(buf,"KeyPress",sz);
+ else TryCopyStr(buf,"KeyRelease",sz);
+ sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
+ return True;
+}
+
+static Bool
+CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbRedirectKeyAction * act;
+char tbuf[32],*tmp;
+unsigned kc;
+unsigned vmods,vmods_mask;
+
+ act= &action->redirect;
+ kc= act->new_key;
+ vmods= XkbSARedirectVMods(act);
+ vmods_mask= XkbSARedirectVModsMask(act);
+ if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
+ (xkb->names->keys[kc].name[0]!='\0')) {
+ char *kn;
+ kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
+ sprintf(tbuf,"key=%s",kn);
+ }
+ else sprintf(tbuf,"key=%d",kc);
+ TryCopyStr(buf,tbuf,sz);
+ if ((act->mods_mask==0)&&(vmods_mask==0))
+ return True;
+ if ((act->mods_mask==XkbAllModifiersMask)&&
+ (vmods_mask==XkbAllVirtualModsMask)) {
+ tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile);
+ TryCopyStr(buf,",mods=",sz);
+ TryCopyStr(buf,tmp,sz);
+ }
+ else {
+ if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
+ tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods,
+ vmods_mask&vmods,XkbXKBFile);
+ TryCopyStr(buf,",mods= ",sz);
+ TryCopyStr(buf,tmp,sz);
+ }
+ if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
+ tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods),
+ vmods_mask&(~vmods),XkbXKBFile);
+ TryCopyStr(buf,",clearMods= ",sz);
+ TryCopyStr(buf,tmp,sz);
+ }
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+ int *sz)
+{
+XkbDeviceBtnAction * act;
+char tbuf[32];
+
+ act= &action->devbtn;
+ sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
+ TryCopyStr(buf,",button=",sz);
+ sprintf(tbuf,"%d",act->button);
+ TryCopyStr(buf,tbuf,sz);
+ if (act->count>0) {
+ sprintf(tbuf,",count=%d",act->count);
+ TryCopyStr(buf,tbuf,sz);
+ }
+ if (action->type==XkbSA_LockDeviceBtn) {
+ switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
+ case XkbSA_LockNoLock:
+ sprintf(tbuf,",affect=unlock"); break;
+ case XkbSA_LockNoUnlock:
+ sprintf(tbuf,",affect=lock"); break;
+ case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
+ sprintf(tbuf,",affect=neither"); break;
+ default:
+ sprintf(tbuf,",affect=both"); break;
+ }
+ TryCopyStr(buf,tbuf,sz);
+ }
+ return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbAnyAction * act;
+char tbuf[32];
+
+ act= &action->any;
+ sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
+ sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
+ return True;
+}
+
+typedef Bool (*actionCopy)(
+ Display * /* dpy */,
+ XkbDescPtr /* xkb */,
+ XkbAction * /* action */,
+ char * /* buf */,
+ int* /* sz */
+);
+static actionCopy copyActionArgs[XkbSA_NumActions] = {
+ CopyNoActionArgs /* NoAction */,
+ CopyModActionArgs /* SetMods */,
+ CopyModActionArgs /* LatchMods */,
+ CopyModActionArgs /* LockMods */,
+ CopyGroupActionArgs /* SetGroup */,
+ CopyGroupActionArgs /* LatchGroup */,
+ CopyGroupActionArgs /* LockGroup */,
+ CopyMovePtrArgs /* MovePtr */,
+ CopyPtrBtnArgs /* PtrBtn */,
+ CopyPtrBtnArgs /* LockPtrBtn */,
+ CopySetPtrDfltArgs /* SetPtrDflt */,
+ CopyISOLockArgs /* ISOLock */,
+ CopyNoActionArgs /* Terminate */,
+ CopySwitchScreenArgs /* SwitchScreen */,
+ CopySetLockControlsArgs /* SetControls */,
+ CopySetLockControlsArgs /* LockControls */,
+ CopyActionMessageArgs /* ActionMessage*/,
+ CopyRedirectKeyArgs /* RedirectKey */,
+ CopyDeviceBtnArgs /* DeviceBtn */,
+ CopyDeviceBtnArgs /* LockDeviceBtn*/
+};
+
+#define ACTION_SZ 256
+
+char *
+XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format)
+{
+char buf[ACTION_SZ],*tmp;
+int sz;
+
+ if (format==XkbCFile) {
+ sprintf(buf,
+ "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
+ XkbActionTypeText(action->type,XkbCFile),
+ action->any.data[0],action->any.data[1],action->any.data[2],
+ action->any.data[3],action->any.data[4],action->any.data[5],
+ action->any.data[6]);
+ }
+ else {
+ sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
+ sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
+ if (action->type<(unsigned)XkbSA_NumActions)
+ (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz);
+ else CopyOtherArgs(dpy,xkb,action,buf,&sz);
+ TryCopyStr(buf,")",&sz);
+ }
+ tmp= tbGetBuffer(strlen(buf)+1);
+ if (tmp!=NULL)
+ strcpy(tmp,buf);
+ return tmp;
+}
+
+char *
+XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
+{
+char buf[256],*tmp;
+
+ if (format==XkbCFile) {
+ if (behavior->type==XkbKB_Default)
+ sprintf(buf,"{ 0, 0 }");
+ else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
+ }
+ else {
+ unsigned type,permanent;
+ type= behavior->type&XkbKB_OpMask;
+ permanent=((behavior->type&XkbKB_Permanent)!=0);
+
+ if (type==XkbKB_Lock) {
+ sprintf(buf,"lock= %s",(permanent?"Permanent":"True"));
+ }
+ else if (type==XkbKB_RadioGroup) {
+ int g;
+ char *tmp;
+ g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
+ if (XkbKB_RGAllowNone&behavior->data) {
+ sprintf(buf,"allowNone,");
+ tmp= &buf[strlen(buf)];
+ }
+ else tmp= buf;
+ if (permanent)
+ sprintf(tmp,"permanentRadioGroup= %d",g);
+ else sprintf(tmp,"radioGroup= %d",g);
+ }
+ else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
+ int ndx,kc;
+ char *kn;
+
+ ndx= ((type==XkbKB_Overlay1)?1:2);
+ kc= behavior->data;
+ if ((xkb)&&(xkb->names)&&(xkb->names->keys))
+ kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
+ else {
+ static char tbuf[8];
+ sprintf(tbuf,"%d",kc);
+ kn= tbuf;
+ }
+ if (permanent)
+ sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
+ else sprintf(buf,"overlay%d= %s",ndx,kn);
+ }
+ }
+ tmp= tbGetBuffer(strlen(buf)+1);
+ if (tmp!=NULL)
+ strcpy(tmp,buf);
+ return tmp;
+}
+
+/***====================================================================***/
+
+char *
+XkbIndentText(unsigned size)
+{
+static char buf[32];
+register int i;
+
+ if (size>31)
+ size= 31;
+
+ for (i=0;i<size;i++) {
+ buf[i]= ' ';
+ }
+ buf[size]= '\0';
+ return buf;
+}
+
diff --git a/nx-X11/programs/Xserver/xkb/xkmread.c b/nx-X11/programs/Xserver/xkb/xkmread.c
new file mode 100644
index 000000000..71b65a4c0
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkmread.c
@@ -0,0 +1,1287 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ 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 name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS 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.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#elif defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <nx-X11/Xos.h>
+#include <nx-X11/Xfuncs.h>
+
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include <nx-X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xkbgeom.h"
+
+Atom
+XkbInternAtom(Display *dpy,char *str,Bool only_if_exists)
+{
+ if (str==NULL)
+ return None;
+ return MakeAtom(str,strlen(str),!only_if_exists);
+}
+
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+/***====================================================================***/
+
+static XPointer
+XkmInsureSize(XPointer oldPtr,int oldCount,int *newCountRtrn,int elemSize)
+{
+int newCount= *newCountRtrn;
+
+ if (oldPtr==NULL) {
+ if (newCount==0)
+ return NULL;
+ oldPtr= (XPointer)_XkbCalloc(newCount,elemSize);
+ }
+ else if (oldCount<newCount) {
+ oldPtr= (XPointer)_XkbRealloc(oldPtr,newCount*elemSize);
+ if (oldPtr!=NULL) {
+ char *tmp= (char *)oldPtr;
+ bzero(&tmp[oldCount*elemSize],(newCount-oldCount)*elemSize);
+ }
+ }
+ else if (newCount<oldCount) {
+ *newCountRtrn= oldCount;
+ }
+ return oldPtr;
+}
+
+#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
+
+static CARD8
+XkmGetCARD8(FILE *file,int *pNRead)
+{
+int tmp;
+ tmp= getc(file);
+ if (pNRead&&(tmp!=EOF))
+ (*pNRead)+= 1;
+ return tmp;
+}
+
+static CARD16
+XkmGetCARD16(FILE *file,int *pNRead)
+{
+CARD16 val;
+
+ if ((fread(&val,2,1,file)==1)&&(pNRead))
+ (*pNRead)+= 2;
+ return val;
+}
+
+static CARD32
+XkmGetCARD32(FILE *file,int *pNRead)
+{
+CARD32 val;
+
+ if ((fread(&val,4,1,file)==1)&&(pNRead))
+ (*pNRead)+= 4;
+ return val;
+}
+
+static int
+XkmSkipPadding(FILE *file,unsigned pad)
+{
+register int i,nRead=0;
+
+ for (i=0;i<pad;i++) {
+ if (getc(file)!=EOF)
+ nRead++;
+ }
+ return nRead;
+}
+
+static int
+XkmGetCountedString(FILE *file,char *str,int max_len)
+{
+int count,nRead=0;
+
+ count= XkmGetCARD16(file,&nRead);
+ if (count>0) {
+ int tmp;
+ if (count>max_len) {
+ tmp= fread(str,1,max_len,file);
+ while (tmp<count) {
+ if ((getc(file))!=EOF)
+ tmp++;
+ else break;
+ }
+ }
+ else {
+ tmp= fread(str,1,count,file);
+ }
+ nRead+= tmp;
+ }
+ if (count>=max_len) str[max_len-1]= '\0';
+ else str[count]= '\0';
+ count= XkbPaddedSize(nRead)-nRead;
+ if (count>0)
+ nRead+= XkmSkipPadding(file,count);
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmVirtualMods(FILE *file,XkbFileInfo *result,XkbChangesPtr changes)
+{
+register unsigned int i,bit;
+unsigned int bound,named,tmp;
+int nRead=0;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ bound= XkmGetCARD16(file,&nRead);
+ named= XkmGetCARD16(file,&nRead);
+ for (i=tmp=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bound&bit) {
+ xkb->server->vmods[i]= XkmGetCARD8(file,&nRead);
+ if (changes)
+ changes->map.vmods|= bit;
+ tmp++;
+ }
+ }
+ if ((i= XkbPaddedSize(tmp)-tmp)>0)
+ nRead+= XkmSkipPadding(file,i);
+ if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmVirtualMods",0);
+ return -1;
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ char name[100];
+ if (named&bit) {
+ if (nRead+=XkmGetCountedString(file,name,100)) {
+ xkb->names->vmods[i]= XkbInternAtom(xkb->dpy,name,False);
+ if (changes)
+ changes->names.changed_vmods|= bit;
+ }
+ }
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeycodes(FILE *file,XkbFileInfo *result,XkbChangesPtr changes)
+{
+register int i;
+unsigned minKC,maxKC,nAl;
+int nRead=0;
+char name[100];
+XkbKeyNamePtr pN;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ name[0]= '\0';
+ nRead+= XkmGetCountedString(file,name,100);
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ if (xkb->min_key_code==0) {
+ xkb->min_key_code= minKC;
+ xkb->max_key_code= maxKC;
+ }
+ else {
+ if (minKC<xkb->min_key_code)
+ xkb->min_key_code= minKC;
+ if (maxKC>xkb->max_key_code) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeycodes",maxKC);
+ return -1;
+ }
+ }
+ nAl= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+
+#define WANTED (XkbKeycodesNameMask|XkbKeyNamesMask|XkbKeyAliasesMask)
+ if (XkbAllocNames(xkb,WANTED,0,nAl)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ if (name[0]!='\0') {
+ xkb->names->keycodes= XkbInternAtom(xkb->dpy,name,False);
+ }
+
+ for (pN=&xkb->names->keys[minKC],i=minKC;i<=(int)maxKC;i++,pN++) {
+ if (fread(pN,1,XkbKeyNameLength,file)!=XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= XkbKeyNameLength;
+ }
+ if (nAl>0) {
+ XkbKeyAliasPtr pAl;
+ for (pAl= xkb->names->key_aliases,i=0;i<nAl;i++,pAl++) {
+ int tmp;
+ tmp= fread(pAl,1,2*XkbKeyNameLength,file);
+ if (tmp!=2*XkbKeyNameLength) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= 2*XkbKeyNameLength;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyAliasesMask;
+ }
+ if (changes)
+ changes->names.changed|= XkbKeyNamesMask;
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmKeyTypes(FILE *file,XkbFileInfo *result,XkbChangesPtr changes)
+{
+register unsigned i,n;
+unsigned num_types;
+int nRead=0;
+int tmp;
+XkbKeyTypePtr type;
+xkmKeyTypeDesc wire;
+XkbKTMapEntryPtr entry;
+xkmKTMapEntryDesc wire_entry;
+char buf[100];
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ if ((tmp= XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ xkb->names->types= XkbInternAtom(xkb->dpy,buf,False);
+ }
+ num_types= XkmGetCARD16(file,&nRead);
+ nRead+= XkmSkipPadding(file,2);
+ if (num_types<1)
+ return nRead;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_types)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeyTypes",0);
+ return nRead;
+ }
+ xkb->map->num_types= num_types;
+ if (num_types<XkbNumRequiredTypes) {
+ _XkbLibError(_XkbErrMissingReqTypes,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ type= xkb->map->types;
+ for (i=0;i<num_types;i++,type++) {
+ if ((int)fread(&wire,SIZEOF(xkmKeyTypeDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKeyTypeDesc);
+ if (((i==XkbOneLevelIndex)&&(wire.numLevels!=1))||
+ (((i==XkbTwoLevelIndex)||(i==XkbAlphabeticIndex)||
+ ((i)==XkbKeypadIndex))&&(wire.numLevels!=2))) {
+ _XkbLibError(_XkbErrBadTypeWidth,"ReadXkmKeyTypes",i);
+ return -1;
+ }
+ tmp= wire.nMapEntries;
+ XkmInsureTypedSize(type->map,type->map_count,&tmp,XkbKTMapEntryRec);
+ if ((wire.nMapEntries>0)&&(type->map==NULL)) {
+ _XkbLibError(_XkbErrBadValue,"ReadXkmKeyTypes",wire.nMapEntries);
+ return -1;
+ }
+ for (n=0,entry= type->map;n<wire.nMapEntries;n++,entry++) {
+ if (fread(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file)<(int)1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmKTMapEntryDesc);
+ entry->active= (wire_entry.virtualMods==0);
+ entry->level= wire_entry.level;
+ entry->mods.mask= wire_entry.realMods;
+ entry->mods.real_mods= wire_entry.realMods;
+ entry->mods.vmods= wire_entry.virtualMods;
+ }
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (((i==XkbOneLevelIndex)&&(strcmp(buf,"ONE_LEVEL")!=0))||
+ ((i==XkbTwoLevelIndex)&&(strcmp(buf,"TWO_LEVEL")!=0))||
+ ((i==XkbAlphabeticIndex)&&(strcmp(buf,"ALPHABETIC")!=0))||
+ ((i==XkbKeypadIndex)&&(strcmp(buf,"KEYPAD")!=0))) {
+ _XkbLibError(_XkbErrBadTypeName,"ReadXkmKeyTypes",0);
+ return -1;
+ }
+ if (buf[0]!='\0') {
+ type->name= XkbInternAtom(xkb->dpy,buf,False);
+ }
+ else type->name= None;
+
+ if (wire.preserve) {
+ xkmModsDesc p_entry;
+ XkbModsPtr pre;
+ XkmInsureTypedSize(type->preserve,type->map_count,&tmp,
+ XkbModsRec);
+ if (type->preserve==NULL) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ for (n=0,pre=type->preserve;n<wire.nMapEntries;n++,pre++) {
+ if (fread(&p_entry,SIZEOF(xkmModsDesc),1,file)<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ nRead+= SIZEOF(xkmModsDesc);
+ pre->mask= p_entry.realMods;
+ pre->real_mods= p_entry.realMods;
+ pre->vmods= p_entry.virtualMods;
+ }
+ }
+ if (wire.nLevelNames>0) {
+ int width= wire.numLevels;
+ if (wire.nLevelNames>(unsigned)width) {
+ _XkbLibError(_XkbErrBadMatch,"ReadXkmKeycodes",0);
+ return -1;
+ }
+ XkmInsureTypedSize(type->level_names,type->num_levels,&width,Atom);
+ if (type->level_names!=NULL) {
+ for (n=0;n<wire.nLevelNames;n++) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if (strlen(buf)==0)
+ type->level_names[n]= None;
+ else type->level_names[n]= XkbInternAtom(xkb->dpy,buf,0);
+ }
+ }
+ }
+ type->mods.mask= wire.realMods;
+ type->mods.real_mods= wire.realMods;
+ type->mods.vmods= wire.virtualMods;
+ type->num_levels= wire.numLevels;
+ type->map_count= wire.nMapEntries;
+ }
+ if (changes) {
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type= 0;
+ changes->map.num_types= xkb->map->num_types;
+ }
+ return nRead;
+}
+
+/***====================================================================***/
+
+static int
+ReadXkmCompatMap(FILE *file,XkbFileInfo *result,XkbChangesPtr changes)
+{
+register int i;
+unsigned num_si,groups;
+char name[100];
+XkbSymInterpretPtr interp;
+xkmSymInterpretDesc wire;
+unsigned tmp;
+int nRead=0;
+XkbDescPtr xkb;
+XkbCompatMapPtr compat;
+
+ xkb= result->xkb;
+ if ((tmp= XkmGetCountedString(file,name,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (name[0]!='\0') {
+ if (XkbAllocNames(xkb,XkbCompatNameMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmCompatMap",0);
+ return -1;
+ }
+ xkb->names->compat= XkbInternAtom(xkb->dpy,name,False);
+ }
+ num_si= XkmGetCARD16(file,&nRead);
+ groups= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,1);
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_si)!=Success)
+ return -1;
+ compat= xkb->compat;
+ compat->num_si= num_si;
+ interp= compat->sym_interpret;
+ for (i=0;i<num_si;i++,interp++) {
+ tmp= fread(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmSymInterpretDesc);
+ interp->sym= wire.sym;
+ interp->mods= wire.mods;
+ interp->match= wire.match;
+ interp->virtual_mod= wire.virtualMod;
+ interp->flags= wire.flags;
+ interp->act.type= wire.actionType;
+ interp->act.data[0]= wire.actionData[0];
+ interp->act.data[1]= wire.actionData[1];
+ interp->act.data[2]= wire.actionData[2];
+ interp->act.data[3]= wire.actionData[3];
+ interp->act.data[4]= wire.actionData[4];
+ interp->act.data[5]= wire.actionData[5];
+ interp->act.data[6]= wire.actionData[6];
+ }
+ if ((num_si>0)&&(changes)) {
+ changes->compat.first_si= 0;
+ changes->compat.num_si= num_si;
+ }
+ if (groups) {
+ register unsigned bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ xkmModsDesc md;
+ if (groups&bit) {
+ tmp= fread(&md,SIZEOF(xkmModsDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmModsDesc);
+ xkb->compat->groups[i].real_mods= md.realMods;
+ xkb->compat->groups[i].vmods= md.virtualMods;
+ if (md.virtualMods != 0) {
+ unsigned mask;
+ if (XkbVirtualModsToReal(xkb,md.virtualMods,&mask))
+ xkb->compat->groups[i].mask= md.realMods|mask;
+ }
+ else xkb->compat->groups[i].mask= md.realMods;
+ }
+ }
+ if (changes)
+ changes->compat.changed_groups|= groups;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmIndicators(FILE *file,XkbFileInfo *result,XkbChangesPtr changes)
+{
+register unsigned nLEDs;
+xkmIndicatorMapDesc wire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ if ((xkb->indicators==NULL)&&(XkbAllocIndicatorMaps(xkb)!=Success)) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator rec",0);
+ return -1;
+ }
+ if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"indicator names",0);
+ return -1;
+ }
+ nLEDs= XkmGetCARD8(file,&nRead);
+ nRead+= XkmSkipPadding(file,3);
+ xkb->indicators->phys_indicators= XkmGetCARD32(file,&nRead);
+ while (nLEDs-->0) {
+ Atom name;
+ XkbIndicatorMapPtr map;
+
+ if ((tmp=XkmGetCountedString(file,buf,100))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp;
+ if (buf[0]!='\0')
+ name= XkbInternAtom(xkb->dpy,buf,False);
+ else name= None;
+ if ((tmp=fread(&wire,SIZEOF(xkmIndicatorMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmIndicators",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmIndicatorMapDesc);
+ if (xkb->names) {
+ xkb->names->indicators[wire.indicator-1]= name;
+ if (changes)
+ changes->names.changed_indicators|= (1<<(wire.indicator-1));
+ }
+ map= &xkb->indicators->maps[wire.indicator-1];
+ map->flags= wire.flags;
+ map->which_groups= wire.which_groups;
+ map->groups= wire.groups;
+ map->which_mods= wire.which_mods;
+ map->mods.mask= wire.real_mods;
+ map->mods.real_mods= wire.real_mods;
+ map->mods.vmods= wire.vmods;
+ map->ctrls= wire.ctrls;
+ }
+ return nRead;
+}
+
+static XkbKeyTypePtr
+FindTypeForKey(XkbDescPtr xkb,Atom name,unsigned width,KeySym *syms)
+{
+ if ((!xkb)||(!xkb->map))
+ return NULL;
+ if (name!=None) {
+ register unsigned i;
+ for (i=0;i<xkb->map->num_types;i++) {
+ if (xkb->map->types[i].name==name) {
+#ifdef DEBUG
+ if (xkb->map->types[i].num_levels!=width)
+ fprintf(stderr,"Group width mismatch between key and type\n");
+#endif
+ return &xkb->map->types[i];
+ }
+ }
+ }
+ if ((width<2)||((syms!=NULL)&&(syms[1]==NoSymbol)))
+ return &xkb->map->types[XkbOneLevelIndex];
+ if (syms!=NULL) {
+ if (XkbKSIsLower(syms[0])&&XkbKSIsUpper(syms[1]))
+ return &xkb->map->types[XkbAlphabeticIndex];
+ else if (XkbKSIsKeypad(syms[0])||XkbKSIsKeypad(syms[1]))
+ return &xkb->map->types[XkbKeypadIndex];
+ }
+ return &xkb->map->types[XkbTwoLevelIndex];
+}
+
+static int
+ReadXkmSymbols(FILE *file,XkbFileInfo *result)
+{
+register int i,g,s,totalVModMaps;
+xkmKeySymMapDesc wireMap;
+char buf[100];
+unsigned minKC,maxKC,groupNames,tmp;
+int nRead=0;
+XkbDescPtr xkb;
+
+ xkb= result->xkb;
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ minKC= XkmGetCARD8(file,&nRead);
+ maxKC= XkmGetCARD8(file,&nRead);
+ groupNames= XkmGetCARD8(file,&nRead);
+ totalVModMaps= XkmGetCARD8(file,&nRead);
+ if (XkbAllocNames(xkb,
+ XkbSymbolsNameMask|XkbPhysSymbolsNameMask|XkbGroupNamesMask,
+ 0,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"physical names",0);
+ return -1;
+ }
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(xkb->dpy,buf,0);
+ xkb->names->symbols= name;
+ xkb->names->phys_symbols= name;
+ }
+ for (i=0,g=1;i<XkbNumKbdGroups;i++,g<<=1) {
+ if (groupNames&g) {
+ if ((tmp=XkmGetCountedString(file,buf,100))<1)
+ return -1;
+ nRead+= tmp;
+ if ((buf[0]!='\0')&&(xkb->names)) {
+ Atom name;
+ name= XkbInternAtom(xkb->dpy,buf,0);
+ xkb->names->groups[i]= name;
+ }
+ else xkb->names->groups[i]= None;
+ }
+ }
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"server map",0);
+ return -1;
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"client map",0);
+ return -1;
+ }
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"controls",0);
+ return -1;
+ }
+ if ((xkb->map==NULL)||(xkb->server==NULL))
+ return -1;
+ if (xkb->min_key_code<8) xkb->min_key_code= minKC;
+ if (xkb->max_key_code<8) xkb->max_key_code= maxKC;
+ if ((minKC>=8)&&(minKC<xkb->min_key_code))
+ xkb->min_key_code= minKC;
+ if ((maxKC>=8)&&(maxKC>xkb->max_key_code)) {
+ _XkbLibError(_XkbErrBadValue,"keys in symbol map",maxKC);
+ return -1;
+ }
+ for (i=minKC;i<=(int)maxKC;i++) {
+ Atom typeName[XkbNumKbdGroups];
+ XkbKeyTypePtr type[XkbNumKbdGroups];
+ if ((tmp=fread(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file))<1) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmSymbols",0);
+ return -1;
+ }
+ nRead+= tmp*SIZEOF(xkmKeySymMapDesc);
+ bzero((char *)typeName,XkbNumKbdGroups*sizeof(Atom));
+ bzero((char *)type,XkbNumKbdGroups*sizeof(XkbKeyTypePtr));
+ if (wireMap.flags&XkmKeyHasTypes) {
+ register int g;
+ for (g=0;g<XkbNumKbdGroups;g++) {
+ if ((wireMap.flags&(1<<g))&&
+ ((tmp=XkmGetCountedString(file,buf,100))>0)) {
+ typeName[g]= XkbInternAtom(xkb->dpy,buf,1);
+ nRead+= tmp;
+ }
+ type[g]=FindTypeForKey(xkb,typeName[g],wireMap.width,NULL);
+ if (type[g]==NULL) {
+ _XkbLibError(_XkbErrMissingTypes,"ReadXkmSymbols",0);
+ return -1;
+ }
+ if (typeName[g]==type[g]->name)
+ xkb->server->explicit[i]|= (1<<g);
+ }
+ }
+ if (wireMap.flags&XkmRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]|= (1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ else if (wireMap.flags&XkmNonRepeatingKey) {
+ xkb->ctrls->per_key_repeat[i/8]&= ~(1<<(i%8));
+ xkb->server->explicit[i]|= XkbExplicitAutoRepeatMask;
+ }
+ xkb->map->modmap[i]= wireMap.modifier_map;
+ if (XkbNumGroups(wireMap.num_groups)>0) {
+ KeySym *sym;
+ int nSyms;
+
+ if (XkbNumGroups(wireMap.num_groups)>xkb->ctrls->num_groups)
+ xkb->ctrls->num_groups= wireMap.num_groups;
+ nSyms= XkbNumGroups(wireMap.num_groups)*wireMap.width;
+ sym= XkbResizeKeySyms(xkb,i,nSyms);
+ if (!sym)
+ return -1;
+ for (s=0;s<nSyms;s++) {
+ *sym++= XkmGetCARD32(file,&nRead);
+ }
+ if (wireMap.flags&XkmKeyHasActions) {
+ XkbAction * act;
+ act= XkbResizeKeyActions(xkb,i,nSyms);
+ for (s=0;s<nSyms;s++,act++) {
+ tmp=fread(act,SIZEOF(xkmActionDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmActionDesc);
+ }
+ xkb->server->explicit[i]|= XkbExplicitInterpretMask;
+ }
+ }
+ for (g=0;g<XkbNumGroups(wireMap.num_groups);g++) {
+ if (((xkb->server->explicit[i]&(1<<g))==0)||(type[g]==NULL)) {
+ KeySym *tmpSyms;
+ tmpSyms= XkbKeySymsPtr(xkb,i)+(wireMap.width*g);
+ type[g]= FindTypeForKey(xkb,None,wireMap.width,tmpSyms);
+ }
+ xkb->map->key_sym_map[i].kt_index[g]= type[g]-(&xkb->map->types[0]);
+ }
+ xkb->map->key_sym_map[i].group_info= wireMap.num_groups;
+ xkb->map->key_sym_map[i].width= wireMap.width;
+ if (wireMap.flags&XkmKeyHasBehavior) {
+ xkmBehaviorDesc b;
+ tmp= fread(&b,SIZEOF(xkmBehaviorDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmBehaviorDesc);
+ xkb->server->behaviors[i].type= b.type;
+ xkb->server->behaviors[i].data= b.data;
+ xkb->server->explicit[i]|= XkbExplicitBehaviorMask;
+ }
+ }
+ if (totalVModMaps>0) {
+ xkmVModMapDesc v;
+ for (i=0;i<totalVModMaps;i++) {
+ tmp= fread(&v,SIZEOF(xkmVModMapDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmVModMapDesc);
+ if (tmp>0)
+ xkb->server->vmodmap[v.key]= v.vmods;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomDoodad(
+ FILE * file,
+ Display * dpy,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+XkbDoodadPtr doodad;
+xkmDoodadDesc doodadWire;
+char buf[100];
+unsigned tmp;
+int nRead=0;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
+ nRead+= SIZEOF(xkmDoodadDesc)*tmp;
+ doodad= XkbAddGeomDoodad(geom,section,XkbInternAtom(dpy,buf,False));
+ if (!doodad)
+ return nRead;
+ doodad->any.type= doodadWire.any.type;
+ doodad->any.priority= doodadWire.any.priority;
+ doodad->any.top= doodadWire.any.top;
+ doodad->any.left= doodadWire.any.left;
+ switch (doodadWire.any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodad->shape.angle= doodadWire.shape.angle;
+ doodad->shape.color_ndx= doodadWire.shape.color_ndx;
+ doodad->shape.shape_ndx= doodadWire.shape.shape_ndx;
+ break;
+ case XkbTextDoodad:
+ doodad->text.angle= doodadWire.text.angle;
+ doodad->text.width= doodadWire.text.width;
+ doodad->text.height= doodadWire.text.height;
+ doodad->text.color_ndx= doodadWire.text.color_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.text= Xstrdup(buf);
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->text.font= Xstrdup(buf);
+ break;
+ case XkbIndicatorDoodad:
+ doodad->indicator.shape_ndx= doodadWire.indicator.shape_ndx;
+ doodad->indicator.on_color_ndx= doodadWire.indicator.on_color_ndx;
+ doodad->indicator.off_color_ndx= doodadWire.indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodad->logo.angle= doodadWire.logo.angle;
+ doodad->logo.color_ndx= doodadWire.logo.color_ndx;
+ doodad->logo.shape_ndx= doodadWire.logo.shape_ndx;
+ nRead+= XkmGetCountedString(file,buf,100);
+ doodad->logo.logo_name= Xstrdup(buf);
+ break;
+ default:
+ /* report error? */
+ return nRead;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomOverlay( FILE * file,
+ Display * dpy,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section)
+{
+char buf[100];
+unsigned tmp;
+int nRead=0;
+XkbOverlayPtr ol;
+XkbOverlayRowPtr row;
+xkmOverlayDesc olWire;
+xkmOverlayRowDesc rowWire;
+register int r;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&olWire,SIZEOF(xkmOverlayDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayDesc);
+ ol= XkbAddGeomOverlay(section,XkbInternAtom(dpy,buf,False),
+ olWire.num_rows);
+ if (!ol)
+ return nRead;
+ for (r=0;r<olWire.num_rows;r++) {
+ int k;
+ xkmOverlayKeyDesc keyWire;
+ tmp= fread(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayRowDesc);
+ row= XkbAddGeomOverlayRow(ol,rowWire.row_under,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomOverlay",0);
+ return nRead;
+ }
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOverlayKeyDesc);
+ memcpy(row->keys[k].over.name,keyWire.over,XkbKeyNameLength);
+ memcpy(row->keys[k].under.name,keyWire.under,XkbKeyNameLength);
+ }
+ row->num_keys= rowWire.num_keys;
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeomSection( FILE * file,
+ Display * dpy,
+ XkbGeometryPtr geom)
+{
+register int i;
+XkbSectionPtr section;
+xkmSectionDesc sectionWire;
+unsigned tmp;
+int nRead= 0;
+char buf[100];
+Atom nameAtom;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(dpy,buf,False);
+ tmp= fread(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
+ nRead+= SIZEOF(xkmSectionDesc)*tmp;
+ section= XkbAddGeomSection(geom,nameAtom,sectionWire.num_rows,
+ sectionWire.num_doodads,
+ sectionWire.num_overlays);
+ if (!section) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ section->top= sectionWire.top;
+ section->left= sectionWire.left;
+ section->width= sectionWire.width;
+ section->height= sectionWire.height;
+ section->angle= sectionWire.angle;
+ section->priority= sectionWire.priority;
+ if (sectionWire.num_rows>0) {
+ register int k;
+ XkbRowPtr row;
+ xkmRowDesc rowWire;
+ XkbKeyPtr key;
+ xkmKeyDesc keyWire;
+
+ for (i=0;i<sectionWire.num_rows;i++) {
+ tmp= fread(&rowWire,SIZEOF(xkmRowDesc),1,file);
+ nRead+= SIZEOF(xkmRowDesc)*tmp;
+ row= XkbAddGeomRow(section,rowWire.num_keys);
+ if (!row) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmKeycodes",0);
+ return nRead;
+ }
+ row->top= rowWire.top;
+ row->left= rowWire.left;
+ row->vertical= rowWire.vertical;
+ for (k=0;k<rowWire.num_keys;k++) {
+ tmp= fread(&keyWire,SIZEOF(xkmKeyDesc),1,file);
+ nRead+= SIZEOF(xkmKeyDesc)*tmp;
+ key= XkbAddGeomKey(row);
+ if (!key) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeomSection",0);
+ return nRead;
+ }
+ memcpy(key->name.name,keyWire.name,XkbKeyNameLength);
+ key->gap= keyWire.gap;
+ key->shape_ndx= keyWire.shape_ndx;
+ key->color_ndx= keyWire.color_ndx;
+ }
+ }
+ }
+ if (sectionWire.num_doodads>0) {
+ for (i=0;i<sectionWire.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,dpy,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ if (sectionWire.num_overlays>0) {
+ for (i=0;i<sectionWire.num_overlays;i++) {
+ tmp= ReadXkmGeomOverlay(file,dpy,geom,section);
+ nRead+= tmp;
+ if (tmp<1)
+ return nRead;
+ }
+ }
+ return nRead;
+}
+
+static int
+ReadXkmGeometry(FILE *file,XkbFileInfo *result)
+{
+register int i;
+char buf[100];
+unsigned tmp;
+int nRead= 0;
+xkmGeometryDesc wireGeom;
+XkbGeometryPtr geom;
+XkbGeometrySizesRec sizes;
+
+ nRead+= XkmGetCountedString(file,buf,100);
+ tmp= fread(&wireGeom,SIZEOF(xkmGeometryDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmGeometryDesc);
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= wireGeom.num_properties;
+ sizes.num_colors= wireGeom.num_colors;
+ sizes.num_shapes= wireGeom.num_shapes;
+ sizes.num_sections= wireGeom.num_sections;
+ sizes.num_doodads= wireGeom.num_doodads;
+ sizes.num_key_aliases= wireGeom.num_key_aliases;
+ if (XkbAllocGeometry(result->xkb,&sizes)!=Success) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ geom= result->xkb->geom;
+ geom->name= XkbInternAtom(result->xkb->dpy,buf,False);
+ geom->width_mm= wireGeom.width_mm;
+ geom->height_mm= wireGeom.height_mm;
+ nRead+= XkmGetCountedString(file,buf,100);
+ geom->label_font= Xstrdup(buf);
+ if (wireGeom.num_properties>0) {
+ char val[1024];
+ for (i=0;i<wireGeom.num_properties;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ nRead+= XkmGetCountedString(file,val,1024);
+ if (XkbAddGeomProperty(geom,buf,val)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ if (wireGeom.num_colors>0) {
+ for (i=0;i<wireGeom.num_colors;i++) {
+ nRead+= XkmGetCountedString(file,buf,100);
+ if (XkbAddGeomColor(geom,buf,i)==NULL) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ }
+ }
+ geom->base_color= &geom->colors[wireGeom.base_color_ndx];
+ geom->label_color= &geom->colors[wireGeom.label_color_ndx];
+ if (wireGeom.num_shapes>0) {
+ XkbShapePtr shape;
+ xkmShapeDesc shapeWire;
+ Atom nameAtom;
+ for (i=0;i<wireGeom.num_shapes;i++) {
+ register int n;
+ XkbOutlinePtr ol;
+ xkmOutlineDesc olWire;
+ nRead+= XkmGetCountedString(file,buf,100);
+ nameAtom= XkbInternAtom(result->xkb->dpy,buf,False);
+ tmp= fread(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmShapeDesc);
+ shape= XkbAddGeomShape(geom,nameAtom,shapeWire.num_outlines);
+ if (!shape) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ for (n=0;n<shapeWire.num_outlines;n++) {
+ register int p;
+ xkmPointDesc ptWire;
+ tmp= fread(&olWire,SIZEOF(xkmOutlineDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmOutlineDesc);
+ ol= XkbAddGeomOutline(shape,olWire.num_points);
+ if (!ol) {
+ _XkbLibError(_XkbErrBadAlloc,"ReadXkmGeometry",0);
+ return nRead;
+ }
+ ol->num_points= olWire.num_points;
+ ol->corner_radius= olWire.corner_radius;
+ for (p=0;p<olWire.num_points;p++) {
+ tmp= fread(&ptWire,SIZEOF(xkmPointDesc),1,file);
+ nRead+= tmp*SIZEOF(xkmPointDesc);
+ ol->points[p].x= ptWire.x;
+ ol->points[p].y= ptWire.y;
+ if (ptWire.x<shape->bounds.x1) shape->bounds.x1= ptWire.x;
+ if (ptWire.x>shape->bounds.x2) shape->bounds.x2= ptWire.x;
+ if (ptWire.y<shape->bounds.y1) shape->bounds.y1= ptWire.y;
+ if (ptWire.y>shape->bounds.y2) shape->bounds.y2= ptWire.y;
+ }
+ }
+ if (shapeWire.primary_ndx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire.primary_ndx];
+ if (shapeWire.approx_ndx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire.approx_ndx];
+ }
+ }
+ if (wireGeom.num_sections>0) {
+ for (i=0;i<wireGeom.num_sections;i++) {
+ tmp= ReadXkmGeomSection(file,result->xkb->dpy,geom);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if (wireGeom.num_doodads>0) {
+ for (i=0;i<wireGeom.num_doodads;i++) {
+ tmp= ReadXkmGeomDoodad(file,result->xkb->dpy,geom,NULL);
+ nRead+= tmp;
+ if (tmp==0)
+ return nRead;
+ }
+ }
+ if ((wireGeom.num_key_aliases>0)&&(geom->key_aliases)) {
+ int sz= XkbKeyNameLength*2;
+ int num= wireGeom.num_key_aliases;
+ if (fread(geom->key_aliases,sz,num,file)!=num) {
+ _XkbLibError(_XkbErrBadLength,"ReadXkmGeometry",0);
+ return -1;
+ }
+ nRead+= (num*sz);
+ geom->num_key_aliases= num;
+ }
+ return nRead;
+}
+
+Bool
+XkmProbe(FILE *file)
+{
+unsigned hdr,tmp;
+int nRead=0;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmProbe",tmp&0xff);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+Bool
+XkmReadTOC(FILE *file,xkmFileInfo* file_info,int max_toc,xkmSectionInfo *toc)
+{
+unsigned hdr,tmp;
+int nRead=0;
+unsigned i,size_toc;
+
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ tmp= XkmGetCARD32(file,&nRead);
+ if (tmp!=hdr) {
+ if ((tmp&(~0xff))==(hdr&(~0xff))) {
+ _XkbLibError(_XkbErrBadFileVersion,"XkmReadTOC",tmp&0xff);
+ }
+ else {
+ _XkbLibError(_XkbErrBadFileType,"XkmReadTOC",tmp);
+ }
+ return 0;
+ }
+ _X_UNUSED int ignored_result;
+ ignored_result = fread(file_info,SIZEOF(xkmFileInfo),1,file);
+ size_toc= file_info->num_toc;
+ if (size_toc>max_toc) {
+#ifdef DEBUG
+ fprintf(stderr,"Warning! Too many TOC entries; last %d ignored\n",
+ size_toc-max_toc);
+#endif
+ size_toc= max_toc;
+ }
+ for (i=0;i<size_toc;i++) {
+ ignored_result = fread(&toc[i],SIZEOF(xkmSectionInfo),1,file);
+ }
+ return 1;
+}
+
+xkmSectionInfo *
+XkmFindTOCEntry(xkmFileInfo *finfo,xkmSectionInfo *toc,unsigned type)
+{
+register int i;
+
+ for (i=0;i<finfo->num_toc;i++) {
+ if (toc[i].type==type)
+ return &toc[i];
+ }
+ return NULL;
+}
+
+Bool
+XkmReadFileSection( FILE * file,
+ xkmSectionInfo * toc,
+ XkbFileInfo * result,
+ unsigned * loaded_rtrn)
+{
+xkmSectionInfo tmpTOC;
+int nRead;
+
+ if ((!result)||(!result->xkb)) {
+ _XkbLibError(_XkbErrBadMatch,"XkmReadFileSection",0);
+ return 0;
+ }
+ fseek(file,toc->offset,SEEK_SET);
+ _X_UNUSED int ignored_result;
+ ignored_result = fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
+ nRead= SIZEOF(xkmSectionInfo);
+ if ((tmpTOC.type!=toc->type)||(tmpTOC.format!=toc->format)||
+ (tmpTOC.size!=toc->size)||(tmpTOC.offset!=toc->offset)) {
+ _XkbLibError(_XkbErrIllegalContents,"XkmReadFileSection",0);
+ return 0;
+ }
+ switch (tmpTOC.type) {
+ case XkmVirtualModsIndex:
+ nRead+= ReadXkmVirtualMods(file,result,NULL);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmVirtualModsMask;
+ break;
+ case XkmTypesIndex:
+ nRead+= ReadXkmKeyTypes(file,result,NULL);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmTypesMask;
+ break;
+ case XkmCompatMapIndex:
+ nRead+= ReadXkmCompatMap(file,result,NULL);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmCompatMapMask;
+ break;
+ case XkmKeyNamesIndex:
+ nRead+= ReadXkmKeycodes(file,result,NULL);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmKeyNamesMask;
+ break;
+ case XkmSymbolsIndex:
+ nRead+= ReadXkmSymbols(file,result);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmSymbolsMask;
+ break;
+ case XkmIndicatorsIndex:
+ nRead+= ReadXkmIndicators(file,result,NULL);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmIndicatorsMask;
+ break;
+ case XkmGeometryIndex:
+ nRead+= ReadXkmGeometry(file,result);
+ if ((loaded_rtrn)&&(nRead>=0))
+ *loaded_rtrn|= XkmGeometryMask;
+ break;
+ default:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(tmpTOC.type,XkbMessage),0);
+ nRead= 0;
+ break;
+ }
+ if (nRead!=tmpTOC.size) {
+ _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+ nRead-tmpTOC.size);
+ return 0;
+ }
+ return (nRead>=0);
+}
+
+char *
+XkmReadFileSectionName(FILE *file,xkmSectionInfo *toc)
+{
+xkmSectionInfo tmpTOC;
+char name[100];
+
+ if ((!file)||(!toc))
+ return 0;
+ switch (toc->type) {
+ case XkmVirtualModsIndex:
+ case XkmIndicatorsIndex:
+ break;
+ case XkmTypesIndex:
+ case XkmCompatMapIndex:
+ case XkmKeyNamesIndex:
+ case XkmSymbolsIndex:
+ case XkmGeometryIndex:
+ fseek(file,toc->offset,SEEK_SET);
+ _X_UNUSED int ignored_result;
+ ignored_result = fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
+ if ((tmpTOC.type!=toc->type)||(tmpTOC.format!=toc->format)||
+ (tmpTOC.size!=toc->size)||(tmpTOC.offset!=toc->offset)) {
+ _XkbLibError(_XkbErrIllegalContents,"XkmReadFileSectionName",0);
+ return 0;
+ }
+ if (XkmGetCountedString(file,name,100)>0)
+ return Xstrdup(name);
+ break;
+ default:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(tmpTOC.type,XkbMessage),0);
+ break;
+ }
+ return NULL;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+unsigned
+XkmReadFile(FILE *file,unsigned need,unsigned want,XkbFileInfo *result)
+{
+register unsigned i;
+xkmSectionInfo toc[MAX_TOC],tmpTOC;
+xkmFileInfo fileInfo;
+unsigned tmp,nRead=0;
+unsigned which= need|want;
+
+ if (!XkmReadTOC(file,&fileInfo,MAX_TOC,toc))
+ return which;
+ if ((fileInfo.present&need)!=need) {
+ _XkbLibError(_XkbErrIllegalContents,"XkmReadFile",
+ need&(~fileInfo.present));
+ return which;
+ }
+ result->type= fileInfo.type;
+ if (result->xkb==NULL)
+ result->xkb= XkbAllocKeyboard();
+ for (i=0;i<fileInfo.num_toc;i++) {
+#ifdef SEEK_SET
+ fseek(file,toc[i].offset,SEEK_SET);
+#else
+ fseek(file,toc[i].offset,0);
+#endif
+ tmp= fread(&tmpTOC,SIZEOF(xkmSectionInfo),1,file);
+ nRead= tmp*SIZEOF(xkmSectionInfo);
+ if ((tmpTOC.type!=toc[i].type)||(tmpTOC.format!=toc[i].format)||
+ (tmpTOC.size!=toc[i].size)||(tmpTOC.offset!=toc[i].offset)) {
+ return which;
+ }
+ if ((which&(1<<tmpTOC.type))==0) {
+ continue;
+ }
+ switch (tmpTOC.type) {
+ case XkmVirtualModsIndex:
+ tmp= ReadXkmVirtualMods(file,result,NULL);
+ break;
+ case XkmTypesIndex:
+ tmp= ReadXkmKeyTypes(file,result,NULL);
+ break;
+ case XkmCompatMapIndex:
+ tmp= ReadXkmCompatMap(file,result,NULL);
+ break;
+ case XkmKeyNamesIndex:
+ tmp= ReadXkmKeycodes(file,result,NULL);
+ break;
+ case XkmIndicatorsIndex:
+ tmp= ReadXkmIndicators(file,result,NULL);
+ break;
+ case XkmSymbolsIndex:
+ tmp= ReadXkmSymbols(file,result);
+ break;
+ case XkmGeometryIndex:
+ tmp= ReadXkmGeometry(file,result);
+ break;
+ default:
+ _XkbLibError(_XkbErrBadImplementation,
+ XkbConfigText(tmpTOC.type,XkbMessage),0);
+ tmp= 0;
+ break;
+ }
+ if (tmp>0) {
+ nRead+= tmp;
+ which&= ~(1<<toc[i].type);
+ result->defined|= (1<<toc[i].type);
+ }
+ if (nRead!=tmpTOC.size) {
+ _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+ nRead-tmpTOC.size);
+ }
+ }
+ return which;
+}